Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ linters:
disable:
- depguard
- funlen
- gochecknoglobals # on this repo, it is hard to refactor without globals/inits and no breaking change
- gochecknoinits
- godox
- exhaustruct
- nlreturn
Expand Down
5 changes: 2 additions & 3 deletions doc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@ import (
"github.com/go-openapi/swag/loading"
)

// Example with default loaders defined at the package level
// Example with default loaders defined at the package level.
func ExampleSpec_file() {

path := "fixtures/yaml/swagger/spec.yml"
doc, err := loads.Spec(path)
if err != nil {
Expand All @@ -28,7 +27,7 @@ func ExampleSpec_file() {
// Output: Spec loaded: "api.example.com"
}

// Example with custom loaders passed as options
// Example with custom loaders passed as options.
func ExampleLoaderOption() {
path := "fixtures/yaml/swagger/spec.yml"

Expand Down
4 changes: 2 additions & 2 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ func (e loaderError) Error() string {
}

const (
// ErrLoads is an error returned by the loads package
// ErrLoads is an error returned by the loads package.
ErrLoads loaderError = "loaderrs error"

// ErrNoLoader indicates that no configured loader matched the input
// ErrNoLoader indicates that no configured loader matched the input.
ErrNoLoader loaderError = "no loader matched"
)
2 changes: 1 addition & 1 deletion examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
//go:embed fixtures
var embeddedFixtures embed.FS

// Loads a JSON document from http, with a custom header
// Loads a JSON document from http, with a custom header.
func ExampleJSONSpec_http_custom_header() {
ts := serveSomeJSONDocument()
defer ts.Close()
Expand Down
16 changes: 13 additions & 3 deletions fmts/fixture_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ import (

var extensions = []string{"json"}

//nolint:unparam
func assertSpecJSON(t testing.TB, specJSON []byte) bool {
//nolint:unparam // reserved for future use
func assertSpecJSON(t *testing.T, specJSON []byte) bool {
t.Helper()

var expected map[string]any
require.NoError(t, json.Unmarshal(specJSON, &expected))

Expand All @@ -34,7 +36,9 @@ func assertSpecJSON(t testing.TB, specJSON []byte) bool {
return assertSpecMaps(t, actual, expected)
}

func assertSpecMaps(t testing.TB, actual, expected map[string]any) bool {
func assertSpecMaps(t *testing.T, actual, expected map[string]any) bool {
t.Helper()

res := true
if id, ok := expected["id"]; ok {
res = assert.Equal(t, id, actual["id"])
Expand All @@ -60,13 +64,17 @@ func assertSpecMaps(t testing.TB, actual, expected map[string]any) bool {

//nolint:unparam
func roundTripTest(t *testing.T, fixtureType, extension, fileName string, schema any) bool {
t.Helper()

if extension == "yaml" {
return roundTripTestYAML(t, fixtureType, fileName, schema)
}
return roundTripTestJSON(t, fixtureType, fileName, schema)
}

func roundTripTestJSON(t *testing.T, fixtureType, fileName string, schema any) bool {
t.Helper()

specName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
t.Logf("verifying %s JSON fixture %q", fixtureType, specName)

Expand All @@ -88,6 +96,8 @@ func roundTripTestJSON(t *testing.T, fixtureType, fileName string, schema any) b
}

func roundTripTestYAML(t *testing.T, fixtureType, fileName string, schema any) bool {
t.Helper()

specName := strings.TrimSuffix(fileName, filepath.Ext(fileName))
t.Logf("verifying %s YAML fixture %q", fixtureType, specName)

Expand Down
10 changes: 5 additions & 5 deletions fmts/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
)

var (
// YAMLMatcher matches yaml
// YAMLMatcher matches yaml.
YAMLMatcher = loading.YAMLMatcher
// YAMLToJSON converts YAML unmarshaled data into json compatible data
// YAMLToJSON converts YAML unmarshaled data into json compatible data.
YAMLToJSON = yamlutils.YAMLToJSON
// BytesToYAMLDoc converts raw bytes to a map[string]interface{}
// BytesToYAMLDoc converts raw bytes to a map[string]interface{}.
BytesToYAMLDoc = yamlutils.BytesToYAMLDoc
// YAMLDoc loads a yaml document from either http or a file and converts it to json
// YAMLDoc loads a yaml document from either http or a file and converts it to json.
YAMLDoc = loading.YAMLDoc
// YAMLData loads a yaml document from either http or a file
// YAMLData loads a yaml document from either http or a file.
YAMLData = loading.YAMLData
)
3 changes: 1 addition & 2 deletions fmts/yaml_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ import (

var errTest = errors.New("expected")

type failJSONMarshal struct {
}
type failJSONMarshal struct{}

func (f failJSONMarshal) MarshalJSON() ([]byte, error) {
return nil, errTest
Expand Down
26 changes: 12 additions & 14 deletions loaders.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ import (
"github.com/go-openapi/swag/loading"
)

var (
// Default chain of loaders, defined at the package level.
//
// By default this matches json and yaml documents.
//
// May be altered with AddLoader().
loaders *loader
)
// Default chain of loaders, defined at the package level.
//
// By default this matches json and yaml documents.
//
// May be altered with AddLoader().
var loaders *loader

func init() {
jsonLoader := &loader{
Expand All @@ -43,10 +41,10 @@ func init() {
spec.PathLoader = loaders.Load
}

// DocLoader represents a doc loader type
// DocLoader represents a doc loader type.
type DocLoader func(string, ...loading.Option) (json.RawMessage, error)

// DocMatcher represents a predicate to check if a loader matches
// DocMatcher represents a predicate to check if a loader matches.
type DocMatcher func(string) bool

// DocLoaderWithMatch describes a loading function for a given extension match.
Expand All @@ -55,7 +53,7 @@ type DocLoaderWithMatch struct {
Match DocMatcher
}

// NewDocLoaderWithMatch builds a DocLoaderWithMatch to be used in load options
// NewDocLoaderWithMatch builds a DocLoaderWithMatch to be used in load options.
func NewDocLoaderWithMatch(fn DocLoader, matcher DocMatcher) DocLoaderWithMatch {
return DocLoaderWithMatch{
Fn: fn,
Expand All @@ -71,7 +69,7 @@ type loader struct {
Next *loader
}

// WithHead adds a loader at the head of the current stack
// WithHead adds a loader at the head of the current stack.
func (l *loader) WithHead(head *loader) *loader {
if head == nil {
return l
Expand All @@ -80,13 +78,13 @@ func (l *loader) WithHead(head *loader) *loader {
return head
}

// WithNext adds a loader at the trail of the current stack
// WithNext adds a loader at the trail of the current stack.
func (l *loader) WithNext(next *loader) *loader {
l.Next = next
return next
}

// Load the raw document from path
// Load the raw document from path.
func (l *loader) Load(path string) (json.RawMessage, error) {
_, erp := url.Parse(path)
if erp != nil {
Expand Down
4 changes: 2 additions & 2 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ func loaderFromOptions(options []LoaderOption) *loader {
return l
}

// LoaderOption allows to fine-tune the spec loader behavior
// LoaderOption allows to fine-tune the spec loader behavior.
type LoaderOption func(*options)

// WithDocLoader sets a custom loader for loading specs
// WithDocLoader sets a custom loader for loading specs.
func WithDocLoader(l DocLoader) LoaderOption {
return func(opt *options) {
if l == nil {
Expand Down
32 changes: 16 additions & 16 deletions spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func init() {
gob.Register([]any{})
}

// Document represents a swagger spec document
// Document represents a swagger spec document.
type Document struct {
// specAnalyzer
Analyzer *analysis.Spec
Expand Down Expand Up @@ -57,7 +57,7 @@ func JSONSpec(path string, opts ...LoaderOption) (*Document, error) {
return doc, nil
}

// Embedded returns a Document based on embedded specs (i.e. as a raw [json.RawMessage]). No analysis is required
// Embedded returns a Document based on embedded specs (i.e. as a raw [json.RawMessage]). No analysis is required.
func Embedded(orig, flat json.RawMessage, opts ...LoaderOption) (*Document, error) {
var origSpec, flatSpec spec.Swagger
if err := json.Unmarshal(orig, &origSpec); err != nil {
Expand Down Expand Up @@ -145,18 +145,18 @@ func trimData(in json.RawMessage) (json.RawMessage, error) {
// assume yaml doc: convert it to json
yml, err := yamlutils.BytesToYAMLDoc(trimmed)
if err != nil {
return nil, fmt.Errorf("analyzed: %v: %w", err, ErrLoads)
return nil, fmt.Errorf("analyzed: %w: %w", err, ErrLoads)
}

d, err := yamlutils.YAMLToJSON(yml)
if err != nil {
return nil, fmt.Errorf("analyzed: %v: %w", err, ErrLoads)
return nil, fmt.Errorf("analyzed: %w: %w", err, ErrLoads)
}

return d, nil
}

// Expanded expands the $ref fields in the spec [Document] and returns a new expanded [Document]
// Expanded expands the $ref fields in the spec [Document] and returns a new expanded [Document].
func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
swspec := new(spec.Swagger)
if err := json.Unmarshal(d.raw, swspec); err != nil {
Expand Down Expand Up @@ -200,63 +200,63 @@ func (d *Document) Expanded(options ...*spec.ExpandOptions) (*Document, error) {
return dd, nil
}

// BasePath the base path for the API specified by this spec
// BasePath the base path for the API specified by this spec.
func (d *Document) BasePath() string {
if d.spec == nil {
return ""
}
return d.spec.BasePath
}

// Version returns the OpenAPI version of this spec (e.g. 2.0)
// Version returns the OpenAPI version of this spec (e.g. 2.0).
func (d *Document) Version() string {
return d.spec.Swagger
}

// Schema returns the swagger 2.0 meta-schema
// Schema returns the swagger 2.0 meta-schema.
func (d *Document) Schema() *spec.Schema {
return d.schema
}

// Spec returns the swagger object model for this API specification
// Spec returns the swagger object model for this API specification.
func (d *Document) Spec() *spec.Swagger {
return d.spec
}

// Host returns the host for the API
// Host returns the host for the API.
func (d *Document) Host() string {
return d.spec.Host
}

// Raw returns the raw swagger spec as json bytes
// Raw returns the raw swagger spec as json bytes.
func (d *Document) Raw() json.RawMessage {
return d.raw
}

// OrigSpec yields the original spec
// OrigSpec yields the original spec.
func (d *Document) OrigSpec() *spec.Swagger {
return d.origSpec
}

// ResetDefinitions yields a shallow copy with the models reset to the original spec
// ResetDefinitions yields a shallow copy with the models reset to the original spec.
func (d *Document) ResetDefinitions() *Document {
d.spec.Definitions = make(map[string]spec.Schema, len(d.origSpec.Definitions))
maps.Copy(d.spec.Definitions, d.origSpec.Definitions)

return d
}

// Pristine creates a new pristine document instance based on the input data
// Pristine creates a new pristine document instance based on the input data.
func (d *Document) Pristine() *Document {
raw, _ := json.Marshal(d.Spec())
raw, _ := json.Marshal(d.Spec()) //nolint:errchkjson // the spec always marshals to JSON
dd, _ := Analyzed(raw, d.Version())
dd.pathLoader = d.pathLoader
dd.specFilePath = d.specFilePath

return dd
}

// SpecFilePath returns the file path of the spec if one is defined
// SpecFilePath returns the file path of the spec if one is defined.
func (d *Document) SpecFilePath() string {
return d.specFilePath
}
Expand Down
14 changes: 8 additions & 6 deletions spec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestLoadsYAMLContent(t *testing.T) {
assert.Equal(t, "1.0.0", sw.Info.Version)
}

// for issue 11
// for issue 11.
func TestRegressionExpand(t *testing.T) {
swaggerFile := "fixtures/yaml/swagger/1/2/3/4/swagger.yaml"
document, err := Spec(swaggerFile)
Expand All @@ -50,7 +50,8 @@ func TestRegressionExpand(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, d)

b, _ := d.Spec().MarshalJSON()
b, err := d.Spec().MarshalJSON()
require.NoError(t, err)
assert.JSONEq(t, expectedExpanded, string(b))
}

Expand All @@ -74,7 +75,7 @@ func TestFailsInvalidJSON(t *testing.T) {
require.Error(t, err)
}

// issue go-swagger/go-swagger#1816 (regression when cloning original spec)
// issue go-swagger/go-swagger#1816 (regression when cloning original spec).
func TestIssue1846(t *testing.T) {
swaggerFile := "fixtures/bugs/1816/fixture-1816.yaml"
document, err := Spec(swaggerFile)
Expand All @@ -84,7 +85,8 @@ func TestIssue1846(t *testing.T) {
sp, err := cloneSpec(document.Spec())
require.NoError(t, err)

jazon, _ := json.MarshalIndent(sp, "", " ")
jazon, err := json.MarshalIndent(sp, "", " ")
require.NoError(t, err)
rex := regexp.MustCompile(`"\$ref":\s*"(.+)"`)
m := rex.FindAllStringSubmatch(string(jazon), -1)
require.NotNil(t, m)
Expand Down Expand Up @@ -629,10 +631,10 @@ definitions:
readOnly: true
`

// PetStoreJSONMessage json raw message for Petstore20
// PetStoreJSONMessage json raw message for Petstore20.
var PetStoreJSONMessage = json.RawMessage([]byte(PetStore20))

// PetStore20 json doc for swagger 2.0 pet store
// PetStore20 json doc for swagger 2.0 pet store.
const PetStore20 = `{
"swagger": "2.0",
"info": {
Expand Down