Giter VIP home page Giter VIP logo

daveshanley / vacuum Goto Github PK

View Code? Open in Web Editor NEW
422.0 422.0 35.0 25.69 MB

vacuum is the worlds fastest OpenAPI 3, OpenAPI 2 / Swagger linter and quality analysis tool. Built in go, it tears through API specs faster than you can think. vacuum is compatible with Spectral rulesets and generates compatible reports.

Home Page: https://quobix.com/vacuum

License: MIT License

Go 89.18% TypeScript 3.61% CSS 0.45% JavaScript 6.26% Dockerfile 0.03% Shell 0.47% Makefile 0.01%
go golang lint linter linters linting oas openapi openapi-spec openapi-specification openapi3 openapi3-1 openapi3-validation openapi31 owasp spectral stoplight swagger swagger-spec swagger-specification

vacuum's People

Contributors

aabedraba avatar daveshanley avatar dependabot[bot] avatar eli-l avatar emilien-puget avatar fedebev avatar fratschi avatar gnuletik avatar inf0serj avatar kdanisme avatar mehdi-sol avatar ntotten avatar nyanprogrammer avatar psm14 avatar rica-graca avatar ricagraca avatar schelv avatar scop avatar t-huyeng avatar theteacat avatar tristanspeakeasy avatar volovikariel avatar xwillq avatar

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

vacuum's Issues

Disable kebab-case rule not working

I want to pass camelCase and snake_case in my api endpoint, but it is not working with the following configuration file.

$ vacuum lint -d api.yaml

Screenshot_20221119_114538

