Skip to content

Commit af7ed75

Browse files
authored
chore: replaced env by options (#5)
* chore: replaced env var SWAGGER_GENERATE_EXTENSION by option Signed-off-by: Frederic BIDON <fredbi@yahoo.com> * chore: replace env var DEBUG by option Signed-off-by: Frederic BIDON <fredbi@yahoo.com> --------- Signed-off-by: Frederic BIDON <fredbi@yahoo.com>
1 parent 95e5dcf commit af7ed75

File tree

10 files changed

+153
-155
lines changed

10 files changed

+153
-155
lines changed

application.go

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,16 @@ import (
99
"go/token"
1010
"go/types"
1111
"log"
12-
"os"
1312
"regexp"
1413
"strings"
1514

1615
"github.com/go-openapi/spec"
17-
"github.com/go-openapi/swag/conv"
1816

1917
"golang.org/x/tools/go/packages"
2018
)
2119

2220
const pkgLoadMode = packages.NeedName | packages.NeedFiles | packages.NeedImports | packages.NeedDeps | packages.NeedTypes | packages.NeedSyntax | packages.NeedTypesInfo
2321

24-
func safeConvert(str string) bool {
25-
b, err := conv.ConvertBool(str)
26-
if err != nil {
27-
return false
28-
}
29-
return b
30-
}
31-
32-
// Debug is true when process is run with DEBUG=1 env var.
33-
var Debug = safeConvert(os.Getenv("DEBUG")) //nolint:gochecknoglobals // package-level configuration from environment
34-
3522
type node uint32
3623

3724
const (
@@ -59,11 +46,14 @@ type Options struct {
5946
RefAliases bool // aliases result in $ref, otherwise aliases are expanded
6047
TransparentAliases bool // aliases are completely transparent, never creating definitions
6148
DescWithRef bool // allow overloaded descriptions together with $ref, otherwise jsonschema draft4 $ref predates everything
49+
SkipExtensions bool // skip generating x-go-* vendor extensions in the spec
50+
Debug bool // enable verbose debug logging during scanning
6251
}
6352

6453
type scanCtx struct {
65-
pkgs []*packages.Package
66-
app *typeIndex
54+
pkgs []*packages.Package
55+
app *typeIndex
56+
debug bool
6757

6858
opts *Options
6959
}
@@ -110,15 +100,17 @@ func newScanCtx(opts *Options) (*scanCtx, error) {
110100
withXNullableForPointers(opts.SetXNullableForPointers),
111101
withRefAliases(opts.RefAliases),
112102
withTransparentAliases(opts.TransparentAliases),
103+
withDebug(opts.Debug),
113104
)
114105
if err != nil {
115106
return nil, err
116107
}
117108

118109
return &scanCtx{
119-
pkgs: pkgs,
120-
app: app,
121-
opts: opts,
110+
pkgs: pkgs,
111+
app: app,
112+
debug: opts.Debug,
113+
opts: opts,
122114
}, nil
123115
}
124116

@@ -307,14 +299,14 @@ func (s *scanCtx) FindDecl(pkgPath, name string) (*entityDecl, bool) {
307299

308300
def, ok := pkg.TypesInfo.Defs[ts.Name]
309301
if !ok {
310-
debugLogf("couldn't find type info for %s", ts.Name)
302+
debugLogf(s.debug, "couldn't find type info for %s", ts.Name)
311303
continue
312304
}
313305

314306
nt, isNamed := def.Type().(*types.Named)
315307
at, isAliased := def.Type().(*types.Alias)
316308
if !isNamed && !isAliased {
317-
debugLogf("%s is not a named or an aliased type but a %T", ts.Name, def.Type())
309+
debugLogf(s.debug, "%s is not a named or an aliased type but a %T", ts.Name, def.Type())
318310
continue
319311
}
320312

@@ -556,6 +548,12 @@ func withTransparentAliases(enabled bool) typeIndexOption {
556548
}
557549
}
558550

551+
func withDebug(enabled bool) typeIndexOption {
552+
return func(a *typeIndex) {
553+
a.debug = enabled
554+
}
555+
}
556+
559557
func newTypeIndex(pkgs []*packages.Package, opts ...typeIndexOption) (*typeIndex, error) {
560558
ac := &typeIndex{
561559
AllPackages: make(map[string]*packages.Package),
@@ -589,6 +587,7 @@ type typeIndex struct {
589587
setXNullableForPointers bool
590588
refAliases bool
591589
transparentAliases bool
590+
debug bool
592591
}
593592

594593
func (a *typeIndex) build(pkgs []*packages.Package) error {
@@ -610,7 +609,7 @@ func (a *typeIndex) build(pkgs []*packages.Package) error {
610609

611610
func (a *typeIndex) processPackage(pkg *packages.Package) error {
612611
if !shouldAcceptPkg(pkg.PkgPath, a.includePkgs, a.excludePkgs) {
613-
debugLogf("package %s is ignored due to rules", pkg.Name)
612+
debugLogf(a.debug, "package %s is ignored due to rules", pkg.Name)
614613
return nil
615614
}
616615

@@ -653,7 +652,7 @@ func (a *typeIndex) collectPathAnnotations(rx *regexp.Regexp, comments []*ast.Co
653652
continue
654653
}
655654
if !shouldAcceptTag(pp.Tags, a.includeTags, a.excludeTags) {
656-
debugLogf("operation %s %s is ignored due to tag rules", pp.Method, pp.Path)
655+
debugLogf(a.debug, "operation %s %s is ignored due to tag rules", pp.Method, pp.Path)
657656
continue
658657
}
659658
dst = append(dst, pp)
@@ -687,21 +686,21 @@ func (a *typeIndex) processDecl(pkg *packages.Package, file *ast.File, n node, g
687686
for _, sp := range gd.Specs {
688687
switch ts := sp.(type) {
689688
case *ast.ValueSpec:
690-
debugLogf("saw value spec: %v", ts.Names)
689+
debugLogf(a.debug, "saw value spec: %v", ts.Names)
691690
return
692691
case *ast.ImportSpec:
693-
debugLogf("saw import spec: %v", ts.Name)
692+
debugLogf(a.debug, "saw import spec: %v", ts.Name)
694693
return
695694
case *ast.TypeSpec:
696695
def, ok := pkg.TypesInfo.Defs[ts.Name]
697696
if !ok {
698-
debugLogf("couldn't find type info for %s", ts.Name)
697+
debugLogf(a.debug, "couldn't find type info for %s", ts.Name)
699698
continue
700699
}
701700
nt, isNamed := def.Type().(*types.Named)
702701
at, isAliased := def.Type().(*types.Alias)
703702
if !isNamed && !isAliased {
704-
debugLogf("%s is not a named or aliased type but a %T", ts.Name, def.Type())
703+
debugLogf(a.debug, "%s is not a named or aliased type but a %T", ts.Name, def.Type())
705704

706705
continue
707706
}
@@ -729,7 +728,7 @@ func (a *typeIndex) processDecl(pkg *packages.Package, file *ast.File, n node, g
729728
case n&responseNode != 0 && decl.HasResponseAnnotation():
730729
a.Responses = append(a.Responses, decl)
731730
default:
732-
debugLogf(
731+
debugLogf(a.debug,
733732
"type %q skipped because it is not tagged as a model, a parameter or a response. %s",
734733
decl.Obj().Name(),
735734
"It may reenter the scope because it is a discovered dependency",
@@ -827,8 +826,8 @@ func (a *typeIndex) detectNodes(file *ast.File) (node, error) {
827826
return n, nil
828827
}
829828

830-
func debugLogf(format string, args ...any) {
831-
if Debug {
829+
func debugLogf(debug bool, format string, args ...any) {
830+
if debug {
832831
_ = log.Output(logCallerDepth, fmt.Sprintf(format, args...))
833832
}
834833
}

application_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ func TestMain(m *testing.M) {
4141
log.SetOutput(io.Discard)
4242
} else {
4343
// enable full debug when test is run with -enable-debug arg
44-
Debug = true
4544
log.SetFlags(log.LstdFlags | log.Lshortfile)
4645
log.SetOutput(os.Stderr)
4746
}
@@ -101,6 +100,7 @@ func loadPetstorePkgsCtx(t *testing.T) *scanCtx {
101100
sctx, err := newScanCtx(&Options{
102101
Packages: []string{"./goparsing/petstore/..."},
103102
WorkDir: "fixtures",
103+
Debug: enableDebug,
104104
})
105105
require.NoError(t, err)
106106
petstoreCtx = sctx
@@ -122,6 +122,7 @@ func loadClassificationPkgsCtx(t *testing.T) *scanCtx {
122122
"./goparsing/classification/operations",
123123
},
124124
WorkDir: "fixtures",
125+
Debug: enableDebug,
125126
})
126127
require.NoError(t, err)
127128
classificationCtx = sctx

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ toolchain go1.26.1
77
require (
88
github.com/go-openapi/loads v0.23.3
99
github.com/go-openapi/spec v0.22.4
10-
github.com/go-openapi/swag/conv v0.25.5
1110
github.com/go-openapi/testify/v2 v2.4.1
1211
go.yaml.in/yaml/v3 v3.0.4
1312
golang.org/x/tools v0.43.0
@@ -17,6 +16,7 @@ require (
1716
require (
1817
github.com/go-openapi/jsonpointer v0.22.5 // indirect
1918
github.com/go-openapi/jsonreference v0.21.5 // indirect
19+
github.com/go-openapi/swag/conv v0.25.5 // indirect
2020
github.com/go-openapi/swag/jsonname v0.25.5 // indirect
2121
github.com/go-openapi/swag/jsonutils v0.25.5 // indirect
2222
github.com/go-openapi/swag/loading v0.25.5 // indirect

parameters.go

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import (
1212
)
1313

1414
type paramTypable struct {
15-
param *spec.Parameter
15+
param *spec.Parameter
16+
skipExt bool
1617
}
1718

1819
func (pt paramTypable) In() string { return pt.param.In }
@@ -28,7 +29,7 @@ func (pt paramTypable) SetRef(ref spec.Ref) {
2829
}
2930

3031
func (pt paramTypable) Items() swaggerTypable { //nolint:ireturn // polymorphic by design
31-
bdt, schema := bodyTypable(pt.param.In, pt.param.Schema)
32+
bdt, schema := bodyTypable(pt.param.In, pt.param.Schema, pt.skipExt)
3233
if bdt != nil {
3334
pt.param.Schema = schema
3435
return bdt
@@ -184,7 +185,7 @@ func (p *parameterBuilder) Build(operations map[string]*spec.Operation) error {
184185
operations[opid] = operation
185186
operation.ID = opid
186187
}
187-
debugLogf("building parameters for: %s", opid)
188+
debugLogf(p.ctx.debug, "building parameters for: %s", opid)
188189

189190
// analyze struct body for fields etc
190191
// each exported struct field:
@@ -208,7 +209,7 @@ func (p *parameterBuilder) buildFromType(otpe types.Type, op *spec.Operation, se
208209
case *types.Named:
209210
return p.buildNamedType(tpe, op, seen)
210211
case *types.Alias:
211-
debugLogf("alias(parameters.buildFromType): got alias %v to %v", tpe, tpe.Rhs())
212+
debugLogf(p.ctx.debug, "alias(parameters.buildFromType): got alias %v to %v", tpe, tpe.Rhs())
212213
return p.buildAlias(tpe, op, seen)
213214
default:
214215
return fmt.Errorf("unhandled type (%T): %s: %w", otpe, tpe.String(), ErrCodeScan)
@@ -224,7 +225,7 @@ func (p *parameterBuilder) buildNamedType(tpe *types.Named, op *spec.Operation,
224225

225226
switch stpe := o.Type().Underlying().(type) {
226227
case *types.Struct:
227-
debugLogf("build from named type %s: %T", o.Name(), tpe)
228+
debugLogf(p.ctx.debug, "build from named type %s: %T", o.Name(), tpe)
228229
if decl, found := p.ctx.DeclForType(o.Type()); found {
229230
return p.buildFromStruct(decl, stpe, op, seen)
230231
}
@@ -284,7 +285,7 @@ func (p *parameterBuilder) buildAlias(tpe *types.Alias, op *spec.Operation, seen
284285
}
285286

286287
func (p *parameterBuilder) buildFromField(fld *types.Var, tpe types.Type, typable swaggerTypable, seen map[string]spec.Parameter) error {
287-
debugLogf("build from field %s: %T", fld.Name(), tpe)
288+
debugLogf(p.ctx.debug, "build from field %s: %T", fld.Name(), tpe)
288289

289290
switch ftpe := tpe.(type) {
290291
case *types.Basic:
@@ -304,7 +305,7 @@ func (p *parameterBuilder) buildFromField(fld *types.Var, tpe types.Type, typabl
304305
case *types.Named:
305306
return p.buildNamedField(ftpe, typable)
306307
case *types.Alias:
307-
debugLogf("alias(parameters.buildFromField): got alias %v to %v", ftpe, ftpe.Rhs()) // TODO
308+
debugLogf(p.ctx.debug, "alias(parameters.buildFromField): got alias %v to %v", ftpe, ftpe.Rhs()) // TODO
308309
return p.buildFieldAlias(ftpe, typable, fld, seen)
309310
default:
310311
return fmt.Errorf("unknown type for %s: %T: %w", fld.String(), fld.Type(), ErrCodeScan)
@@ -336,7 +337,7 @@ func (p *parameterBuilder) buildFromFieldMap(ftpe *types.Map, typable swaggerTyp
336337
ctx: p.ctx,
337338
}
338339

339-
if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1}); err != nil {
340+
if err := sb.buildFromType(ftpe.Elem(), schemaTypable{schema, typable.Level() + 1, p.ctx.opts.SkipExtensions}); err != nil {
340341
return err
341342
}
342343

@@ -469,10 +470,10 @@ func (p *parameterBuilder) buildFieldAlias(tpe *types.Alias, typable swaggerTypa
469470
return p.buildFromField(fld, rhs, typable, seen)
470471
}
471472

472-
func spExtensionsSetter(ps *spec.Parameter) func(*spec.Extensions) {
473+
func spExtensionsSetter(ps *spec.Parameter, skipExt bool) func(*spec.Extensions) {
473474
return func(exts *spec.Extensions) {
474475
for name, value := range *exts {
475-
addExtension(&ps.VendorExtensible, name, value)
476+
addExtension(&ps.VendorExtensible, name, value, skipExt)
476477
}
477478
}
478479
}
@@ -522,13 +523,13 @@ func (p *parameterBuilder) buildFromStruct(decl *entityDecl, tpe *types.Struct,
522523
// Returns the parameter name if the field was processed, or "" if it was skipped.
523524
func (p *parameterBuilder) processParamField(fld *types.Var, decl *entityDecl, seen map[string]spec.Parameter) (string, error) {
524525
if !fld.Exported() {
525-
debugLogf("skipping field %s because it's not exported", fld.Name())
526+
debugLogf(p.ctx.debug, "skipping field %s because it's not exported", fld.Name())
526527
return "", nil
527528
}
528529

529530
afld := findASTField(decl.File, fld.Pos())
530531
if afld == nil {
531-
debugLogf("can't find source associated with %s", fld.String())
532+
debugLogf(p.ctx.debug, "can't find source associated with %s", fld.String())
532533
return "", nil
533534
}
534535

@@ -559,9 +560,9 @@ func (p *parameterBuilder) processParamField(fld *types.Var, decl *entityDecl, s
559560

560561
ps := seen[name]
561562
ps.In = in
562-
var pty swaggerTypable = paramTypable{&ps}
563+
var pty swaggerTypable = paramTypable{&ps, p.ctx.opts.SkipExtensions}
563564
if in == bodyTag {
564-
pty = schemaTypable{pty.Schema(), 0}
565+
pty = schemaTypable{pty.Schema(), 0, p.ctx.opts.SkipExtensions}
565566
}
566567

567568
if in == "formData" && afld.Doc != nil && fileParam(afld.Doc) {
@@ -586,9 +587,9 @@ func (p *parameterBuilder) processParamField(fld *types.Var, decl *entityDecl, s
586587
}
587588

588589
if ps.Ref.String() != "" {
589-
setupRefParamTaggers(sp, &ps)
590+
setupRefParamTaggers(sp, &ps, p.ctx.opts.SkipExtensions, p.ctx.debug)
590591
} else {
591-
if err := setupInlineParamTaggers(sp, &ps, name, afld); err != nil {
592+
if err := setupInlineParamTaggers(sp, &ps, name, afld, p.ctx.opts.SkipExtensions, p.ctx.debug); err != nil {
592593
return "", err
593594
}
594595
}
@@ -605,7 +606,7 @@ func (p *parameterBuilder) processParamField(fld *types.Var, decl *entityDecl, s
605606
}
606607

607608
if name != fld.Name() {
608-
addExtension(&ps.VendorExtensible, "x-go-name", fld.Name())
609+
addExtension(&ps.VendorExtensible, "x-go-name", fld.Name(), p.ctx.opts.SkipExtensions)
609610
}
610611

611612
seen[name] = ps

parser.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,16 +1493,18 @@ func parseEnum(val string, s *spec.SimpleSchema) []any {
14931493
// alphaChars used when parsing for Vendor Extensions.
14941494
const alphaChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
14951495

1496-
func newSetExtensions(setter func(*spec.Extensions)) *setOpExtensions {
1496+
func newSetExtensions(setter func(*spec.Extensions), debug bool) *setOpExtensions {
14971497
return &setOpExtensions{
1498-
set: setter,
1499-
rx: rxExtensions,
1498+
set: setter,
1499+
rx: rxExtensions,
1500+
debug: debug,
15001501
}
15011502
}
15021503

15031504
type setOpExtensions struct {
1504-
set func(*spec.Extensions)
1505-
rx *regexp.Regexp
1505+
set func(*spec.Extensions)
1506+
rx *regexp.Regexp
1507+
debug bool
15061508
}
15071509

15081510
type extensionObject struct {
@@ -1711,7 +1713,7 @@ func (ss *setOpExtensions) Parse(lines []string) error {
17111713
} else if m, ok := ext.Root.(map[string]any); ok {
17121714
exts.AddExtension(ext.Extension, m[ext.Extension])
17131715
} else {
1714-
debugLogf("Unknown Extension type: %s", fmt.Sprint(reflect.TypeOf(ext.Root)))
1716+
debugLogf(ss.debug, "Unknown Extension type: %s", fmt.Sprint(reflect.TypeOf(ext.Root)))
17151717
}
17161718
}
17171719

0 commit comments

Comments
 (0)