Git Product home page Git Product logo

oasdiff's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oasdiff's Issues

Ignore parameter name changes

Problem

I have the same (in theory) API spec generated from two different sources, which have different names for the URL path parameters. This causes oasdiff to consider those endpoints to be both new and deleted, even though the API is not any different.

Proposal

Treat URL path parameter names as opaque, and equivalent between the base and revision specs (if the parameters have the same schema, eg the same (lack of) reg-ex).

Alternatives

I currently manually update the OpenAPI spec to have matching path parameters, but this is prone to error.

Removing a pattern is flagged as breaking change

Describe the bug
If a pattern is removed it's flagged as a breaking change, I'm not 100% sure if this is desire, considering that we are making the spec more flexible and as such should not break expectations from clients

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -base pattern-base.yaml -revision pattern-revision.yaml -breaking-only
    Where pattern-base.yaml
openapi: 3.0.1
info:
  version: "1.0"
servers:
- url: https://localhost:9080
paths:
  /api/v1.0/groups:
    post:
      operationId: createOneGroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupView'
        description: Creates one project.
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Create One Project
  /api/v1.0/groups/{groupId}:
    get:
      operationId: returnOneGroup
      parameters:
      - $ref: '#/components/parameters/groupId'
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Return One Project
components:
  parameters:
    groupId:
      in: path
      name: groupId
      required: true
      schema:
        type: string
  schemas:
    GroupView:
      type: object
      properties:
        created:
          type: string
          format: date-time
          readOnly: true
          pattern: "^+w$"
        id:
          type: string
          readOnly: true
        name:
          type: string
      required:
      - name

and pattern-revision.yaml

openapi: 3.0.1
info:
  version: "1.0"
servers:
- url: https://localhost:9080
paths:
  /api/v1.0/groups:
    post:
      operationId: createOneGroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupView'
        description: Creates one project.
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Create One Project
  /api/v1.0/groups/{groupId}:
    get:
      operationId: returnOneGroup
      parameters:
      - $ref: '#/components/parameters/groupId'
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Return One Project
components:
  parameters:
    groupId:
      in: path
      name: groupId
      required: true
      schema:
        type: string
  schemas:
    GroupView:
      type: object
      properties:
        created:
          type: string
          format: date-time
          readOnly: true
        id:
          type: string
          readOnly: true
        name:
          type: string
      required:
      - name

Expected behavior
I would not expect removal of a pattern to be a breaking change

Desktop (please complete the following information):

  • OS: macOS
  • Version 1.2.3

Add a version command

Is your feature request related to a problem? Please describe.
As I was filling the report for #126 there's an ask for version but no easy way to find the version of the bin I have installed, I have to go and do brew info oasdiff

Describe the solution you'd like
Add a oasdiff version or oasdif -version option to the CLI, given the use of go native flag implementation more inclined to the use of oasdiff version to stay consistent with other go tooling

Describe alternatives you've considered
brew info oasdiff only works when installed via brew and is not a comamnd many will be familiar vs the common version option of many CLIs

Additional context
Happy to help to implement this feature as I've done it before for other go CLIs as long as we agree on the option

Request fields were optional but now required

Describe the bug
Request fields were optional but now required

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -check-breaking -base swaggerSpec.yaml -revision openApiSpec.yaml -strip-prefix-base /partner-api -strip-prefix-revision /partner-api
  2. https://codeshare.io/QnD6J7 - swaggerSpec
  3. https://codeshare.io/bvbjm6 - openApiSpec
  4. Empty output (no diff)

Expected behavior

I expect to get a breaking change, because before this the fields were optional, and API users could not fill them out, but now they are required, and people's code can break

how to integration with

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Issue with oneOf and allOf aggregators for the same objects (bidirectional)

Describe the bug

kin-openapi fails with circular dependencies when number of objects in allOf or oneOf aggregator are bigger than 3.
Example schema: https://gist.github.com/wtrocki/2e272375386ddecff69d6228c89d2a05

This happens because oasdiff doesn't change default (very conservative) value in kin-openapi library:

CircularReferenceCounter

To Reproduce
Steps to reproduce the behavior:}
0. Download openapi file https://gist.github.com/wtrocki/2e272375386ddecff69d6228c89d2a05

  1. Run oasdiff -base openapi.yaml -revision openapi.yaml
  2. see error Failed to load base spec from "circularapi.yaml" with kin-openapi bug found: circular schema reference not handled - #/components/schemas/OnlineArchiveScheduleView -> #/components/schemas/DefaultScheduleView -> #/components/schemas/OnlineArchiveScheduleView -> #/components/schemas/DailyScheduleView -> #/components/schemas/OnlineArchiveScheduleView -> #/components/schemas/WeeklyScheduleView -> #/components/schemas/OnlineArchiveScheduleView

Expected behavior
OpenAPI is parsed

Fix build warning

Describe the bug
There are some warnings in the build process which need to be fixed before they break the build:
Warning: The `set-output` command is deprecated and will be disabled soon.
Warning: The `save-state` command is deprecated and will be disabled soon.

To Reproduce
Commit a change a check the build logs in GitHub.
Also here: https://github.com/Tufin/oasdiff/actions/runs/4197201506/jobs/7279305547

Expected behavior
No warnings

Screenshots
image

OASDIFF giving error with API specifications with multiple callbacks

Describe the bug
Getting the error "diff failed with request body reference is nil" while running the oasdiff between two API spec yaml files. It is giving this error in the scenario where specs files have more than one callback tag defined. Files getting compared are identical, then also getting this error.

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -base spec_1.yaml -revision spec_2.yaml

  2. attached spec_1 and spec_2
    Files.zip

  3. Snippet attached of the error for the comparison of two identical files
    snippet_error

Expected behavior
No output is expected as both files are identical

Screenshots
NA

Desktop (please complete the following information):

  • OS: [e.g. iOS] - Windows 10
  • Browser [e.g. chrome, safari] - Local
  • Version [e.g. 22]

Smartphone (please complete the following information):
NA

Additional context
NA

Changing a request property to enum should be breaking

Changing this ...

"type" {
    "type": "string"
}

... into this ...

"type": {
    "type": "string",
    "enum": [
        "article",
        "user",
        "image"
    ]
}

... in a request should be considered breaking since a client that could previously send in any string is now restricted to those expressed in the enum.

Allow the usage of "-format" with the new method

Is your feature request related to a problem? Please describe.
I am planning to use oasdiff not to detect changes, but to compare the designed OAPI with the one generated by the code. But I am expecting some differences, so I need to process the result with another mechanism. And will be easier to do so using the JSON or YAML format.

Describe the solution you'd like
As JSON is easier to deal in a script I will prefer over YAML, but I can work with the 3 options that used to work with the old method.

Describe alternatives you've considered
As the old method is deprecated I hope that this will be implemented before it is removed.

Additional note
As not all flags are common between both methods it will be better if this is clear in the documentation and/or help page.

malformed YAML structure for endpoints

Describe the bug
When using the diff with YAML format the Endpoints/Modified structure has a malformed YAML structure because the key is not a string.

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff.exe -format=text -base petstore.yaml -revision petstore_2.yaml -format yaml
  2. We will receive an malformed YAML because key under endpoints/modified 2 strings as identifier:
paths:
    modified:
        /pets:
            operations:
                modified:
                    GET:
                        parameters:
                            added:
                                query:
                                    - page_size
endpoints:
    modified:
        ?   method: GET
            path: /pets
        :   parameters:
                added:
                    query:
                        - page_size

Expected behavior
The structure under endpoints/modified can be converted to an array with one "id" structure and the "changes", in this case it will be presented as:

endpoints:
- modified:
  - id:
    - method: GET
      path: "/pets"
    changes:
    - parameters:
      - added:
        - query:
          - page_size

A second alternative is to exclude this structure from the YAML, using a flag or by default.

Desktop (please complete the following information):

  • OS: [e.g. iOS] Windows
  • Browser [e.g. chrome, safari] Chrome
  • Version [e.g. 22] 1.3.1

Additional context
petstore.yaml at https://gist.githubusercontent.com/peruzzof/affe59e40f5b257751462775775b7b7c/raw/b0d2299c3a3eba76bcb96bf9258bef68aaf50f74/petstore.yaml

petstore_2.yaml at https://gist.githubusercontent.com/peruzzof/affe59e40f5b257751462775775b7b7c/raw/b0d2299c3a3eba76bcb96bf9258bef68aaf50f74/petstore_2.yaml

Deep change of property in requestBody is not detected

Describe the bug
Given a request body view, when an item within a property has the object altered, no breaking changes are detected.

