go2idl: Allow ... pkg specs

This is closer to standard Go semantics and obsoletes our custom --recursive
flag.
This commit is contained in:
Tim Hockin 2016-06-22 15:07:24 +09:00
parent 51394e862d
commit 1ba6f5df9e
5 changed files with 35 additions and 20 deletions

View File

@ -54,9 +54,6 @@ type GeneratorArgs struct {
// Which directories to parse. // Which directories to parse.
InputDirs []string InputDirs []string
// If true, recurse into all children of InputDirs
Recursive bool
// Source tree to write results to. // Source tree to write results to.
OutputBase string OutputBase string
@ -89,7 +86,6 @@ func (g *GeneratorArgs) AddFlags(fs *pflag.FlagSet) {
fs.StringVarP(&g.OutputFileBaseName, "output-file-base", "O", g.OutputFileBaseName, "Base name (without .go suffix) for output files.") fs.StringVarP(&g.OutputFileBaseName, "output-file-base", "O", g.OutputFileBaseName, "Base name (without .go suffix) for output files.")
fs.StringVarP(&g.GoHeaderFilePath, "go-header-file", "h", g.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.") fs.StringVarP(&g.GoHeaderFilePath, "go-header-file", "h", g.GoHeaderFilePath, "File containing boilerplate header text. The string YEAR will be replaced with the current 4-digit year.")
fs.BoolVar(&g.VerifyOnly, "verify-only", g.VerifyOnly, "If true, only verify existing output, do not write anything.") fs.BoolVar(&g.VerifyOnly, "verify-only", g.VerifyOnly, "If true, only verify existing output, do not write anything.")
fs.BoolVar(&g.Recursive, "recursive", g.VerifyOnly, "If true, recurse into all children of input directories.")
fs.StringVar(&g.GeneratedBuildTag, "build-tag", g.GeneratedBuildTag, "A Go build tag to use to identify files generated by this command. Should be unique.") fs.StringVar(&g.GeneratedBuildTag, "build-tag", g.GeneratedBuildTag, "A Go build tag to use to identify files generated by this command. Should be unique.")
} }
@ -111,14 +107,14 @@ func (g *GeneratorArgs) NewBuilder() (*parser.Builder, error) {
b.AddBuildTags(g.GeneratedBuildTag) b.AddBuildTags(g.GeneratedBuildTag)
for _, d := range g.InputDirs { for _, d := range g.InputDirs {
if g.Recursive { var err error
if err := b.AddDirRecursive(d); err != nil { if strings.HasSuffix(d, "/...") {
return nil, fmt.Errorf("unable to add directory %q: %v", d, err) err = b.AddDirRecursive(strings.TrimSuffix(d, "/..."))
}
} else { } else {
if err := b.AddDir(d); err != nil { err = b.AddDir(d)
return nil, fmt.Errorf("unable to add directory %q: %v", d, err) }
} if err != nil {
return nil, fmt.Errorf("unable to add directory %q: %v", d, err)
} }
} }
return b, nil return b, nil

View File

@ -121,7 +121,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
glog.Fatalf("Failed loading boilerplate: %v", err) glog.Fatalf("Failed loading boilerplate: %v", err)
} }
inputs := sets.NewString(arguments.InputDirs...) inputs := sets.NewString(context.Inputs...)
packages := generator.Packages{} packages := generator.Packages{}
header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...) header := append([]byte(fmt.Sprintf("// +build !%s\n\n", arguments.GeneratedBuildTag)), boilerplate...)
header = append(header, []byte( header = append(header, []byte(

View File

@ -152,6 +152,9 @@ type Context struct {
// All the types, in case you want to look up something. // All the types, in case you want to look up something.
Universe types.Universe Universe types.Universe
// All the user-specified packages. This is after recursive expansion.
Inputs []string
// The canonical ordering of the types (will be filtered by both the // The canonical ordering of the types (will be filtered by both the
// Package's and Generator's Filter methods). // Package's and Generator's Filter methods).
Order []*types.Type Order []*types.Type
@ -168,14 +171,15 @@ type Context struct {
// NewContext generates a context from the given builder, naming systems, and // NewContext generates a context from the given builder, naming systems, and
// the naming system you wish to construct the canonical ordering from. // the naming system you wish to construct the canonical ordering from.
func NewContext(b *parser.Builder, nameSystems namer.NameSystems, canonicalOrderName string) (*Context, error) { func NewContext(b *parser.Builder, nameSystems namer.NameSystems, canonicalOrderName string) (*Context, error) {
u, err := b.FindTypes() universe, err := b.FindTypes()
if err != nil { if err != nil {
return nil, err return nil, err
} }
c := &Context{ c := &Context{
Namers: namer.NameSystems{}, Namers: namer.NameSystems{},
Universe: u, Universe: universe,
Inputs: b.FindPackages(),
FileTypes: map[string]FileType{ FileTypes: map[string]FileType{
GolangFileType: NewGolangFile(), GolangFileType: NewGolangFile(),
}, },
@ -185,7 +189,7 @@ func NewContext(b *parser.Builder, nameSystems namer.NameSystems, canonicalOrder
c.Namers[name] = systemNamer c.Namers[name] = systemNamer
if name == canonicalOrderName { if name == canonicalOrderName {
orderer := namer.Orderer{Namer: systemNamer} orderer := namer.Orderer{Namer: systemNamer}
c.Order = orderer.OrderUniverse(u) c.Order = orderer.OrderUniverse(universe)
} }
} }
return c, nil return c, nil

View File

@ -70,11 +70,10 @@ func main() {
// Override defaults. These are Kubernetes specific input and output // Override defaults. These are Kubernetes specific input and output
// locations. // locations.
arguments.InputDirs = []string{ arguments.InputDirs = []string{
"k8s.io/kubernetes/pkg/", "k8s.io/kubernetes/pkg/...",
"k8s.io/kubernetes/cmd/", "k8s.io/kubernetes/cmd/...",
"k8s.io/kubernetes/plugin/", "k8s.io/kubernetes/plugin/...",
} }
arguments.Recursive = true
// arguments.VerifyOnly = true // arguments.VerifyOnly = true
if err := arguments.Execute( if err := arguments.Execute(

View File

@ -129,7 +129,9 @@ func (b *Builder) buildPackage(pkgPath string) (*build.Package, error) {
} }
pkg, err = b.context.Import(pkgPath, cwd, build.ImportComment) pkg, err = b.context.Import(pkgPath, cwd, build.ImportComment)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to import %q: %v", pkgPath, err) if _, ok := err.(*build.NoGoError); !ok {
return nil, fmt.Errorf("unable to import %q: %v", pkgPath, err)
}
} }
b.buildInfo[pkgPath] = pkg b.buildInfo[pkgPath] = pkg
@ -350,6 +352,20 @@ func (b *Builder) makePackages() error {
return nil return nil
} }
// FindPackages fetches a list of the user-imported packages.
func (b *Builder) FindPackages() []string {
result := []string{}
for pkgPath := range b.pkgs {
if b.userRequested[pkgPath] {
// Since walkType is recursive, all types that are in packages that
// were directly mentioned will be included. We don't need to
// include all types in all transitive packages, though.
result = append(result, pkgPath)
}
}
return result
}
// FindTypes finalizes the package imports, and searches through all the // FindTypes finalizes the package imports, and searches through all the
// packages for types. // packages for types.
func (b *Builder) FindTypes() (types.Universe, error) { func (b *Builder) FindTypes() (types.Universe, error) {