1 // Copyright (c) 2020 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
26 "github.com/sirupsen/logrus"
28 "git.fd.io/govpp.git/binapigen/vppapi"
32 OutputDir string // output directory for generated files
33 ImportPrefix string // prefix for import paths
34 NoVersionInfo bool // disables generating version info
37 func Run(apiDir string, filesToGenerate []string, opts Options, f func(*Generator) error) {
38 if err := run(apiDir, filesToGenerate, opts, f); err != nil {
39 fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), err)
44 func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generator) error) error {
45 apifiles, err := vppapi.ParseDir(apiDir)
50 if opts.ImportPrefix == "" {
51 opts.ImportPrefix = resolveImportPath(opts.OutputDir)
52 logrus.Debugf("resolved import prefix: %s", opts.ImportPrefix)
55 gen, err := New(opts, apifiles, filesToGenerate)
60 gen.vppVersion = vppapi.ResolveVPPVersion(apiDir)
61 if gen.vppVersion == "" {
62 gen.vppVersion = "unknown"
68 if err := fn(gen); err != nil {
73 if err = gen.Generate(); err != nil {
80 func GenerateDefault(gen *Generator) {
81 for _, file := range gen.Files {
85 GenerateAPI(gen, file)
86 GenerateRPC(gen, file)
90 var Logger = logrus.New()
93 if debug := os.Getenv("DEBUG_GOVPP"); strings.Contains(debug, "binapigen") {
94 Logger.SetLevel(logrus.DebugLevel)
95 logrus.SetLevel(logrus.DebugLevel)
96 } else if debug != "" {
97 Logger.SetLevel(logrus.InfoLevel)
99 Logger.SetLevel(logrus.WarnLevel)
103 func logf(f string, v ...interface{}) {
104 Logger.Debugf(f, v...)
107 func resolveImportPath(dir string) string {
108 absPath, err := filepath.Abs(dir)
112 modRoot := findGoModuleRoot(absPath)
114 logrus.Fatalf("module root not found at: %s", absPath)
116 modPath := findModulePath(path.Join(modRoot, "go.mod"))
118 logrus.Fatalf("module path not found")
120 relDir, err := filepath.Rel(modRoot, absPath)
124 return filepath.Join(modPath, relDir)
127 func findGoModuleRoot(dir string) (root string) {
131 dir = filepath.Clean(dir)
132 // Look for enclosing go.mod.
134 if fi, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil && !fi.IsDir() {
137 d := filepath.Dir(dir)
147 modulePathRE = regexp.MustCompile(`module[ \t]+([^ \t\r\n]+)`)
150 func findModulePath(file string) string {
151 data, err := ioutil.ReadFile(file)
155 m := modulePathRE.FindSubmatch(data)