In the example below, "role" is renamed to "newRoleName"

  • Also, why required property removal for requestBody is classified as a warn? Shouldn't this be an error?

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -base base.yaml -revision revision.yaml
2. WIth base.yaml
paths:
  /api/roleMappings:
    post:
      summary: Add One Role Mapping 
      description: "Adds one role mapping to the specified organization in the specified\
      requestBody:
        description: The role mapping that you want to create.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleMappingView'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleMappingView'
  components:
  schemas:
    RoleAssignment:
      type: object
      properties:
        role:
          type: string
          description: RoleAssignment object
          enum:
          - OPTION_1
          - OPTION_2
          - OPTION_3
    RoleMappingView:
      title: Role Mapping
      required:
      - otherProp
      type: object
      properties:
        otherProp:
          maxLength: 200
          type: string
          description: Another property in role mapping
        roleAssignments:
          uniqueItems: true
          type: array
          description: Unique role assignment object.
          items:
            $ref: '#/components/schemas/RoleAssignment'
      description: Mapping settings
3. With revision.yaml
paths:
  /api/roleMappings:
    post:
      summary: Add One Role Mapping 
      description: "Adds one role mapping to the specified organization in the specified\
      requestBody:
        description: The role mapping that you want to create.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleMappingView'
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleMappingView'
  components:
  schemas:
    RoleAssignment:
      type: object
      properties:
        newRoleName:
          type: string
          description: RoleAssignment object
          enum:
          - OPTION_1
          - OPTION_2
          - OPTION_3
    RoleMappingView:
      title: Role Mapping
      required:
      - otherProp
      type: object
      properties:
        otherProp:
          maxLength: 200
          type: string
          description: Another property in role mapping
        roleAssignments:
          uniqueItems: true
          type: array
          description: Unique role assignment object.
          items:
            $ref: '#/components/schemas/RoleAssignment'
      description: Mapping settings
  1. Receive
    Empty result:

Expected behavior

warning	[request-property-removed] at revisionyaml
	in API POST /api/roleMappings
		removed the request property 'roleAssignments/role'

Desktop (please complete the following information):

  • OS: MacOS

Additional context
I have a fix for the issue, will open a PR

Changing a response property to nullable should be breaking

Changing this ...

"id": {
    "type": "string"
}

... into this ...

"id": {
    "type": "string",
    "nullable": true
}

... in a response should be considered breaking since the client now needs to handle null values when they previously always got a string.

Is allOf working properly ?

Is allOf attribute working properly in latest version?

In below response its shows all "allOf" attribute as deleted even if property is present in specification.

Modified response: 200
Content changed
Modified media type: application/json;charset=utf-8
Schema changed
Items changed
Property 'AllOf' changed
2 schemas added
Properties changed
Deleted property: @basetype
Deleted property: @schemaLocation
Deleted property: @type
Deleted property: aristocraticTitle
Deleted property: birthDate
Deleted property: contactMedium
Deleted property: countryOfBirth
Deleted property: creditRating
Deleted property: deathDate
Deleted property: disability
Deleted property: externalReference
Deleted property: familyName

Oasdiff does not recognize changes in Security Requirement Object

Describe the bug
Changes to an existing Security Requirement Object are not being recognized.

To Reproduce
Steps to reproduce the behavior:

  1. Create 2 different yaml specification files with security scheme
securitySchemes:
    petstore_auth:
      type: oauth2
      flows: 
        implicit:
          authorizationUrl: http://example.org/api/oauth/dialog
          scopes:
            write:pets: modify pets in your account
            read:pets: read your pets

where the first one (spec1.yaml) will have the following security object

security:
     - petstore_auth:
            - write:pets
            - read:pets

and the second one (spec2.yaml) will have the following security object

security:
     - petstore_auth:
            - write:pets
  1. Run oasdiff -base spec1.yaml -revision spec2,yaml
  2. No differences are detected

Expected behavior
I believe that the differences should be detected and that it should be marked as a breaking change

Screenshots
N/A

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: N/A
  • Version [e.g. 22]

Fail if a difference between specs has been found.

I have been using oasdiff inside a Gitlab pipeline which checks for breaking changes when a PR is submitted. Currently I grep the output oasdiff with -summary flag set.

It would be lovely to have an optional flag for the process to fail if a difference has been found.

Readonly-required properties are being marked as breaking changes

Describe the bug
Oasdiff ignores readOnly: true for required fields marking them as breaking changes when they are not

To Reproduce
Steps to reproduce the behavior:
base example

openapi: 3.0.1
info:  
  version: "1.0"
servers:
- url: https://localhost:9080
paths:
  /api/v1.0/groups:    
    post:     
      operationId: createOneGroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupView'
        description: Creates one project.
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK        
      summary: Create One Project
  /api/v1.0/groups/{groupId}:
    get:      
      operationId: returnOneGroup
      parameters:      
      - $ref: '#/components/parameters/groupId'      
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Return One Project
components:
  parameters:
    groupId:      
      in: path
      name: groupId
      required: true
      schema:
        type: string        
  schemas:
    GroupView:
      type: object
      properties:        
        created:
          type: string
          format: date-time          
          readOnly: true
        id:
          type: string          
          readOnly: true        
        name:
          type: string                  
      required:    
      - name

revision example

openapi: 3.0.1
info:  
  version: "1.0"
servers:
- url: https://localhost:9080
paths:
  /api/v1.0/groups:    
    post:     
      operationId: createOneGroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupView'
        description: Creates one project.
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK        
      summary: Create One Project
  /api/v1.0/groups/{groupId}:
    get:      
      operationId: returnOneGroup
      parameters:      
      - $ref: '#/components/parameters/groupId'      
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupView'
          description: OK
      summary: Return One Project
components:
  parameters:
    groupId:      
      in: path
      name: groupId
      required: true
      schema:
        type: string        
  schemas:
    GroupView:
      type: object
      properties:        
        created:
          type: string
          format: date-time          
          readOnly: true
        id:
          type: string          
          readOnly: true        
        name:
          type: string                  
      required:    
      - name
      - created
      - id
  1. Run oasdiff -breaking-only -base base.yaml -revision revision.yaml
  2. Receive
    modified:
        ?   method: POST
            path: /api/atlas/v1.0/groups
        :   requestBody:
                content:
                    mediaTypeModified:
                        application/json:
                            schema:
                                required:
                                    stringsdiff:
                                        added:
                                            - id
                                            - created

Expected behavior
It should not be a diff for POST, only GET and not a breaking change

Screenshots
redocly safely ignores read_only fields

Screenshot 2022-08-02 at 14 17 29

Desktop (please complete the following information):

  • OS: macOS
  • Version 1.1.39

Additional context
From the OAS definition

Relevant only for Schema "properties" definitions. Declares the property as "read only". This means that it MAY be sent as part of a response but SHOULD NOT be sent as part of the request. If the property is marked as readOnly being true and is in the required list, the required will take effect on the response only. A property MUST NOT be marked as both readOnly and writeOnly being true. Default value is false.

Node JS support

Could you please let me know?

  1. Is there a Node JS version of this same library?
  2. Can I call this Go library from Node JS backend?

oasdiff considers `/path/to/api/` and `/path/to/api` the same path but different endpoints.

Describe the bug
oasdiff considers /path/to/api/ and /path/to/api the same path but different endpoints.

To Reproduce
Consider the following file:

components: {}
info:
  description: API Info
  title: js
openapi: 3.0.0
paths:
  /path/to/api:
    post:
      requestBody:
        content:
          application/json:
            schema:
              properties:
                searchText:
                  type: string
              type: object
        required: true
      responses:
        default:
          description: Default response
  /path/to/api/:
    get:
      responses:
        default:
          description: Default response

We have two different paths, one with a trailing slash and one without. This is legal according to the specification and RFC3986.

Let's diff it with itself.

$ oasdiff -format text -base ex.yaml -revision ex.yaml

### New Endpoints: 1
--------------------
POST /path/to/api/

### Deleted Endpoints: 1
------------------------
GET /path/to/api/

### Modified Endpoints: None
----------------------------

diff.getPathsDiff doesn't detect any differences here but diff.getEndpointsDiff returns this object:

*github.com/tufin/oasdiff/diff.EndpointsDiff {Added: github.com/tufin/oasdiff/diff.Endpoints len: 1, cap: 1, 

value of the above:
github.com/tufin/oasdiff/diff.Endpoint {Method: "POST", Path: "/path/to/api/"}

[(*"github.com/tufin/oasdiff/diff.Endpoint")(0xc0002b82c0)], Deleted: github.com/tufin/oasdiff/diff.Endpoints len: 1, cap: 1, 

value of the above:
github.com/tufin/oasdiff/diff.Endpoint {Method: "GET", Path: "/path/to/api/"}

[(*"github.com/tufin/oasdiff/diff.Endpoint")(0xc0002b82e0)], Modified: github.com/tufin/oasdiff/diff.ModifiedEndpoints []}

Note how the Path in both items has the trailing slash.

