main.go 2.8 KB

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