From a4e8bf2efe9189ce795f87ab07adbb3780d01d7d Mon Sep 17 00:00:00 2001 From: Vladimir Lavor Date: Wed, 19 Aug 2020 16:08:39 +0200 Subject: Binapi generator: improved file input In addition to the standard file name input (for example "vpe"), binary API generator now again accepts full file path like "/usr/share/vpp/api/core/vpe.api.json" as an input direcotry or argument. Change-Id: I591b5d26e7f101cdcc4af64d3bdabaab48b5b2ef Signed-off-by: Vladimir Lavor --- binapigen/binapigen_test.go | 4 ++-- binapigen/generator.go | 39 +++++++++++++++++++++++++-------------- binapigen/run.go | 4 ++-- binapigen/vppapi/vppapi.go | 25 ++++++++++++++----------- cmd/binapi-generator/main.go | 1 + 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/binapigen/binapigen_test.go b/binapigen/binapigen_test.go index 9a25420..0352635 100644 --- a/binapigen/binapigen_test.go +++ b/binapigen/binapigen_test.go @@ -40,11 +40,11 @@ func TestGenerator(t *testing.T) { t.Run(test.name, func(t *testing.T) { RegisterTestingT(t) - apifiles := []*vppapi.File{test.file} + apiFiles := []*vppapi.File{test.file} gen, err := New(Options{ ImportPrefix: "test", - }, apifiles, nil) + }, apiFiles, nil) Expect(err).ToNot(HaveOccurred(), "unexpected generator error: %v", err) Expect(gen.Files).To(HaveLen(1)) diff --git a/binapigen/generator.go b/binapigen/generator.go index ce0954a..a6f1615 100644 --- a/binapigen/generator.go +++ b/binapigen/generator.go @@ -38,6 +38,7 @@ import ( type Generator struct { Files []*File FilesByName map[string]*File + FilesByPath map[string]*File opts Options apifiles []*vppapi.File @@ -53,11 +54,12 @@ type Generator struct { messagesByName map[string]*Message } -func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator, error) { +func New(opts Options, apiFiles []*vppapi.File, filesToGen []string) (*Generator, error) { gen := &Generator{ FilesByName: make(map[string]*File), + FilesByPath: make(map[string]*File), opts: opts, - apifiles: apifiles, + apifiles: apiFiles, filesToGen: filesToGen, enumsByName: map[string]*Enum{}, aliasesByName: map[string]*Alias{}, @@ -68,9 +70,9 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator // Normalize API files SortFilesByImports(gen.apifiles) - for _, apifile := range apifiles { - RemoveImportedTypes(gen.apifiles, apifile) - SortFileObjectsByName(apifile) + for _, apiFile := range apiFiles { + RemoveImportedTypes(gen.apifiles, apiFile) + SortFileObjectsByName(apiFile) } // prepare package names and import paths @@ -96,6 +98,7 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator } gen.Files = append(gen.Files, file) gen.FilesByName[apifile.Name] = file + gen.FilesByPath[apifile.Path] = file logrus.Debugf("added file %q (path: %v)", apifile.Name, apifile.Path) } @@ -103,16 +106,24 @@ func New(opts Options, apifiles []*vppapi.File, filesToGen []string) (*Generator // mark files for generation if len(gen.filesToGen) > 0 { logrus.Debugf("Checking %d files to generate: %v", len(gen.filesToGen), gen.filesToGen) - for _, genfile := range gen.filesToGen { - file, ok := gen.FilesByName[genfile] - if !ok { - return nil, fmt.Errorf("nol API file found for: %v", genfile) + for _, genFile := range gen.filesToGen { + markGen := func(file *File) { + file.Generate = true + // generate all imported files + for _, impFile := range file.importedFiles(gen) { + impFile.Generate = true + } } - file.Generate = true - // generate all imported files - for _, impFile := range file.importedFiles(gen) { - impFile.Generate = true + if file, ok := gen.FilesByName[genFile]; ok { + markGen(file) + continue + } + logrus.Debugf("File %s was not found by name", genFile) + if file, ok := gen.FilesByPath[genFile]; ok { + markGen(file) + continue } + return nil, fmt.Errorf("no API file found for: %v", genFile) } } else { logrus.Debugf("Files to generate not specified, marking all %d files for generate", len(gen.Files)) @@ -233,7 +244,7 @@ func (g *GenFile) injectImports(original []byte) ([]byte, error) { var importPaths []Import for importPath := range g.packageNames { importPaths = append(importPaths, Import{ - Name: string(g.packageNames[GoImportPath(importPath)]), + Name: string(g.packageNames[importPath]), Path: string(importPath), }) } diff --git a/binapigen/run.go b/binapigen/run.go index f7776c9..8bb88fb 100644 --- a/binapigen/run.go +++ b/binapigen/run.go @@ -43,7 +43,7 @@ func Run(apiDir string, filesToGenerate []string, opts Options, f func(*Generato } func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generator) error) error { - apifiles, err := vppapi.ParseDir(apiDir) + apiFiles, err := vppapi.ParseDir(apiDir) if err != nil { return err } @@ -56,7 +56,7 @@ func run(apiDir string, filesToGenerate []string, opts Options, fn func(*Generat logrus.Infof("resolved import path prefix: %s", opts.ImportPrefix) } - gen, err := New(opts, apifiles, filesToGenerate) + gen, err := New(opts, apiFiles, filesToGenerate) if err != nil { return err } diff --git a/binapigen/vppapi/vppapi.go b/binapigen/vppapi/vppapi.go index 665fa81..b54d287 100644 --- a/binapigen/vppapi/vppapi.go +++ b/binapigen/vppapi/vppapi.go @@ -24,6 +24,9 @@ import ( const ( // DefaultDir is default location of API files. DefaultDir = "/usr/share/vpp/api" + + // APIFileExtension is a VPP API file extension suffix + APIFileExtension = ".api.json" ) // FindFiles finds API files located in dir or in a nested directory that is not nested deeper than deep. @@ -40,7 +43,7 @@ func FindFiles(dir string, deep int) (files []string, err error) { } else { files = append(files, nested...) } - } else if !e.IsDir() && strings.HasSuffix(e.Name(), ".api.json") { + } else if !e.IsDir() && strings.HasSuffix(e.Name(), APIFileExtension) { files = append(files, filepath.Join(dir, e.Name())) } } @@ -54,13 +57,13 @@ func Parse() ([]*File, error) { // ParseDir finds and parses API files in given directory and returns parsed files. // Supports API files in JSON format (.api.json) only. -func ParseDir(apidir string) ([]*File, error) { - list, err := FindFiles(apidir, 1) +func ParseDir(apiDir string) ([]*File, error) { + list, err := FindFiles(apiDir, 1) if err != nil { return nil, err } - logf("found %d files in API dir %q", len(list), apidir) + logf("found %d files in API dir %q", len(list), apiDir) var files []*File for _, file := range list { @@ -74,17 +77,17 @@ func ParseDir(apidir string) ([]*File, error) { } // ParseFile parses API file and returns File. -func ParseFile(apifile string) (*File, error) { - if !strings.HasSuffix(apifile, ".api.json") { - return nil, fmt.Errorf("unsupported file format: %q", apifile) +func ParseFile(apiFile string) (*File, error) { + if !strings.HasSuffix(apiFile, APIFileExtension) { + return nil, fmt.Errorf("unsupported file format: %q", apiFile) } - data, err := ioutil.ReadFile(apifile) + data, err := ioutil.ReadFile(apiFile) if err != nil { - return nil, fmt.Errorf("reading file %s failed: %v", apifile, err) + return nil, fmt.Errorf("reading file %s failed: %v", apiFile, err) } - base := filepath.Base(apifile) + base := filepath.Base(apiFile) name := base[:strings.Index(base, ".")] logf("parsing file %q", base) @@ -94,7 +97,7 @@ func ParseFile(apifile string) (*File, error) { return nil, fmt.Errorf("parsing file %s failed: %v", base, err) } module.Name = name - module.Path = apifile + module.Path = apiFile return module, nil } diff --git a/cmd/binapi-generator/main.go b/cmd/binapi-generator/main.go index 3dc2c08..af60628 100644 --- a/cmd/binapi-generator/main.go +++ b/cmd/binapi-generator/main.go @@ -32,6 +32,7 @@ import ( func init() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [OPTION] API_FILES\n", os.Args[0]) + fmt.Fprintln(os.Stderr, "Provide API_FILES by file name, or with full path including extension.") fmt.Fprintln(os.Stderr, "Parse API_FILES and generate Go bindings based on the options given:") flag.PrintDefaults() } -- cgit 1.2.3-korg