main.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. // Copyright 2018-present the CoreDHCP Authors. All rights reserved
  2. // This source code is licensed under the MIT license found in the
  3. // LICENSE file in the root directory of this source tree.
  4. package main
  5. import (
  6. "bufio"
  7. "flag"
  8. "fmt"
  9. "html/template"
  10. "io/ioutil"
  11. "log"
  12. "os"
  13. "path"
  14. "strings"
  15. )
  16. const (
  17. defaultTemplateFile = "coredhcp.go.template"
  18. )
  19. var (
  20. flagTemplate = flag.String("template", defaultTemplateFile, "Template file name")
  21. flagOutfile = flag.String("outfile", "", "Output file path")
  22. flagFromFile = flag.String("from", "", "Optional file name to get the plugin list from, one import path per line")
  23. )
  24. var funcMap = template.FuncMap{
  25. "importname": func(importPath string) (string, error) {
  26. parts := strings.Split(importPath, "/")
  27. if len(parts) < 1 {
  28. return "", fmt.Errorf("no components found in import path '%s'", importPath)
  29. }
  30. return parts[len(parts)-1], nil
  31. },
  32. }
  33. func main() {
  34. flag.Parse()
  35. data, err := ioutil.ReadFile(*flagTemplate)
  36. if err != nil {
  37. log.Fatalf("Failed to read template file '%s': %v", *flagTemplate, err)
  38. }
  39. t, err := template.New("coredhcp").Funcs(funcMap).Parse(string(data))
  40. if err != nil {
  41. log.Fatalf("Template parsing failed: %v", err)
  42. }
  43. plugins := make(map[string]bool)
  44. for _, pl := range flag.Args() {
  45. pl := strings.TrimSpace(pl)
  46. if pl == "" {
  47. continue
  48. }
  49. plugins[pl] = true
  50. }
  51. if *flagFromFile != "" {
  52. // additional plugin names from a text file, one line per plugin import
  53. // path
  54. fd, err := os.Open(*flagFromFile)
  55. if err != nil {
  56. log.Fatalf("Failed to read file '%s': %v", *flagFromFile, err)
  57. }
  58. defer func() {
  59. if err := fd.Close(); err != nil {
  60. log.Printf("Error closing file '%s': %v", *flagFromFile, err)
  61. }
  62. }()
  63. sc := bufio.NewScanner(fd)
  64. for sc.Scan() {
  65. pl := strings.TrimSpace(sc.Text())
  66. if pl == "" {
  67. continue
  68. }
  69. plugins[pl] = true
  70. }
  71. if err := sc.Err(); err != nil {
  72. log.Fatalf("Error reading file '%s': %v", *flagFromFile, err)
  73. }
  74. }
  75. if len(plugins) == 0 {
  76. log.Fatalf("No plugin specified!")
  77. }
  78. outfile := *flagOutfile
  79. if outfile == "" {
  80. tmpdir, err := ioutil.TempDir("", "coredhcp")
  81. if err != nil {
  82. log.Fatalf("Cannot create temporary directory: %v", err)
  83. }
  84. outfile = path.Join(tmpdir, "coredhcp.go")
  85. }
  86. log.Printf("Generating output file '%s' with %d plugin(s):", outfile, len(plugins))
  87. idx := 1
  88. for pl := range plugins {
  89. log.Printf("% 3d) %s", idx, pl)
  90. idx++
  91. }
  92. outFD, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, 0644)
  93. if err != nil {
  94. log.Fatalf("Failed to create output file '%s': %v", outfile, err)
  95. }
  96. defer func() {
  97. if err := outFD.Close(); err != nil {
  98. log.Printf("Error while closing file descriptor for '%s': %v", outfile, err)
  99. }
  100. }()
  101. // WARNING: no escaping of the provided strings is done
  102. pluginList := make([]string, 0, len(plugins))
  103. for pl := range plugins {
  104. pluginList = append(pluginList, pl)
  105. }
  106. if err := t.Execute(outFD, pluginList); err != nil {
  107. log.Fatalf("Template execution failed: %v", err)
  108. }
  109. log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)
  110. }