rules:
    component-description:
        category:
            description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions.
            id: descriptions
            name: Descriptions
        description: Component description check
        formats:
            - oas3
            - oas3_1
        given: $
        howToFix: Components are the inputs and outputs of a specification. A user needs to be able to understand each component and what id does. Descriptions are critical to understanding components. Add a description!
        id: component-description
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasComponentDescriptions
        type: validation
    description-duplication:
        category:
            description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions.
            id: descriptions
            name: Descriptions
        description: Description duplication check
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Descriptions are only useful, if they are meaningful. If a description is meaningful, then it won't be something you copy and paste. Please don't duplicate descriptions, make them deliberate and meaningful.
        id: description-duplication
        recommended: true
        severity: info
        then:
            function: oasDescriptionDuplication
        type: validation
    duplicated-entry-in-enum:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: Enum values must not have duplicate entry
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Enums need to be unique, you can't duplicate them in the same definition. Please remove the duplicate value.
        id: duplicated-entry-in-enum
        recommended: true
        severity: error
        then:
            function: duplicatedEnum
        type: validation
    info-description:
        category:
            description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed.
            id: information
            name: Contract Information
        description: Info section is missing a description
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.info
        howToFix: The 'info' section is missing a description, surely you want people to know what this spec is all about, right?
        id: info-description
        recommended: true
        resolved: true
        severity: error
        then:
            field: description
            function: truthy
        type: validation
    no-$ref-siblings:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: $ref values cannot be placed next to other properties (like a description)
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: $ref values must not be placed next to sibling nodes, There should only be a single node  when using $ref. A common mistake is adding 'description' next to a $ref. This is wrong. remove all siblings!
        id: no-$ref-siblings
        recommended: true
        severity: error
        then:
            function: refSiblings
        type: validation
    no-ambiguous-paths:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Paths need to resolve unambiguously from one another
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Paths must all resolve unambiguously, they can't be confused with one another (/{id}/ambiguous and /ambiguous/{id} are the same thing. Make sure every path and the variables used are unique and do conflict with one another. Check the ordering of variables and the naming of path segments.
        id: no-ambiguous-paths
        recommended: true
        resolved: true
        severity: error
        then:
            function: ambiguousPaths
        type: validation
    no-eval-in-markdown:
        category:
            description: Validation rules make sure that certain characters or patterns have not been used that may causeissues when rendering in different types of applications.
            id: validation
            name: Validation
        description: Markdown descriptions must not have `eval()` statements'
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Remove all references to 'eval()' in the description. These can be used by malicious actors to embed code in contracts that is then executed when read by a browser.
        id: no-eval-in-markdown
        recommended: true
        resolved: true
        severity: error
        then:
            function: noEvalDescription
            functionOptions:
                pattern: eval\(
        type: validation
    no-http-verbs-in-path:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Path segments must not contain an HTTP verb
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: When HTTP verbs (get/post/put etc) are used in path segments, it muddies the semantics of REST and creates a confusing and inconsistent experience. It's highly recommended that verbs are not used in path segments. Replace those HTTP verbs with more meaningful nouns.
        id: no-http-verbs-in-path
        recommended: true
        severity: warn
        then:
            function: noVerbsInPath
        type: style
    no-script-tags-in-markdown:
        category:
            description: Validation rules make sure that certain characters or patterns have not been used that may causeissues when rendering in different types of applications.
            id: validation
            name: Validation
        description: Markdown descriptions must not have `<script>` tags'
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Remove all references to '<script>' tags from the description. These can be used by malicious actors to load remote code if the spec is being parsed by a browser.
        id: no-script-tags-in-markdown
        recommended: true
        resolved: true
        severity: error
        then:
            function: noEvalDescription
            functionOptions:
                pattern: <script
        type: validation
    oas2-anyOf:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: "`anyOf` was introduced in OpenAPI 3.0, cannot be used un OpenAPI 2 specs"
        formats:
            - oas2
        given: $
        howToFix: You can't use 'anyOf' in Swagger/OpenAPI 2 specs. It was added in version 3. You have to remove it
        id: oas2-anyOf
        recommended: true
        severity: error
        then:
            function: oasPolymorphicAnyOf
        type: validation
    oas2-api-host:
        category:
            description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed.
            id: information
            name: Contract Information
        description: OpenAPI `host` must be present and a non-empty string
        formats:
            - oas2
        given: $
        howToFix: The 'host' value is missing. How is a user supposed to know where the API actually lives? The host is critical in order for consumers to be able to call the API. Add an API host!
        id: oas2-api-host
        recommended: true
        severity: info
        then:
            field: host
            function: truthy
        type: style
    oas2-api-schemes:
        category:
            description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed.
            id: information
            name: Contract Information
        description: OpenAPI host `schemes` must be present and non-empty array
        formats:
            - oas2
        given: $
        howToFix: Add an array of supported host 'schemes' to the root of the specification. These are the available API schemes (like https/http).
        id: oas2-api-schemes
        recommended: true
        severity: warn
        then:
            field: schemes
            function: schema
            functionOptions:
                forceValidation: true
                schema:
                    items:
                        minItems: 1
                        type: string
                    type: array
                    uniqueItems: true
        type: validation
    oas2-discriminator:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: discriminators are used correctly in schemas
        formats:
            - oas2
        given: $
        howToFix: When using polymorphism, a discriminator should also be provided to allow tools to understand how to compose your models when generating code. Add a correct discriminator.
        id: oas2-discriminator
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasDiscriminator
        type: validation
    oas2-host-not-example:
        category:
            description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed.
            id: information
            name: Contract Information
        description: Host URL should not point at example.com
        formats:
            - oas2
        given: $.host
        howToFix: Remove 'example.com' from the host URL, it's not going to work.
        id: oas2-host-not-example
        recommended: true
        severity: warn
        then:
            function: pattern
            functionOptions:
                notMatch: example\.com
        type: style
    oas2-host-trailing-slash:
        category:
            description: The info object contains licencing, contact, authorship details and more. Checks to confirm required details have been completed.
            id: information
            name: Contract Information
        description: Host URL should not contain a trailing slash
        formats:
            - oas2
        given: $.host
        howToFix: Remove the trailing slash from the host URL. This may cause some tools to incorrectly add a double slash to paths.
        id: oas2-host-trailing-slash
        recommended: true
        severity: warn
        then:
            function: pattern
            functionOptions:
                notMatch: /$
        type: style
    oas2-oneOf:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: "`oneOf` was introduced in OpenAPI 3.0, cannot be used un OpenAPI 2 specs"
        formats:
            - oas2
        given: $
        howToFix: You can't use 'oneOf' in Swagger/OpenAPI 2 specs. It was added in version 3. You have to remove it
        id: oas2-oneOf
        recommended: true
        severity: error
        then:
            function: oasPolymorphicOneOf
        type: validation
    oas2-operation-formData-consume-check:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: "Operations with `in: formData` parameter must include `application/x-www-form-urlencoded` or `multipart/form-data` in their `consumes` property."
        formats:
            - oas2
        given: $
        howToFix: When using 'formData', the parameter must include the correct mime-types. Make sure you use 'application/x-www-form-urlencoded' or 'multipart/form-data' as the 'consumes' value in your parameter.
        id: oas2-operation-formData-consume-check
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasOpFormDataConsumeCheck
        type: validation
    oas2-operation-security-defined:
        category:
            description: Security plays a central role in RESTful APIs. These rules make sure that the correct definitionshave been used and put in the right places.
            id: security
            name: Security
        description: "`security` values must match a scheme defined in securityDefinitions"
        formats:
            - oas2
        given: $
        howToFix: When defining security definitions for operations, you need to ensure they match the globally defined security schemes. Check $.securityDefinitions to make sure your values align.
        id: oas2-operation-security-defined
        recommended: true
        resolved: true
        severity: error
        then:
            function: oas2OpSecurityDefined
        type: validation
    oas2-parameter-description:
        category:
            description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions.
            id: descriptions
            name: Descriptions
        description: Parameter description checks
        formats:
            - oas2
        given: $
        howToFix: All parameters should have a description. Descriptions are critical to understanding how an API works correctly. Please add a description to all parameters.
        id: oas2-parameter-description
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasParamDescriptions
        type: style
    oas2-schema:
        category:
            description: Validation rules make sure that certain characters or patterns have not been used that may causeissues when rendering in different types of applications.
            id: validation
            name: Validation
        description: OpenAPI 2 specification is invalid
        formats:
            - oas2
        given: $
        howToFix: The schema isn't valid Swagger/OpenAPI 2. Check the errors for more details
        id: oas2-schema
        recommended: true
        severity: error
        then:
            function: oasDocumentSchema
        type: validation
    oas2-unused-definition:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: Check for unused definitions and bad references
        formats:
            - oas2
        given: $
        howToFix: Orphaned components are not used by anything. You might have plans to use them later, or they could be older schemas that never got cleaned up. A clean spec is a happy spec. Prune your orphaned components.
        id: oas2-unused-definition
        recommended: true
        severity: warn
        then:
            function: oasUnusedComponent
        type: validation
    oas2-valid-schema-example:
        category:
            description: Examples help consumers understand how API calls should look. They are really important forautomated tooling for mocking and testing. These rules check examples have been added to component schemas, parameters and operations. These rules also check that examples match the schema and types provided.
            id: examples
            name: Examples
        description: Examples must be present and valid for operations and components
        formats:
            - oas2
        given: $
        howToFix: Examples are critical for consumers to be able to understand schemas and models defined by the spec. Without examples, developers can't understand the type of data the API will return in real life. Examples are turned into mocks and can provide a rich testing capability for APIs. Add detailed examples everywhere!
        id: oas2-valid-schema-example
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasExample
        type: validation
    oas3-api-servers:
        category:
            description: Validation rules make sure that certain characters or patterns have not been used that may causeissues when rendering in different types of applications.
            id: validation
            name: Validation
        description: Check for valid API servers definition
        formats:
            - oas3
        given: $
        howToFix: Ensure server URIs are correct and valid, check the schemes, ensure descriptions are complete.
        id: oas3-api-servers
        recommended: true
        severity: error
        then:
            function: oasAPIServers
        type: validation
    oas3-operation-security-defined:
        category:
            description: Security plays a central role in RESTful APIs. These rules make sure that the correct definitionshave been used and put in the right places.
            id: security
            name: Security
        description: "`security` values must match a scheme defined in components.securitySchemes"
        formats:
            - oas3
            - oas3_1
        given: $
        howToFix: When defining security values for operations, you need to ensure they match the globally defined security schemes. Check $.components.securitySchemes to make sure your values align.
        id: oas3-operation-security-defined
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasOpSecurityDefined
            functionOptions:
                schemesPath: $.components.securitySchemes
        type: validation
    oas3-parameter-description:
        category:
            description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions.
            id: descriptions
            name: Descriptions
        description: Parameter description checks
        formats:
            - oas3
            - oas3_1
        given: $
        howToFix: All parameters should have a description. Descriptions are critical to understanding how an API works correctly. Please add a description to all parameters.
        id: oas3-parameter-description
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasParamDescriptions
        type: style
    oas3-schema:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: OpenAPI 3 specification is invalid
        formats:
            - oas3
        given: $
        howToFix: The schema isn't valid OpenAPI 3. Check the errors for more details
        id: oas3-schema
        recommended: true
        severity: error
        then:
            function: oasDocumentSchema
        type: validation
    oas3-unused-component:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: Check for unused components and bad references
        formats:
            - oas3
            - oas3_1
        given: $
        howToFix: Unused components / definitions are generally the result of the OpenAPI contract being updated without considering references. Another reference could have been updated, or an operation changed that no longer references this component. Remove this component from the spec, or re-link to it from another component or operation to fix the problem.
        id: oas3-unused-component
        recommended: true
        severity: warn
        then:
            function: oasUnusedComponent
        type: validation
    oas3-valid-schema-example:
        category:
            description: Examples help consumers understand how API calls should look. They are really important forautomated tooling for mocking and testing. These rules check examples have been added to component schemas, parameters and operations. These rules also check that examples match the schema and types provided.
            id: examples
            name: Examples
        description: Examples must be present and valid for operations and components
        formats:
            - oas3
            - oas3_1
        given: $
        howToFix: Examples are critical for consumers to be able to understand schemas and models defined by the spec. Without examples, developers can't understand the type of data the API will return in real life. Examples are turned into mocks and can provide a rich testing capability for APIs. Add detailed examples everywhere!
        id: oas3-valid-schema-example
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasExample
        type: validation
    operation-description:
        category:
            description: Documentation is really important, in OpenAPI, just about everything can and should have a description. This set of rules checks for absent descriptions, poor quality descriptions (copy/paste), or short descriptions.
            id: descriptions
            name: Descriptions
        description: Operation description checks
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: All operations must have a description. Descriptions explain how the operation works, and how users should use it and what to expect. Operation descriptions make up the bulk of API documentation. so please, add a description!
        id: operation-description
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasDescriptions
            functionOptions:
                minWords: "1"
        type: validation
    operation-operationId:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Every operation must contain an `operationId`.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Every single operation needs an operationId. It's a critical requirement to be able to identify each individual operation uniquely. Please add an operationId to the operation.
        id: operation-operationId
        recommended: true
        severity: error
        then:
            function: oasOpId
        type: validation
    operation-operationId-unique:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Every operation must have unique `operationId`.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths
        howToFix: An operationId needs to be unique, there can't be any duplicates in the document, you can't re-use them. Make sure the ID used for this operation is unique.
        id: operation-operationId-unique
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasOpIdUnique
        type: validation
    operation-operationId-valid-in-url:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: OperationId must use URL friendly characters
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths[*][*]
        howToFix: An operationId is critical to correct code generation and operation identification. The operationId should really be designed in a way to make it friendly when used as part of an URL. Remove non-standard URL characters.
        id: operation-operationId-valid-in-url
        recommended: true
        resolved: true
        severity: error
        then:
            field: operationId
            function: pattern
            functionOptions:
                match: ^[A-Za-z0-9-._~:/?#\[\]@!\$&'()*+,;=]*$
        type: validation
    operation-parameters:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Operation parameters are unique and non-repeating.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths
        howToFix: Make sure that all the operation parameters are unique and non-repeating, don't duplicate names, don'tre-use parameter names in the same operation.
        id: operation-parameters
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasOpParams
        type: validation
    operation-success-response:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Operation must have at least one `2xx` or a `3xx` response.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Make sure that your operation returns a 'success' response via  2xx or 3xx response code. An API consumer will always expect a success response
        id: operation-success-response
        recommended: true
        resolved: true
        severity: warn
        then:
            field: responses
            function: oasOpSuccessResponse
        type: style
    operation-tag-defined:
        category:
            description: Tags are used as meta-data for operations. They are mainly used by tooling as a taxonomy mechanism to build navigation, search and more. Tags are important as they help consumers navigate the contract when using documentation, testing, code generation or analysis tools.
            id: tags
            name: Tags
        description: Operation tags must be defined in global tags.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: This tag has not been defined in the global scope, you should always ensure that any tags used in operations, are defined globally in the root 'tags' definition.
        id: operation-tag-defined
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasTagDefined
        type: validation
    operation-tags:
        category:
            description: Tags are used as meta-data for operations. They are mainly used by tooling as a taxonomy mechanism to build navigation, search and more. Tags are important as they help consumers navigate the contract when using documentation, testing, code generation or analysis tools.
            id: tags
            name: Tags
        description: Operation `tags` are missing/empty
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Operations use tags to define the domain(s) they are apart of. Generally a single tag per operation is used, however some tools use multiple tags. The point is that you need tags! Add some tags to the operation that match the globally available ones.
        id: operation-tags
        recommended: true
        resolved: true
        severity: warn
        then:
            function: oasOperationTags
        type: validation
    path-declarations-must-exist:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Path parameter declarations must not be empty ex. `/api/{}` is invalid
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths
        howToFix: Paths define the endpoint for operations. Without paths, there is no API. You need to add 'paths' to the root of the specification.
        id: path-declarations-must-exist
        recommended: true
        resolved: true
        severity: error
        then:
            function: pattern
            functionOptions:
                notMatch: "{}"
        type: validation
    path-keys-no-trailing-slash:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Path must not end with a slash
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths
        howToFix: Paths should not end with a trailing slash, it can confuse tooling and isn't valid as a path Remove the trailing slash from the path.
        id: path-keys-no-trailing-slash
        recommended: true
        resolved: true
        severity: warn
        then:
            function: pattern
            functionOptions:
                notMatch: .+\/$
        type: validation
    path-not-include-query:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Path must not include query string
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $.paths
        howToFix: Query strings are defined as parameters for an operation, they should not be included in the path Please remove it and correctly define as a parameter.
        id: path-not-include-query
        recommended: true
        resolved: true
        severity: error
        then:
            function: pattern
            functionOptions:
                notMatch: \?
        type: validation
    path-params:
        category:
            description: Operations are the core of the contract, they define paths and HTTP methods. These rules check operations have been well constructed, looks for operationId, parameter, schema and return types in depth.
            id: operations
            name: Operations
        description: Path parameters must be defined and valid.
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Path parameters need to match up with the parameters defined for the path, or in an operation that sits under that path. Make sure variable names match up and are defined correctly.
        id: path-params
        recommended: true
        resolved: true
        severity: error
        then:
            function: oasPathParam
        type: validation
    typed-enum:
        category:
            description: Schemas are how request bodies and response payloads are defined. They define the data going in and the data flowing out of an operation. These rules check for structural validity, checking types, checkingrequired fields and validating correct use of structures.
            id: schemas
            name: Schemas
        description: Enum values must respect the specified type
        formats:
            - oas3
            - oas3_1
            - oas2
        given: $
        howToFix: Enum values lock down the number of variable inputs a parameter or schema can have. The problem here is that the Enum defined, does not match the specified type. Fix the type!
        id: typed-enum
        recommended: true
        resolved: true
        severity: warn
        then:
            function: typedEnum
        type: validation

`vacuum` doesn't detect present `info.contact` and `info.license` objects

Using the sample OpenAPI spec below, with valid info.contact and info.license objects, vacuum (v0.0.49) reports the following warnings:

{
    "message": "Info section is missing contact details: `contact` must be set",
    "range": {
        "start": {
            "line": 3,
            "character": 3
        },
        "end": {
            "line": 11,
            "character": 5
        }
    },
    "path": "$.info",
    "ruleId": "info-contact",
    "ruleSeverity": "warn"
},
{
    "message": "Info section should contain a license: `license` must be set",
    "range": {
        "start": {
            "line": 3,
            "character": 3
        },
        "end": {
            "line": 11,
            "character": 5
        }
    },
    "path": "$.info",
    "ruleId": "info-license",
    "ruleSeverity": "info"
}

Sample spec:

openapi: "3.0.0"
info:
  version: 1.0.0
  title: Swagger Petstore
  description: The Petstore REST API.
  contact:
    name: API team
    url: https://smartbear.com/contact-us/
    email: [email protected]
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
servers:
  - url: http://petstore.swagger.io/v1
paths:
  /pets:
    get:
      summary: List all pets
      operationId: listPets
      tags:
        - pets
      parameters:
        - name: limit
          in: query
          description: How many items to return at one time (max 100)
          required: false
          schema:
            type: integer
            format: int32
      responses:
        200:
          description: An paged array of pets
          headers:
            x-next:
              description: A link to the next page of responses
              schema:
                type: string
          content:
            application/json:    
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
    post:
      summary: Create a pet
      operationId: createPets
      tags:
        - pets
      responses:
        201:
          description: Null response
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /pets/{petId}:
    get:
      summary: Info for a specific pet
      operationId: showPetById
      tags:
        - pets
      parameters:
        - name: petId
          in: path
          required: true
          description: The id of the pet to retrieve
          schema:
            type: string
      responses:
        200:
          description: Expected response to a valid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Pets"
        default:
          description: unexpected error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  schemas:
    Pet:
      required:
        - id
        - name
      properties:
        id:
          type: integer
          format: int64
        name:
          type: string
        tag:
          type: string
    Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"
    Error:
      required:
        - code
        - message
      properties:
        code:
          type: integer
          format: int32
        message:
          type: string

RFE: make `go install ./...` work

Currently:

$๎‚ฐ go install ./...
# github.com/daveshanley/vacuum/plugin/sample
runtime.main_mainยทf: function main is undeclared in the main package

This isn't really a bug because it's not documented to work; instead there's a Makefile target for doing the intended thing, and plain go install does work.

Why I'm asking go install ./... to work is that I was preparing a pre-commit hook for inclusion here, and pre-commit uses that command unconditionally, so the installation will fail, and a native build of this tool in its current setup won't be auto-installable by pre-commit.

(pre-commit could install vacuum via the npm option I suppose, and at least with the docker image it would be usable, but those are not easily integratable in a config in this repo because both those options requires embedding the version in .pre-commit-hooks.yaml which to me looks like something that the maintainers here would have to remember to update manually before tagging new vacuum releases, or some automation added which would take care of that. The native install wouldn't have that problem.)

discussion: rule - operation description triggers when operation has a summary instead of a description

Just interested to hear your thoughts on https://quobix.com/vacuum/rules/descriptions/operation-description/

This rule gets triggered if an operation doesn't have a description, regardless of it having a summary or not.

For our own API spec sometimes the APIs are really quite simple (a get that returns an object that is already well documented within its schema) and so we use a single line summary string only, without the need for a description that would end up just being a duplicate of the summary.

A lot of documentation tooling also treats the summary as you would expect if the description is absent

Turn off output coloring on CI

Hi

Our CI workflow is organized in such a way that the output of the vacuum is published on GitHub in the corresponding Pull Request. However, due to the fact that the output contains special color codes, it is not possible to read this report:

๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆโ–ˆ    โ–ˆโ–ˆโ–ˆ ๏ฟฝ[0m
๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ   โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ      ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆ ๏ฟฝ[0m
๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ      ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆ ๏ฟฝ[0m
๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆ  โ–ˆโ–ˆ  ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ   โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ      ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ    โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ  โ–ˆโ–ˆ  โ–ˆโ–ˆ ๏ฟฝ[0m
๏ฟฝ[38;2;153;51;255m  โ–ˆโ–ˆโ–ˆโ–ˆ   ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ   โ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255m โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  ๏ฟฝ[0m๏ฟฝ[38;2;153;51;255mโ–ˆโ–ˆ      โ–ˆโ–ˆ ๏ฟฝ[0m

version: ๏ฟฝ[92mlatest๏ฟฝ[0m | compiled: ๏ฟฝ[92m2023-01-31 08:36:12 UTC๏ฟฝ[0m
๏ฟฝ[36m๐Ÿ”— https://quobix.com/vacuum | https://github.com/daveshanley/vacuum๏ฟฝ[0m


๏ฟฝ[30;46m๏ฟฝ[30;46m INFO ๏ฟฝ[0m๏ฟฝ[0m ๏ฟฝ[96m๏ฟฝ[96mLinting against 42 rules: https://quobix.com/vacuum/rulesets/recommended๏ฟฝ[0m๏ฟฝ[0m


# ๏ฟฝ[1;33m๏ฟฝ[1;33mOperations Issues๏ฟฝ[0m
๏ฟฝ[1;33m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mLine / Column๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mSeverity๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mMessage                                                                               ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mPath                                ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m(6676:7)     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[91merror๏ฟฝ[0m๏ฟฝ[39m   ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39mthe 'get' operation at path '/document/{documentId}' does not contain an operationId  ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m$.paths./document/{documentId}.get  ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m(6696:7)     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[91merror๏ฟฝ[0m๏ฟฝ[39m   ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39mthe 'post' operation at path '/document/{documentId}' does not contain an operationId ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m$.paths./document/{documentId}.post ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m(6719:7)     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[91merror๏ฟฝ[0m๏ฟฝ[39m   ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39mthe 'patch' operation at path '/document/{documentId}' does not contain an operationId๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m$.paths./document/{documentId}.patch๏ฟฝ[0m๏ฟฝ[0m

# ๏ฟฝ[1;33m๏ฟฝ[1;33mTags Issues๏ฟฝ[0m
๏ฟฝ[1;33m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mLine / Column๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mSeverity๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mMessage๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mPath๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m

# ๏ฟฝ[1;33m๏ฟฝ[1;33mDescriptions Issues๏ฟฝ[0m
๏ฟฝ[1;33m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mLine / Column๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mSeverity๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mMessage๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mPath๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m

# ๏ฟฝ[1;33m๏ฟฝ[1;33mExamples Issues๏ฟฝ[0m
๏ฟฝ[1;33m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mLine / Column๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mSeverity๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mMessage                            ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mPath๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39m             ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m        ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[91m...23 more violations not rendered.๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m    ๏ฟฝ[0m๏ฟฝ[0m

๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96mCategory    ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96m๏ฟฝ[91mErrors๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96m๏ฟฝ[93mWarnings๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[96m๏ฟฝ[94mInfo๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[96m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39mOperations  ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m3     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m7       ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0   ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39mTags        ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m3       ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0   ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39mDescriptions๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m19      ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m155 ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[39m๏ฟฝ[39mExamples    ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m223     ๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m๏ฟฝ[90m๏ฟฝ[90m | ๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[0m๏ฟฝ[0m๏ฟฝ[39m๏ฟฝ[39m0   ๏ฟฝ[0m๏ฟฝ[0m


๏ฟฝ[41m๏ฟฝ[41m                                                                              ๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[41m๏ฟฝ[41m๏ฟฝ[97;1m๏ฟฝ[97;1m          Linting failed with 3 errors, 252 warnings and 155 informs          ๏ฟฝ[0m๏ฟฝ[41m๏ฟฝ[0m๏ฟฝ[41m๏ฟฝ[0m๏ฟฝ[0m
๏ฟฝ[41m๏ฟฝ[41m                                                                              ๏ฟฝ[0m๏ฟฝ[0m

We use the following command:

vacuum lint -d -e .build/v1.yml

Is there an option to turn off output coloring on CI?

[BUG] vacuum complains there is no 2XX response when there is a 200

Spec:

openapi: 3.0.1
info:
  title: Harbor API
  description: These APIs provide services for manipulating Harbor project.
  version: "2.0"
servers:
 - url: https://{env}-[URL]
   description: 'Harbor Server'
   variables:
     env:
      enum:
        - 'preprod'
        - 'prod'
      default: 'preprod'
security:
- basic: []
paths:
  /projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/tags:
    get:
      tags:
      - artifact
      summary: List tags
      description: List tags of the specific artifact
      operationId: listTags
      parameters:
      - name: X-Request-Id
        in: header
        description: An unique ID for the request
        schema:
          minLength: 1
          type: string
      - name: project_name
        in: path
        description: The name of the project
        required: true
        schema:
          type: string
      - name: repository_name
        in: path
        description: The name of the repository. If it contains slash, encode it with
          URL encoding. e.g. a/b -> a%252Fb
        required: true
        schema:
          type: string
      - name: reference
        in: path
        description: The reference of the artifact, can be digest or tag
        required: true
        schema:
          type: string
      - name: q
        in: query
        description: Query string to query resources. Supported query patterns are
          "exact match(k=v)", "fuzzy match(k=~v)", "range(k=[min~max])", "list with
          union releationship(k={v1 v2 v3})" and "list with intersetion relationship(k=(v1
          v2 v3))". The value of range and list can be string(enclosed by " or '),
          integer or time(in format "2020-04-09 02:36:00"). All of these query patterns
          should be put in the query string "q=xxx" and splitted by ",". e.g. q=k1=v1,k2=~v2,k3=[min~max]
        schema:
          type: string
      - name: sort
        in: query
        description: Sort the resource list in ascending or descending order. e.g.
          sort by field1 in ascending orderr and field2 in descending order with "sort=field1,-field2"
        schema:
          type: string
      - name: page
        in: query
        description: The page number
        schema:
          type: integer
          format: int64
          default: 1
      - name: page_size
        in: query
        description: The size of per page
        schema:
          maximum: 100
          type: integer
          format: int64
          default: 10
      - name: with_signature
        in: query
        description: Specify whether the signature is included inside the returning
          tags
        schema:
          type: boolean
          default: false
      - name: with_immutable_status
        in: query
        description: Specify whether the immutable status is included inside the returning
          tags
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: Success
          headers:
            X-Total-Count:
              description: The total count of tags
              schema:
                type: integer
            Link:
              description: Link refers to the previous page and next page
              schema:
                type: string
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'
        400:
          description: Bad request
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        401:
          description: Unauthorized
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        403:
          description: Forbidden
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        404:
          description: Not found
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        500:
          description: Internal server error
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
    post:
      tags:
      - artifact
      summary: Create tag
      description: Create a tag for the specified artifact
      operationId: createTag
      parameters:
      - name: X-Request-Id
        in: header
        description: An unique ID for the request
        schema:
          minLength: 1
          type: string
      - name: project_name
        in: path
        description: The name of the project
        required: true
        schema:
          type: string
      - name: repository_name
        in: path
        description: The name of the repository. If it contains slash, encode it with
          URL encoding. e.g. a/b -> a%252Fb
        required: true
        schema:
          type: string
      - name: reference
        in: path
        description: The reference of the artifact, can be digest or tag
        required: true
        schema:
          type: string
      requestBody:
        description: The JSON object of tag.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Tag'
        required: true
      responses:
        201:
          description: Created
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
            Location:
              description: The location of the resource
              schema:
                type: string
        400:
          description: Bad request
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        401:
          description: Unauthorized
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        403:
          description: Forbidden
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        404:
          description: Not found
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        405:
          description: Method not allowed
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        409:
          description: Conflict
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        500:
          description: Internal server error
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
      x-codegen-request-body-name: tag
components:
  securitySchemes:
    basic:
      type: http
      scheme: basic
  schemas:
    Errors:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/Error'
      description: The error array that describe the errors got during the handling
        of request
    Error:
      type: object
      properties:
        code:
          type: string
          description: The error code
        message:
          type: string
          description: The error message
      description: a model for all the error response coming from harbor
    Tag:
      type: object
      properties:
        id:
          type: integer
          description: The ID of the tag
          format: int64
        repository_id:
          type: integer
          description: The ID of the repository that the tag belongs to
          format: int64
        artifact_id:
          type: integer
          description: The ID of the artifact that the tag attached to
          format: int64
        name:
          type: string
          description: The name of the tag
        push_time:
          type: string
          description: The push time of the tag
          format: date-time
        pull_time:
          type: string
          description: The latest pull time of the tag
          format: date-time
        immutable:
          type: boolean
          description: The immutable status of the tag
          x-omitempty: false
        signed:
          type: boolean
          description: The attribute indicates whether the tag is signed or not
          x-omitempty: false

Complains:
Operation must have at least one 2xx or a 3xx response.
$.paths./projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/tags.get.responses
$.paths./projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/tags.post.responses

But
/projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/tags.get.responses
contains a 200
And the the post contains a 201

The openapi spec asks that there be:

  • a default response
  • or a 2XX or 3XX where XX is any number
  • or a 2XX or 3XX response

Homebrew install failing?

Hi there - Homebrew seems to be unable to install Vacuum? Also, can't see it listed on their website?

Add support for AsyncAPI

Vacuum might be the best linter for OpenAPI. It would be very nice, if it supported AsyncAPI too. Do you plan to support it in the future?

False unused/orphaned positive with polymorphic responses

components:
  schemas:
    ErrSomething:
      # ...
paths:
  /fish/paste:
    get:
      responses:
        default:
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: "#/components/schemas/ErrSomething"
                  # ...
                discriminator:
                  # ...

Here, I get a warning

#/components/schemas/ErrSomething` is potentially unused or has been orphaned

This specific one seems to occur for polymorphic responses, i.e. components that are schema alternatives in a oneOf only in the doc, i.e. not as direct $refs below response schema.

I haven't checked if this happens similarly for polymorphic requests, but I guess it might.

https://github.com/OAI/OpenAPI-Specification/blob/3.1.0/versions/3.1.0.md#discriminator-object

nil pointer dereference on $ref without # character

Issue

When running vacuum lint openapi.yaml I get a "nil pointer dereference" error.
In the openapi.yaml I have the following $ref: $ref: 'common/parameters/authorization.yaml'. If the $ref contains a # character at the end of the file name, e.g. $ref: 'common/parameters/authorization.yaml#' - the issue is gone and lint produces normal output.

Details

Full error output:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0xaec5f2]

goroutine 81 [running]:
github.com/daveshanley/vacuum/functions/openapi.OperationParameters.RunRule({}, {0xc000532090?, 0xf0e080?, 0x1?}, {0xc0000ad410, 0xc0001048f0, {0xf0a600, 0x11ee520}, {0x0, 0x0}, ...})
	/home/some-path/vacuum/functions/openapi/operation_parameters.go:73 +0xd72
github.com/daveshanley/vacuum/motor.buildResults({0xc0001048f0, 0xc0003c2dc0, {0x11f39b0, 0xc0003f4a60}, 0xc0003f60f0, 0xc0003ded10, 0xc0003f6060, 0xc000580400, 0xc0003c2e60, 0x0, ...}, ...)
	/home/some-path/vacuum/motor/rule_applicator.go:405 +0x61c
github.com/daveshanley/vacuum/motor.runRule({0xc0001048f0, 0xc0003c2dc0, {0x11f39b0, 0xc0003f4a60}, 0xc0003f60f0, 0xc0003ded10, 0xc0003f6060, 0xc000580400, 0xc0003c2e60, 0x0, ...})
	/home/some-path/vacuum/motor/rule_applicator.go:330 +0x40f
created by github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet
	/home/some-path/vacuum/motor/rule_applicator.go:165 +0x72e

Full contents of openapi.yaml:

---
openapi: 3.0.3
info:
  title: My service
  description: Nil pointer dereference service.
  version: 1.0.0
  contact:
    name: Me
    email: [email protected]

tags:
  - name: Devices
    description: Device operations

paths:
  /v1/devices:
    post:
      tags:
        - Devices
      summary: Create a device
      description: Create a device resource.
      operationId: devices::create
      parameters:
        - $ref: 'common/parameters/authorization.yaml'
      responses:
        '200':
          description: OK
          content:
            application/vnd.api+json:
              schema:
                type: object
                properties:
                  meta:
                    type: object
                    properties:
                      message:
                        type: string
                        example: 'OK'

Full contents of common/parameters/authorization.yaml:

name: Authorization
in: header
required: true
schema:
  type: string
  example: Bearer <JWT token>

Non-operation fields under paths treated as operations

In a 3.0.3 spec, for a structure like:

paths:
  /items/{type}/{id}:
    parameters:
      # ...
    get:
      # ...
    post:
      # ...

...it appears that parameters is treated as if it was an operation. I'm seeing for example the following warnings:

(77:5)        | warning  | Tags for `parameters` operation at path `/items/{type}/{id}` are missing     | $.paths./items/{type}/{id}.parameters
(78:7)        | warning  | Operation `parameters` at path `/items/{type}/{id}` is missing a description | $.paths./items/{type}/{id}.parameters

I haven't checked if this happens for other non-operation fields below a path besides parameters, but maybe there is a type check missing from somewhere before applying operation checks on them. https://github.com/OAI/OpenAPI-Specification/blob/3.0.3/versions/3.0.3.md#fixed-fields-7

compatibility spectral

Hello,
I try to use some rules copied from spectral
Several rules are working with spectral but have issue with vacuum.
By instance:

  adidas-oas3-request-support-json:
    description: Every request MUST support `application/json` media type
    formats:
      - oas3
    recommended: true
    severity: error
    message: "{{description}}: {{error}}"
    given: $.paths.[*].requestBody.content[?(@property.indexOf('json') === -1)]^
    then:
      function: falsy

With spectral it is OK:
image

with vacuum, I have the following issue:
image

I have tried with quote but no solution.
Could you help me?

thanks

Error on Valid Schema

I have simple Open API specification which is based on version 3.1.0

On running analyze, I get two errors at the title line:

  1. OpenAPI specification is invalid: /properties/info/$ref doesn't validate with '/definitions/Info'
  2. OpenAPI specification is invalid: /properties/openapi/pattern does not match pattern '^3\.0\.\d(-.+)?$'

In both cases, "How to fix violation" shows "The schema isn't valid OpenAPI 3. Check the errors for more details".

Not sure whats wrong with the YAML manifest:

openapi: 3.1.0
info:
  title: Backend of microblogging application
  description: |-
    Mockroblog is a backend application based on course CPSC-449 Web Back-end Engineering, for the batch of Fall 2021.
    
    Links:
    - [Application homepage](https://blogger.st)
    - [Project repository](https://github.com/saurami/mockroblog)
  contact:
    name: Saurabh Mishra
    url: https://saurabh.cc
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: 1.0

servers:
  - url: https://blogger.st/api/v1
    description: Production APIs

tags:
  - name: hello
    description: Hello world

paths:
  /hello:
    get:
      tags:
        - hello
      summary: Get "Hello, world!" response
      description: Get "Hello, world!" as a utf-8 encoded text response
      operationId: helloHandler
      responses:
        '200':
          description: successful operation
          content:
            text/plain:
              schema:
                type: string
              example: 'Hello!'

Add support for multiple specifications.

One spec is fun, but vacuum should be able to support multiple specifications, as many as you like.

  • It should be able to find all the specifications through a directory recursively.
  • It should be able to resolve all exploded / remote specifications
  • It should be able to accept a list of HTTP locations to download specifications from

Junit reporting

Hello.
I have a question regarding to reporting type. To be more exactly, I have a feature request. Is it possible to have reporting in junit format? Would be nice to have this feature, because I have a job in Jenkins which I run it constantly and is required a JUnit reporting type. In the original Spectral has JUnit reporting, but they have an issue with blocks me using them.

Please, consider the issue addressed to the Spectral.

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

Hi,

I just caught a runtime error and can reproduce it.

version: 0.0.43 | compiled: 2022-12-08T12:58:30Z

vacuum generate-ruleset recommended
vacuum lint -r ruleset-recommended.yaml example.yml

example.yml as follows:

openapi: 3.0.3

info:
  version: 1.0.0
  title: Example

tags:
  - name: my-tag
    description: A description for My Tag

servers:
  - url: 'http://127.0.0.1:8080'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

paths:
  /v1/users:
    get:
      summary: Some summary
      operationId: users.get
      responses:
        '204':
          description: No content

    head:
      summary: Some summary
      operationId: users.head
      responses:
        '204':
          description: No content

    post:
      summary: Some summary
      operationId: users.post
      responses:
        '204':
          description: No content

    patch:
      summary: Some summary
      # operationId: users.patch
      responses:
        '204':
          description: No content

Let me know if I can provide more information that would be helpful.


panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x90 pc=0x102f75340]

goroutine 72 [running]:
regexp.(*Regexp).doExecute(0x1037d3840?, {0x0?, 0x0?}, {0x0?, 0x1400079bba0?, 0x140004b1bd0?}, {0x140002c6078?, 0x0?}, 0x1037d33c0?, 0x140007931d0?, ...)
	/opt/hostedtoolcache/go/1.19.3/x64/src/regexp/exec.go:527 +0x50
regexp.(*Regexp).doMatch(...)
	/opt/hostedtoolcache/go/1.19.3/x64/src/regexp/exec.go:514
regexp.(*Regexp).MatchString(...)
	/opt/hostedtoolcache/go/1.19.3/x64/src/regexp/regexp.go:533
github.com/daveshanley/vacuum/functions/openapi.NoEvalInDescriptions.RunRule({}, {0x14000716030?, 0x8?, 0x103d413e0?}, {0x14000712180, 0x140007cd760, {0x1037a7a60, 0x1400079bb50}, {0x1037d33c0, 0x140007931d0}, ...})
	/home/runner/work/vacuum/vacuum/functions/openapi/no_eval_descriptions.go:41 +0x1d0
github.com/daveshanley/vacuum/motor.buildResults({0x140007cd760, 0x140001400a0, {0x10386b348, 0x140003f48e0}, 0x140007b85a0, 0x140006104d0, 0x1400058c180, 0x14000159000, 0x140001401e0, 0x0}, ...)
	/home/runner/work/vacuum/vacuum/motor/rule_applicator.go:387 +0x568
github.com/daveshanley/vacuum/motor.runRule({0x140007cd760, 0x140001400a0, {0x10386b348, 0x140003f48e0}, 0x140007b85a0, 0x140006104d0, 0x1400058c180, 0x14000159000, 0x140001401e0, 0x0})
	/home/runner/work/vacuum/vacuum/motor/rule_applicator.go:314 +0x304
created by github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet
	/home/runner/work/vacuum/vacuum/motor/rule_applicator.go:157 +0x628

Running vaccum in Docker introduces an EOF error.

Hi,

I'm trying to check a yaml file within docker.
Locally, vacuum does not creates this error with the same yaml file.

I searched for the cause of this error in the source-code and in the libopenapi dependency, but i wasn't able to find it.

I would like to fix this, but i need at least a hint what goes wrong or which component is creating the error.

Error:

# Schemas Issues


Line / Column | Severity | Message                                        | Path
(1:1)         | error    | Swagger specification cannot be validated: EOF | $   

Dockerfile

FROM alpine:latest
RUN apk --no-cache add curl && \
    curl -fsSL https://quobix.com/scripts/install_vacuum.sh | sh

COPY ./openapi /tmp/api

WORKDIR /tmp/api/core/
RUN vacuum lint -d test.yaml

test.yaml

openapi: 3.0.3
info:
  version: 1.0.0
  description: test
  title: test
servers:
  - url: 'https://test.de'
tags:
  - name: xxx
    description: xxxx
components:
  schemas:
    Version:
      type: object
      properties:
        version:
          type: string
          description: The version of the service
          example: 2022.06.28.7233
      required:
        - version
paths:
  /core/tenant/v1/version:
    get:
      operationId: version
      tags:
        - xxx
      description: Gets the version of the service
      responses:
        '200':
          description: version of the service
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Version'

oas3-schema rule output is hard to grok

The oas3-schema rule seems to do a lot of the high level validation of a document, but I find the output hard to digest and it doesn't help guide a user towards a solution.

For example:

(1:1)         | error    | OpenAPI specification is invalid: /properties/paths/$ref doesn't validate with '/definitions/Paths' | $                              
(1:1)         | error    | OpenAPI specification is invalid: /properties/tags/uniqueItems items at index 0 and 1 are equal     | $                              
(1:1)         | error    | OpenAPI specification is invalid: /properties/servers                                               | $

Here is some example output from a OpenAPI 3.0 document

  • The first error talks about /properties/paths/$ref which I am unsure what it relates to and then references /definitions/Paths which I believe is a Swagger reference instead of an OpenAPI 3 reference.
  • The second error seems to catch the duplicate tags I was asking for in this #206 but has no valid line number or path reference to the tags and the /properties/tags/uniqueItems notation is unclear to what it is referring to.
  • The third error is because the top level servers object is invalid but once again the notation is unclear and there are no valid line numbers or paths to find where the issue is.

Would be good to see the errors produce by this rule improved as it does seem to catch a lot of validation issues not present in other rules

feature request: expose rule-id constants and a method for building rulesets programatically

Would love to be able to build a ruleset programmatically when using the API directly instead of via the CLI similar to how the default ruleset is built here: https://github.com/daveshanley/vacuum/blob/main/rulesets/rulesets.go#L251

Basically exposing the constants for the rule keys and maybe having a method that takes a map of rules and returns a ruleset that can be used in the ApplyRulesToRuleSet call

Error for path ending with slash

Paths ending with slashes result in the error Path must not end with a slash: matches the expression '.+\/$'

The explanation at https://quobix.com/vacuum/rules/operations/path-keys-no-trailing-slash/ just says it's important not to do that, but provides no rationale. Spectral docs at https://meta.stoplight.io/docs/spectral/4dec24461f3af-open-api-rules#path-keys-no-trailing-slash do provide some reasoning, which makes sense to me.

However, I believe no OpenAPI specification actually forbids this. Therefore I was wondering if this should be downgraded to a warning, and perhaps the quobix.com/vacuum docs updated to elaborate a bit on the reasoning?

Incorrect interpretation of the field description

Hi,

vacuum says that description at line 165 is a duplicate of line 62

Which is obviously a somewhat useless warning, due to the fact that these are fields of different models. Here, description field is not part of the OpenAPI syntax, this field describes an object attribute.

Log:

% vacuum lint -d contracts/documentation.yaml

โ–ˆโ–ˆ    โ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆ    โ–ˆโ–ˆโ–ˆ
โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ   โ–ˆโ–ˆ โ–ˆโ–ˆ      โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆ
โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆ      โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ โ–ˆโ–ˆโ–ˆโ–ˆ โ–ˆโ–ˆ
 โ–ˆโ–ˆ  โ–ˆโ–ˆ  โ–ˆโ–ˆ   โ–ˆโ–ˆ โ–ˆโ–ˆ      โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ    โ–ˆโ–ˆ โ–ˆโ–ˆ  โ–ˆโ–ˆ  โ–ˆโ–ˆ
  โ–ˆโ–ˆโ–ˆโ–ˆ   โ–ˆโ–ˆ   โ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ   โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆ      โ–ˆโ–ˆ

version: latest | compiled: 2023-02-05 10:49:14 CET
๐Ÿ”— https://quobix.com/vacuum | https://github.com/daveshanley/vacuum


 INFO  Linting against 42 rules: https://quobix.com/vacuum/rulesets/recommended


# Descriptions Issues

Line / Column | Severity | Message                                               | Path
(165:21)      | info     | Description at line `165` is a duplicate of line `62` | $.paths./v1/products/{id}.get.responses.400.content.applicat...
(182:21)      | info     | Description at line `182` is a duplicate of line `62` | $.paths./v1/products/{id}.get.responses.404.content.applicat...

# Examples Issues

Line / Column | Severity | Message                                                                     | Path
(133:15)      | warning  | Schema for `application/json` does not contain any examples or example data | $.paths./v1/products.get.responses.200
(157:15)      | warning  | Schema for `application/json` does not contain any examples or example data | $.paths./v1/products/{id}.get.responses.400
(174:15)      | warning  | Schema for `application/json` does not contain any examples or example data | $.paths./v1/products/{id}.get.responses.404

Category     | Errors | Warnings | Info
Descriptions | 0      | 0        | 2
Examples     | 0      | 3        | 0



          Linting passed, but with 3 warnings and 2 informs

Full OpeanAPI example:

---
openapi: 3.0.3

info:
  version: '1.0'
  title: Products API
  description: Example API to test Specmatic features.

servers:
  - description: Localhost
    url: http://127.0.0.1:5000

tags:
  - name: products
    description: Products related API.

components:
  parameters:
    AcceptHeader:
      in: header
      name: Accept
      description: Accept Header
      schema:
        type: string
        enum: [application/json, '*/*']
      example: application/json
    IdParam:
      in: path
      name: id
      description: Entity ID param
      schema:
        type: integer
        format: int32
        minimum: 1
      required: true
      example: 42

  schemas:
    Product:
      title: Product
      allOf:
        - $ref: '#/components/schemas/ProductId'
        - $ref: '#/components/schemas/ProductDetails'
    ProductId:
      title: Product ID
      type: object
      properties:
        id:
          type: integer
          format: int32
          minimum: 1
          example: 42
      required: [id]
    ProductDetails:
      title: Product Details
      type: object
      properties:
        title:
          type: string
          example: iPhone 9
        description:
          type: string
          example: An apple mobile which is nothing like apple
        price:
          type: number
          minimum: 0
          example: 549
        discount:
          type: number
          minimum: 0.0
          example: 12.96
        rating:
          type: number
          minimum: 0.0
          maximum: 5.0
          example: 4.69
        stock:
          type: integer
          format: int32
          minimum: 0
          example: 856
        brand:
          type: string
          example: Apple, Inc.
        category:
          $ref: '#/components/schemas/ProductCategory'
      required:
        - title
        - description
        - price
        - discount
        - rating
        - stock
        - brand
        - category
    ProductCategory:
      title: Product Category
      type: string
      enum:
        - smartphones
        - laptops
      example: smartphones

paths:
  /v1/products:
    get:
      summary: List of all products.
      operationId: products.index
      tags: [products]
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
        - name: category
          description: Filter by product category.
          in: query
          required: false
          schema:
            type: string
          allowEmptyValue: true
          example: laptops
        - name: q
          description: Search term.
          in: query
          required: false
          schema:
            type: string
          allowEmptyValue: true
          example: samsung
      responses:
        '200':
          description: List of products
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Product'

  '/v1/products/{id}':
    get:
      summary: Get product.
      operationId: products.get
      tags: [products]
      parameters:
        - $ref: '#/components/parameters/AcceptHeader'
        - $ref: '#/components/parameters/IdParam'
      responses:
        '200':
          description: Get product
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                    format: int32
                    example: 400
                  description:
                    type: string
                    example: Invalid product ID data type
                  name:
                    type: string
                    example: Bad Request
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                type: object
                properties:
                  code:
                    type: integer
                    format: int32
                    example: 404
                  description:
                    type: string
                    example: Product not found
                  name:
                    type: string
                    example: Not Found

bug: typed-enum is incorrectly returning warnings about type

For this doc: https://raw.githubusercontent.com/speakeasy-api/openapi-directory/main/APIs/twitter.com/current/2.21/openapi.yaml

It has an enum at line 1563 that looks like:

enum:
  - media_key
  - duration_ms
  - height
  - preview_image_url
  - type
  - url
  - width
  - public_metrics
  - non_public_metrics
  - organic_metrics
  - promoted_metrics
  - alt_text
type: string

which produces the below errors complaining about "string" defined as "type"

(1563:13)     | warning  | enum type mismatch: enum value 'height' is a string, but it's defined as a 'type'                 | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'duration_ms' is a string, but it's defined as a 'type'            | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'type' is a string, but it's defined as a 'type'                   | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'public_metrics' is a string, but it's defined as a 'type'         | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'url' is a string, but it's defined as a 'type'                    | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'promoted_metrics' is a string, but it's defined as a 'type'       | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'preview_image_url' is a string, but it's defined as a 'type'      | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'alt_text' is a string, but it's defined as a 'type'               | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'media_key' is a string, but it's defined as a 'type'              | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'organic_metrics' is a string, but it's defined as a 'type'        | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'width' is a string, but it's defined as a 'type'                  | $                                                              
(1563:13)     | warning  | enum type mismatch: enum value 'non_public_metrics' is a string, but it's defined as a 'type'     | $

Inaccurate message for missing `requestBody` description

For a 3.0.3 spec, like:

paths:
  /items/{type}/{id}:
    post:
      requestBody:
        content:
        # ...

...where requestBody is missing a description, I'm seeing warning like:

(94:7)        | warning  | Operation `requestBody` for method `post` at path `/items/{type}/{id}` is missing a description | $.paths./items/{type}/{id}.post.requestBody        

I think there are two issues with this message:

  • requestBody is not an operation
  • In OpenAPI speak, post is not a method, but an operation

I suggest changing this to read "Field requestBody for operation post ...".

Different order of parameters in HTML Report

First of all great project!

I use vacuum to generate html reports for all the openapis we have created within the bunddev project,
For this I created a Go-script which runs every night and creates a PR if changes of the HTML-reports exist. I already removed the line where the generated time has been set with a small hack. But it looks like the order of parameters is different on some runs.

See this PR (which was created through the github action):
t-huyeng/check-bundesAPI-repos#8

It shows the changes of the html files: as far as I see it the changes are because of a changed order of parameters or other information.

Can you confirm that the order is not always the same? Could you thing about implementing something which keeps the order the same for every run?

Thanks

Spectral rule support

Do you support all rules? Including rules in Javascript. Can you load the module from NPM?

unknown escape character

Dear all,

First of all, thanks for creating and sharing this nice tool! ๐Ÿ™

Just started playing with it and it seems very promising, not just speedy.

However, just testing a Spectral rule (that is presented here) included in such a ruleset:

extends: [[spectral:oas, recommended]]

rules:
  must-use-paths-kebab-case:
    description: MUST use lowercase and separate words with hyphens for path segments (kebab-case).
    message: "{{description}}"
    formats: [oas3]
    type: style
    severity: error
    given: $.paths[*]~
    then:
      function: pattern
      functionOptions:
        match: "^(\/|[a-z0-9-.]+|{[a-zA-Z0-9]+})+$"

And trying to use it:

  • using vacuum lint -d path/to/openapi.yaml -r path/to/ruleset.yaml
  • it throws Unable to parse ruleset file: yaml: line 14: found unknown escape character.

Testing this ^(\/|[a-z0-9-.]+|{[a-zA-Z0-9]+})+$ regular expression in regex101.com it looks fine.

Now, if it is declared in that match element without the double quotes, like this:

        match: ^(\/|[a-z0-9-.]+|{[a-zA-Z0-9]+})+$

it seems that vacuum (and linting as well) works fine.

However, in Adding Rules section of Custom Ruleset page, there is an example with these quotes.

Is it ok to continue defining the match without the double quotes โ”

Thanks!

[BUG] vacuum reports tag error for allowed use case

Spec:

openapi: 3.0.1
info:
  title: Harbor API
  description: These APIs provide services for manipulating Harbor project.
  version: "2.0"
servers:
 - url: https://{env}-[URL]
   description: 'Harbor Server'
   variables:
     env:
      enum:
        - 'preprod'
        - 'prod'
      default: 'preprod'
security:
- basic: []
paths:
  /projects/{project_name}/repositories/{repository_name}/artifacts/{reference}/tags:
    get:
      tags:
      - artifact
      summary: List tags
      description: List tags of the specific artifact
      operationId: listTags
      parameters:
      - name: X-Request-Id
        in: header
        description: An unique ID for the request
        schema:
          minLength: 1
          type: string
      - name: project_name
        in: path
        description: The name of the project
        required: true
        schema:
          type: string
      - name: repository_name
        in: path
        description: The name of the repository. If it contains slash, encode it with
          URL encoding. e.g. a/b -> a%252Fb
        required: true
        schema:
          type: string
      - name: reference
        in: path
        description: The reference of the artifact, can be digest or tag
        required: true
        schema:
          type: string
      - name: q
        in: query
        description: Query string to query resources. Supported query patterns are
          "exact match(k=v)", "fuzzy match(k=~v)", "range(k=[min~max])", "list with
          union releationship(k={v1 v2 v3})" and "list with intersetion relationship(k=(v1
          v2 v3))". The value of range and list can be string(enclosed by " or '),
          integer or time(in format "2020-04-09 02:36:00"). All of these query patterns
          should be put in the query string "q=xxx" and splitted by ",". e.g. q=k1=v1,k2=~v2,k3=[min~max]
        schema:
          type: string
      - name: sort
        in: query
        description: Sort the resource list in ascending or descending order. e.g.
          sort by field1 in ascending orderr and field2 in descending order with "sort=field1,-field2"
        schema:
          type: string
      - name: page
        in: query
        description: The page number
        schema:
          type: integer
          format: int64
          default: 1
      - name: page_size
        in: query
        description: The size of per page
        schema:
          maximum: 100
          type: integer
          format: int64
          default: 10
      - name: with_signature
        in: query
        description: Specify whether the signature is included inside the returning
          tags
        schema:
          type: boolean
          default: false
      - name: with_immutable_status
        in: query
        description: Specify whether the immutable status is included inside the returning
          tags
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: Success
          headers:
            X-Total-Count:
              description: The total count of tags
              schema:
                type: integer
            Link:
              description: Link refers to the previous page and next page
              schema:
                type: string
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'
        400:
          description: Bad request
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        401:
          description: Unauthorized
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        403:
          description: Forbidden
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        404:
          description: Not found
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        500:
          description: Internal server error
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
    post:
      tags:
      - artifact
      summary: Create tag
      description: Create a tag for the specified artifact
      operationId: createTag
      parameters:
      - name: X-Request-Id
        in: header
        description: An unique ID for the request
        schema:
          minLength: 1
          type: string
      - name: project_name
        in: path
        description: The name of the project
        required: true
        schema:
          type: string
      - name: repository_name
        in: path
        description: The name of the repository. If it contains slash, encode it with
          URL encoding. e.g. a/b -> a%252Fb
        required: true
        schema:
          type: string
      - name: reference
        in: path
        description: The reference of the artifact, can be digest or tag
        required: true
        schema:
          type: string
      requestBody:
        description: The JSON object of tag.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Tag'
        required: true
      responses:
        201:
          description: Created
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
            Location:
              description: The location of the resource
              schema:
                type: string
        400:
          description: Bad request
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        401:
          description: Unauthorized
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        403:
          description: Forbidden
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        404:
          description: Not found
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        405:
          description: Method not allowed
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        409:
          description: Conflict
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
        500:
          description: Internal server error
          headers:
            X-Request-Id:
              description: The ID of the corresponding request for the response
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Errors'
      x-codegen-request-body-name: tag
components:
  securitySchemes:
    basic:
      type: http
      scheme: basic
  schemas:
    Errors:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/Error'
      description: The error array that describe the errors got during the handling
        of request
    Error:
      type: object
      properties:
        code:
          type: string
          description: The error code
        message:
          type: string
          description: The error message
      description: a model for all the error response coming from harbor
    Tag:
      type: object
      properties:
        id:
          type: integer
          description: The ID of the tag
          format: int64
        repository_id:
          type: integer
          description: The ID of the repository that the tag belongs to
          format: int64
        artifact_id:
          type: integer
          description: The ID of the artifact that the tag attached to
          format: int64
        name:
          type: string
          description: The name of the tag
        push_time:
          type: string
          description: The push time of the tag
          format: date-time
        pull_time:
          type: string
          description: The latest pull time of the tag
          format: date-time
        immutable:
          type: boolean
          description: The immutable status of the tag
          x-omitempty: false
        signed:
          type: boolean
          description: The attribute indicates whether the tag is signed or not
          x-omitempty: false

vacuum says the lack of tags at the top level of the spec is an error:
Operation tags must be defined in global tags.

But that's not true per the openapi spec:
spec.tags: Not all tags that are used by the [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#operationObject) must be declared. The tags that are not declared MAY be organized randomly or based on the tools' logic. Each tag name in the list MUST be unique.

Path level parameters suppress warning on missing requestBody description

This structure correctly causes the warning

Field requestBody for operation post at path /some/path is missing a description

paths:
  /some/path:
    post:
      requestBody:
        # no description here

However, if the path has any path level parameters, the error is not emitted, for example:

paths:
  /some/path/{id}:
    parameters:
      - in: path
        name: id
        type: string
    post:
      requestBody:
        # no description here, but no warning emitted

Vacuum doesn't catch missing references

Using the example below, no errors are returned when running vacuum lint openapi.yaml -d.

I would expect it to return an error mentioning that the component Item is not defined

openapi: 3.0.3
info:
  title: Test
  version: 0.0.1
  description: test
servers:
  - url: https://httpbin.org
paths:
  /test:
    get:
      operationId: test
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Item'

path parameters function doesn't seem to capture missing path parameters in operations

This doc:

openapi: 3.0.3
info:
  title: Test
  version: 0.0.1
  description: A test API
servers:
  - url: https://example.com
security:
  - basicAuth: []
tags:
  - name: tag1
paths:
  /update/{something}:
    post:
      operationId: postSomething
      summary: Post something
      tags:
        - tag1
      responses:
        '200':
          description: Post OK
    get:
      operationId: getSomething
      summary: Get something
      tags:
        - tag1
      responses:
        '200':
          description: Get OK
components:
  securitySchemes:
    basicAuth:
      type: http
      scheme: basic

returns this result from vacuum:

vacuum lint ../openapi-specs/path-param-test.yaml -d

INFO  Linting against 42 rules: https://quobix.com/vacuum/rulesets/recommended

Linting passed, A perfect score! well done!

looking at the code I can see there is a check to detect the fact there is no path param defined for {something} but it doesn't seem to be catching that it isn't defined

oas3-valid-schema-example does not support non-string enums

Vacuum appears to use treat all enum values as strings when validating examples, regardless of their actual type.

Example Config

components:
  schemas:
    NotAuthorized:
      type: integer
      enum: [401]
      example: 401

Expected

No error pertaining to the example, as it is a member of the enum and the specified type

Actual

I get an error for oas3-valid-schema-example with the following message:

Example for component NotAuthorized is not valid: (root) must be one of the following: "401". Value 401 is not compatible

feature request: add index for getting all "schema" objects

At the moment there is a GetAllSchemas method on an index but this is a little misleading as this is only returning schemas that live within components/schemas.

I am looking to make a custom function that will validate property names on "all" schema objects whether they live within components or inline in other schemas/request bodies/responses/parameters etc etc

False unused/orphaned positive for basic and session auth

For a swagger 2.0 spec:

securityDefinitions:
  basicAuth:
    type: basic
  sessionAuth:
    type: apiKey
    in: header
    name: X-API-Key

security:
  - basicAuth: []
  - sessionAuth: []

...current vacuum warns the false positives:

`#/securityDefinitions/basicAuth` is potentially unused or has been orphaned
`#/securityDefinitions/sessionAuth` is potentially unused or has been orphaned

Runtime error when creating html-report on yaml with external-file-referenced parameter component

When trying to use vacuum html-report on a file with $ref to external file, vacuum throws runtime error below.

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x20 pc=0x100402be0]

goroutine 68 [running]:
github.com/daveshanley/vacuum/functions/openapi.OperationParameters.RunRule({}, {0x1400078bba0?, 0x8?, 0x14000056480?}, {0x14000a48a50, 0x1400016a8f0, {0x1009dbba0, 0x100a9b2a8}, {0x0, 0x0}, ...})
        /home/runner/work/vacuum/vacuum/functions/openapi/operation_parameters.go:73 +0xa00
github.com/daveshanley/vacuum/motor.buildResults({0x1400016a8f0, 0x14000428e60, {0x100a9f188, 0x14000472920}, 0x14000474168, 0x1400045cca0, 0x140008fec48, 0x140003fcc00, 0x14000428f00, 0x0, ...}, ...)
        /home/runner/work/vacuum/vacuum/motor/rule_applicator.go:405 +0x568
github.com/daveshanley/vacuum/motor.runRule({0x1400016a8f0, 0x14000428e60, {0x100a9f188, 0x14000472920}, 0x14000474168, 0x1400045cca0, 0x140008fec48, 0x140003fcc00, 0x14000428f00, 0x0, ...})
        /home/runner/work/vacuum/vacuum/motor/rule_applicator.go:330 +0x378
created by github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet
        /home/runner/work/vacuum/vacuum/motor/rule_applicator.go:165 +0x628

My OpenAPI structure is like this

# openapi.yaml
# ...
paths:
  /foo:
    get:
      parameters:
        - $ref: "./bar.yaml"
# bar.yaml

in: query
name: bar
schema:
  type: string
description: ...
allowEmptyValue: true

It was OK when I separated schema components from the main file, but it started to crash right after separating parameters component.

Segmentation fault on incorrect case for parameter name

Hi,

The following code:

# ...

components:
  parameters:
    CategoryFilter:
      in: query
      name: category
      description: Filter by product category.
      required: false
      schema:
        type: string
      examples:
        single:
          value: laptops
          summary: A sample category to filter products.

paths:
  /v1/products:
    get:
      summary: Get products
      description: Returns a list of all products.
      operationId: products.index
      tags: [products]
      parameters:
        - $ref: '#/components/parameters/categoryFilter'

# ...

leads to segmentation fault as show bellow:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x20 pc=0x10134f3d0]

goroutine 59 [running]:
github.com/daveshanley/vacuum/functions/openapi.OperationParameters.RunRule({}, {0x14000124048?, 0x8?, 0x14000088000?}, {0x14000114150, 0x140001048f0, {0x10196de00, 0x101a4b378}, {0x0, 0x0}, ...})
	/Users/egrep/go/pkg/mod/github.com/daveshanley/[email protected]/functions/openapi/operation_parameters.go:73 +0xa00
github.com/daveshanley/vacuum/motor.buildResults({0x140001048f0, 0x140003e8aa0, {0x101a50670, 0x140003e0410}, 0x140000bff08, 0x140003caa00, 0x140004960c0, 0x14000539800, 0x140003e8b40, 0x0, ...}, ...)
	/Users/egrep/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:400 +0x55c
github.com/daveshanley/vacuum/motor.runRule({0x140001048f0, 0x140003e8aa0, {0x101a50670, 0x140003e0410}, 0x140000bff08, 0x140003caa00, 0x140004960c0, 0x14000539800, 0x140003e8b40, 0x0, ...})
	/Users/egrep/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:327 +0x36c
created by github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet
	/Users/egrep/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:162 +0x628

Of course this can be fixed in the following way:

# ...

components:
  parameters:
    CategoryFilter:
      in: query
      name: category
      description: Filter by product category.
      required: false
      schema:
        type: string
      examples:
        single:
          value: laptops
          summary: A sample category to filter products.

paths:
  /v1/products:
    get:
      summary: Get products
      description: Returns a list of all products.
      operationId: products.index
      tags: [products]
      parameters:
-       - $ref: '#/components/parameters/categoryFilter'
+       - $ref: '#/components/parameters/CategoryFilter'

# ...

However, finding this error in automatic mode at CI/CD phase is almost impossible because vacuum crashes without specifying on which line you have an error.

Steps to reproduce: sergeyklay/provider-pact-example#8 (see "Lint OpenAPI" check)

panics in vacuum goroutines can't be handled

If a panic occurs in a custom rule, because it seems the document is being evaluated with goroutines these can't be caught using recover and so can cause crashes for a server.

It would be good if vacuum can recover from panicing goroutines and then throw this panic on the main thread so then these panics can be caught by the code calling vacuum.

here is an example callstack

panic: ...truncated `

goroutine 298 [running]:
... truncated
github.com/daveshanley/vacuum/motor.buildResults({0xc000b70bb0, 0xc0002ce140, {0x12835b0, 0xc000b20d30}, 0xc000b1c450, 0xc000b18500, 0xc000b1c0a8, 0xc000601000, 0xc000b29360, 0xc000b1b470}, ...)
        /home/trist/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:387 +0x608
github.com/daveshanley/vacuum/motor.runRule({0xc000b70bb0, 0xc0002ce140, {0x12835b0, 0xc000b20d30}, 0xc000b1c450, 0xc000b18500, 0xc000b1c0a8, 0xc000601000, 0xc000b29360, 0xc000b1b470})
        /home/trist/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:314 +0x350
created by github.com/daveshanley/vacuum/motor.ApplyRulesToRuleSet
        /home/trist/go/pkg/mod/github.com/daveshanley/[email protected]/motor/rule_applicator.go:157 +0x72e
exit status 2

Stdin/stdout support

For integration with editors, accepting data from stdin and outputting to stdout is extremely helpful.

Taking inputs from stdin means being able to give live updates when typing changes, without having to write the file to disk. Outputting machine parseable records to stdout (e.g., JSON or a one-line-per-message structured format) means being able to easily map results to editor-specific formats. While the built-in report formats are great (report, spectral-report), those force a write to disk rather than being available through stdout, and attempting workarounds such as /dev/stdout are difficult because of the pretty-printed info that's included in the normal output.

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.