diff --git a/cmd/swag/main.go b/cmd/swag/main.go index 9c043d0f9..61f2ce04c 100644 --- a/cmd/swag/main.go +++ b/cmd/swag/main.go @@ -24,6 +24,7 @@ func main() { mainAPIFile := c.String("generalInfo") strategy := c.String("propertyStrategy") outputDir := c.String("output") + parseVendor := c.Bool("parseVendor") switch strategy { case swag.CamelCase, swag.SnakeCase, swag.PascalCase: @@ -36,6 +37,7 @@ func main() { MainAPIFile: mainAPIFile, PropNamingStrategy: strategy, OutputDir: outputDir, + ParseVendor: parseVendor, }) }, Flags: []cli.Flag{ @@ -59,6 +61,10 @@ func main() { Value: "./docs", Usage: "Output directory for al the generated files(swagger.json, swagger.yaml and doc.go)", }, + cli.BoolFlag{ + Name: "parseVendor", + Usage: "Parse go files in 'vendor' folder, disabled by default", + }, }, }, } diff --git a/gen/gen.go b/gen/gen.go index aadd5eb26..c2fc54b1e 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -36,6 +36,9 @@ type Config struct { //PropNamingStrategy represents property naming strategy like snakecase,camelcase,pascalcase PropNamingStrategy string + + //ParseVendor whether swag should be parse vendor folder + ParseVendor bool } // Build builds swagger json file for gived searchDir and mainAPIFile. Returns json @@ -47,6 +50,7 @@ func (g *Gen) Build(config *Config) error { log.Println("Generate swagger docs....") p := swag.New() p.PropNamingStrategy = config.PropNamingStrategy + p.ParseVendor = config.ParseVendor if err := p.ParseAPI(config.SearchDir, config.MainAPIFile); err != nil { return err diff --git a/operation.go b/operation.go index feb4ae1cf..9228eb075 100644 --- a/operation.go +++ b/operation.go @@ -117,9 +117,9 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro } // ParseParamComment parses params return []string of param properties -// @Param queryText form string true "The email for login" -// [param name] [paramType] [data type] [is mandatory?] [Comment] -// @Param some_id path int true "Some ID" +// E.g. @Param queryText form string true "The email for login" +// [param name] [paramType] [data type] [is mandatory?] [Comment] +// E.g. @Param some_id path int true "Some ID" func (operation *Operation) ParseParamComment(commentLine string, astFile *ast.File) error { re := regexp.MustCompile(`(\S+)[\s]+([\w]+)[\s]+([\S.]+)[\s]+([\w]+)[\s]+"([^"]+)"`) matches := re.FindStringSubmatch(commentLine) diff --git a/parser.go b/parser.go index adda0fc3f..6d2db5cd2 100644 --- a/parser.go +++ b/parser.go @@ -50,6 +50,8 @@ type Parser struct { PropNamingStrategy string + ParseVendor bool + // structStack stores full names of the structures that were already parsed or are being parsed now structStack []string } @@ -1044,7 +1046,7 @@ func (parser *Parser) getAllGoFileInfo(searchDir string) error { } func (parser *Parser) visit(path string, f os.FileInfo, err error) error { - if err := Skip(f); err != nil { + if err := parser.Skip(path, f); err != nil { return err } @@ -1061,10 +1063,12 @@ func (parser *Parser) visit(path string, f os.FileInfo, err error) error { } // Skip returns filepath.SkipDir error if match vendor and hidden folder -func Skip(f os.FileInfo) error { - // exclude vendor folder - if f.IsDir() && f.Name() == "vendor" { - return filepath.SkipDir +func (parser *Parser) Skip(path string, f os.FileInfo) error { + + if !parser.ParseVendor { // ignore vendor + if f.IsDir() && f.Name() == "vendor" { + return filepath.SkipDir + } } // exclude all hidden folder diff --git a/parser_test.go b/parser_test.go index f3f507117..82bf61c78 100644 --- a/parser_test.go +++ b/parser_test.go @@ -2328,22 +2328,54 @@ func Test3(){ func TestSkip(t *testing.T) { folder1 := "/tmp/vendor" - os.Mkdir(folder1, 777) + os.Mkdir(folder1, os.ModePerm) f1, _ := os.Stat(folder1) - assert.True(t, Skip(f1) == filepath.SkipDir) + parser := New() + + assert.True(t, parser.Skip(folder1, f1) == filepath.SkipDir) + assert.NoError(t, os.Remove(folder1)) + + folder2 := "/tmp/.git" + os.Mkdir(folder2, os.ModePerm) + f2, _ := os.Stat(folder2) + + assert.True(t, parser.Skip(folder2, f2) == filepath.SkipDir) + assert.NoError(t, os.Remove(folder2)) + + currentPath := "./" + currentPathInfo, _ := os.Stat(currentPath) + assert.True(t, parser.Skip(currentPath, currentPathInfo) == nil) +} + +func TestSkipMustParseVendor(t *testing.T) { + folder1 := "/tmp/vendor" + os.Mkdir(folder1, os.ModePerm) + f1, _ := os.Stat(folder1) + + parser := New() + parser.ParseVendor = true + + assert.True(t, parser.Skip(folder1, f1) == nil) assert.NoError(t, os.Remove(folder1)) folder2 := "/tmp/.git" - os.Mkdir(folder2, 777) + os.Mkdir(folder2, os.ModePerm) f2, _ := os.Stat(folder2) - assert.True(t, Skip(f2) == filepath.SkipDir) + assert.True(t, parser.Skip(folder2, f2) == filepath.SkipDir) assert.NoError(t, os.Remove(folder2)) currentPath := "./" currentPathInfo, _ := os.Stat(currentPath) - assert.True(t, Skip(currentPathInfo) == nil) + assert.True(t, parser.Skip(currentPath, currentPathInfo) == nil) + + folder3 := "/tmp/test/vendor/github.com/swaggo/swag" + assert.NoError(t, os.MkdirAll(folder3, os.ModePerm)) + f3, _ := os.Stat(folder3) + + assert.Nil(t, parser.Skip(folder3, f3)) + assert.NoError(t, os.RemoveAll("/tmp/test")) } // func TestParseDeterministic(t *testing.T) {