add all files from Hong
This commit is contained in:
144
cmds/coredhcp-generator/main.go
Normal file
144
cmds/coredhcp-generator/main.go
Normal file
@@ -0,0 +1,144 @@
|
||||
// Copyright 2018-present the CoreDHCP Authors. All rights reserved
|
||||
// This source code is licensed under the MIT license found in the
|
||||
// LICENSE file in the root directory of this source tree.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultTemplateFile = "coredhcp.go.template"
|
||||
importBase = "github.com/coredhcp/coredhcp/"
|
||||
)
|
||||
|
||||
var (
|
||||
flagTemplate = flag.StringP("template", "t", defaultTemplateFile, "Template file name")
|
||||
flagOutfile = flag.StringP("outfile", "o", "", "Output file path")
|
||||
flagFromFile = flag.StringP("from", "f", "", "Optional file name to get the plugin list from, one import path per line")
|
||||
)
|
||||
|
||||
var funcMap = template.FuncMap{
|
||||
"importname": func(importPath string) (string, error) {
|
||||
parts := strings.Split(importPath, "/")
|
||||
if len(parts) < 1 {
|
||||
return "", fmt.Errorf("no components found in import path '%s'", importPath)
|
||||
}
|
||||
return "pl_" + parts[len(parts)-1], nil
|
||||
},
|
||||
}
|
||||
|
||||
func usage() {
|
||||
fmt.Fprintf(flag.CommandLine.Output(),
|
||||
"%s [-template tpl] [-outfile out] [-from pluginlist] [plugin [plugin...]]\n",
|
||||
os.Args[0],
|
||||
)
|
||||
flag.PrintDefaults()
|
||||
fmt.Fprintln(flag.CommandLine.Output(), ` plugin
|
||||
Plugin name to include, as go import path.
|
||||
Short names can be used for builtin coredhcp plugins (eg "serverid")`)
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Usage = usage
|
||||
flag.Parse()
|
||||
|
||||
data, err := os.ReadFile(*flagTemplate)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read template file '%s': %v", *flagTemplate, err)
|
||||
}
|
||||
t, err := template.New("coredhcp").Funcs(funcMap).Parse(string(data))
|
||||
if err != nil {
|
||||
log.Fatalf("Template parsing failed: %v", err)
|
||||
}
|
||||
plugins := make(map[string]bool)
|
||||
for _, pl := range flag.Args() {
|
||||
pl := strings.TrimSpace(pl)
|
||||
if pl == "" {
|
||||
continue
|
||||
}
|
||||
if !strings.ContainsRune(pl, '/') {
|
||||
// A bare name was specified, not a full import path.
|
||||
// Coredhcp plugins aren't in the standard library, and it's unlikely someone
|
||||
// would put them at the base of $GOPATH/src.
|
||||
// Assume this is one of the builtin plugins. If needed, use the -from option
|
||||
// which always requires (and uses) exact paths
|
||||
|
||||
// XXX: we could also look into github.com/coredhcp/plugins
|
||||
pl = importBase + pl
|
||||
}
|
||||
plugins[pl] = true
|
||||
}
|
||||
if *flagFromFile != "" {
|
||||
// additional plugin names from a text file, one line per plugin import
|
||||
// path
|
||||
fd, err := os.Open(*flagFromFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to read file '%s': %v", *flagFromFile, err)
|
||||
}
|
||||
defer func() {
|
||||
if err := fd.Close(); err != nil {
|
||||
log.Printf("Error closing file '%s': %v", *flagFromFile, err)
|
||||
}
|
||||
}()
|
||||
sc := bufio.NewScanner(fd)
|
||||
for sc.Scan() {
|
||||
pl := strings.TrimSpace(sc.Text())
|
||||
if pl == "" {
|
||||
continue
|
||||
}
|
||||
plugins[pl] = true
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
log.Fatalf("Error reading file '%s': %v", *flagFromFile, err)
|
||||
}
|
||||
}
|
||||
if len(plugins) == 0 {
|
||||
log.Fatalf("No plugin specified!")
|
||||
}
|
||||
outfile := *flagOutfile
|
||||
if outfile == "" {
|
||||
tmpdir, err := os.MkdirTemp("", "coredhcp")
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot create temporary directory: %v", err)
|
||||
}
|
||||
outfile = path.Join(tmpdir, "coredhcp.go")
|
||||
}
|
||||
|
||||
log.Printf("Generating output file '%s' with %d plugin(s):", outfile, len(plugins))
|
||||
idx := 1
|
||||
for pl := range plugins {
|
||||
log.Printf("% 3d) %s", idx, pl)
|
||||
idx++
|
||||
}
|
||||
outFD, err := os.OpenFile(outfile, os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create output file '%s': %v", outfile, err)
|
||||
}
|
||||
defer func() {
|
||||
if err := outFD.Close(); err != nil {
|
||||
log.Printf("Error while closing file descriptor for '%s': %v", outfile, err)
|
||||
}
|
||||
}()
|
||||
// WARNING: no escaping of the provided strings is done
|
||||
pluginList := make([]string, 0, len(plugins))
|
||||
for pl := range plugins {
|
||||
pluginList = append(pluginList, pl)
|
||||
}
|
||||
sort.Strings(pluginList)
|
||||
if err := t.Execute(outFD, pluginList); err != nil {
|
||||
log.Fatalf("Template execution failed: %v", err)
|
||||
}
|
||||
log.Printf("Generated file '%s'. You can build it by running 'go build' in the output directory.", outfile)
|
||||
fmt.Println(path.Dir(outfile))
|
||||
}
|
||||
Reference in New Issue
Block a user