diff --git a/cmd/swag/main.go b/cmd/swag/main.go index a2dfa4181..1d55b7ff6 100644 --- a/cmd/swag/main.go +++ b/cmd/swag/main.go @@ -39,6 +39,7 @@ const ( templateDelimsFlag = "templateDelims" packageName = "packageName" collectionFormatFlag = "collectionFormat" + packagePrefixFlag = "packagePrefix" ) var initFlags = []cli.Flag{ @@ -167,6 +168,11 @@ var initFlags = []cli.Flag{ Value: "csv", Usage: "Set default collection format", }, + &cli.StringFlag{ + Name: packagePrefixFlag, + Value: "", + Usage: "Parse only packages whose import path match the given prefix, comma separated", + }, } func initAction(ctx *cli.Context) error { @@ -235,6 +241,7 @@ func initAction(ctx *cli.Context) error { PackageName: ctx.String(packageName), Debugger: logger, CollectionFormat: collectionFormat, + PackagePrefix: ctx.String(packagePrefixFlag), }) } diff --git a/gen/gen.go b/gen/gen.go index 7a90c2655..5cbd942a6 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -138,6 +138,9 @@ type Config struct { // CollectionFormat set default collection format CollectionFormat string + + // Parse only packages whose import path match the given prefix, comma separated + PackagePrefix string } // Build builds swagger json file for given searchDir and mainAPIFile. Returns json. @@ -197,6 +200,7 @@ func (g *Gen) Build(config *Config) error { swag.ParseUsingGoList(config.ParseGoList), swag.SetTags(config.Tags), swag.SetCollectionFormat(config.CollectionFormat), + swag.SetPackagePrefix(config.PackagePrefix), ) p.PropNamingStrategy = config.PropNamingStrategy diff --git a/golist.go b/golist.go index 8f47118f9..fa0b2cd9e 100644 --- a/golist.go +++ b/golist.go @@ -53,6 +53,10 @@ func (parser *Parser) getAllGoFileInfoFromDepsByList(pkg *build.Package, parseFl return nil } + if parser.skipPackageByPrefix(pkg.ImportPath) { + return nil // ignored by user-defined package path prefixes + } + srcDir := pkg.Dir var err error for i := range pkg.GoFiles { diff --git a/parser.go b/parser.go index 3c1704771..817510700 100644 --- a/parser.go +++ b/parser.go @@ -153,6 +153,10 @@ type Parser struct { // excludes excludes dirs and files in SearchDir excludes map[string]struct{} + // packagePrefix is a list of package path prefixes, packages that do not + // match any one of them will be excluded when searching. + packagePrefix []string + // tells parser to include only specific extension parseExtension string @@ -273,6 +277,20 @@ func SetExcludedDirsAndFiles(excludes string) func(*Parser) { } } +// SetPackagePrefix sets a list of package path prefixes from a comma-separated +// string, packages that do not match any one of them will be excluded when +// searching. +func SetPackagePrefix(packagePrefix string) func(*Parser) { + return func(p *Parser) { + for _, f := range strings.Split(packagePrefix, ",") { + f = strings.TrimSpace(f) + if f != "" { + p.packagePrefix = append(p.packagePrefix, f) + } + } + } +} + // SetTags sets the tags to be included func SetTags(include string) func(*Parser) { return func(p *Parser) { @@ -343,6 +361,20 @@ func (parser *Parser) ParseAPI(searchDir string, mainAPIFile string, parseDepth return parser.ParseAPIMultiSearchDir([]string{searchDir}, mainAPIFile, parseDepth) } +// skipPackageByPrefix returns true the given pkgpath does not match +// any user-defined package path prefixes. +func (parser *Parser) skipPackageByPrefix(pkgpath string) bool { + if len(parser.packagePrefix) == 0 { + return false + } + for _, prefix := range parser.packagePrefix { + if strings.HasPrefix(pkgpath, prefix) { + return false + } + } + return true +} + // ParseAPIMultiSearchDir is like ParseAPI but for multiple search dirs. func (parser *Parser) ParseAPIMultiSearchDir(searchDirs []string, mainAPIFile string, parseDepth int) error { for _, searchDir := range searchDirs { @@ -1623,6 +1655,9 @@ func defineTypeOfExample(schemaType, arrayType, exampleValue string) (interface{ // GetAllGoFileInfo gets all Go source files information for given searchDir. func (parser *Parser) getAllGoFileInfo(packageDir, searchDir string) error { + if parser.skipPackageByPrefix(packageDir) { + return nil // ignored by user-defined package path prefixes + } return filepath.Walk(searchDir, func(path string, f os.FileInfo, _ error) error { err := parser.Skip(path, f) if err != nil { @@ -1648,6 +1683,10 @@ func (parser *Parser) getAllGoFileInfoFromDeps(pkg *depth.Pkg, parseFlag ParseFl return nil } + if pkg.Raw != nil && parser.skipPackageByPrefix(pkg.Raw.ImportPath) { + return nil // ignored by user-defined package path prefixes + } + // Skip cgo if pkg.Raw == nil && pkg.Name == "C" { return nil diff --git a/parser_test.go b/parser_test.go index 90891e13d..d818f705c 100644 --- a/parser_test.go +++ b/parser_test.go @@ -4048,3 +4048,25 @@ func TestParser_collectionFormat(t *testing.T) { }) } } + +func TestParser_skipPackageByPrefix(t *testing.T) { + t.Parallel() + + parser := New() + + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag")) + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag/cmd")) + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag/gen")) + + parser = New(SetPackagePrefix("github.com/swaggo/swag/cmd")) + + assert.True(t, parser.skipPackageByPrefix("github.com/swaggo/swag")) + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag/cmd")) + assert.True(t, parser.skipPackageByPrefix("github.com/swaggo/swag/gen")) + + parser = New(SetPackagePrefix("github.com/swaggo/swag/cmd,github.com/swaggo/swag/gen")) + + assert.True(t, parser.skipPackageByPrefix("github.com/swaggo/swag")) + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag/cmd")) + assert.False(t, parser.skipPackageByPrefix("github.com/swaggo/swag/gen")) +}