Expected behavior
These are the same. We should not see differences.

Redirect all error related messages to stderr

Is your feature request related to a problem? Please describe.
Currently, oasdiff only displays exit codes into stderr, which makes it difficult for automation scripts to gather all the displayed information about an error. Furthermore, from a CLI perspective, error messages are expected to be redirected to stderr.

Describe the solution you'd like
The details in the error (example) should also be redirected to stderr:

failed to load base spec from "openapi_prod.yaml" with openapi_prod.yaml: no such file or directory
Command failed: process encountered problem: exit code 102

Describe alternatives you've considered
Redirect stdout to a file and check if the command threw an error, if so, cat the stdout and assume it is the error details.

Additional context
If we agree this is a good feature to be implemented, I'm happy to discuss further and come up with a PR to contribute and help improve oasdiff error handling.

String formating problem in [request-parameter-default-value-changed]

Good afternoon. I noticed an error in the formation of the request-parameter-default-value-changed error message:
[request-parameter-default-value-changed] error at spec_compatibility/openApiSpec.yaml, in API GET /accounting/products for the 'query' request parameter 'take', default value was changed from '%!s(<nil>)' to '100.00'

Support ignoring deprecated resource removal

Is your feature request related to a problem? Please describe.
When we have a deprecated resource for some time, we don't want mark the removal of that resource a breaking change.

Describe the solution you'd like
Could we have a flag --ignore-deprecated-removal so that we can optionally remove it without having this reported as a breaking change?

Describe alternatives you've considered
Considered using --filter-extension to remove the deprecated word, but seems a bit hacky based on the extension's definition - https://swagger.io/docs/specification/openapi-extensions/. Is that correct?

Additional context
We're deciding if we'll be able to use this tool based on the flexibility of contributing with some optional flags to help. Would that be possible? Thanks!

ResponsePropertyBecameOptionalCheck panics on property removal

Describe the bug
ResponsePropertyBecameOptionalCheck throws a panic error on property removal

To Reproduce
Steps to reproduce the behavior:

  1. Run -base {source_path}/breaking-changes-test-spec-base.yaml -revision {source_path}/breaking-changes-test-spec-revision.yaml -deprecation-days=365 -check-breaking"
  2. With base
  3. And revision
  4. Recieve
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x104753ad0]

goroutine 1 [running]:
github.com/tufin/oasdiff/checker.ResponsePropertyBecameOptionalCheck(0x14000306870, 0x140000109a8, {{0x140001648c0, 0x38, 0x38}, 0x1f, 0xb4, {{0x10491566e, 0x2}, {0x10491566e, ...}, ...}})
	/<redactedpath>/workplace/oasdiff/checker/check-response-property-became-optional.go:39 +0x5c0
github.com/tufin/oasdiff/checker.CheckBackwardCompatibility({{0x140001648c0, 0x38, 0x38}, 0x1f, 0xb4, {{0x10491566e, 0x2}, {0x10491566e, 0x2}, 0x1400007f5c0}}, ...)
	/<redactedpath>/workplace/oasdiff/checker/checker.go:118 +0x14c
main.main()
	/<redactedpath>/workplace/oasdiff/main.go:172 +0xdcc
  1. Expected behavior
Backward compatibility errors (1):
error at /<redactedpath>/workplace/mms/server/openapi/atlas/breaking-changes-test-spec-revision.yaml, in API GET /api/atlas/v2/removeOutputFieldTest removed the required property 'name' from the response with the '200' status [response-required-property-removed]. 

Desktop (please complete the following information):

  • OS: macOS Monterey
  • Browserchrome
  • Version oasdiff version: 1.3.4

Additional comments
Opening a PR to fix it now

panic: runtime error: invalid memory address or nil pointer dereference

Describe the bug

It seems when one spec has oauth2 flow and the other does not, I get panic: runtime error: invalid memory address or nil pointer dereference.

To Reproduce

I have in one spec:

  securitySchemes:
    AccessToken:
      type: oauth2
      flows:
        ...

and in the other:

  securitySchemes:
    AccessToken:
      type: http
      scheme: bearer

Expected behavior

I get some diff.

Additional context

I think the problem is in this code inside getOAuthFlowsDiffInternal:

        if flows1 == nil && flows2 == nil {
                return nil
        }

        result := OAuthFlowsDiff{}

        result.ExtensionsDiff = getExtensionsDiff(config, flows1.ExtensionProps, flows2.ExtensionProps)

The if checks only if both of flows are nil, but it seems in my case one is nil and the other is not, so once you get to flows1.ExtensionProps, if flows1 is nil, you get a panic.

Smarter detection of path changes

Recently we detected that one of our OAS files had the path prefix included in the path operations instead of the server URL, we moved to fix this, by stripping and moving the prefix to the server.
OAS Diff doing its job, detected those as breaking changes, something that would be true if we really changed the entire path of the operation.
But since this was only moved to the server the true path was not truly modified in a breaking way.

Describe the solution you'd like
Compare the entire URL of the operation (including the server)

Additional context
Example of breaking change:

==========================================================================
==                            API CHANGE LOG                            ==
==========================================================================
                               Test                               
--------------------------------------------------------------------------
--                              What's New                              --
--------------------------------------------------------------------------
- GET    /test/
- GET    /test/{id}
--------------------------------------------------------------------------
--                            What's Deleted                            --
--------------------------------------------------------------------------
- GET    /api/v2/test/
- GET    /api/v2/test/{id}
--------------------------------------------------------------------------
--                                Result                                --
--------------------------------------------------------------------------
                 API changes broke backward compatibility                 
--------------------------------------------------------------------------

An Issue with comparing

When I start comparing with a docker container I get the error:
The file size of my API YAML is 1670737 bytes.
My docker command is docker run -ti -v /d/data:/data tufin/oasdiff -format yaml -base /data/v25.yaml -revision /data/v26.yaml

runtime: goroutine stack exceeds 1000000000-byte limit
runtime: sp=0xc0221e6370 stack=[0xc0221e6000, 0xc0421e6000]
fatal error: stack overflow

runtime stack:
runtime.throw(0x9582af, 0xe)
/usr/local/go/src/runtime/panic.go:1117 +0x72
runtime.newstack()
/usr/local/go/src/runtime/stack.go:1069 +0x7ed
runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:458 +0x8f

