diff --git a/README.md b/README.md index 4a48fa6ff..45d96b965 100644 --- a/README.md +++ b/README.md @@ -17,34 +17,49 @@ Swag converts Go annotations to Swagger Documentation 2.0. We've created a variety of plugins for popular [Go web frameworks](#supported-web-frameworks). This allows you to quickly integrate with an existing Go project (using Swagger UI). ## Contents - - [Getting started](#getting-started) - - [Supported Web Frameworks](#supported-web-frameworks) - - [How to use it with Gin](#how-to-use-it-with-gin) - - [The swag formatter](#the-swag-formatter) - - [Implementation Status](#implementation-status) - - [Declarative Comments Format](#declarative-comments-format) - - [General API Info](#general-api-info) - - [API Operation](#api-operation) - - [Security](#security) - - [Examples](#examples) - - [Descriptions over multiple lines](#descriptions-over-multiple-lines) - - [User defined structure with an array type](#user-defined-structure-with-an-array-type) - - [Function scoped struct declaration](#function-scoped-struct-declaration) - - [Model composition in response](#model-composition-in-response) - - [Add a headers in response](#add-a-headers-in-response) - - [Use multiple path params](#use-multiple-path-params) - - [Example value of struct](#example-value-of-struct) - - [SchemaExample of body](#schemaexample-of-body) - - [Description of struct](#description-of-struct) - - [Use swaggertype tag to supported custom type](#use-swaggertype-tag-to-supported-custom-type) - - [Use global overrides to support a custom type](#use-global-overrides-to-support-a-custom-type) - - [Use swaggerignore tag to exclude a field](#use-swaggerignore-tag-to-exclude-a-field) - - [Add extension info to struct field](#add-extension-info-to-struct-field) - - [Rename model to display](#rename-model-to-display) - - [How to use security annotations](#how-to-use-security-annotations) - - [Add a description for enum items](#add-a-description-for-enum-items) - - [Generate only specific docs file types](#generate-only-specific-docs-file-types) -- [About the Project](#about-the-project) +- [swag](#swag) + - [Contents](#contents) + - [Getting started](#getting-started) + - [swag cli](#swag-cli) + - [Supported Web Frameworks](#supported-web-frameworks) + - [How to use it with Gin](#how-to-use-it-with-gin) + - [The swag formatter](#the-swag-formatter) + - [Implementation Status](#implementation-status) +- [Declarative Comments Format](#declarative-comments-format) + - [General API Info](#general-api-info) + - [Using markdown descriptions](#using-markdown-descriptions) + - [API Operation](#api-operation) + - [Mime Types](#mime-types) + - [Param Type](#param-type) + - [Data Type](#data-type) + - [Security](#security) + - [Attribute](#attribute) + - [Available](#available) + - [Future](#future) + - [Examples](#examples) + - [Descriptions over multiple lines](#descriptions-over-multiple-lines) + - [User defined structure with an array type](#user-defined-structure-with-an-array-type) + - [Function scoped struct declaration](#function-scoped-struct-declaration) + - [Model composition in response](#model-composition-in-response) + - [Add a headers in response](#add-a-headers-in-response) + - [Use multiple path params](#use-multiple-path-params) + - [Add multiple paths](#add-multiple-paths) + - [Example value of struct](#example-value-of-struct) + - [SchemaExample of body](#schemaexample-of-body) + - [Description of struct](#description-of-struct) + - [Use swaggertype tag to supported custom type](#use-swaggertype-tag-to-supported-custom-type) + - [Use global overrides to support a custom type](#use-global-overrides-to-support-a-custom-type) + - [Use swaggerignore tag to exclude a field](#use-swaggerignore-tag-to-exclude-a-field) + - [Add extension info to struct field](#add-extension-info-to-struct-field) + - [Rename model to display](#rename-model-to-display) + - [How to use security annotations](#how-to-use-security-annotations) + - [Add a description for enum items](#add-a-description-for-enum-items) + - [Generate only specific docs file types](#generate-only-specific-docs-file-types) + - [About the Project](#about-the-project) + - [Contributors](#contributors) + - [Backers](#backers) + - [Sponsors](#sponsors) + - [License](#license) ## Getting started @@ -104,6 +119,7 @@ OPTIONS: --overridesFile value File to read global type overrides from. (default: ".swaggo") --parseGoList Parse dependency via 'go list' (default: true) --tags value, -t value A comma-separated list of tags to filter the APIs for which the documentation is generated.Special case if the tag is prefixed with the '!' character then the APIs with that tag will be excluded + --regexTags value, --rt value A tag use the regex pattern to find the tag which match the pattern --collectionFormat value, --cf value Set default collection format (default: "csv") --help, -h show help (default: false) ``` diff --git a/cmd/swag/main.go b/cmd/swag/main.go index 1b325865e..c3b1eecb0 100644 --- a/cmd/swag/main.go +++ b/cmd/swag/main.go @@ -34,6 +34,7 @@ const ( parseGoListFlag = "parseGoList" quietFlag = "quiet" tagsFlag = "tags" + regexTagsFlag = "regexTags" parseExtensionFlag = "parseExtension" packageName = "packageName" collectionFormatFlag = "collectionFormat" @@ -154,6 +155,12 @@ var initFlags = []cli.Flag{ Value: "csv", Usage: "Set default collection format", }, + &cli.StringFlag{ + Name: regexTagsFlag, + Aliases: []string{"rt"}, + Value: "", + Usage: "A tag use the regex pattern to find the tag which match the pattern", + }, } func initAction(ctx *cli.Context) error { @@ -200,6 +207,7 @@ func initAction(ctx *cli.Context) error { ParseGoList: ctx.Bool(parseGoListFlag), Tags: ctx.String(tagsFlag), PackageName: ctx.String(packageName), + RegexTags: ctx.String(regexTagsFlag), Debugger: logger, CollectionFormat: collectionFormat, }) diff --git a/gen/gen.go b/gen/gen.go index 21111bbe9..b8008863d 100644 --- a/gen/gen.go +++ b/gen/gen.go @@ -132,6 +132,9 @@ type Config struct { // CollectionFormat set default collection format CollectionFormat string + + // search the tags base on the regex pattern + RegexTags string } // Build builds swagger json file for given searchDir and mainAPIFile. Returns json. @@ -183,6 +186,7 @@ func (g *Gen) Build(config *Config) error { swag.ParseUsingGoList(config.ParseGoList), swag.SetTags(config.Tags), swag.SetCollectionFormat(config.CollectionFormat), + swag.SetRegexTags(config.RegexTags), ) p.PropNamingStrategy = config.PropNamingStrategy diff --git a/go.mod b/go.mod index 52fa6b894..d3ed2d6ca 100644 --- a/go.mod +++ b/go.mod @@ -4,8 +4,8 @@ go 1.18 require ( github.com/KyleBanks/depth v1.2.1 - github.com/go-openapi/spec v0.20.4 - github.com/stretchr/testify v1.7.0 + github.com/go-openapi/spec v0.20.8 + github.com/stretchr/testify v1.8.2 github.com/urfave/cli/v2 v2.3.0 golang.org/x/tools v0.7.0 sigs.k8s.io/yaml v1.3.0 @@ -14,19 +14,22 @@ require ( require ( github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect + github.com/cpuguy83/go-md2man v1.0.10 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-openapi/jsonpointer v0.19.5 // indirect - github.com/go-openapi/jsonreference v0.19.6 // indirect - github.com/go-openapi/swag v0.19.15 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.6 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/russross/blackfriday v1.5.2 // indirect github.com/russross/blackfriday/v2 v2.0.1 // indirect github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect + github.com/swaggo/cli v1.22.2 // indirect golang.org/x/net v0.8.0 // indirect golang.org/x/sys v0.6.0 // indirect golang.org/x/text v0.8.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 8ef14012f..44f1e4a05 100644 --- a/go.sum +++ b/go.sum @@ -5,6 +5,8 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= +github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -14,16 +16,26 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs= github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M= github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/spec v0.20.8 h1:ubHmXNY3FCIOinT8RNrrPfGc9t7I1qhPtdOGoG2AxRU= +github.com/go-openapi/spec v0.20.8/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM= github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -32,19 +44,32 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA= github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= +github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/swaggo/cli v1.22.2 h1:HcOuWl50wxecZWnAA3eIrf2XcOki3XeRK7HljCzP9Vg= +github.com/swaggo/cli v1.22.2/go.mod h1:mod7cSpILRjdhkgSKDd1HJFDMN4hopy6uH5pkXELHkM= github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= @@ -67,6 +92,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -74,5 +100,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/parser.go b/parser.go index 2e453960a..15b087d35 100644 --- a/parser.go +++ b/parser.go @@ -15,6 +15,7 @@ import ( "os/exec" "path/filepath" "reflect" + "regexp" "sort" "strconv" "strings" @@ -170,6 +171,9 @@ type Parser struct { // tags to filter the APIs after tags map[string]struct{} + + // regex tags pattern + tagsRegex *regexp.Regexp } // FieldParserFactory create FieldParser. @@ -285,6 +289,23 @@ func SetTags(include string) func(*Parser) { } } +func SetRegexTags(tagRegex string) func(*Parser) { + return func(p *Parser) { + + if tagRegex == "" { + return + } + + regex, err := regexp.Compile(tagRegex) + + if err != nil { + return + } + + p.tagsRegex = regex + } +} + // SetParseExtension parses only those operations which match given extension func SetParseExtension(parseExtension string) func(*Parser) { return func(p *Parser) { @@ -867,15 +888,24 @@ func getTagsFromComment(comment string) (tags []string) { } func (parser *Parser) matchTags(comments []*ast.Comment) (match bool) { - if len(parser.tags) != 0 { + if len(parser.tags) != 0 || parser.tagsRegex != nil { for _, comment := range comments { for _, tag := range getTagsFromComment(comment.Text) { - if _, has := parser.tags["!"+tag]; has { - return false + if parser.tagsRegex != nil { + if parser.tagsRegex.MatchString(tag) { + match = true + } } - if _, has := parser.tags[tag]; has { - match = true // keep iterating as it may contain a tag that is excluded + + if len(parser.tags) != 0 && !match { + if _, has := parser.tags["!"+tag]; has { + return false + } + if _, has := parser.tags[tag]; has { + match = true // keep iterating as it may contain a tag that is excluded + } } + } } return diff --git a/parser_test.go b/parser_test.go index f070376db..55b8500d6 100644 --- a/parser_test.go +++ b/parser_test.go @@ -3889,6 +3889,87 @@ func TestParser_matchTags(t *testing.T) { } } +func TestParse_matchRegexPatternTags(t *testing.T) { + type args struct { + comments []*ast.Comment + } + tests := []struct { + name string + parser *Parser + args args + wantMatch bool + }{ + { + name: "no Regex tags filter", + parser: New(), + args: args{comments: []*ast.Comment{{Text: "//@Tags tag1,tag2,tag3"}}}, + wantMatch: true, + }, + { + name: "with Regex tags filter but no match", + parser: New(SetRegexTags("Tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags tag1,tag2,tag3"}}}, + wantMatch: false, + }, + { + name: "with tags filter but match", + parser: New(SetRegexTags("tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags tag1,tag2,tag3"}}}, + wantMatch: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotMatch := tt.parser.matchTags(tt.args.comments); gotMatch != tt.wantMatch { + t.Errorf("Parser.matchTags() = %v, want %v", gotMatch, tt.wantMatch) + } + }) + } +} + +func TestParse_matchRegexPatternTagsAndTags(t *testing.T) { + type args struct { + comments []*ast.Comment + } + + tests := []struct { + name string + parser *Parser + args args + wantMatch bool + }{ + { + name: "no match tag and regex tag", + parser: New(SetTags("tag1, tag2, tag3"), SetRegexTags("tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags Tag4,Tag5,Tag6"}}}, + wantMatch: false, + }, { + name: "only match tag", + parser: New(SetTags("tag1, tag2, tag3"), SetRegexTags("Tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags tag1,tag5,tag6"}}}, + wantMatch: true, + }, { + name: "only match regex tag", + parser: New(SetTags("tag1, tag2, tag3"), SetRegexTags("Tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags Tag1,tag5,tag6"}}}, + wantMatch: true, + }, { + name: "match regex tag and tags", + parser: New(SetTags("Tag1, tag2, tag3"), SetRegexTags("Tag?")), + args: args{comments: []*ast.Comment{{Text: "//@Tags Tag1,tag5,tag6"}}}, + wantMatch: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if gotMatch := tt.parser.matchTags(tt.args.comments); gotMatch != tt.wantMatch { + t.Errorf("Parser.matchTags() = %v, want %v", gotMatch, tt.wantMatch) + } + }) + } +} + func TestParser_parseExtension(t *testing.T) { packagePath := "testdata/parseExtension" filePath := packagePath + "/parseExtension.go"