diff --git a/.automation/test/clojure/README.md b/.automation/test/clojure/README.md new file mode 100644 index 00000000..6606ef5b --- /dev/null +++ b/.automation/test/clojure/README.md @@ -0,0 +1,13 @@ +# Clojure Test Cases +This folder holds the test cases for **Clojure**. + +## Additional Docs +No Additional information is needed for this test case. + +## Good Test Cases +The test cases denoted: `LANGUAGE_good_FILE.EXTENSION` are all valid, and should pass successfully when linted. +- **Note:** They are linted utilizing the default linter rules. + +## Bad Test Cases +The test cases denoted: `LANGUAGE_bad_FILE.EXTENSION` are **NOT** valid, and should trigger errors when linted. +- **Note:** They are linted utilizing the default linter rules. diff --git a/.automation/test/clojure/clojure_bad_1.clj b/.automation/test/clojure/clojure_bad_1.clj new file mode 100644 index 00000000..c8366066 --- /dev/null +++ b/.automation/test/clojure/clojure_bad_1.clj @@ -0,0 +1,64 @@ +(ns foo + (:require + [clojure.string :as str] + ;; We're never using this namespace. Also, the namespaces aren't sorted. + [clojure.set :as set])) + +;; Here we made a typo, so the symbol is unresolved: +(but-last [1 2 3]) + +;; Clj-kondo knows about arities of clojure namespaces, but you can also teach +;; it about your libraries or own namespaces +(str/join) + +;; foo has an arity of 2, but we're not actually using y +(defn foo-fn [x y] + ;; this do is redundant: + (do + ;; this is handy for debugging, but please remove it before pushing your code: + (def tmp_x x) + (let [y (fn [] (inc x))] + ;; the next let can be squashed together with the previous: + (let [z y] + ;; whoopsy, calling a local function with an incorrect number of args: + (y x) + ;; also wrong: + (recur))))) + +(letfn + [(f [] (h 1)) + (h [] (f 1))]) + +(defn- private-fn []) +;; redefining it... +(defn- private-fn []) + +(defn foo [] :foo) +;; Type error, because foo doesn't return a number! +(inc (foo)) + +;; I'm tired now, let's sleep... +;; Oops, not happening because of wrong amount of args: +(Thread/sleep 1000 1 2) + +;; Here we switch to another namespace and require the previous: +(ns bar (:require [foo :as f])) + +;; Wrong arity when calling a function from the previous namespace: +(f/foo-fn) + +;; private: +(f/private-fn) + +;; this won't pass the reader: +{:a 1 :a 2} +;; and neither will this: +#{1 1} +;; nor this: +{:a 1 :b} + +(ns bar-test (:require [clojure.test :as t])) + +(t/deftest my-tests + ;; you're not actually testing something here: + (odd? (inc 1))) \ No newline at end of file diff --git a/.automation/test/clojure/clojure_good_1.clj b/.automation/test/clojure/clojure_good_1.clj new file mode 100644 index 00000000..391f4688 --- /dev/null +++ b/.automation/test/clojure/clojure_good_1.clj @@ -0,0 +1,34 @@ +(ns foo + (:require + [clojure.string :as str])) + +(butlast [1 2 3]) + +(str/join "" "") + +(defn foo-fn [x] + (let [y (fn [] (inc x))] + (y))) + +(letfn + [(f [g] (h g)) + (h [i] (f i))]) + +(defn foo [] 1) +(inc (foo)) + +(Thread/sleep 1000 1) + +;; Here we switch to another namespace and require the previous: +(ns bar (:require [foo :as f])) + +(f/foo-fn 1) + +{:a 1 :b 2} +#{1 2} +{:a 1 :b 2} + +(ns bar-test (:require [clojure.test :as t])) + +(t/deftest my-tests + (t/is (odd? (inc 1)))) \ No newline at end of file diff --git a/.automation/test/openapi/README.md b/.automation/test/openapi/README.md new file mode 100644 index 00000000..6f5d2c24 --- /dev/null +++ b/.automation/test/openapi/README.md @@ -0,0 +1,14 @@ +# OpenAPI Test Cases +This folder holds the test cases for **OpenAPI**. + +## Additional Docs +The `_bad_` tests are valid `.yml`/`.json` but invalid OpenAPI specs. +The test extensions used are `.ymlopenapi`/`.jsonopenapi` instead of `.yml`/`.json`. This is to prevent the [YAML] and [JSON] tests from picking them up. + +## Good Test Cases +The test cases denoted: `LANGUAGE_good_FILE.EXTENSION` are all valid, and should pass successfully when linted. +- **Note:** They are linted utilizing the default linter rules. + +## Bad Test Cases +The test cases denoted: `LANGUAGE_bad_FILE.EXTENSION` are **NOT** valid, and should trigger errors when linted. +- **Note:** They are linted utilizing the default linter rules. diff --git a/.automation/test/openapi/openapi_bad_1.ymlopenapi b/.automation/test/openapi/openapi_bad_1.ymlopenapi new file mode 100644 index 00000000..6c86b1b4 --- /dev/null +++ b/.automation/test/openapi/openapi_bad_1.ymlopenapi @@ -0,0 +1 @@ +openapi: '3.0.0' diff --git a/.automation/test/openapi/openapi_bad_2.jsonopenapi b/.automation/test/openapi/openapi_bad_2.jsonopenapi new file mode 100644 index 00000000..b0b97ddb --- /dev/null +++ b/.automation/test/openapi/openapi_bad_2.jsonopenapi @@ -0,0 +1,3 @@ +{ + "openapi": "3.0.0" +} diff --git a/.automation/test/openapi/openapi_good_1.ymlopenapi b/.automation/test/openapi/openapi_good_1.ymlopenapi new file mode 100644 index 00000000..eb4924a1 --- /dev/null +++ b/.automation/test/openapi/openapi_good_1.ymlopenapi @@ -0,0 +1,13 @@ +openapi: 3.0.0 +info: + title: Example + version: '1.0' + contact: + name: Justin Kalland + email: justin@kalland.com + description: Test for super-linter +servers: + - url: 'http://localhost:3000' +paths: {} +tags: + - name: example diff --git a/.automation/test/openapi/openapi_good_2.jsonopenapi b/.automation/test/openapi/openapi_good_2.jsonopenapi new file mode 100644 index 00000000..93f59635 --- /dev/null +++ b/.automation/test/openapi/openapi_good_2.jsonopenapi @@ -0,0 +1,23 @@ +{ + "openapi": "3.0.0", + "info": { + "title": "Example", + "version": "1.0", + "contact": { + "name": "Justin Kalland", + "email": "justin@kalland.com" + }, + "description": "Test for super-linter" + }, + "servers": [ + { + "url": "http://localhost:3000" + } + ], + "paths": {}, + "tags": [ + { + "name": "example" + } + ] +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 253b1933..86d05b97 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -33,9 +33,10 @@ Draft pull requests are also welcome to get feedback early on, or if there is so If you are the current maintainer of this action: 1. Update `README.md` and the wiki to reflect new version number in the example workflow file sections 2. Draft [Release](https://help.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) with a summarized changelog -3. A GitHub Action will Publish the Docker image to GitHub Package Registry once a Release is created -4. A GitHub Action will Publish the Docker image to Docker Hub once a Release is created -5. Look for approval from [CODEOWNERS](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners) +3. Ensure you check the box for [publishing to the marketplace](https://help.github.com/en/actions/creating-actions/publishing-actions-in-github-marketplace#publishing-an-action) +4. A GitHub Action will Publish the Docker image to GitHub Package Registry once a Release is created +5. A GitHub Action will Publish the Docker image to Docker Hub once a Release is created +6. Look for approval from [CODEOWNERS](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners) ## Resources - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) diff --git a/.github/actions/spelling/allow/Dockerfile.txt b/.github/actions/spelling/allow/Dockerfile.txt deleted file mode 100644 index bb490a92..00000000 --- a/.github/actions/spelling/allow/Dockerfile.txt +++ /dev/null @@ -1,7 +0,0 @@ -musl -nvq -rdoc -setuptools -uninstall -wget -WORKDIR diff --git a/.github/actions/spelling/allow/cleanup-docker.sh.txt b/.github/actions/spelling/allow/cleanup-docker.sh.txt deleted file mode 100644 index 1efe4ad7..00000000 --- a/.github/actions/spelling/allow/cleanup-docker.sh.txt +++ /dev/null @@ -1 +0,0 @@ -alnum diff --git a/.github/actions/spelling/allow/disabling-linters.md.txt b/.github/actions/spelling/allow/disabling-linters.md.txt deleted file mode 100644 index fe1303c8..00000000 --- a/.github/actions/spelling/allow/disabling-linters.md.txt +++ /dev/null @@ -1,3 +0,0 @@ -noqa -toc -todo diff --git a/.github/actions/spelling/allow/ghe-api-config-apply.yml.txt b/.github/actions/spelling/allow/ghe-api-config-apply.yml.txt deleted file mode 100644 index 8d39ee0b..00000000 --- a/.github/actions/spelling/allow/ghe-api-config-apply.yml.txt +++ /dev/null @@ -1,2 +0,0 @@ -configcheck -nohup diff --git a/.github/actions/spelling/allow/ghe-config-apply.sh.txt b/.github/actions/spelling/allow/ghe-config-apply.sh.txt deleted file mode 100644 index 0570567b..00000000 --- a/.github/actions/spelling/allow/ghe-config-apply.sh.txt +++ /dev/null @@ -1,2 +0,0 @@ -args -pid diff --git a/.github/actions/spelling/allow/ghe-initial-configuration.yml.txt b/.github/actions/spelling/allow/ghe-initial-configuration.yml.txt deleted file mode 100644 index a09f0564..00000000 --- a/.github/actions/spelling/allow/ghe-initial-configuration.yml.txt +++ /dev/null @@ -1 +0,0 @@ -initialconfig diff --git a/.github/actions/spelling/allow/ghe-ldap-configuration.yml.txt b/.github/actions/spelling/allow/ghe-ldap-configuration.yml.txt deleted file mode 100644 index 04b1c12f..00000000 --- a/.github/actions/spelling/allow/ghe-ldap-configuration.yml.txt +++ /dev/null @@ -1,2 +0,0 @@ -ldapconfig -openldap diff --git a/.github/actions/spelling/allow/gitignore.txt b/.github/actions/spelling/allow/gitignore.txt deleted file mode 100644 index 6fcb9a9c..00000000 --- a/.github/actions/spelling/allow/gitignore.txt +++ /dev/null @@ -1,8 +0,0 @@ -cov -eslintcache -jscoverage -jspm -nyc -tgz -typings -wscript diff --git a/.github/actions/spelling/allow/linter.sh.txt b/.github/actions/spelling/allow/linter.sh.txt deleted file mode 100644 index 9bd25b2f..00000000 --- a/.github/actions/spelling/allow/linter.sh.txt +++ /dev/null @@ -1,7 +0,0 @@ -cw -Mstrict -printenv -rcfile -tf -tolower -whoami diff --git a/.github/actions/spelling/allow/main.yml.txt b/.github/actions/spelling/allow/main.yml.txt deleted file mode 100644 index 877e71bb..00000000 --- a/.github/actions/spelling/allow/main.yml.txt +++ /dev/null @@ -1,8 +0,0 @@ -Autobots -basemap -cas -cn -crt -rsa -tlsv -tmp diff --git a/.github/actions/spelling/allow/settings.json.j2.txt b/.github/actions/spelling/allow/settings.json.j2.txt deleted file mode 100644 index 7f01269b..00000000 --- a/.github/actions/spelling/allow/settings.json.j2.txt +++ /dev/null @@ -1,4 +0,0 @@ -dotcom -identicons -oauth -timezone diff --git a/.github/actions/spelling/allow/words.txt b/.github/actions/spelling/allow/words.txt deleted file mode 100644 index 0e91754b..00000000 --- a/.github/actions/spelling/allow/words.txt +++ /dev/null @@ -1,158 +0,0 @@ -admiralawkbar -ansible -api -apk -aws -baz -beardofedu -certs -changeset -codebase -CODEOWNERS -coffeelint -coffeescript -collectd -concat -config -configs -css -dest -devops -dirname -dockerfile -dockerfilelint -dockerfilelintrc -dotenv -elif -emails -entrypoint -Errorf -eslint -eslintrc -filetype -func -gcc -getenv -ghe -GHES -ghl -github -globals -golang -golangci -Google -gpg -gql -Grafana -graphql -grep -homepage -hookshot -hostname -hostvars -http -https -hubot -idp -ip -Jani -javascript -jq -json -jsonlint -jwiebalk -JWT -ldap -len -lfs -libxml -linted -linting -loadbalancer -localhost -loglevel -markdownlint -millis -mkdir -nodejs -NONINFRINGEMENT -noproxy -noreply -npm -ntp -opensource -opensourcefriday -perl -plugin -posix -pprint -Prego -prettyjson -Println -probot -px -py -pylint -rb -readlines -README -regex -regexp -resqued -rgba -rien -Rubo -rubocop -saml -screenshots -shellcheck -signup -smtp -snmp -socio -splunk -src -ssh -ssl -sso -stackoverflow -stacktraces -standardjs -stringify -stylelint -stylelintrc -subdomain -subfolders -sudo -sys -syslog -taz -terraform -tflint -tileserver -tls -typeof -ubuntu -udp -uid -undef -uniq -uri -url -urlencode -username -usr -utils -Vape -vnd -webhook -wiki -wildcards -workflow -xml -xmllint -yaml -yamllint -yml -yq -zkoppert diff --git a/.github/actions/spelling/excludes.txt b/.github/actions/spelling/excludes.txt deleted file mode 100644 index 549b89c5..00000000 --- a/.github/actions/spelling/excludes.txt +++ /dev/null @@ -1,2 +0,0 @@ -^\.github/linters/ -^TEMPLATES/\.\S* diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt deleted file mode 100644 index 64d9960d..00000000 --- a/.github/actions/spelling/expect.txt +++ /dev/null @@ -1,39 +0,0 @@ -cdxml -changelog -chmod -Dockerhub -EOL -GPR -IAm -icu -jre -kotlin -krb -ktlint -libgcc -libintl -libssl -libstdc -linux -lttng -microsoft -ncurses -nq -openjdk -php -powershell -println -psd -psm -psrc -pssc -psscriptanalyzer -pwsh -rcu -rhc -ry -terminfo -tzdata -userspace -xargs -zlib diff --git a/.github/actions/spelling/patterns.txt b/.github/actions/spelling/patterns.txt deleted file mode 100644 index 5c595e9b..00000000 --- a/.github/actions/spelling/patterns.txt +++ /dev/null @@ -1,7 +0,0 @@ -https?:\S* -# ignore long runs of a single character: -([A-Za-z])\1{3,} -# Any CLI args (-xzf -aef) -\ -\w+\b -# Hex colors (dummy group to not be treated as comment) -(?:#)([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3}) diff --git a/.github/linters/.clj-kondo/config.edn b/.github/linters/.clj-kondo/config.edn new file mode 100644 index 00000000..30cae4c6 --- /dev/null +++ b/.github/linters/.clj-kondo/config.edn @@ -0,0 +1,2 @@ +{:linters {:unresolved-symbol {:exclude [(compojure.api.sweet/defroutes)]} + :refer-all {:exclude [clj-time.jdbc]}}} diff --git a/.github/linters/.openapirc.yml b/.github/linters/.openapirc.yml new file mode 100644 index 00000000..fdf641e1 --- /dev/null +++ b/.github/linters/.openapirc.yml @@ -0,0 +1,9 @@ +--- + +########################## +########################## +## OpenAPI Linter rules ## +########################## +########################## + +extends: spectral:oas diff --git a/.github/workflows/check-spelling.yml b/.github/workflows/check-spelling.yml deleted file mode 100644 index b99524b0..00000000 --- a/.github/workflows/check-spelling.yml +++ /dev/null @@ -1,48 +0,0 @@ ---- -#################### -## Check spelling ## -#################### - -# -# Documentation: -# https://help.github.com/en/articles/workflow-syntax-for-github-actions -# - -name: Spell checking -############################# -# Start the job on all push # -############################# -on: - push: - branches-ignore: - - 'master' - -############### -# Set the Job # -############### -jobs: - build: - # Name the Job - name: Spell checking - # Set the agent to run on - runs-on: ubuntu-latest - ################## - # Load all steps # - ################## - steps: - ########################## - # Checkout the code base # - ########################## - - name: Checkout Code - uses: actions/checkout@v2 - - ############################# - # Run check spelling action # - ############################# - - name: Check spelling - uses: check-spelling/check-spelling@0.0.16-alpha - with: - bucket: .github/actions - project: spelling - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 0c70da66..e529ffb7 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,6 @@ typings/ # next.js build output .next + +# clj-kondo cache +.cache \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 49a5dbb1..d0c3a70b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN apk add --no-cache \ libxml2-utils perl \ ruby ruby-dev ruby-bundler ruby-rdoc make \ py3-setuptools ansible-lint \ - go \ + go \ openjdk8-jre \ php7 \ ca-certificates less ncurses-terminfo-base \ @@ -72,6 +72,7 @@ RUN npm config set package-lock false \ eslint-plugin-jest \ stylelint \ stylelint-config-standard \ + @stoplight/spectral \ && npm --no-cache install \ markdownlint-cli \ jsonlint prettyjson \ @@ -131,6 +132,15 @@ RUN curl -Ls "$(curl -Ls https://api.github.com/repos/terraform-linters/tflint/r RUN wget "https://github.com/dotenv-linter/dotenv-linter/releases/latest/download/dotenv-linter-alpine-x86_64.tar.gz" -O - -q | tar -xzf - \ && mv "dotenv-linter" /usr/bin +##################### +# Install clj-kondo # +##################### +ARG CLJ_KONDO_VERSION='2020.06.12' +RUN curl -sLO https://github.com/borkdude/clj-kondo/releases/download/v${CLJ_KONDO_VERSION}/clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ + && unzip clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ + && rm clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ + && mv clj-kondo /usr/bin/ + ################## # Install ktlint # ################## @@ -166,8 +176,10 @@ ENV GITHUB_SHA=${GITHUB_SHA} \ VALIDATE_TERRAFORM=${VALIDATE_TERRAFORM} \ VALIDATE_CSS=${VALIDATE_CSS} \ VALIDATE_ENV=${VALIDATE_ENV} \ + VALIDATE_CLOJURE=${VALIDATE_CLOJURE} \ VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \ VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \ + VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \ ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \ RUN_LOCAL=${RUN_LOCAL} \ TEST_CASE_RUN=${TEST_CASE_RUN} \ diff --git a/README.md b/README.md index 19a816cd..567bb466 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | --- | --- | | **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) | | **CSS** | [stylelint](https://stylelint.io/) | +| **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) | | **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | | **Dockerfile** | [dockerfilelint](https://github.com/replicatedhq/dockerfilelint.git) | | **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) | @@ -54,6 +55,7 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | **PowerShell** | [PSScriptAnalyzer](https://github.com/PowerShell/Psscriptanalyzer) | | **ENV** | [dotenv-linter](https://github.com/dotenv-linter/dotenv-linter) | | **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) | +| **OpenAPI** | [spectral](https://github.com/stoplightio/spectral) | ## How to use To use this **GitHub** Action you will need to complete the following: @@ -160,7 +162,9 @@ and won't run anything unexpected. | **VALIDATE_TERRAFORM** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_CSS** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_ENV** | `true` | Flag to enable or disable the linting process of the language. | +| **VALIDATE_CLOJURE** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_KOTLIN** | `true` | Flag to enable or disable the linting process of the language. | +| **VALIDATE_OPENAPI** | `true` | Flag to enable or disable the linting process of the language. | | **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s). | | **ACTIONS_RUNNER_DEBUG** | `false` | Flag to enable additional information about the linter, versions, and additional output. | | **DISABLE_ERRORS** | `false` | Flag to have the linter complete with exit code 0 even if errors were detected. | diff --git a/TEMPLATES/.clj-kondo/config.edn b/TEMPLATES/.clj-kondo/config.edn new file mode 100644 index 00000000..30cae4c6 --- /dev/null +++ b/TEMPLATES/.clj-kondo/config.edn @@ -0,0 +1,2 @@ +{:linters {:unresolved-symbol {:exclude [(compojure.api.sweet/defroutes)]} + :refer-all {:exclude [clj-time.jdbc]}}} diff --git a/TEMPLATES/.openapirc.yml b/TEMPLATES/.openapirc.yml new file mode 100644 index 00000000..fdf641e1 --- /dev/null +++ b/TEMPLATES/.openapirc.yml @@ -0,0 +1,9 @@ +--- + +########################## +########################## +## OpenAPI Linter rules ## +########################## +########################## + +extends: spectral:oas diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index 9c6ecf0a..408eba19 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -24,6 +24,7 @@ Below are examples and documentation for each language and the various methods t - [CSS](#stylelint) - [ENV](#dotenv-linter) - [Kotlin](#kotlin) +- [OpenAPI](#openapi) @@ -607,3 +608,44 @@ import package.b.* ### ktlint disable entire file - There is currently **No** way to disable rules inline of the file(s) + +-------------------------------------------------------------------------------- + +## OpenAPI +- [spectral](https://github.com/stoplightio/spectral) + +### OpenAPI Config file +- `.github/linters/.openapirc.yml` +- You can add, extend, and disable rules +- Documentation at [Spectral Custom Rulesets](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/4-custom-rulesets.md) +- File should be located at: `.github/linters/.openapirc.yml` + +### OpenAPI disable single line +- There is currently **No** way to disable rules inline of the file(s) + +### OpenAPI disable code block +- There is currently **No** way to disable rules inline of the file(s) + +### OpenAPI disable entire file +- There is currently **No** way to disable rules inline of the file(s) +- However, you can make [rule exceptions](https://stoplight.io/p/docs/gh/stoplightio/spectral/docs/guides/6-exceptions.md?srn=gh/stoplightio/spectral/docs/guides/6-exceptions.md) in the config for individual file(s). + +-------------------------------------------------------------------------------- + +## Clojure +- [clj-kondo](https://github.com/borkdude/clj-kondo) +- Since clj-kondo approaches static analysis in a very Clojure way, it is advised to read the [configuration docs](https://github.com/borkdude/clj-kondo/blob/master/doc/config.md) + +### clj-kondo standard Config file +- `.github/linters/.clj-kondo/config.edn` + +### clj-kondo disable single line +- There is currently **No** way to disable rules in a single line + +### clj-kondo disable code block +- There is currently **No** way to disable rules in a code block + +### clj-kondo disable entire file +```clojure +{:output {:exclude-files ["path/to/file"]}} +``` diff --git a/lib/linter.sh b/lib/linter.sh index 41d36428..2dd5d3cb 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -54,6 +54,12 @@ POWERSHELL_LINTER_RULES="$DEFAULT_RULES_LOCATION/$POWERSHELL_FILE_NAME" # Pat # CSS Vars CSS_FILE_NAME='.stylelintrc.json' # Name of the file CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to the CSS lint rules +# OpenAPI Vars +OPENAPI_FILE_NAME='.openapirc.yml' # Name of the file +OPENAPI_LINTER_RULES="$DEFAULT_RULES_LOCATION/$OPENAPI_FILE_NAME" # Path to the OpenAPI lint rules +# Clojure Vars +CLOJURE_FILE_NAME='.clj-kondo/config.edn' +CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" ####################################### # Linter array for information prints # @@ -61,7 +67,7 @@ CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to th LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" "pylint" "perl" "rubocop" "coffeelint" "eslint" "standard" "ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint" - "stylelint" "dotenv-linter" "powershell" "ktlint") + "stylelint" "dotenv-linter" "powershell" "ktlint" "clj-kondo" "spectral") ############################# # Language array for prints # @@ -69,7 +75,7 @@ LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'PHP' 'RUBY' 'PYTHON' 'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES' 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM' - 'ENV' 'POWERSHELL' 'KOTLIN') + 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'CLOJURE' 'OPENAPI') ################### # GitHub ENV Vars # @@ -100,9 +106,11 @@ VALIDATE_DOCKER="${VALIDATE_DOCKER}" # Boolean to validate lang VALIDATE_GO="${VALIDATE_GO}" # Boolean to validate language VALIDATE_CSS="${VALIDATE_CSS}" # Boolean to validate language VALIDATE_ENV="${VALIDATE_ENV}" # Boolean to validate language +VALIDATE_CLOJURE="${VALIDATE_CLOJURE}" # Boolean to validate language VALIDATE_TERRAFORM="${VALIDATE_TERRAFORM}" # Boolean to validate language VALIDATE_POWERSHELL="${VALIDATE_POWERSHELL}" # Boolean to validate language VALIDATE_KOTLIN="${VALIDATE_KOTLIN}" # Boolean to validate language +VALIDATE_OPENAPI="${VALIDATE_OPENAPI}" # Boolean to validate language TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases DISABLE_ERRORS="${DISABLE_ERRORS}" # Boolean to enable warning-only output without throwing errors @@ -126,6 +134,7 @@ RAW_FILE_ARRAY=() # Array of all files that were changed READ_ONLY_CHANGE_FLAG=0 # Flag set to 1 if files changed are not txt or md TEST_CASE_FOLDER='.automation/test' # Folder for test cases we should always ignore DEFAULT_DISABLE_ERRORS='false' # Default to enabling errors +DEFAULT_IFS="$IFS" # Get the Default IFS for updating ########################## # Array of changed files # @@ -150,7 +159,9 @@ FILE_ARRAY_TERRAFORM=() # Array of files to check FILE_ARRAY_POWERSHELL=() # Array of files to check FILE_ARRAY_CSS=() # Array of files to check FILE_ARRAY_ENV=() # Array of files to check +FILE_ARRAY_CLOJURE=() # Array of files to check FILE_ARRAY_KOTLIN=() # Array of files to check +FILE_ARRAY_OPENAPI=() # Array of files to check ############ # Counters # @@ -176,7 +187,9 @@ ERRORS_FOUND_TERRAFORM=0 # Count of errors found ERRORS_FOUND_POWERSHELL=0 # Count of errors found ERRORS_FOUND_CSS=0 # Count of errors found ERRORS_FOUND_ENV=0 # Count of errors found +ERRORS_FOUND_CLOJURE=0 # Count of errors found ERRORS_FOUND_KOTLIN=0 # Count of errors found +ERRORS_FOUND_OPENAPI=0 # Count of errors found ################################################################################ ########################## FUNCTIONS BELOW ##################################### @@ -558,6 +571,42 @@ LintAnsibleFiles() fi fi } + +################################################################################ +#### Function DetectOpenAPIFile ################################################ +DetectOpenAPIFile() +{ + ################ + # Pull in vars # + ################ + FILE="$1" + + ############################### + # Check the file for keywords # + ############################### + grep -E '"openapi":|"swagger":|^openapi:|^swagger:' "$GITHUB_WORKSPACE/$FILE" > /dev/null + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -eq 0 ]; then + ######################## + # Found string in file # + ######################## + return 0 + else + ################### + # No string match # + ################### + return 1 + fi +} + ################################################################################ #### Function GetGitHubVars #################################################### GetGitHubVars() @@ -757,7 +806,9 @@ GetValidationInfo() VALIDATE_POWERSHELL=$(echo "$VALIDATE_POWERSHELL" | awk '{print tolower($0)}') VALIDATE_CSS=$(echo "$VALIDATE_CSS" | awk '{print tolower($0)}') VALIDATE_ENV=$(echo "$VALIDATE_ENV" | awk '{print tolower($0)}') + VALIDATE_CLOJURE=$(echo "$VALIDATE_CLOJURE" | awk '{print tolower($0)') VALIDATE_KOTLIN=$(echo "$VALIDATE_KOTLIN" | awk '{print tolower($0)}') + VALIDATE_OPENAPI=$(echo "$VALIDATE_OPENAPI" | awk '{print tolower($0)}') ################################################ # Determine if any linters were explicitly set # @@ -784,6 +835,8 @@ GetValidationInfo() -n "$VALIDATE_POWERSHELL" || \ -n "$VALIDATE_CSS" || \ -n "$VALIDATE_ENV" || \ + -n "$VALIDATE_CLOJURE" || \ + -n "$VALIDATE_OPENAPI" || \ -n "$VALIDATE_KOTLIN" ]]; then ANY_SET="true" fi @@ -1096,6 +1149,33 @@ GetValidationInfo() VALIDATE_KOTLIN="true" fi + ####################################### + # Validate if we should check OPENAPI # + ####################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_OPENAPI" ]]; then + # OPENAPI flag was not set - default to false + VALIDATE_OPENAPI="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_OPENAPI="true" + fi + + ####################################### + # Validate if we should check Clojure # + ####################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_CLOJURE" ]]; then + # Clojure flag was not set - default to false + VALIDATE_CLOJURE="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_CLOJURE="true" + fi ####################################### # Print which linters we are enabling # @@ -1200,6 +1280,11 @@ GetValidationInfo() else PRINT_ARRAY+=("- Excluding [CSS] files in code base...") fi + if [[ "$VALIDATE_CLOJURE" == "true" ]]; then + PRINT_ARRAY+=("- Validating [CLOJURE] files in code base...") + else + PRINT_ARRAY+=("- Excluding [CLOJURE] files in code base...") + fi if [[ "$VALIDATE_ENV" == "true" ]]; then PRINT_ARRAY+=("- Validating [ENV] files in code base...") else @@ -1210,6 +1295,11 @@ GetValidationInfo() else PRINT_ARRAY+=("- Excluding [KOTLIN] files in code base...") fi + if [[ "$VALIDATE_OPENAPI" == "true" ]]; then + PRINT_ARRAY+=("- Validating [OPENAPI] files in code base...") + else + PRINT_ARRAY+=("- Excluding [OPENAPI] files in code base...") + fi ############################## # Validate Ansible Directory # @@ -1406,6 +1496,12 @@ BuildFileList() # Append the file to the array # ################################ FILE_ARRAY_YML+=("$FILE") + ############################ + # Check if file is OpenAPI # + ############################ + if DetectOpenAPIFile "$FILE"; then + FILE_ARRAY_OPENAPI+=("$FILE") + fi ########################################################## # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## @@ -1418,6 +1514,12 @@ BuildFileList() # Append the file to the array # ################################ FILE_ARRAY_JSON+=("$FILE") + ############################ + # Check if file is OpenAPI # + ############################ + if DetectOpenAPIFile "$FILE"; then + FILE_ARRAY_OPENAPI+=("$FILE") + fi ########################################################## # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## @@ -1608,6 +1710,15 @@ BuildFileList() # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE" == "clj" ] || [ "$FILE" == "cljs" ] || [ "$FILE" == "cljc" ] || [ "$FILE" == "edn" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_CLOJURE+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 else ############################################## # Use file to see if we can parse what it is # @@ -1761,12 +1872,22 @@ LintCodebase() # We have files added to array of files to check LIST_FILES=("${FILE_ARRAY[@]}") # Copy the array into list else + ############################################################################### + # Set the file seperator to newline to allow for grabbing objects with spaces # + ############################################################################### + IFS=$'\n' + ################################# # Get list of all files to lint # ################################# # shellcheck disable=SC2207,SC2086 LIST_FILES=($(cd "$GITHUB_WORKSPACE" || exit; find . -type f -regex "$FILE_EXTENSIONS" 2>&1)) + ########################### + # Set IFS back to default # + ########################### + IFS="$DEFAULT_IFS" + ############################################################ # Set it back to empty if loaded with blanks from scanning # ############################################################ @@ -1933,11 +2054,21 @@ TestCodebase() # shellcheck disable=SC2207,SC2086,SC2010 LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; ls ansible/ | grep ".yml" 2>&1)) else + ############################################################################### + # Set the file seperator to newline to allow for grabbing objects with spaces # + ############################################################################### + IFS=$'\n' + ################################# # Get list of all files to lint # ################################# # shellcheck disable=SC2207,SC2086 LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" 2>&1)) + + ########################### + # Set IFS back to default # + ########################### + IFS="$DEFAULT_IFS" fi ################## @@ -2137,6 +2268,8 @@ Footer() [ "$ERRORS_FOUND_RUBY" -ne 0 ] || \ [ "$ERRORS_FOUND_CSS" -ne 0 ] || \ [ "$ERRORS_FOUND_ENV" -ne 0 ] || \ + [ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || \ + [ "$ERRORS_FOUND_CLOJURE" -ne 0 ] || \ [ "$ERRORS_FOUND_KOTLIN" -ne 0 ]; then # Failed exit echo "Exiting with errors found!" @@ -2192,13 +2325,15 @@ RunTestCases() TestCodebase "JAVASCRIPT_STANDARD" "standard" "standard $JAVASCRIPT_STANDARD_LINTER_RULES" ".*\.\(js\)\$" TestCodebase "TYPESCRIPT_ES" "eslint" "eslint --no-eslintrc -c $TYPESCRIPT_LINTER_RULES" ".*\.\(ts\)\$" TestCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$" - TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint" ".*\(Dockerfile\)\$" + TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$" TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint" TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" + TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" + TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" ################# # Footer prints # @@ -2527,7 +2662,21 @@ if [ "$VALIDATE_DOCKER" == "true" ]; then # Lint the docker files # ######################### # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" - LintCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint" ".*\(Dockerfile\)\$" "${FILE_ARRAY_DOCKER[@]}" + LintCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint -c $DOCKER_LINTER_RULES" ".*\(Dockerfile\)\$" "${FILE_ARRAY_DOCKER[@]}" +fi + +################### +# CLOJURE LINTING # +################### +if [ "$VALIDATE_CLOJURE" == "true" ]; then + ################################# + # Get Clojure standard rules # + ################################# + GetStandardRules "clj-kondo" + ######################### + # Lint the Clojure files # + ######################### + LintCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "${FILE_ARRAY_CLOJURE[@]}" fi ###################### @@ -2541,6 +2690,39 @@ if [ "$VALIDATE_POWERSHELL" == "true" ]; then LintCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "${FILE_ARRAY_POWERSHELL[@]}" fi +################### +# OPENAPI LINTING # +################### +if [ "$VALIDATE_OPENAPI" == "true" ]; then + # If we are validating all codebase we need to build file list because not every yml/json file is an OpenAPI file + if [ "$VALIDATE_ALL_CODEBASE" == "true" ]; then + ############################################################################### + # Set the file seperator to newline to allow for grabbing objects with spaces # + ############################################################################### + IFS=$'\n' + + # shellcheck disable=SC2207 + LIST_FILES=($(cd "$GITHUB_WORKSPACE" || exit; find . -type f -regex ".*\.\(yml\|yaml\|json\)\$" 2>&1)) + for FILE in "${LIST_FILES[@]}" + do + if DetectOpenAPIFile "$FILE"; then + FILE_ARRAY_OPENAPI+=("$FILE") + fi + done + + ########################### + # Set IFS back to default # + ########################### + IFS="$DEFAULT_IFS" + fi + + ########################## + # Lint the OpenAPI files # + ########################## + # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" + LintCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" "disabledfileext" "${FILE_ARRAY_OPENAPI[@]}" +fi + ########## # Footer # ##########