goroutine 1 [running]:
reflect.Value.Type(0x8c0e20, 0xc00da7e0a0, 0x98, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:1905 +0x18f fp=0xc0221e6380 sp=0xc0221e6378 pc=0x49d20f
reflect.deepValueEqual(0x8c0e20, 0xc00da7e0a0, 0x98, 0x8c0e20, 0xc00da7e0b0, 0x98, 0xc0221e6540, 0x30)
/usr/local/go/src/reflect/deepequal.go:28 +0x9f fp=0xc0221e64a0 sp=0xc0221e6380 pc=0x48a73f
reflect.DeepEqual(0x8c0e20, 0xc00da7e0a0, 0x8c0e20, 0xc00da7e0b0, 0x0)
/usr/local/go/src/reflect/deepequal.go:218 +0x2a7 fp=0xc0221e6698 sp=0xc0221e64a0 pc=0x48bf27
github.com/tufin/oasdiff/diff.getValueDiff(...)
/go/src/app/diff/value_diff.go:21
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:104 +0x447 fp=0xc0221e6810 sp=0xc0221e6698 pc=0x724ce7
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e6990 sp=0xc0221e6810 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221e6b10 sp=0xc0221e6990 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221e6b88 sp=0xc0221e6b10 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221e6c18 sp=0xc0221e6b88 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221e6c78 sp=0xc0221e6c18 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221e6df0 sp=0xc0221e6c78 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e6f70 sp=0xc0221e6df0 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b35e9f0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221e71c0, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221e70f0 sp=0xc0221e6f70 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da801c0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221e7201)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221e7140 sp=0xc0221e70f0 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b35e900)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221e7290 sp=0xc0221e7140 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221e72d0 sp=0xc0221e7290 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221e7448 sp=0xc0221e72d0 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e75c8 sp=0xc0221e7448 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221e7748 sp=0xc0221e75c8 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221e77c0 sp=0xc0221e7748 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221e7850 sp=0xc0221e77c0 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221e78b0 sp=0xc0221e7850 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221e7a28 sp=0xc0221e78b0 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e7ba8 sp=0xc0221e7a28 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b35e750, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221e7df8, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221e7d28 sp=0xc0221e7ba8 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da80100, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221e7e01)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221e7d78 sp=0xc0221e7d28 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b35e630)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221e7ec8 sp=0xc0221e7d78 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221e7f08 sp=0xc0221e7ec8 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221e8080 sp=0xc0221e7f08 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e8200 sp=0xc0221e8080 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221e8380 sp=0xc0221e8200 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221e83f8 sp=0xc0221e8380 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221e8488 sp=0xc0221e83f8 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221e84e8 sp=0xc0221e8488 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221e8660 sp=0xc0221e84e8 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e87e0 sp=0xc0221e8660 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b35e4b0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221e8a30, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221e8960 sp=0xc0221e87e0 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da80040, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221e8a01)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221e89b0 sp=0xc0221e8960 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b35e360)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221e8b00 sp=0xc0221e89b0 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221e8b40 sp=0xc0221e8b00 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221e8cb8 sp=0xc0221e8b40 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e8e38 sp=0xc0221e8cb8 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221e8fb8 sp=0xc0221e8e38 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221e9030 sp=0xc0221e8fb8 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221e90c0 sp=0xc0221e9030 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221e9120 sp=0xc0221e90c0 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x400, 0x7f005012f000, 0x20300300000000)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221e9298 sp=0xc0221e9120 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e9418 sp=0xc0221e9298 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b35e1e0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221e9668, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221e9598 sp=0xc0221e9418 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da73f80, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221e9601)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221e95e8 sp=0xc0221e9598 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b35e0c0)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221e9738 sp=0xc0221e95e8 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221e9778 sp=0xc0221e9738 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221e98f0 sp=0xc0221e9778 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221e9a70 sp=0xc0221e98f0 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221e9bf0 sp=0xc0221e9a70 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221e9c68 sp=0xc0221e9bf0 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221e9cf8 sp=0xc0221e9c68 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221e9d58 sp=0xc0221e9cf8 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221e9ed0 sp=0xc0221e9d58 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221ea050 sp=0xc0221e9ed0 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b355ef0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221ea2a0, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221ea1d0 sp=0xc0221ea050 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da73ec0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221ea301)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221ea220 sp=0xc0221ea1d0 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b355e00)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221ea370 sp=0xc0221ea220 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221ea3b0 sp=0xc0221ea370 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221ea528 sp=0xc0221ea3b0 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221ea6a8 sp=0xc0221ea528 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221ea828 sp=0xc0221ea6a8 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221ea8a0 sp=0xc0221ea828 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221ea930 sp=0xc0221ea8a0 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221ea990 sp=0xc0221ea930 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221eab08 sp=0xc0221ea990 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221eac88 sp=0xc0221eab08 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b355c50, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221eaed8, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221eae08 sp=0xc0221eac88 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da73e00, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221eaf01)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221eae58 sp=0xc0221eae08 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b355b60)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221eafa8 sp=0xc0221eae58 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221eafe8 sp=0xc0221eafa8 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221eb160 sp=0xc0221eafe8 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221eb2e0 sp=0xc0221eb160 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221eb460 sp=0xc0221eb2e0 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221eb4d8 sp=0xc0221eb460 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221eb568 sp=0xc0221eb4d8 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221eb5c8 sp=0xc0221eb568 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221eb740 sp=0xc0221eb5c8 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221eb8c0 sp=0xc0221eb740 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b3559b0, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221ebb10, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221eba40 sp=0xc0221eb8c0 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da73d40, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221ebb01)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221eba90 sp=0xc0221eba40 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b355890)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221ebbe0 sp=0xc0221eba90 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221ebc20 sp=0xc0221ebbe0 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221ebd98 sp=0xc0221ebc20 pc=0x725a85
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x8, 0x415165)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221ebf18 sp=0xc0221ebd98 pc=0x72479d
github.com/tufin/oasdiff/diff.findSchema(0xc0421e5f48, 0xc000531a40, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x8, 0x0)
/go/src/app/diff/schema_list_diff.go:79 +0x85 fp=0xc0221ec098 sp=0xc0221ebf18 pc=0x727925
github.com/tufin/oasdiff/diff.schemaRefsContained(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0, ...)
/go/src/app/diff/schema_list_diff.go:65 +0xb4 fp=0xc0221ec110 sp=0xc0221ec098 pc=0x727774
github.com/tufin/oasdiff/diff.getSchemaListsDiffInternal(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0xc0018b4d80, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:34 +0x8e fp=0xc0221ec1a0 sp=0xc0221ec110 pc=0x72746e
github.com/tufin/oasdiff/diff.getSchemaListsDiff(0xc0421e5f48, 0xc000415f20, 0x1, 0x4, 0xc000d00ee0, 0x1, 0x4, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_list_diff.go:22 +0x74 fp=0xc0221ec200 sp=0xc0221ec1a0 pc=0x727334
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:88 +0x1fa fp=0xc0221ec378 sp=0xc0221ec200 pc=0x724a9a
github.com/tufin/oasdiff/diff.getSchemaDiff(0xc0421e5f48, 0xc0005319b0, 0xc0018c2378, 0x7f004f5064d0, 0xd0, 0xd0)
/go/src/app/diff/schema_diff.go:59 +0x5d fp=0xc0221ec4f8 sp=0xc0221ec378 pc=0x72479d
github.com/tufin/oasdiff/diff.ModifiedSchemas.addSchemaDiff(0xc00b355710, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0xc0221ec748, 0xffffffffffffffff)
/go/src/app/diff/modified_schemas.go:12 +0x5d fp=0xc0221ec678 sp=0xc0221ec4f8 pc=0x71d8dd
github.com/tufin/oasdiff/diff.(*SchemasDiff).addModifiedSchema(0xc00da73c80, 0xc0421e5f48, 0xc0005284c8, 0x4, 0xc0005319b0, 0xc0018c2378, 0x8c0e20, 0xc0221ec701)
/go/src/app/diff/schemas_diff.go:113 +0x65 fp=0xc0221ec6c8 sp=0xc0221ec678 pc=0x728425
github.com/tufin/oasdiff/diff.getSchemasDiffInternal(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0xc00b3555c0)
/go/src/app/diff/schemas_diff.go:66 +0x406 fp=0xc0221ec818 sp=0xc0221ec6c8 pc=0x727f86
github.com/tufin/oasdiff/diff.getSchemasDiff(0xc0421e5f48, 0xc00131b770, 0xc0018b4d20, 0x0, 0x0, 0x0)
/go/src/app/diff/schemas_diff.go:41 +0x45 fp=0xc0221ec858 sp=0xc0221ec818 pc=0x727ac5
github.com/tufin/oasdiff/diff.getSchemaDiffInternal(0xc0421e5f48, 0xc000531a40, 0xc0018c23f0, 0x0, 0x0, 0x0)
/go/src/app/diff/schema_diff.go:137 +0x11e5 fp=0xc0221ec9d0 sp=0xc0221ec858 pc=0x725a85

Coloured output

Problem

A little difficult to distinguish between context, added, deleted, and modified properties in monochromatic output.

Proposal

Add option to have coloured output:

  • For YAML, JSON and text format, if the output is a TTY, using terminal escapes
  • For HTML, using CSS (ideally via classes)

Perhaps on by default (-color auto), with explicit enable/disable (disregard output not being a TTY for -color always).

Blue for context (endpoint method/paths, 'XXX changed'), red for deleted, orange/yellow for modified, and green for added.

Alternatives

Deal with no colours.

oasdiff.exe seems to infinite loop

oasdiff.exe -base 202201200951-confluxeyservicesint.json -revision 202201280912-confluxeyservicesint.json --breaking-only -format yaml

Both JSON files are OpenAPI3 and the JSON is valid (via JSONLINT).

O/S: Windows 10 Patched

go version
go version go1.17.6 windows/amd64

To Reproduce
Steps to reproduce the behavior:

  1. Use the sample files
  2. Repeat command above
  3. Observed infinite loop

Expected behavior
Diff is generated in YAML

Notes

  1. Only seems to impact some file comparisons, others work fine
  2. I can supply the problematic files for repo, please e-mail [email protected] and I'll send them to you
  3. I apologize for lacking more detailed debugging, I don't speak GO, yet

command-line with sub-commands

Currently the oasdiff cmd-line has many arguments, some of which are incompatible with each-other.
This is a result of a natural evolution from a single-purpose diff tool, through options that were added later, including the addition of two breaking-changes implementations and a future change-log option.

It is time to move to a sub-command design which will simplify the user experience and implementation.
Please see the design document.

Comments are welcome.

err-ignore subpaths skipped

Describe the bug
if you have the same breaking change in both a path and its subpath and you try to add both lines to the err-ignore file, the first one will be omitted from the oasdiff, but the subsequent ones will still show up.

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff on a spec that contains multiple endpoints under the same root and another spec that omits them to produce the following output

error [api-path-removed-without-deprecation] at original_source=Conga.Revenue.Catalog.API/swagger.json
in API GET /health
api path removed without deprecation

error [api-path-removed-without-deprecation] at original_source=Conga.Revenue.Catalog.API/swagger.json
in API GET /health/live
api path removed without deprecation

error [api-path-removed-without-deprecation] at original_source=Conga.Revenue.Catalog.API/swagger.json
in API GET /health/ready
api path removed without deprecation

  1. Add all 3 errors to the the err-ignore.txt file:
    get /health api path removed without deprecation
    get /health/live api path removed without deprecation
    get /health/ready api path removed without deprecation

Expected behavior
All 3 errors will be omitted from the oasdiff output

Actual behavior
only the first /health endpoint is ignored and the /health/ready and /health/live errors still show. Interestingly, even if you only have one of the subpath errors in the err-ignore.txt file, it still just ignores the first /health error.

I believe its because of the matching logic on line 32 of ignore.go. The logic is if the line contains (err.Operation+" "+err.Path) and all 3 of those lines meet that criteria for the /health error.

-format text fails to report server changes

Describe the bug
When running oasdiff with the -format text option it fails to report certain changes.

To Reproduce

$ ./oasdiff -fail-on-diff -breaking-only -format text -base "./current.json" -revision "./new.json"
No endpoint changes
$ echo $?
1

Executing the same command with -format yaml shows changes to servers and paths:

paths:
    modified:
        /foo:
            servers:
                deleted:
                    - ...
servers:
    deleted:
        - ...

Expected behavior
Report changes to paths and deleted servers in text format.

Desktop (please complete the following information):

  • OS: Ubuntu 20.04

Add support for OpenAPI custom extensions

Is your feature request related to a problem? Please describe.
Some of our OpenAPI specifications are new and under development, it becomes difficult to exclude them from automating backward compatibility checks (as they will often fail due to changes).

Describe the solution you'd like
Add support for filtering based on OpenAPI custom extensions (e.g. -exclude-extension x-beta)

Describe alternatives you've considered

  • Manual script parsing schemas and comparing against oasdiff
  • Enabling manually oasdiff for specific APIs (increases maintenance, defies automation).

Additional context
Add any other context or screenshots about the feature request here.

Path Parameter false positive

Describe the bug
I keep getting the error added the new path request parameter 'categoryId' . Even though its the same path parameter in the base vs the revision. I've tried adding the line to an err-ignore.txt file, but its still giving me the error:

GET /categories/{categoryId}/products added the new path request parameter 'categoryId'

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -check-breaking -base my.yaml -revision my.json --err-ignore .\Documentation\err-ignore.txt
  2. With base https://pastebin.com/FZLCyCWm
  3. And revision https://pastebin.com/SaE42n7H

Expected behavior
oasdiff should not be flagging the path parameter as an error because the base and revision are identical

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: Windows 11 (using the windows executable version 1.3.17)

goroutine stack exceeds 1000000000-byte limit

Describe the bug
I encountered the following crash when comparing two swagger Json files (which I can't share, sorry). Looks like recursion in resolveSchemaRef which I assume means one or both the Swagger files contains circular references.

Is there an easy way to dump out what it's doing? I was using the Docker image to run the utility.

To Reproduce
runtime: goroutine stack exceeds 1000000000-byte limit runtime: sp=0xc140fd2388 stack=[0xc140fd2000, 0xc160fd2000] fatal error: stack overflow runtime stack: runtime.throw({0x8df207?, 0xbfc7a0?})
/usr/local/go/src/runtime/panic.go:992 +0x71 runtime.newstack()
/usr/local/go/src/runtime/stack.go:1101 +0x5cc runtime.morestack()
/usr/local/go/src/runtime/asm_amd64.s:547 +0x8b goroutine 1 [running]: runtime.resolveNameOff(0x8707e0?, 0xbec8)
/usr/local/go/src/runtime/type.go:188 +0x274 fp=0xc140fd2398 sp=0xc140fd2390 pc=0x459ab4 reflect.resolveNameOff(0x0?, 0x0?)
/usr/local/go/src/runtime/runtime1.go:498 +0x19 fp=0xc140fd23b8 sp=0xc140fd2398 pc=0x45ed59 reflect.(*rtype).nameOff(...)
/usr/local/go/src/reflect/type.go:729 reflect.(*rtype).String(0x8707e0)
/usr/local/go/src/reflect/type.go:799 +0x25 fp=0xc140fd23d8 sp=0xc140fd23b8 pc=0x481d05 reflect.(*rtype).Name(0x8707e0?)
/usr/local/go/src/reflect/type.go:916 +0x2a fp=0xc140fd23f8 sp=0xc140fd23d8 pc=0x4829aa encoding/json.indirect({0x8707e0?, 0xc2440b0b28?, 0x0?}, 0x0)
/usr/local/go/src/encoding/json/decode.go:443 +0x76 fp=0xc140fd2490 sp=0xc140fd23f8 pc=0x554796 encoding/json.(*decodeState).object(0xc1955ed290, {0x8707e0?, 0xc2440b0b28?, 0x18?})
/usr/local/go/src/encoding/json/decode.go:608 +0x69 fp=0xc140fd26e0 sp=0xc140fd2490 pc=0x555529 encoding/json.(*decodeState).value(0xc1955ed290, {0x8707e0?, 0xc2440b0b28?, 0x874c20?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd2750 sp=0xc140fd26e0 pc=0x554505 encoding/json.(*decodeState).object(0xc1955ed290, {0x84c9a0?, 0xc18f446cc8?, 0x0?})
/usr/local/go/src/encoding/json/decode.go:774 +0xca5 fp=0xc140fd29a0 sp=0xc140fd2750 pc=0x556165 encoding/json.(*decodeState).value(0xc1955ed290, {0x84c9a0?, 0xc18f446cc8?, 0x90?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd2a10 sp=0xc140fd29a0 pc=0x554505 encoding/json.(*decodeState).unmarshal(0xc1955ed290, {0x84c9a0?, 0xc18f446cc8?})
/usr/local/go/src/encoding/json/decode.go:180 +0x1de fp=0xc140fd2a88 sp=0xc140fd2a10 pc=0x553e1e encoding/json.Unmarshal({0xc1955e484c, 0x5e, 0x2b4}, {0x84c9a0, 0xc18f446cc8})
/usr/local/go/src/encoding/json/decode.go:107 +0x125 fp=0xc140fd2ac0 sp=0xc140fd2a88 pc=0x553925 github.com/getkin/kin-openapi/jsoninfo.NewObjectDecoder({0xc1955e484c, 0x5e, 0x2b4})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/unmarshal.go:27 +0x56 fp=0xc140fd2b20 sp=0xc140fd2ac0 pc=0x6c5536 github.com/getkin/kin-openapi/jsoninfo.UnmarshalStrictStruct({0xc1955e484c?, 0x5e?, 0x1?}, {0x9c5290, 0xc1955f4680})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/unmarshal.go:13 +0x28 fp=0xc140fd2b50 sp=0xc140fd2b20 pc=0x6c5448 github.com/getkin/kin-openapi/openapi3.(*Schema).UnmarshalJSON(0xc1955ed200?, {0xc1955e484c?, 0x0?, 0xc1955e4800?})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/schema.go:176 +0x31 fp=0xc140fd2b88 sp=0xc140fd2b50 pc=0x6e02b1 encoding/json.(*decodeState).object(0xc1955ed200, {0x847a60?, 0xc2440b0b08?, 0x0?})
/usr/local/go/src/encoding/json/decode.go:612 +0x68a fp=0xc140fd2dd8 sp=0xc140fd2b88 pc=0x555b4a encoding/json.(*decodeState).value(0xc1955ed200, {0x847a60?, 0xc2440b0b08?, 0x90?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd2e48 sp=0xc140fd2dd8 pc=0x554505 encoding/json.(*decodeState).unmarshal(0xc1955ed200, {0x847a60?, 0xc2440b0b08?})
/usr/local/go/src/encoding/json/decode.go:180 +0x1de fp=0xc140fd2ec0 sp=0xc140fd2e48 pc=0x553e1e encoding/json.Unmarshal({0xc1955e484c, 0x5e, 0x2b4}, {0x847a60, 0xc2440b0b08})
/usr/local/go/src/encoding/json/decode.go:107 +0x125 fp=0xc140fd2ef8 sp=0xc140fd2ec0 pc=0x553925 github.com/getkin/kin-openapi/jsoninfo.UnmarshalRef({0xc1955e484c, 0x5e, 0x2b4}, 0xc2440b0af8, {0x847a60, 0xc2440b0b08})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/marshal_ref.go:25 +0xd1 fp=0xc140fd2f38 sp=0xc140fd2ef8 pc=0x6c50b1 github.com/getkin/kin-openapi/openapi3.(*SchemaRef).UnmarshalJSON(0xc1955ed0e0?, {0xc1955e484c?, 0x84e920?, 0xc19532c000?})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/refs.go:286 +0x3a fp=0xc140fd2f78 sp=0xc140fd2f38 pc=0x6de2fa encoding/json.(*decodeState).object(0xc1955ed0e0, {0x88b880?, 0xc18f446cc0?, 0x8?})
/usr/local/go/src/encoding/json/decode.go:612 +0x68a fp=0xc140fd31c8 sp=0xc140fd2f78 pc=0x555b4a encoding/json.(*decodeState).value(0xc1955ed0e0, {0x88b880?, 0xc18f446cc0?, 0x8855a0?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd3238 sp=0xc140fd31c8 pc=0x554505 encoding/json.(*decodeState).object(0xc1955ed0e0, {0x86d180?, 0xc1955f4638?, 0x0?})
/usr/local/go/src/encoding/json/decode.go:774 +0xca5 fp=0xc140fd3488 sp=0xc140fd3238 pc=0x556165 encoding/json.(*decodeState).value(0xc1955ed0e0, {0x86d180?, 0xc1955f4638?, 0x90?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd34f8 sp=0xc140fd3488 pc=0x554505 encoding/json.(*decodeState).unmarshal(0xc1955ed0e0, {0x86d180?, 0xc1955f4638?})
/usr/local/go/src/encoding/json/decode.go:180 +0x1de fp=0xc140fd3570 sp=0xc140fd34f8 pc=0x553e1e encoding/json.Unmarshal({0xc1955e4840, 0x29d, 0x2c0}, {0x86d180, 0xc1955f4638})
/usr/local/go/src/encoding/json/decode.go:107 +0x125 fp=0xc140fd35a8 sp=0xc140fd3570 pc=0x553925 github.com/getkin/kin-openapi/jsoninfo.(*ObjectDecoder).DecodeStructFieldsAndExtensions(0xc1956a1a40, {0x8d3b00, 0xc1955f44e0?})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/unmarshal.go:105 +0x614 fp=0xc140fd3778 sp=0xc140fd35a8 pc=0x6c5c94 github.com/getkin/kin-openapi/openapi3.(*ExtensionProps).DecodeWith(0xc1955f44e0, 0xc1956a1a40, {0x8d3b00?, 0xc1955f44e0?})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/extension.go:28 +0x54 fp=0xc140fd3830 sp=0xc140fd3778 pc=0x6cc2d4 github.com/getkin/kin-openapi/jsoninfo.UnmarshalStrictStruct({0xc1955e4580?, 0x2bc?, 0x1?}, {0x9c5290, 0xc1955f44e0})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/unmarshal.go:17 +0x54 fp=0xc140fd3860 sp=0xc140fd3830 pc=0x6c5474 github.com/getkin/kin-openapi/openapi3.(*Schema).UnmarshalJSON(0xc1955ecfc0?, {0xc1955e4580?, 0x0?, 0xc1955e4800?})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/schema.go:176 +0x31 fp=0xc140fd3898 sp=0xc140fd3860 pc=0x6e02b1 encoding/json.(*decodeState).object(0xc1955ecfc0, {0x847a60?, 0xc243e6c760?, 0x0?})
/usr/local/go/src/encoding/json/decode.go:612 +0x68a fp=0xc140fd3ae8 sp=0xc140fd3898 pc=0x555b4a encoding/json.(*decodeState).value(0xc1955ecfc0, {0x847a60?, 0xc243e6c760?, 0x90?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd3b58 sp=0xc140fd3ae8 pc=0x554505 encoding/json.(*decodeState).unmarshal(0xc1955ecfc0, {0x847a60?, 0xc243e6c760?})
/usr/local/go/src/encoding/json/decode.go:180 +0x1de fp=0xc140fd3bd0 sp=0xc140fd3b58 pc=0x553e1e encoding/json.Unmarshal({0xc1955e4580, 0x2bc, 0x2c0}, {0x847a60, 0xc243e6c760})
/usr/local/go/src/encoding/json/decode.go:107 +0x125 fp=0xc140fd3c08 sp=0xc140fd3bd0 pc=0x553925 github.com/getkin/kin-openapi/jsoninfo.UnmarshalRef({0xc1955e4580, 0x2bc, 0x2c0}, 0xc243e6c750, {0x847a60, 0xc243e6c760})
/go/pkg/mod/github.com/getkin/[email protected]/jsoninfo/marshal_ref.go:25 +0xd1 fp=0xc140fd3c48 sp=0xc140fd3c08 pc=0x6c50b1 github.com/getkin/kin-openapi/openapi3.(*SchemaRef).UnmarshalJSON(0xc1955ecea0?, {0xc1955e4580?, 0xc2440b08a0?, 0x100000000851900?})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/refs.go:286 +0x3a fp=0xc140fd3c88 sp=0xc140fd3c48 pc=0x6de2fa encoding/json.(*decodeState).object(0xc1955ecea0, {0x88b880?, 0xc243e6c750?, 0x0?})
/usr/local/go/src/encoding/json/decode.go:612 +0x68a fp=0xc140fd3ed8 sp=0xc140fd3c88 pc=0x555b4a encoding/json.(*decodeState).value(0xc1955ecea0, {0x88b880?, 0xc243e6c750?, 0x90?})
/usr/local/go/src/encoding/json/decode.go:373 +0x45 fp=0xc140fd3f48 sp=0xc140fd3ed8 pc=0x554505 encoding/json.(*decodeState).unmarshal(0xc1955ecea0, {0x88b880?, 0xc243e6c750?})
/usr/local/go/src/encoding/json/decode.go:180 +0x1de fp=0xc140fd3fc0 sp=0xc140fd3f48 pc=0x553e1e encoding/json.Unmarshal({0xc1955e4580, 0x2bc, 0x2c0}, {0x88b880, 0xc243e6c750})
/usr/local/go/src/encoding/json/decode.go:107 +0x125 fp=0xc140fd3ff8 sp=0xc140fd3fc0 pc=0x553925 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveComponent.func2({0x8750a0?, 0xc1adcfeab0?}, {0x88b880, 0xc243e6c750})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:322 +0x45 fp=0xc140fd4030 sp=0xc140fd3ff8 pc=0x6d1925 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveComponent(0xc226bb6900?, 0x48?, {0xc226bb6900?, 0x412219?}, 0xc000110120, {0x88b880?, 0xc243e6c750})
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:327 +0x703 fp=0xc140fd42f0 sp=0xc140fd4030 pc=0x6d20a3 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc243e6c0d8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:694 +0x1ab fp=0xc140fd4420 sp=0xc140fd42f0 pc=0x6d4dcb github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc243e6c078, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd4550 sp=0xc140fd4420 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc243a07d10, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd4680 sp=0xc140fd4550 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc243a07758, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd47b0 sp=0xc140fd4680 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc243a076b0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd48e0 sp=0xc140fd47b0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc2437bd320, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd4a10 sp=0xc140fd48e0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2437bccf0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd4b40 sp=0xc140fd4a10 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2437bcc78, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd4c70 sp=0xc140fd4b40 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc24358a918, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd4da0 sp=0xc140fd4c70 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24358a2b8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd4ed0 sp=0xc140fd4da0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24358a258, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd5000 sp=0xc140fd4ed0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc243119e90, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd5130 sp=0xc140fd5000 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2431198d8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd5260 sp=0xc140fd5130 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc243119860, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd5390 sp=0xc140fd5260 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc242ecf500, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd54c0 sp=0xc140fd5390 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242ecf008, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd55f0 sp=0xc140fd54c0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242ecef90, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd5720 sp=0xc140fd55f0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc242ca0c78, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd5850 sp=0xc140fd5720 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242ca0690, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd5980 sp=0xc140fd5850 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242ca05e8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd5ab0 sp=0xc140fd5980 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc242a4a2a0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd5be0 sp=0xc140fd5ab0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242805c08, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd5d10 sp=0xc140fd5be0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242805ba8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd5e40 sp=0xc140fd5d10 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc2425c78f0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd5f70 sp=0xc140fd5e40 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2425c72f0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd60a0 sp=0xc140fd5f70 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2425c7278, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd61d0 sp=0xc140fd60a0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc242374f00, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd6300 sp=0xc140fd61d0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242374900, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd6430 sp=0xc140fd6300 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc242374870, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd6560 sp=0xc140fd6430 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc24212a570, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd6690 sp=0xc140fd6560 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241ee5ed8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd67c0 sp=0xc140fd6690 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241ee5e48, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd68f0 sp=0xc140fd67c0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc241c91ae8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd6a20 sp=0xc140fd68f0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241c914e8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd6b50 sp=0xc140fd6a20 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241c91470, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd6c80 sp=0xc140fd6b50 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc241a4d0f8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd6db0 sp=0xc140fd6c80 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241a4cab0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd6ee0 sp=0xc140fd6db0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241a4ca20, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd7010 sp=0xc140fd6ee0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc241812690, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd7140 sp=0xc140fd7010 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2418120f0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd7270 sp=0xc140fd7140 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241812078, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd73a0 sp=0xc140fd7270 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc24137bcc8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd74d0 sp=0xc140fd73a0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24137b740, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd7600 sp=0xc140fd74d0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24137b6e0, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd7730 sp=0xc140fd7600 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc241151338, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd7860 sp=0xc140fd7730 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241150e70, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd7990 sp=0xc140fd7860 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc241150df8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd7ac0 sp=0xc140fd7990 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc240f04a68, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd7bf0 sp=0xc140fd7ac0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc240f044f8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd7d20 sp=0xc140fd7bf0 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc240f04480, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd7e50 sp=0xc140fd7d20 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc240cd2048, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd7f80 sp=0xc140fd7e50 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc240aaf968, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd80b0 sp=0xc140fd7f80 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc240aaf8d8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd81e0 sp=0xc140fd80b0 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc24086b518, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd8310 sp=0xc140fd81e0 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24086b098, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd8440 sp=0xc140fd8310 pc=0x6d4df1 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc24086b038, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:712 +0x3ce fp=0xc140fd8570 sp=0xc140fd8440 pc=0x6d4fee github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0x48?, 0xc240624c90, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:717 +0x4c5 fp=0xc140fd86a0 sp=0xc140fd8570 pc=0x6d50e5 github.com/getkin/kin-openapi/openapi3.(*Loader).resolveSchemaRef(0xc000150b80, 0xc0003a0000?, 0xc2406247c8, 0xc000110120)
/go/pkg/mod/github.com/getkin/[email protected]/openapi3/loader.go:698 +0x1d1 fp=0xc140fd87d0 sp=0xc140fd86a0 pc=0x6d4df1

Breaking changes does not get detected for response body

Describe the bug
Breaking changes does not get detected when changing a response body property from required to optional

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -fail-on-diff -breaking-only -format text -base base.json -revision revision.json
  2. With base.txt - please convert the txt file and rename it to JSON as I wasn't allowed to upload a json file
  3. And revision.txt - please convert the txt file and rename it to JSON as I wasn't allowed to upload a json file
  4. Receive No changes outputted from the cli

Expected behavior
As we are changing a property from the response body from required to optional we would expect it to detect a breaking change.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: MAC OS BIG SUR version 11.6.2 (20G314)
  • Browser - N/A
  • Version N/A

Smartphone (please complete the following information):

  • Device: N/A
  • OS: N/A
  • Browser N/A
  • Version N/A

Additional context
We are using latest version v1.1.28 of oasdiff to run the diff against

(Bug) Error during diff where spec file contains 2 endpoints with similar but distinct paths

I have 2 paths that have different parameter names (and types), but otherwise are identical. Lets use the swagger.io petstore example to reproduce this:
For the reproduction example we have paths /pet/{petId1} /pet/{petId2} and /pet/{petId3}
petId1 is an integer type
petId2 is a string type with format of uuid
petId3 is a string type with no format specified

We are running on windows and run the command:
.\bin\oasdiff.exe -base ".\petstore.json" -revision ".\petstore.json" -exclude-examples
and receive the following error:
diff failed with duplicate endpoint (GET /pet/{petId}) found in .\petstore.json and .\petstore.json. You may add the x-since-date extension to specify order
with exit code 104

We are currently using 1.3.4, but I pulled down the latest 1.3.14 and it still has the issue.

Below is an example json file that accurately reproduces the issue we are experience.

{
  "openapi": "3.0.3",
  "info": {
    "title": "Swagger Petstore - OpenAPI 3.0",
    "description": "This is a sample Pet Store Server based on the OpenAPI 3.0 specification.  You can find out more about\nSwagger at [https://swagger.io](https://swagger.io). In the third iteration of the pet store, we've switched to the design first approach!\nYou can now help us improve the API whether it's by making changes to the definition itself or to the code.\nThat way, with time, we can improve the API in general, and expose some of the new features in OAS3.\n\n_If you're looking for the Swagger 2.0/OAS 2.0 version of Petstore, then click [here](https://editor.swagger.io/?url=https://petstore.swagger.io/v2/swagger.yaml). Alternatively, you can load via the `Edit > Load Petstore OAS 2.0` menu option!_\n\nSome useful links:\n- [The Pet Store repository](https://github.com/swagger-api/swagger-petstore)\n- [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml)",
    "termsOfService": "http://swagger.io/terms/",
    "contact": {
      "email": "[email protected]"
    },
    "license": {
      "name": "Apache 2.0",
      "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "version": "1.0.11"
  },
  "externalDocs": {
    "description": "Find out more about Swagger",
    "url": "http://swagger.io"
  },
  "servers": [
    {
      "url": "https://petstore3.swagger.io/api/v3"
    }
  ],
  "tags": [
    {
      "name": "pet",
      "description": "Everything about your Pets",
      "externalDocs": {
        "description": "Find out more",
        "url": "http://swagger.io"
      }
    },
    {
      "name": "store",
      "description": "Access to Petstore orders",
      "externalDocs": {
        "description": "Find out more about our store",
        "url": "http://swagger.io"
      }
    },
    {
      "name": "user",
      "description": "Operations about user"
    }
  ],
  "paths": {
    "/pet/{petId}": {
      "get": {
        "tags": [
          "pet"
        ],
        "summary": "Find pet by ID",
        "description": "Returns a single pet",
        "operationId": "getPetById",
        "parameters": [
          {
            "name": "petId",
            "in": "path",
            "description": "ID of pet to return",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              },
              "application/xml": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Pet not found"
          }
        },
        "security": [
          {
            "api_key": []
          },
          {
            "petstore_auth": [
              "write:pets",
              "read:pets"
            ]
          }
        ]
      }
    },
    "/pet/{petId2}": {
      "get": {
        "tags": [
          "pet"
        ],
        "summary": "Find pet by ID",
        "description": "Returns a single pet",
        "operationId": "getPetById2",
        "parameters": [
          {
            "name": "petId2",
            "in": "path",
            "description": "ID of pet to return",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              },
              "application/xml": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Pet not found"
          }
        },
        "security": [
          {
            "api_key": []
          },
          {
            "petstore_auth": [
              "write:pets",
              "read:pets"
            ]
          }
        ]
      }
    },
    "/pet/{petId3}": {
      "get": {
        "tags": [
          "pet"
        ],
        "summary": "Find pet by ID",
        "description": "Returns a single pet",
        "operationId": "getPetById3",
        "parameters": [
          {
            "name": "petId3",
            "in": "path",
            "description": "ID of pet to return",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              },
              "application/xml": {
                "schema": {
                  "$ref": "#/components/schemas/Pet"
                }
              }
            }
          },
          "400": {
            "description": "Invalid ID supplied"
          },
          "404": {
            "description": "Pet not found"
          }
        },
        "security": [
          {
            "api_key": []
          },
          {
            "petstore_auth": [
              "write:pets",
              "read:pets"
            ]
          }
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "example": 1
          },
          "name": {
            "type": "string",
            "example": "Dogs"
          }
        },
        "xml": {
          "name": "category"
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "example": 10
          },
          "username": {
            "type": "string",
            "example": "theUser"
          },
          "firstName": {
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "example": "James"
          },
          "email": {
            "type": "string",
            "example": "[email protected]"
          },
          "password": {
            "type": "string",
            "example": "12345"
          },
          "phone": {
            "type": "string",
            "example": "12345"
          },
          "userStatus": {
            "type": "integer",
            "description": "User Status",
            "format": "int32",
            "example": 1
          }
        },
        "xml": {
          "name": "user"
        }
      },
      "Tag": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          }
        },
        "xml": {
          "name": "tag"
        }
      },
      "Pet": {
        "required": [
          "name",
          "photoUrls"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "example": 10
          },
          "name": {
            "type": "string",
            "example": "doggie"
          },
          "category": {
            "$ref": "#/components/schemas/Category"
          },
          "photoUrls": {
            "type": "array",
            "xml": {
              "wrapped": true
            },
            "items": {
              "type": "string",
              "xml": {
                "name": "photoUrl"
              }
            }
          },
          "tags": {
            "type": "array",
            "xml": {
              "wrapped": true
            },
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "status": {
            "type": "string",
            "description": "pet status in the store",
            "enum": [
              "available",
              "pending",
              "sold"
            ]
          }
        },
        "xml": {
          "name": "pet"
        }
      }
    },
    "requestBodies": {
      "Pet": {
        "description": "Pet object that needs to be added to the store",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Pet"
            }
          },
          "application/xml": {
            "schema": {
              "$ref": "#/components/schemas/Pet"
            }
          }
        }
      },
      "UserArray": {
        "description": "List of user object",
        "content": {
          "application/json": {
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/User"
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "petstore_auth": {
        "type": "oauth2",
        "flows": {
          "implicit": {
            "authorizationUrl": "https://petstore3.swagger.io/oauth/authorize",
            "scopes": {
              "write:pets": "modify pets in your account",
              "read:pets": "read your pets"
            }
          }
        }
      },
      "api_key": {
        "type": "apiKey",
        "name": "api_key",
        "in": "header"
      }
    }
  }
}

Support ignoring 'Servers Changed'

It would be nice to be able to ignore the 'Servers changed' property, especially when failing on diff and breaking changes. We would like to compare a staging environment to a currently deployed version, but doing so always will fail due to the difference in server URLs.

Thank you!

Option to ignore description/title changes

Problem

I have the same (in theory) API spec generated from two different sources, which have different descriptions (and summary) and schema titles, due to differences in style conventions and other minor reasons. This causes oasdiff to report these differences, contributing to diff noise, even though the API isn't any different.

Proposal

Add an option to ignore description, title, and summary modifications, so they won't be included in the output.

Alternatives

Deal with the aforementioned modifications in the output.

Need an option to expand "allOf" blocks for proper semantical difference

Describe the bug
"allOf" construct from JSON-schema is a recommended and widely used approach to combine schemas in OpenAPI specs and avoid copy-pasting. Sometimes we refactor specs and replace plain schemas with full equivalents using "allOf". As far as I can see OASDIFF always detects it as a breaking change, even if underlying schemas are fully equivalent.

To Reproduce
Steps to reproduce the behavior:

  1. Run `oasdiff -format text -base oasdiff-test1.yml -revision oasdiff-test12.yml
  2. With oasdiff-allof-test.zip
  3. Receive the following result:
### Modified Endpoints: 1
-------------------------
GET /test
- Responses changed
  - Modified response: 200
    - Content changed
      - Modified media type: application/json
        - Schema changed
          - Property 'AllOf' changed
            - 2 schemas added
          - Type changed from 'object' to ''
          - Properties changed
            - Deleted property: description
            - Deleted property: name         
 

Expected behavior
I expect to have a command line option to get rid of "allOf" and convert them to equivalent inline schemas.
So that two semantically equivalent specs (like in my example) will not be considered as different:

### Modified Endpoints: 0

#154 could be about the same thing

Default parameter changes are not detected as breaking changes in -check-breaking

Describe the bug
Previously, the breaking-only flag would detect any changes to the default value of a param as a breaking change. -check-breaking does not classisfy that as a breaking change. We'd like to either have the check under -check-breaking or have it as a custom check.

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -base base.yaml -revision revision.yaml -check-breaking

  2. With base.yaml

openapi: 3.0.1
info:
  title: Test API
tags:
- name: Tests
  description: Test tag.
paths:
  /api/changeToDefaultParameterValues/{pathParam}:
    get:
      tags:
      - Tests
      summary: This is a test
      description: Test description.
      operationId: getTest
      parameters:
      - name: queryParam
        in: query
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: default
      - name: pathParam
        in: path
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: default
      - name: headerParam
        in: header
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: default
      requestBody:
        description: Request body
        content:
          application/text:
            schema:
              type: string
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
  1. With revision.yaml
openapi: 3.0.1
info:
  title: Test API
tags:
- name: Tests
  description: Test tag.
paths:
  /api/ChangeToDefaultParameterValues/{pathParam}:
    get:
      tags:
      - Tests
      summary: This is a test
      description: Test description.
      operationId: getTest
      parameters:
      - name: queryParam
        in: query
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: newDefault
      - name: pathParam
        in: path
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: newDefault
      - name: headerParam
        in: header
        description: Query param
        required: true
        schema:
          maxLength: 10
          minLength: 1
          type: string
          default: newDefault
      requestBody:
        description: Request body
        content:
          application/text:
            schema:
              type: string
        required: true
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
  1. Recieve : ""

Expected behavior
Same as breaking-only:
~ โฏ oasdiff -base base.yaml -revision revision.yaml -deprecation-days=365 -breaking-only -breaking-only

paths:
    modified:
        /api/atlas/v2/changeToDefaultParameterValues/{pathParam}:
            operations:
                modified:
                    GET:
                        parameters:
                            modified:
                                header:
                                    headerParam:
                                        schema:
                                            default:
                                                from: default
                                                to: newDefault
                                path:
                                    pathParam:
                                        schema:
                                            default:
                                                from: default
                                                to: newDefault
                                query:
                                    queryParam:
                                        schema:
                                            default:
                                                from: default
                                                to: newDefault

Desktop (please complete the following information):

  • OS: MacOS Monterey

OperationID considered breaking changes?

Describe the bug
Changes in operation ids are considered breaking API changes

To Reproduce
Steps to reproduce the behavior:

  1. Generate 2 specs with the same API but differing operation ids

Expected behavior
No breaking changes should be found

Enum value deletion/update is not detected as a breaking change by check-breaking

Describe the bug

Previously, the breaking-only flag would detect any enum value deletion as a breaking change, which makes sense as this can cause customer's automation to break if they rely on an enum value in a request. -check-breaking does not classisfy that as a breaking change. We'd like to either have the check under -check-breaking or have it as a custom check.

To Reproduce
Steps to reproduce the behavior:

  1. Run oasdiff -base base.yaml -revision revision.yaml -check-breaking
  2. With base.yaml
openapi: 3.0.1
info:
  title: Test API
tags:
- name: Tests
  description: Test tag.
paths:
  /api/deleteEnumTest:
    get:
      tags:
      - Tests
      summary: This is a test
      description: Test description.
      operationId: getTest
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                description: Enum values
                enum:
                - VALUE_1
                - VALUE_2
                - VALUE_3
  1. With revision.yaml
openapi: 3.0.1
info:
  title: Test API
tags:
- name: Tests
  description: Test tag.
paths:
  /api/deleteEnumTest:
    get:
      tags:
      - Tests
      summary: This is a test
      description: Test description.
      operationId: getTest
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
                description: Enum values
                enum:
                - VALUE_1
                - VALUE_2
                - VALUE_5
  1. Recieve

Expected behavior
Similar to -breaking-only

paths:
    modified:
        /api/atlas/v2/deleteEnumTest:
            operations:
                modified:
                    GET:
                        responses:
                            modified:
                                "200":
                                    content:
                                        mediaTypeModified:
                                            application/json:
                                                schema:
                                                    enum:
                                                        deleted:
                                                            - VALUE_3
endpoints:

Desktop (please complete the following information):

  • OS: Mac OS Monterey

Inconsistent behavior when response status codes are changed

Describe the bug
Changing a response code from 4xx to 5xx is handled differently by -breaking-only and -check-breaking flags:

  • -breaking-only considers it as a breaking change, reporting the removal of 4xx
  • -check-breaking considers it as a non-breaking change. Here only the removal of 2xx codes is considered breaking (ResponseSuccessStatusRemoved checker).

To Reproduce
Given specs:

  1. base.yaml:
openapi: 3.0.1
info:
  title: Test API
paths:
  /api/changeOfStatusCodesTest:
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
        "400":
          description: Bad request.
          content:
            application/json:
              schema:
                type: string
  1. revision.yaml
openapi: 3.0.1
info:
  title: Test API
paths:
  /api/changeOfStatusCodesTest:
    get:
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: string
        "500":
          description: Internal server error.
          content:
            application/json:
              schema:
                type: string

Steps to reproduce the behavior:

  1. Run oasdiff -base base.yaml -revision revision.yaml -breaking-only -format yaml
  2. Recieve:
paths:
    modified:
        /api/atlas/v2/changeOfStatusCodesTest:
            operations:
                modified:
                    GET:
                        responses:
                            deleted:
                                - "400"
  1. Run oasdiff -base base.yaml -revision revision.yaml -check-breaking -format text
  2. Recieve: no output (no breaking change detected)

Expected behavior
-check-breaking should consider the removal of any response status code (not only 2xx) as a breaking change.

Desktop (please complete the following information):

  • OS: macOS Ventura

Describe alternatives you've considered
one option I would be willing to work on is to add 2 new args -include-checks and -exclude-checks that will give us the ability to customize breaking changes default profile.
oasdiff -base base.yaml -revision revision.yaml -check-breaking -include-checks response-status-code-removed -format text

Example YAML appears to be invalid

First of all, thanks for such a cool tool! This is awesome.

Description

I was following the tutorial and tinkering a bit and realized that the example YAML output is actually invalid YAML. See the screenshot from the README of the repo below.

image

To Reproduce

It's the main README - but for the sake of conforming to the issue template ๐Ÿ™‚ here's the command from the root of the repo:

oasdiff -base data/openapi-test1.yaml -revision data/openapi-test2.yaml

Expected behavior
I would expect the YAML to be valid. I wasn't sure if this was just a diff format thing - but I would assume that we'd want a way to generate valid YAML.

I'm excited to get this working! ๐Ÿ˜„ Cool stuff!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.