diff --git a/.automation/test/protobuf/README.md b/.automation/test/protobuf/README.md new file mode 100644 index 00000000..7048213f --- /dev/null +++ b/.automation/test/protobuf/README.md @@ -0,0 +1,19 @@ +# Protobuf Test Cases + +This folder holds the test cases for **Protobuf**. + +## 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/protobuf/protobuf_bad_1.proto b/.automation/test/protobuf/protobuf_bad_1.proto new file mode 100644 index 00000000..b42980ba --- /dev/null +++ b/.automation/test/protobuf/protobuf_bad_1.proto @@ -0,0 +1,48 @@ +syntax = "proto3"; +// A broken example of the official reference +// See https://developers.google.com/protocol-buffers/docs/reference/proto3-spec#proto_file +package examplePb; + +option java_package = "com.example.foo"; + +import "other.proto"; +import public "new.proto"; + +import "google/protobuf/empty.proto"; +import "google/protobuf/timestamp.proto"; + +import "myproject/other_protos.proto"; +import "myproject/main_protos.proto"; + +enum enumAllowingAlias { + option allow_alias = true; + UNKNOWN = 0; + STARTED = 1; + RUNNING = 2 [(custom_option) = "hello world"]; +} +message outer { + option (my_option).a = true; + // inner is an inner message. + message inner { // Level 2 + int64 ival = 1; + } + repeated inner inner_message = 2; + EnumAllowingAlias enum_field =3; + map my_map = 4; + string reason_for_error = 5; + string end_of_support_version= 6; + message AccountForAdmin {} + message SpecialEndOfSupport {} + required inner inner_message = 7; + group Result = 8 { + string url = 9; + } + repeated group Result = 10 { + } + repeated inner paper = 11; + repeated group Regular = 12 { + } +} +service SearchApi { + rpc search (SearchRequest) returns (SearchResponse) {}; +}; diff --git a/.automation/test/protobuf/protobuf_good_1.proto b/.automation/test/protobuf/protobuf_good_1.proto new file mode 100644 index 00000000..76022990 --- /dev/null +++ b/.automation/test/protobuf/protobuf_good_1.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; +import public "other.proto"; +option java_package = "com.example.foo"; +enum EnumAllowingAlias { + option allow_alias = true; + ALLOWING_UNSPECIFIED = 0; + STARTED = 1; + RUNNING = 2 [(custom_option) = "hello world"]; +} +message Outer { + option (my_option).a = true; + message Inner { // Level 2 + int64 ival = 1; + } + inner inner_message = 2; + EnumAllowingAlias enum_field =3; + map my_map = 4; +} diff --git a/.automation/upload-docker.sh b/.automation/upload-docker.sh index 12c15635..eefb5c50 100755 --- a/.automation/upload-docker.sh +++ b/.automation/upload-docker.sh @@ -26,6 +26,8 @@ REGISTRY="${REGISTRY}" # What registry to upload | or &1 + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # ERROR + echo "ERROR! failed to [tag] Dockerfile!" + exit 1 + else + # SUCCESS + echo "Successfully tagged image!" + fi fi } ################################################################################ @@ -328,7 +378,7 @@ UploadImage() exit 1 else # SUCCESS - echo "Successfully Uploaded Docker image to $REGISTRY!" + echo "Successfully Uploaded Docker image:[$IMAGE_VERSION] to $REGISTRY!" fi ######################### @@ -371,6 +421,33 @@ UploadImage() echo "Size:[$SIZE]" echo "----------------------------------------------" fi + + ############################################################### + # Check if we need to upload the major tagged version as well # + ############################################################### + if [ $UPDATE_MAJOR_TAG -eq 1 ]; then + ############################################ + # Upload the docker image that was created # + ############################################ + docker push "$IMAGE_REPO:$MAJOR_TAG" 2>&1 + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # ERROR + echo "ERROR! failed to [upload] MAJOR_TAG:[$MAJOR_TAG] Dockerfile!" + exit 1 + else + # SUCCESS + echo "Successfully Uploaded TAGOR_TAG:[$MAJOR_TAG] Docker image to $REGISTRY!" + fi + fi } ################################################################################ #### Function Footer ########################################################### diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000..75057d9f --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,10 @@ +# Devcontainer +This file specifies to vscode how to run the container + +For format details, see [documentation](https://aka.ms/vscode-remote/devcontainer.json) or this file's [README](https://github.com/microsoft/vscode-dev-containers/tree/v0.123.0/containers/docker-existing-dockerfile) + + +context: Sets the run context to one level up instead of the .devcontainer folder. +dockerFile: Update the 'dockerFile' property if you aren't using the standard 'Dockerfile' filename. +settings: Set *default* container specific settings.json values on container create. +extensions: Add the IDs of extensions you want installed when the container is created. \ No newline at end of file diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..ac0ac8e1 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "SUPER-LINTER", + "context": "..", + "dockerFile": "..//Dockerfile", + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + }, + "extensions": [ + "github.vscode-pull-request-github", + "rogalmic.bash-debug" + ] +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..5dc46e6b --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.{cmd,[cC][mM][dD]} text eol=crlf +*.{bat,[bB][aA][tT]} text eol=crlf \ No newline at end of file diff --git a/.github/linters/.protolintrc.yml b/.github/linters/.protolintrc.yml new file mode 100644 index 00000000..7bd3e0ce --- /dev/null +++ b/.github/linters/.protolintrc.yml @@ -0,0 +1,7 @@ +# Lint directives. +lint: + # Linter rules. + # Run `protolint list` to see all available rules. + rules: + # Set the default to all linters. + all_default: false diff --git a/.github/linters/.python-lint b/.github/linters/.python-lint index 8e9cc00e..e3d9f5b5 100644 --- a/.github/linters/.python-lint +++ b/.github/linters/.python-lint @@ -1,4 +1,5 @@ [MASTER] +errors-only= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may @@ -157,7 +158,7 @@ output-format=text reports=no # Activate the evaluation score. -score=yes +score=no [REFACTORING] diff --git a/.github/workflows/versioning.yml b/.github/workflows/versioning.yml new file mode 100644 index 00000000..01039a30 --- /dev/null +++ b/.github/workflows/versioning.yml @@ -0,0 +1,16 @@ +name: Keep the versions up-to-date + +on: + release: + types: [published, edited] + +jobs: + actions-tagger: + runs-on: windows-latest + steps: + - uses: actions/checkout@v2 + - uses: Actions-R-Us/actions-tagger@latest + with: + publish_latest_tag: true + env: + GITHUB_TOKEN: "${{secrets.GITHUB_TOKEN}}" diff --git a/.github/workflows/welcome_new_people.yml b/.github/workflows/welcome_new_people.yml deleted file mode 100644 index 985ee57e..00000000 --- a/.github/workflows/welcome_new_people.yml +++ /dev/null @@ -1,13 +0,0 @@ -name: Greetings - -on: [pull_request, issues] - -jobs: - greeting: - runs-on: ubuntu-latest - steps: - - uses: actions/first-interaction@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - issue-message: 'Thanks for opening your first issue in the **super-linter** repo! :tada:' - pr-message: 'Thanks for opening your first pr in the **super-linter** repo! :tada: This project is built on contributions just like this.' diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..77e1ced2 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "bashdb", + "request": "launch", + "name": "Test Linter", + "program": ".vscode/testlinter.sh", + "cwd": "${workspaceFolder}", + "internalConsoleOptions": "openOnSessionStart", + "presentation": { + "group": "aLinter" + } + } + ] +} \ No newline at end of file diff --git a/.vscode/testlinter.sh b/.vscode/testlinter.sh new file mode 100644 index 00000000..8d778d16 --- /dev/null +++ b/.vscode/testlinter.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# At this point you can use the debug console to add export GITHUB_WORKSPACE=/path to test only a specific folder +# You can also use ln -s /path /tmp/lint as an alternative +# If you do neither, this will default to running against the test automation files + +########### +# GLOBALS # +########### +CODE_PATH='/tmp/lint' # Path to code base + +################## +# Check the path # +################## +if [ ! -L $CODE_PATH ]; then + # Create symbolic link + ln -s "$PWD"/.automation/test $CODE_PATH +fi + +######################### +# Export to run locally # +######################### +export RUN_LOCAL=true + +# shellcheck disable=SC1091,SC1090 +source "$PWD"/lib/linter.sh diff --git a/Dockerfile b/Dockerfile index 9806ee49..0af0a65e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -126,6 +126,14 @@ RUN wget -O- -nvq https://raw.githubusercontent.com/golangci/golangci-lint/maste RUN curl -Ls "$(curl -Ls https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E "https://.+?_linux_amd64.zip")" -o tflint.zip && unzip tflint.zip && rm tflint.zip \ && mv "tflint" /usr/bin/ +###################### +# Install protolint # +###################### +RUN curl -LsS "$(curl -Ls https://api.github.com/repos/yoheimuta/protolint/releases/latest | grep -o -E "https://.+?_Linux_x86_64.tar.gz")" -o protolint.tar.gz \ + && tar -xzf protolint.tar.gz \ + && rm protolint.tar.gz \ + && mv "protolint" /usr/bin/ + ######################### # Install dotenv-linter # ######################### @@ -180,6 +188,7 @@ ENV GITHUB_SHA=${GITHUB_SHA} \ VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \ VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \ VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \ + VALIDATE_PROTOBUF=${VALIDATE_PROTOBUF} \ ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \ RUN_LOCAL=${RUN_LOCAL} \ TEST_CASE_RUN=${TEST_CASE_RUN} \ diff --git a/README.md b/README.md index fb3ceb35..4feb70f8 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Super-Linter -This repository is for the **GitHub Action** to run a **Super-Linter**. +This repository is for the **GitHub Action** to run a **Super-Linter**. It is a simple combination of various linters, written in `bash`, to help validate your source code. The end goal of this tool: @@ -32,32 +32,34 @@ The design of the **Super-Linter** is currently to allow linting to occur in **G Developers on **GitHub** can call the **GitHub Action** to lint their code base with the following list of linters: -| *Language* | *Linter* | -| --- | --- | -| **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) | -| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | -| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | -| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) | -| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) | -| **PHP** | [PHP](https://www.php.net/) | -| **Python3** | [pylint](https://www.pylint.org/) | -| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | -| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) | -| **Terraform** | [tflint](https://github.com/terraform-linters/tflint) | -| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | -| **XML** | [LibXML](http://xmlsoft.org/) | -| **YAML** | [YamlLint](https://github.com/adrienverge/yamllint) | -| **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) | +| *Language* | *Linter* | +| --- | --- | +| **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) | +| **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | +| **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | +| **Markdown** | [markdownlint](https://github.com/igorshubovych/markdownlint-cli#readme) | +| **Perl** | [perl](https://pkgs.alpinelinux.org/package/edge/main/x86/perl) | +| **PHP** | [PHP](https://www.php.net/) | +| **Python3** | [pylint](https://www.pylint.org/) | +| **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | +| **Shell** | [Shellcheck](https://github.com/koalaman/shellcheck) | +| **Terraform** | [tflint](https://github.com/terraform-linters/tflint) | +| **TypeScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | +| **XML** | [LibXML](http://xmlsoft.org/) | +| **YAML** | [YamlLint](https://github.com/adrienverge/yamllint) | +| **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) | +| **Protocol Buffers** | [protolint](https://github.com/yoheimuta/protolint) | | **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-lint/) | + ## How to use To use this **GitHub** Action you will need to complete the following: - Add the **GitHub** Action: **Super-Linter** to your current **GitHub** Actions workflow @@ -117,21 +119,21 @@ jobs: # Run Linter against code base # ################################ - name: Lint Code Base - uses: docker://github/super-linter:v2.2.0 + uses: docker://github/super-linter:v3 env: VALIDATE_ALL_CODEBASE: false VALIDATE_ANSIBLE: false ... ``` -**NOTE:** Using the line:`uses: docker://github/super-linter:v2.2.0` will pull the image down from **DockerHub** and run the **GitHub Super-Linter**. Using the line: `uses: github/super-linter@v2.2.0` will build and compile the **GitHub Super-Linter** at build time. This can be far more costly in time... +**NOTE:** Using the line:`uses: docker://github/super-linter:v3` will pull the image down from **DockerHub** and run the **GitHub Super-Linter**. Using the line: `uses: github/super-linter@v3` will build and compile the **GitHub Super-Linter** at build time. This can be far more costly in time... ## Environment variables The super-linter allows you to pass the following `ENV` variables to be able to trigger different functionality. -*Note:* All the `VALIDATE_[LANGUAGE]` variables behave in a specific way. -If none of them are passed, then they all default to true. -However if any one of the variables are set, we default to leaving any unset variable to false. +*Note:* All the `VALIDATE_[LANGUAGE]` variables behave in a specific way. +If none of them are passed, then they all default to true. +However if any one of the variables are set, we default to leaving any unset variable to false. This means that if you run the linter "out of the box", all languages will be checked. But if you wish to select specific linters, we give you full control to choose which linters are run, and won't run anything unexpected. @@ -169,6 +171,7 @@ and won't run anything unexpected. | **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. | | **VALIDATE_CLOUDFORMATION** | `true` | Flag to enable or disable the linting process of the language. | +| **VALIDATE_PROTOBUF** | `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. | @@ -208,6 +211,12 @@ Below are a list of the known limitations for the **GitHub Super-Linter**: ## How to contribute If you would like to help contribute to this **GitHub** Action, please see [CONTRIBUTING](https://github.com/github/super-linter/blob/master/.github/CONTRIBUTING.md) +### Visual Studio Code +You can checkout this repository using [Container Remote Development](https://code.visualstudio.com/docs/remote/containers), and debug the linter using the `Test Linter` task. +![Example](https://user-images.githubusercontent.com/15258962/85165778-2d2ce700-b21b-11ea-803e-3f6709d8e609.gif) + +We will also support [Github Codespaces](https://github.com/features/codespaces/) once it becomes available + -------------------------------------------------------------------------------- ### License diff --git a/TEMPLATES/.protolintrc.yml b/TEMPLATES/.protolintrc.yml new file mode 100644 index 00000000..7bd3e0ce --- /dev/null +++ b/TEMPLATES/.protolintrc.yml @@ -0,0 +1,7 @@ +# Lint directives. +lint: + # Linter rules. + # Run `protolint list` to see all available rules. + rules: + # Set the default to all linters. + all_default: false diff --git a/TEMPLATES/.python-lint b/TEMPLATES/.python-lint index 8e9cc00e..e3d9f5b5 100644 --- a/TEMPLATES/.python-lint +++ b/TEMPLATES/.python-lint @@ -1,4 +1,5 @@ [MASTER] +errors-only= # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may @@ -157,7 +158,7 @@ output-format=text reports=no # Activate the evaluation score. -score=yes +score=no [REFACTORING] diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index cc8071bf..dc6393a6 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -26,6 +26,7 @@ Below are examples and documentation for each language and the various methods t - [ENV](#dotenv-linter) - [Kotlin](#kotlin) - [OpenAPI](#openapi) +- [Protocol Buffers](#protocol-buffers) @@ -669,6 +670,53 @@ import package.b.* -------------------------------------------------------------------------------- +## Protocol Buffers + +- [protolint](https://github.com/yoheimuta/protolint) + +### protolint Config file + +- `.github/linters/.protolintrc.yml` +- You can add, extend, and disable rules +- Documentation at [Rules](https://github.com/yoheimuta/protolint#rules) and [Configuring](https://github.com/yoheimuta/protolint#configuring) + +### protolint disable single line + +```protobuf +enum Foo { + // protolint:disable:next ENUM_FIELD_NAMES_UPPER_SNAKE_CASE + firstValue = 0; + second_value = 1; // protolint:disable:this ENUM_FIELD_NAMES_UPPER_SNAKE_CASE + THIRD_VALUE = 2; +} +``` + +### protolint disable code block + +```protobuf +// protolint:disable ENUM_FIELD_NAMES_UPPER_SNAKE_CASE +enum Foo { + firstValue = 0; + second_value = 1; + THIRD_VALUE = 2; +} +// protolint:enable ENUM_FIELD_NAMES_UPPER_SNAKE_CASE +``` + +### protolint disable entire file + +- You can disable entire files with the `lint.files.exclude` property in `.protolintrc.yml` + +```yaml +# Lint directives. +lint: + # Linter files to walk. + files: + # The specific files to exclude. + exclude: + - path/to/file +``` + ## 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) diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 00000000..500e2142 --- /dev/null +++ b/lib/README.md @@ -0,0 +1,15 @@ +# Super-Linter Library + +## Main script +The file `linter.sh` is the main script that is called for the process and loads all other scripts as functions. + +## Functions +The additional files in the folder are functions to help streamline the main build process and allow for easier maintenance. +- `possum.sh` + - Official mascot of the **Super-Linter** +- `buildFileList.sh` + - Functions to help find files that were modified, or need to be scanned +- `validation.sh` + - Logic to see what linters are enabled +- `worker.sh` + - Calls to the various linters and the test cases for each diff --git a/lib/buildFileList.sh b/lib/buildFileList.sh new file mode 100755 index 00000000..d39f7a64 --- /dev/null +++ b/lib/buildFileList.sh @@ -0,0 +1,421 @@ +#!/usr/bin/env bash +# shellcheck disable=SC2034 + +################################################################################ +################################################################################ +########### Super-Linter Build File List Functions @admiralawkbar ############## +################################################################################ +################################################################################ +########################## FUNCTION CALLS BELOW ################################ +################################################################################ +################################################################################ +#### Function BuildFileList #################################################### +function BuildFileList() +{ + # Need to build a list of all files changed + # This can be pulled from the GITHUB_EVENT_PATH payload + + ################ + # print header # + ################ + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + echo "" + echo "----------------------------------------------" + echo "Pulling in code history and branches..." + fi + + ################################################################################# + # Switch codebase back to the default branch to get a list of all files changed # + ################################################################################# + SWITCH_CMD=$(cd "$GITHUB_WORKSPACE" || exit; git pull --quiet; git checkout "$DEFAULT_BRANCH" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Error + echo "Failed to switch to $DEFAULT_BRANCH branch to get files changed!" + echo "ERROR:[$SWITCH_CMD]" + exit 1 + fi + + ################ + # print header # + ################ + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + echo "" + echo "----------------------------------------------" + echo "Generating Diff with:[git diff --name-only '$DEFAULT_BRANCH..$GITHUB_SHA' --diff-filter=d]" + fi + + ################################################# + # Get the Array of files changed in the commits # + ################################################# + # shellcheck disable=SC2207 + RAW_FILE_ARRAY=($(cd "$GITHUB_WORKSPACE" || exit; git diff --name-only "$DEFAULT_BRANCH..$GITHUB_SHA" --diff-filter=d 2>&1)) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Error + echo "ERROR! Failed to gain a list of all files changed!" + echo "ERROR:[${RAW_FILE_ARRAY[*]}]" + exit 1 + fi + + ################################################ + # Iterate through the array of all files found # + ################################################ + echo "" + echo "----------------------------------------------" + echo "Files that have been modified in the commit(s):" + for FILE in "${RAW_FILE_ARRAY[@]}" + do + ############## + # Print file # + ############## + echo "File:[$FILE]" + + ########################### + # Get the files extension # + ########################### + # Extract just the file and extension, reverse it, cut off extension, + # reverse it back, substitute to lowercase + FILE_TYPE=$(basename "$FILE" | rev | cut -f1 -d'.' | rev | awk '{print tolower($0)}') + + ######### + # DEBUG # + ######### + #echo "FILE_TYPE:[$FILE_TYPE]" + + ##################### + # Get the YML files # + ##################### + if [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ]; then + ################################ + # 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 # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ###################### + # Get the JSON files # + ###################### + elif [ "$FILE_TYPE" == "json" ]; then + ################################ + # 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 # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ##################### + # Get the XML files # + ##################### + elif [ "$FILE_TYPE" == "xml" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_XML+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ########################## + # Get the MARKDOWN files # + ########################## + elif [ "$FILE_TYPE" == "md" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_MD+=("$FILE") + ###################### + # Get the BASH files # + ###################### + elif [ "$FILE_TYPE" == "sh" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_BASH+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ###################### + # Get the PERL files # + ###################### + elif [ "$FILE_TYPE" == "pl" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_PERL+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ###################### + # Get the PHP files # + ###################### + elif [ "$FILE_TYPE" == "php" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_PHP+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ###################### + # Get the RUBY files # + ###################### + elif [ "$FILE_TYPE" == "rb" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_RUBY+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ######################## + # Get the PYTHON files # + ######################## + elif [ "$FILE_TYPE" == "py" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_PYTHON+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ######################## + # Get the COFFEE files # + ######################## + elif [ "$FILE_TYPE" == "coffee" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_COFFEESCRIPT+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ############################ + # Get the JavaScript files # + ############################ + elif [ "$FILE_TYPE" == "js" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_JAVASCRIPT_ES+=("$FILE") + FILE_ARRAY_JAVASCRIPT_STANDARD+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ############################ + # Get the TypeScript files # + ############################ + elif [ "$FILE_TYPE" == "ts" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_TYPESCRIPT_ES+=("$FILE") + FILE_ARRAY_TYPESCRIPT_STANDARD+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ######################## + # Get the Golang files # + ######################## + elif [ "$FILE_TYPE" == "go" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_GO+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ########################### + # Get the Terraform files # + ########################### + elif [ "$FILE_TYPE" == "tf" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_TERRAFORM+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ########################### + # Get the Powershell files # + ########################### + elif [ "$FILE_TYPE" == "ps1" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_POWERSHELL+=("$FILE") + elif [ "$FILE_TYPE" == "css" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_CSS+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE_TYPE" == "env" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_ENV+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE_TYPE" == "kt" ] || [ "$FILE_TYPE" == "kts" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_KOTLIN+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + ############################ + # Get the Protocol Buffers files # + ############################ + elif [ "$FILE_TYPE" == "proto" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_PROTOBUF+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE" == "Dockerfile" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_DOCKER+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE_TYPE" == "clj" ] || [ "$FILE_TYPE" == "cljs" ] || [ "$FILE_TYPE" == "cljc" ] || [ "$FILE_TYPE" == "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 # + ############################################## + GET_FILE_TYPE_CMD=$(file "$FILE" 2>&1) + + ################# + # Check if bash # + ################# + if [[ "$GET_FILE_TYPE_CMD" == *"Bourne-Again shell script"* ]]; then + ####################### + # It is a bash script # + ####################### + echo "WARN! Found bash script without extension:[.sh]" + echo "Please update file with proper extensions." + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_BASH+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + elif [[ "$GET_FILE_TYPE_CMD" == *"Ruby script"* ]]; then + ####################### + # It is a Ruby script # + ####################### + echo "WARN! Found ruby script without extension:[.rb]" + echo "Please update file with proper extensions." + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_RUBY+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + else + ############################ + # Extension was not found! # + ############################ + echo " - WARN! Failed to get filetype for:[$FILE]!" + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 + fi + fi + done + + ######################################### + # Need to switch back to branch of code # + ######################################### + SWITCH2_CMD=$(cd "$GITHUB_WORKSPACE" || exit; git checkout --progress --force "$GITHUB_SHA" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Error + echo "Failed to switch back to branch!" + echo "ERROR:[$SWITCH2_CMD]" + exit 1 + fi + + ################ + # Footer print # + ################ + echo "" + echo "----------------------------------------------" + echo "Successfully gathered list of files..." +} diff --git a/lib/linter.sh b/lib/linter.sh index f297295c..11431dcd 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# shellcheck disable=SC1003,SC2016 +# shellcheck disable=SC1003,SC2016,SC1091 ################################################################################ ################################################################################ @@ -7,6 +7,13 @@ ################################################################################ ################################################################################ +######################### +# Source Function Files # +######################### +source /action/lib/buildFileList.sh # Source the function script(s) +source /action/lib/validation.sh # Source the function script(s) +source /action/lib/worker.sh # Source the function script(s) + ########### # GLOBALS # ########### @@ -60,6 +67,9 @@ CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to th # 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 +# Protocol Buffers Vars +PROTOBUF_FILE_NAME='.protolintrc.yml' # Name of the file +PROTOBUF_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PROTOBUF_FILE_NAME" # Path to the Protocol Buffers lint rules # Clojure Vars CLOJURE_FILE_NAME='.clj-kondo/config.edn' CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" @@ -70,8 +80,9 @@ CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" 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" "clj-kondo" "spectral" - "cfn-lint") + "stylelint" "dotenv-linter" "powershell" "ktlint" "protolint" "clj-kondo" + "spectral" "cfn-lint") + ############################# # Language array for prints # @@ -79,7 +90,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' - 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'CLOJURE' 'OPENAPI' 'CFN') + 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' 'CFN') ################### # GitHub ENV Vars # @@ -121,24 +132,32 @@ DISABLE_ERRORS="${DISABLE_ERRORS}" # Boolean to enable warnin ############## # Debug Vars # ############## -RUN_LOCAL="${RUN_LOCAL}" # Boolean to see if we are running locally -ACTIONS_RUNNER_DEBUG="${ACTIONS_RUNNER_DEBUG}" # Boolean to see even more info (debug) +RUN_LOCAL="${RUN_LOCAL}" # Boolean to see if we are running locally +ACTIONS_RUNNER_DEBUG="${ACTIONS_RUNNER_DEBUG:-false}" # Boolean to see even more info (debug) ################ # Default Vars # ################ DEFAULT_VALIDATE_ALL_CODEBASE='true' # Default value for validate all files DEFAULT_WORKSPACE="${DEFAULT_WORKSPACE:-/tmp/lint}" # Default workspace if running locally -DEFAULT_ANSIBLE_DIRECTORY="$GITHUB_WORKSPACE/ansible" # Default Ansible Directory DEFAULT_RUN_LOCAL='false' # Default value for debugging locally DEFAULT_TEST_CASE_RUN='false' # Flag to tell code to run only test cases -DEFAULT_ACTIONS_RUNNER_DEBUG='false' # Default value for debugging output -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 +############################################################### +# Default Vars that are called in Subs and need to be ignored # +############################################################### +# shellcheck disable=SC2034 +DEFAULT_DISABLE_ERRORS='false' # Default to enabling errors +# shellcheck disable=SC2034 +RAW_FILE_ARRAY=() # Array of all files that were changed +# shellcheck disable=SC2034 +READ_ONLY_CHANGE_FLAG=0 # Flag set to 1 if files changed are not txt or md +# shellcheck disable=SC2034 +TEST_CASE_FOLDER='.automation/test' # Folder for test cases we should always ignore +# shellcheck disable=SC2034 +DEFAULT_ANSIBLE_DIRECTORY="$GITHUB_WORKSPACE/ansible" # Default Ansible Directory + ########################## # Array of changed files # ########################## @@ -165,6 +184,7 @@ 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_PROTOBUF=() # Array of files to check FILE_ARRAY_OPENAPI=() # Array of files to check ############ @@ -194,6 +214,7 @@ 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_PROTOBUF=0 # Count of errors found ERRORS_FOUND_OPENAPI=0 # Count of errors found ################################################################################ @@ -395,188 +416,6 @@ GetStandardRules() TYPESCRIPT_STANDARD_LINTER_RULES="$(echo -e "${ENV_STRING}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')" fi } -################################################################################ -#### Function LintAnsibleFiles ################################################# -LintAnsibleFiles() -{ - ###################### - # Create Print Array # - ###################### - PRINT_ARRAY=() - - ################ - # print header # - ################ - PRINT_ARRAY+=("") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("Linting [Ansible] files...") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("----------------------------------------------") - - ###################### - # Name of the linter # - ###################### - LINTER_NAME="ansible-lint" - - ########################################### - # Validate we have ansible-lint installed # - ########################################### - # shellcheck disable=SC2230 - VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Failed - echo "ERROR! Failed to find $LINTER_NAME in system!" - echo "ERROR:[$VALIDATE_INSTALL_CMD]" - exit 1 - else - # Success - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - # Success - echo "Successfully found binary in system" - echo "Location:[$VALIDATE_INSTALL_CMD]" - fi - fi - - ########################## - # Initialize empty Array # - ########################## - LIST_FILES=() - - ####################### - # Create flag to skip # - ####################### - SKIP_FLAG=0 - - ###################################################### - # Only go into ansible linter if we have base folder # - ###################################################### - if [ -d "$ANSIBLE_DIRECTORY" ]; then - - ############################################################ - # Check to see if we need to go through array or all files # - ############################################################ - if [ "$VALIDATE_ALL_CODEBASE" == "false" ]; then - # We need to only check the ansible playbooks that have updates - #LIST_FILES=("${ANSIBLE_ARRAY[@]}") - # shellcheck disable=SC2164,SC2010,SC2207 - LIST_FILES=($(cd "$ANSIBLE_DIRECTORY"; ls | grep ".yml" 2>&1)) - else - ################################# - # Get list of all files to lint # - ################################# - # shellcheck disable=SC2164,SC2010,SC2207 - LIST_FILES=($(cd "$ANSIBLE_DIRECTORY"; ls | grep ".yml" 2>&1)) - fi - - ############################################################### - # Set the list to empty if only MD and TXT files were changed # - ############################################################### - # No need to run the full ansible checks on read only file changes - if [ "$READ_ONLY_CHANGE_FLAG" -eq 0 ]; then - ########################## - # Set the array to empty # - ########################## - LIST_FILES=() - ################################### - # Send message that were skipping # - ################################### - #echo "- Skipping Ansible lint run as file(s) that were modified were read only..." - ############################ - # Create flag to skip loop # - ############################ - SKIP_FLAG=1 - fi - - #################################### - # Check if we have data to look at # - #################################### - if [ $SKIP_FLAG -eq 0 ]; then - for LINE in "${PRINT_ARRAY[@]}" - do - ######################### - # Print the header line # - ######################### - echo "$LINE" - done - fi - - ################## - # Lint the files # - ################## - for FILE in "${LIST_FILES[@]}" - do - - ######################################## - # Make sure we dont lint certain files # - ######################################## - if [[ $FILE == *"vault.yml"* ]] || [[ $FILE == *"galaxy.yml"* ]]; then - # This is a file we dont look at - continue - fi - - #################### - # Get the filename # - #################### - FILE_NAME=$(basename "$ANSIBLE_DIRECTORY/$FILE" 2>&1) - - ############## - # File print # - ############## - echo "---------------------------" - echo "File:[$FILE]" - - ################################ - # Lint the file with the rules # - ################################ - LINT_CMD=$("$LINTER_NAME" -v -c "$ANSIBLE_LINTER_RULES" "$ANSIBLE_DIRECTORY/$FILE" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - ######### - # Error # - ######### - echo "ERROR! Found errors in [$LINTER_NAME] linter!" - echo "ERROR:[$LINT_CMD]" - # Increment error count - ((ERRORS_FOUND_ANSIBLE++)) - else - ########### - # Success # - ########### - echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" - fi - done - else # No ansible directory found in path - ############################### - # Check to see if debug is on # - ############################### - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - ######################## - # No Ansible dir found # - ######################## - echo "WARN! No Ansible base directory found at:[$ANSIBLE_DIRECTORY]" - echo "skipping ansible lint" - fi - fi -} - ################################################################################ #### Function DetectOpenAPIFile ################################################ DetectOpenAPIFile() @@ -685,6 +524,14 @@ GetGitHubVars() ########################################## echo "NOTE: ENV VAR [RUN_LOCAL] has been set to:[true]" echo "bypassing GitHub Actions variables..." + + ############################ + # Set the GITHUB_WORKSPACE # + ############################ + if [ -z "$GITHUB_WORKSPACE" ]; then + GITHUB_WORKSPACE="$DEFAULT_WORKSPACE" + fi + echo "Linting all files in mapped directory:[$DEFAULT_WORKSPACE]" # No need to touch or set the GITHUB_SHA @@ -692,10 +539,6 @@ GetGitHubVars() # No need to touch or set the GITHUB_ORG # No need to touch or set the GITHUB_REPO - ############################ - # Set the GITHUB_WORKSPACE # - ############################ - GITHUB_WORKSPACE="$DEFAULT_WORKSPACE" ################################# # Set the VALIDATE_ALL_CODEBASE # @@ -775,1508 +618,6 @@ GetGitHubVars() fi } ################################################################################ -#### Function GetValidationInfo ################################################ -GetValidationInfo() -{ - ############################################ - # Print headers for user provided env vars # - ############################################ - echo "" - echo "--------------------------------------------" - echo "Gathering user validation information..." - - ########################################### - # Skip validation if were running locally # - ########################################### - if [[ "$RUN_LOCAL" != "true" ]]; then - ############################### - # Convert string to lowercase # - ############################### - VALIDATE_ALL_CODEBASE=$(echo "$VALIDATE_ALL_CODEBASE" | awk '{print tolower($0)}') - ###################################### - # Validate we should check all files # - ###################################### - if [[ "$VALIDATE_ALL_CODEBASE" != "false" ]]; then - # Set to true - VALIDATE_ALL_CODEBASE="$DEFAULT_VALIDATE_ALL_CODEBASE" - echo "- Validating ALL files in code base..." - else - # Its false - echo "- Only validating [new], or [edited] files in code base..." - fi - fi - - ###################### - # Create Print Array # - ###################### - PRINT_ARRAY=() - - ################################ - # Convert strings to lowercase # - ################################ - VALIDATE_YAML=$(echo "$VALIDATE_YAML" | awk '{print tolower($0)}') - VALIDATE_JSON=$(echo "$VALIDATE_JSON" | awk '{print tolower($0)}') - VALIDATE_XML=$(echo "$VALIDATE_XML" | awk '{print tolower($0)}') - VALIDATE_MD=$(echo "$VALIDATE_MD" | awk '{print tolower($0)}') - VALIDATE_BASH=$(echo "$VALIDATE_BASH" | awk '{print tolower($0)}') - VALIDATE_PERL=$(echo "$VALIDATE_PERL" | awk '{print tolower($0)}') - VALIDATE_PHP=$(echo "$VALIDATE_PHP" | awk '{print tolower($0)}') - VALIDATE_PYTHON=$(echo "$VALIDATE_PYTHON" | awk '{print tolower($0)}') - VALIDATE_CLOUDFORMATION=$(echo "$VALIDATE_CLOUDFORMATION" | awk '{print tolower($0)}') - VALIDATE_RUBY=$(echo "$VALIDATE_RUBY" | awk '{print tolower($0)}') - VALIDATE_COFFEE=$(echo "$VALIDATE_COFFEE" | awk '{print tolower($0)}') - VALIDATE_ANSIBLE=$(echo "$VALIDATE_ANSIBLE" | awk '{print tolower($0)}') - VALIDATE_JAVASCRIPT_ES=$(echo "$VALIDATE_JAVASCRIPT_ES" | awk '{print tolower($0)}') - VALIDATE_JAVASCRIPT_STANDARD=$(echo "$VALIDATE_JAVASCRIPT_STANDARD" | awk '{print tolower($0)}') - VALIDATE_TYPESCRIPT_ES=$(echo "$VALIDATE_TYPESCRIPT_ES" | awk '{print tolower($0)}') - VALIDATE_TYPESCRIPT_STANDARD=$(echo "$VALIDATE_TYPESCRIPT_STANDARD" | awk '{print tolower($0)}') - VALIDATE_DOCKER=$(echo "$VALIDATE_DOCKER" | awk '{print tolower($0)}') - VALIDATE_GO=$(echo "$VALIDATE_GO" | awk '{print tolower($0)}') - VALIDATE_TERRAFORM=$(echo "$VALIDATE_TERRAFORM" | awk '{print tolower($0)}') - 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 # - ################################################ - ANY_SET="false" - if [[ -n "$VALIDATE_YAML" || \ - -n "$VALIDATE_JSON" || \ - -n "$VALIDATE_XML" || \ - -n "$VALIDATE_MD" || \ - -n "$VALIDATE_BASH" || \ - -n "$VALIDATE_PERL" || \ - -n "$VALIDATE_PHP" || \ - -n "$VALIDATE_PYTHON" || \ - -n "$VALIDATE_CLOUDFORMATION" || \ - -n "$VALIDATE_RUBY" || \ - -n "$VALIDATE_COFFEE" || \ - -n "$VALIDATE_ANSIBLE" || \ - -n "$VALIDATE_JAVASCRIPT_ES" || \ - -n "$VALIDATE_JAVASCRIPT_STANDARD" || \ - -n "$VALIDATE_TYPESCRIPT_ES" || \ - -n "$VALIDATE_TYPESCRIPT_STANDARD" || \ - -n "$VALIDATE_DOCKER" || \ - -n "$VALIDATE_GO" || \ - -n "$VALIDATE_TERRAFORM" || \ - -n "$VALIDATE_POWERSHELL" || \ - -n "$VALIDATE_CSS" || \ - -n "$VALIDATE_ENV" || \ - -n "$VALIDATE_CLOJURE" || \ - -n "$VALIDATE_OPENAPI" || \ - -n "$VALIDATE_KOTLIN" ]]; then - ANY_SET="true" - fi - - #################################### - # Validate if we should check YAML # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_YAML" ]]; then - # YAML flag was not set - default to false - VALIDATE_YAML="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_YAML="true" - fi - - #################################### - # Validate if we should check JSON # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_JSON" ]]; then - # JSON flag was not set - default to false - VALIDATE_JSON="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_JSON="true" - fi - - ################################### - # Validate if we should check XML # - ################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_XML" ]]; then - # XML flag was not set - default to false - VALIDATE_XML="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_XML="true" - fi - - ######################################## - # Validate if we should check MARKDOWN # - ######################################## - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_MD" ]]; then - # MD flag was not set - default to false - VALIDATE_MD="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_MD="true" - fi - - #################################### - # Validate if we should check BASH # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_BASH" ]]; then - # BASH flag was not set - default to false - VALIDATE_BASH="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_BASH="true" - fi - - #################################### - # Validate if we should check PERL # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_PERL" ]]; then - # PERL flag was not set - default to false - VALIDATE_PERL="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_PERL="true" - fi - - #################################### - # Validate if we should check PHP # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_PHP" ]]; then - # PHP flag was not set - default to false - VALIDATE_PHP="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_PHP="true" - fi - - ###################################### - # Validate if we should check PYTHON # - ###################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_PYTHON" ]]; then - # PYTHON flag was not set - default to false - VALIDATE_PYTHON="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_PYTHON="true" - fi - - ############################################## - # Validate if we should check Cloudformation # - ############################################## - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_CLOUDFORMATION" ]]; then - # CFN flag was not set - default to false - VALIDATE_CLOUDFORMATION="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_CLOUDFORMATION="true" - fi - - #################################### - # Validate if we should check RUBY # - #################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_RUBY" ]]; then - # RUBY flag was not set - default to false - VALIDATE_RUBY="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_RUBY="true" - fi - - ###################################### - # Validate if we should check COFFEE # - ###################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_COFFEE" ]]; then - # COFFEE flag was not set - default to false - VALIDATE_COFFEE="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_COFFEE="true" - fi - - ####################################### - # Validate if we should check ANSIBLE # - ####################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_ANSIBLE" ]]; then - # ANSIBLE flag was not set - default to false - VALIDATE_ANSIBLE="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_ANSIBLE="true" - fi - - ############################################# - # Validate if we should check JAVASCRIPT_ES # - ############################################# - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_JAVASCRIPT_ES" ]]; then - # JAVASCRIPT_ES flag was not set - default to false - VALIDATE_JAVASCRIPT_ES="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_JAVASCRIPT_ES="true" - fi - - ################################################### - # Validate if we should check JAVASCRIPT_STANDARD # - ################################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_JAVASCRIPT_STANDARD" ]]; then - # JAVASCRIPT_STANDARD flag was not set - default to false - VALIDATE_JAVASCRIPT_STANDARD="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_JAVASCRIPT_STANDARD="true" - fi - - ############################################# - # Validate if we should check TYPESCRIPT_ES # - ############################################# - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_TYPESCRIPT_ES" ]]; then - # TYPESCRIPT_ES flag was not set - default to false - VALIDATE_TYPESCRIPT_ES="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_TYPESCRIPT_ES="true" - fi - - ################################################### - # Validate if we should check TYPESCRIPT_STANDARD # - ################################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_TYPESCRIPT_STANDARD" ]]; then - # TYPESCRIPT_STANDARD flag was not set - default to false - VALIDATE_TYPESCRIPT_STANDARD="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_TYPESCRIPT_STANDARD="true" - fi - - ###################################### - # Validate if we should check DOCKER # - ###################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_DOCKER" ]]; then - # DOCKER flag was not set - default to false - VALIDATE_DOCKER="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_DOCKER="true" - fi - - ################################## - # Validate if we should check GO # - ################################## - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_GO" ]]; then - # GO flag was not set - default to false - VALIDATE_GO="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_GO="true" - fi - - ######################################### - # Validate if we should check TERRAFORM # - ######################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_TERRAFORM" ]]; then - # TERRAFORM flag was not set - default to false - VALIDATE_TERRAFORM="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_TERRAFORM="true" - fi - - ######################################### - # Validate if we should check POWERSHELL # - ######################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_POWERSHELL" ]]; then - # POWERSHELL flag was not set - default to false - VALIDATE_POWERSHELL="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_POWERSHELL="true" - fi - - ################################### - # Validate if we should check CSS # - ################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_CSS" ]]; then - # CSS flag was not set - default to false - VALIDATE_CSS="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_CSS="true" - fi - - ################################### - # Validate if we should check ENV # - ################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_ENV" ]]; then - # ENV flag was not set - default to false - VALIDATE_ENV="false" - fi - else - # No linter flags were set - default all to true - VALIDATE_ENV="true" - fi - - ###################################### - # Validate if we should check KOTLIN # - ###################################### - if [[ "$ANY_SET" == "true" ]]; then - # Some linter flags were set - only run those set to true - if [[ -z "$VALIDATE_KOTLIN" ]]; then - # ENV flag was not set - default to false - VALIDATE_KOTLIN="false" - fi - else - # No linter flags were set - default all to true - 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 # - ####################################### - if [[ "$VALIDATE_YAML" == "true" ]]; then - PRINT_ARRAY+=("- Validating [YAML] files in code base...") - else - PRINT_ARRAY+=("- Excluding [YAML] files in code base...") - fi - if [[ "$VALIDATE_JSON" == "true" ]]; then - PRINT_ARRAY+=("- Validating [JSON] files in code base...") - else - PRINT_ARRAY+=("- Excluding [JSON] files in code base...") - fi - if [[ "$VALIDATE_XML" == "true" ]]; then - PRINT_ARRAY+=("- Validating [XML] files in code base...") - else - PRINT_ARRAY+=("- Excluding [XML] files in code base...") - fi - if [[ "$VALIDATE_MD" == "true" ]]; then - PRINT_ARRAY+=("- Validating [MARKDOWN] files in code base...") - else - PRINT_ARRAY+=("- Excluding [MARKDOWN] files in code base...") - fi - if [[ "$VALIDATE_BASH" == "true" ]]; then - PRINT_ARRAY+=("- Validating [BASH] files in code base...") - else - PRINT_ARRAY+=("- Excluding [BASH] files in code base...") - fi - if [[ "$VALIDATE_PERL" == "true" ]]; then - PRINT_ARRAY+=("- Validating [PERL] files in code base...") - else - PRINT_ARRAY+=("- Excluding [PERL] files in code base...") - fi - if [[ "$VALIDATE_PHP" == "true" ]]; then - PRINT_ARRAY+=("- Validating [PHP] files in code base...") - else - PRINT_ARRAY+=("- Excluding [PHP] files in code base...") - fi - if [[ "$VALIDATE_PYTHON" == "true" ]]; then - PRINT_ARRAY+=("- Validating [PYTHON] files in code base...") - else - PRINT_ARRAY+=("- Excluding [PYTHON] files in code base...") - fi - if [[ "$VALIDATE_CLOUDFORMATION" == "true" ]]; then - PRINT_ARRAY+=("- Validating [CFN] files in code base...") - else - PRINT_ARRAY+=("- Excluding [CFN] files in code base...") - fi - if [[ "$VALIDATE_RUBY" == "true" ]]; then - PRINT_ARRAY+=("- Validating [RUBY] files in code base...") - else - PRINT_ARRAY+=("- Excluding [RUBY] files in code base...") - fi - if [[ "$VALIDATE_COFFEE" == "true" ]]; then - PRINT_ARRAY+=("- Validating [COFFEE] files in code base...") - else - PRINT_ARRAY+=("- Excluding [COFFEE] files in code base...") - fi - if [[ "$VALIDATE_ANSIBLE" == "true" ]]; then - PRINT_ARRAY+=("- Validating [ANSIBLE] files in code base...") - else - PRINT_ARRAY+=("- Excluding [ANSIBLE] files in code base...") - fi - if [[ "$VALIDATE_JAVASCRIPT_ES" == "true" ]]; then - PRINT_ARRAY+=("- Validating [JAVASCRIPT(eslint)] files in code base...") - else - PRINT_ARRAY+=("- Excluding [JAVASCRIPT(eslint)] files in code base...") - fi - if [[ "$VALIDATE_JAVASCRIPT_STANDARD" == "true" ]]; then - PRINT_ARRAY+=("- Validating [JAVASCRIPT(standard)] files in code base...") - else - PRINT_ARRAY+=("- Excluding [JAVASCRIPT(standard)] files in code base...") - fi - if [[ "$VALIDATE_TYPESCRIPT_ES" == "true" ]]; then - PRINT_ARRAY+=("- Validating [TYPESCRIPT(eslint)] files in code base...") - else - PRINT_ARRAY+=("- Excluding [TYPESCRIPT(eslint)] files in code base...") - fi - if [[ "$VALIDATE_TYPESCRIPT_STANDARD" == "true" ]]; then - PRINT_ARRAY+=("- Validating [TYPESCRIPT(standard)] files in code base...") - else - PRINT_ARRAY+=("- Excluding [TYPESCRIPT(standard)] files in code base...") - fi - if [[ "$VALIDATE_DOCKER" == "true" ]]; then - PRINT_ARRAY+=("- Validating [DOCKER] files in code base...") - else - PRINT_ARRAY+=("- Excluding [DOCKER] files in code base...") - fi - if [[ "$VALIDATE_GO" == "true" ]]; then - PRINT_ARRAY+=("- Validating [GOLANG] files in code base...") - else - PRINT_ARRAY+=("- Excluding [GOLANG] files in code base...") - fi - if [[ "$VALIDATE_TERRAFORM" == "true" ]]; then - PRINT_ARRAY+=("- Validating [TERRAFORM] files in code base...") - else - PRINT_ARRAY+=("- Excluding [TERRAFORM] files in code base...") - fi - if [[ "$VALIDATE_POWERSHELL" == "true" ]]; then - PRINT_ARRAY+=("- Validating [POWERSHELL] files in code base...") - else - PRINT_ARRAY+=("- Excluding [POWERSHELL] files in code base...") - fi - if [[ "$VALIDATE_CSS" == "true" ]]; then - PRINT_ARRAY+=("- Validating [CSS] files in code base...") - 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 - PRINT_ARRAY+=("- Excluding [ENV] files in code base...") - fi - if [[ "$VALIDATE_KOTLIN" == "true" ]]; then - PRINT_ARRAY+=("- Validating [KOTLIN] files in code base...") - 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 # - ############################## - if [ -z "$ANSIBLE_DIRECTORY" ]; then - # No Value, need to default - ANSIBLE_DIRECTORY="$DEFAULT_ANSIBLE_DIRECTORY" - else - # Check if first char is '/' - if [[ ${ANSIBLE_DIRECTORY:0:1} == "/" ]]; then - # Remove first char - ANSIBLE_DIRECTORY="${ANSIBLE_DIRECTORY:1}" - fi - # Need to give it full path - TEMP_ANSIBLE_DIRECTORY="$GITHUB_WORKSPACE/$ANSIBLE_DIRECTORY" - # Set the value - ANSIBLE_DIRECTORY="$TEMP_ANSIBLE_DIRECTORY" - fi - - ############################### - # Get the disable errors flag # - ############################### - if [ -z "$DISABLE_ERRORS" ]; then - ################################## - # No flag passed, set to default # - ################################## - DISABLE_ERRORS="$DEFAULT_DISABLE_ERRORS" - fi - - ############################### - # Convert string to lowercase # - ############################### - DISABLE_ERRORS=$(echo "$DISABLE_ERRORS" | awk '{print tolower($0)}') - - ############################ - # Set to false if not true # - ############################ - if [ "$DISABLE_ERRORS" != "true" ]; then - DISABLE_ERRORS="false" - fi - - ############################ - # Get the run verbose flag # - ############################ - if [ -z "$ACTIONS_RUNNER_DEBUG" ]; then - ################################## - # No flag passed, set to default # - ################################## - ACTIONS_RUNNER_DEBUG="$DEFAULT_ACTIONS_RUNNER_DEBUG" - fi - - ############################### - # Convert string to lowercase # - ############################### - ACTIONS_RUNNER_DEBUG=$(echo "$ACTIONS_RUNNER_DEBUG" | awk '{print tolower($0)}') - - ############################ - # Set to true if not false # - ############################ - if [ "$ACTIONS_RUNNER_DEBUG" != "false" ]; then - ACTIONS_RUNNER_DEBUG="true" - fi - - ################### - # Debug on runner # - ################### - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - ########################### - # Print the validate info # - ########################### - for LINE in "${PRINT_ARRAY[@]}" - do - echo "$LINE" - done - - echo "--- DEBUG INFO ---" - echo "---------------------------------------------" - RUNNER=$(whoami) - echo "Runner:[$RUNNER]" - echo "ENV:" - printenv - echo "---------------------------------------------" - fi -} -################################################################################ -#### Function BuildFileList #################################################### -BuildFileList() -{ - # Need to build a list of all files changed - # This can be pulled from the GITHUB_EVENT_PATH payload - - ################ - # print header # - ################ - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - echo "" - echo "----------------------------------------------" - echo "Pulling in code history and branches..." - fi - - ################################################################################# - # Switch codebase back to the default branch to get a list of all files changed # - ################################################################################# - SWITCH_CMD=$(cd "$GITHUB_WORKSPACE" || exit; git pull --quiet; git checkout "$DEFAULT_BRANCH" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Error - echo "Failed to switch to $DEFAULT_BRANCH branch to get files changed!" - echo "ERROR:[$SWITCH_CMD]" - exit 1 - fi - - ################ - # print header # - ################ - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - echo "" - echo "----------------------------------------------" - echo "Generating Diff with:[git diff --name-only '$DEFAULT_BRANCH..$GITHUB_SHA' --diff-filter=d]" - fi - - ################################################# - # Get the Array of files changed in the commits # - ################################################# - # shellcheck disable=SC2207 - RAW_FILE_ARRAY=($(cd "$GITHUB_WORKSPACE" || exit; git diff --name-only "$DEFAULT_BRANCH..$GITHUB_SHA" --diff-filter=d 2>&1)) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Error - echo "ERROR! Failed to gain a list of all files changed!" - echo "ERROR:[${RAW_FILE_ARRAY[*]}]" - exit 1 - fi - - ################################################ - # Iterate through the array of all files found # - ################################################ - echo "" - echo "----------------------------------------------" - echo "Files that have been modified in the commit(s):" - for FILE in "${RAW_FILE_ARRAY[@]}" - do - ############## - # Print file # - ############## - echo "File:[$FILE]" - - ########################### - # Get the files extension # - ########################### - # Extract just the file and extension, reverse it, cut off extension, - # reverse it back, substitute to lowercase - FILE_TYPE=$(basename "$FILE" | rev | cut -f1 -d'.' | rev | awk '{print tolower($0)}') - - ######### - # DEBUG # - ######### - #echo "FILE_TYPE:[$FILE_TYPE]" - - ##################### - # Get the YML files # - ##################### - if [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ]; then - ################################ - # 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 # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ###################### - # Get the JSON files # - ###################### - elif [ "$FILE_TYPE" == "json" ]; then - ################################ - # 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 # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ##################### - # Get the CFN files # - ##################### - elif [ "$FILE_TYPE" == "json" ] || [ "$FILE_TYPE" == "yml" ] || [ "$FILE_TYPE" == "yaml" ] && DetectCloudFormationFile "$FILE"; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_CFN+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ##################### - # Get the XML files # - ##################### - elif [ "$FILE_TYPE" == "xml" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_XML+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ########################## - # Get the MARKDOWN files # - ########################## - elif [ "$FILE_TYPE" == "md" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_MD+=("$FILE") - ###################### - # Get the BASH files # - ###################### - elif [ "$FILE_TYPE" == "sh" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_BASH+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ###################### - # Get the PERL files # - ###################### - elif [ "$FILE_TYPE" == "pl" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_PERL+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ###################### - # Get the PHP files # - ###################### - elif [ "$FILE_TYPE" == "php" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_PHP+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ###################### - # Get the RUBY files # - ###################### - elif [ "$FILE_TYPE" == "rb" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_RUBY+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ######################## - # Get the PYTHON files # - ######################## - elif [ "$FILE_TYPE" == "py" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_PYTHON+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ######################## - # Get the COFFEE files # - ######################## - elif [ "$FILE_TYPE" == "coffee" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_COFFEESCRIPT+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ############################ - # Get the JavaScript files # - ############################ - elif [ "$FILE_TYPE" == "js" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_JAVASCRIPT_ES+=("$FILE") - FILE_ARRAY_JAVASCRIPT_STANDARD+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ############################ - # Get the TypeScript files # - ############################ - elif [ "$FILE_TYPE" == "ts" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_TYPESCRIPT_ES+=("$FILE") - FILE_ARRAY_TYPESCRIPT_STANDARD+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ######################## - # Get the Golang files # - ######################## - elif [ "$FILE_TYPE" == "go" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_GO+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ########################### - # Get the Terraform files # - ########################### - elif [ "$FILE_TYPE" == "tf" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_TERRAFORM+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - ########################### - # Get the Powershell files # - ########################### - elif [ "$FILE_TYPE" == "ps1" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_POWERSHELL+=("$FILE") - elif [ "$FILE_TYPE" == "css" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_CSS+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - elif [ "$FILE_TYPE" == "env" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_ENV+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - elif [ "$FILE_TYPE" == "kt" ] || [ "$FILE_TYPE" == "kts" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_KOTLIN+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - elif [ "$FILE" == "Dockerfile" ]; then - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_DOCKER+=("$FILE") - ########################################################## - # 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 # - ############################################## - GET_FILE_TYPE_CMD=$(file "$FILE" 2>&1) - - ################# - # Check if bash # - ################# - if [[ "$GET_FILE_TYPE_CMD" == *"Bourne-Again shell script"* ]]; then - ####################### - # It is a bash script # - ####################### - echo "WARN! Found bash script without extension:[.sh]" - echo "Please update file with proper extensions." - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_BASH+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - elif [[ "$GET_FILE_TYPE_CMD" == *"Ruby script"* ]]; then - ####################### - # It is a Ruby script # - ####################### - echo "WARN! Found ruby script without extension:[.rb]" - echo "Please update file with proper extensions." - ################################ - # Append the file to the array # - ################################ - FILE_ARRAY_RUBY+=("$FILE") - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - else - ############################ - # Extension was not found! # - ############################ - echo " - WARN! Failed to get filetype for:[$FILE]!" - ########################################################## - # Set the READ_ONLY_CHANGE_FLAG since this could be exec # - ########################################################## - READ_ONLY_CHANGE_FLAG=1 - fi - fi - done - - ######################################### - # Need to switch back to branch of code # - ######################################### - SWITCH2_CMD=$(cd "$GITHUB_WORKSPACE" || exit; git checkout --progress --force "$GITHUB_SHA" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Error - echo "Failed to switch back to branch!" - echo "ERROR:[$SWITCH2_CMD]" - exit 1 - fi - - ################ - # Footer print # - ################ - echo "" - echo "----------------------------------------------" - echo "Successfully gathered list of files..." -} -################################################################################ -#### Function LintCodebase ##################################################### -LintCodebase() -{ - #################### - # Pull in the vars # - #################### - FILE_TYPE="$1" && shift # Pull the variable and remove from array path (Example: JSON) - LINTER_NAME="$1" && shift # Pull the variable and remove from array path (Example: jsonlint) - LINTER_COMMAND="$1" && shift # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file) - FILE_EXTENSIONS="$1" && shift # Pull the variable and remove from array path (Example: *.json) - FILE_ARRAY=("$@") # Array of files to validate (Example: $FILE_ARRAY_JSON) - - ###################### - # Create Print Array # - ###################### - PRINT_ARRAY=() - - ################ - # print header # - ################ - PRINT_ARRAY+=("") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("Linting [$FILE_TYPE] files...") - PRINT_ARRAY+=("----------------------------------------------") - PRINT_ARRAY+=("----------------------------------------------") - - ####################################### - # Validate we have jsonlint installed # - ####################################### - # shellcheck disable=SC2230 - VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Failed - echo "ERROR! Failed to find [$LINTER_NAME] in system!" - echo "ERROR:[$VALIDATE_INSTALL_CMD]" - exit 1 - else - # Success - if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then - echo "Successfully found binary in system" - echo "Location:[$VALIDATE_INSTALL_CMD]" - fi - fi - - ########################## - # Initialize empty Array # - ########################## - LIST_FILES=() - - ################ - # Set the flag # - ################ - SKIP_FLAG=0 - - ############################################################ - # Check to see if we need to go through array or all files # - ############################################################ - if [ ${#FILE_ARRAY[@]} -eq 0 ] && [ "$VALIDATE_ALL_CODEBASE" == "false" ]; then - # No files found in commit and user has asked to not validate code base - SKIP_FLAG=1 - # echo " - No files found in changeset to lint for language:[$FILE_TYPE]" - elif [ ${#FILE_ARRAY[@]} -ne 0 ]; then - # 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 # - ############################################################ - if [ ${#LIST_FILES[@]} -lt 1 ]; then - ###################### - # Set to empty array # - ###################### - LIST_FILES=() - ############################# - # Skip as we found no files # - ############################# - SKIP_FLAG=1 - fi - fi - - ############################### - # Check if any data was found # - ############################### - if [ $SKIP_FLAG -eq 0 ]; then - ###################### - # Print Header array # - ###################### - for LINE in "${PRINT_ARRAY[@]}" - do - ######################### - # Print the header info # - ######################### - echo "$LINE" - done - - ################## - # Lint the files # - ################## - for FILE in "${LIST_FILES[@]}" - do - ##################### - # Get the file name # - ##################### - FILE_NAME=$(basename "$FILE" 2>&1) - - ##################################################### - # Make sure we dont lint node modules or test cases # - ##################################################### - if [[ $FILE == *"node_modules"* ]]; then - # This is a node modules file - continue - elif [[ $FILE == *"$TEST_CASE_FOLDER"* ]]; then - # This is the test cases, we should always skip - continue - fi - - # don't test normal json/yaml files wih cfn-lint - if [ "$LINTER_NAME" == "cfn-lint" ] && ! DetectCloudFormationFile "$GITHUB_WORKSPACE/$FILE"; then - # TODO: PRINT_ARRAY still contains "Linting [CFN] files..." - continue - fi - - # don't test CloudFormation files with {json,yaml}lint - if [ "$LINTER_NAME" == "jsonlint" ] || [ "$LINTER_NAME" == "yamllint" ] && DetectCloudFormationFile "$GITHUB_WORKSPACE/$FILE"; then - continue - fi - - ############## - # File print # - ############## - echo "---------------------------" - echo "File:[$FILE]" - - #################### - # Set the base Var # - #################### - LINT_CMD='' - - ####################################### - # Corner case for Powershell subshell # - ####################################### - if [[ "$FILE_TYPE" == "POWERSHELL" ]]; then - ################################ - # Lint the file with the rules # - ################################ - # Need to append "'" to make the pwsh call syntax correct, also exit with exit code from inner subshell - LINT_CMD=$(cd "$GITHUB_WORKSPACE" || exit; $LINTER_COMMAND "$FILE"; exit $? 2>&1) - else - ################################ - # Lint the file with the rules # - ################################ - LINT_CMD=$(cd "$GITHUB_WORKSPACE" || exit; $LINTER_COMMAND "$FILE" 2>&1) - fi - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - ######### - # Error # - ######### - echo "ERROR! Found errors in [$LINTER_NAME] linter!" - echo "ERROR:[$LINT_CMD]" - # Increment the error count - (("ERRORS_FOUND_$FILE_TYPE++")) - else - ########### - # Success # - ########### - echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" - fi - done - fi -} -################################################################################ -#### Function TestCodebase ##################################################### -TestCodebase() -{ - #################### - # Pull in the vars # - #################### - FILE_TYPE="$1" # Pull the variable and remove from array path (Example: JSON) - LINTER_NAME="$2" # Pull the variable and remove from array path (Example: jsonlint) - LINTER_COMMAND="$3" # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file) - FILE_EXTENSIONS="$4" # Pull the variable and remove from array path (Example: *.json) - - ################ - # print header # - ################ - echo "" - echo "----------------------------------------------" - echo "----------------------------------------------" - echo "Testing Codebase [$FILE_TYPE] files..." - echo "----------------------------------------------" - echo "----------------------------------------------" - echo "" - - ##################################### - # Validate we have linter installed # - ##################################### - # shellcheck disable=SC2230 - VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - # Failed - echo "ERROR! Failed to find [$LINTER_NAME] in system!" - echo "ERROR:[$VALIDATE_INSTALL_CMD]" - exit 1 - else - # Success - echo "Successfully found binary in system" - echo "Location:[$VALIDATE_INSTALL_CMD]" - fi - - ########################## - # Initialize empty Array # - ########################## - LIST_FILES=() - - ############################################ - # Check if its ansible, as its the outlier # - ############################################ - if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then - ################################# - # Get list of all files to lint # - ################################# - # 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" - - # don't check yaml/json files with cnf-lint - # don't check CloudFormation files with json/yaml linters - if [ "$FILE_TYPE" == "CFN" ]; then - LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" ! -path "*./json*" ! -path "*./yml*" 2>&1)) - fi - if [ "$FILE_TYPE" == "JSON" ] || [ "$FILE_TYPE" == "YML" ]; then - LIST_FILES=($(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; find . -type f -regex "$FILE_EXTENSIONS" ! -path "*./ansible*" ! -path "*./cfn*" 2>&1)) - fi - fi - - ################## - # Lint the files # - ################## - for FILE in "${LIST_FILES[@]}" - do - ##################### - # Get the file name # - ##################### - FILE_NAME=$(basename "$FILE" 2>&1) - - ############################ - # Get the file pass status # - ############################ - # Example: markdown_good_1.md -> good - FILE_STATUS=$(echo "$FILE_NAME" |cut -f2 -d'_') - - ######################################################### - # If not found, assume it should be linted successfully # - ######################################################### - if [ -z "$FILE_STATUS" ] || [[ "$FILE" == *"README"* ]]; then - ################################## - # Set to good for proper linting # - ################################## - FILE_STATUS="good" - fi - - ############## - # File print # - ############## - echo "---------------------------" - echo "File:[$FILE]" - - ######################## - # Set the lint command # - ######################## - LINT_CMD='' - - ####################################### - # Check if docker and get folder name # - ####################################### - if [[ "$FILE_TYPE" == "DOCKER" ]]; then - if [[ "$FILE" == *"good"* ]]; then - ############# - # Good file # - ############# - FILE_STATUS='good' - else - ############ - # Bad file # - ############ - FILE_STATUS='bad' - fi - fi - - ##################### - # Check for ansible # - ##################### - if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then - ######################################## - # Make sure we dont lint certain files # - ######################################## - if [[ $FILE == *"vault.yml"* ]] || [[ $FILE == *"galaxy.yml"* ]]; then - # This is a file we dont look at - continue - fi - - ################################ - # Lint the file with the rules # - ################################ - LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/ansible" || exit; $LINTER_COMMAND "$FILE" 2>&1) - elif [[ "$FILE_TYPE" == "POWERSHELL" ]]; then - ################################ - # Lint the file with the rules # - ################################ - # Need to append "'" to make the pwsh call syntax correct, also exit with exit code from inner subshell - LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; $LINTER_COMMAND "$FILE"; exit $? 2>&1) - else - ################################ - # Lint the file with the rules # - ################################ - LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; $LINTER_COMMAND "$FILE" 2>&1) - fi - - ####################### - # Load the error code # - ####################### - ERROR_CODE=$? - - ######################################## - # Check for if it was supposed to pass # - ######################################## - if [[ "$FILE_STATUS" == "good" ]]; then - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -ne 0 ]; then - ######### - # Error # - ######### - echo "ERROR! Found errors in [$LINTER_NAME] linter!" - echo "ERROR:[$LINT_CMD]" - echo "ERROR: Linter CMD:[$LINTER_COMMAND $FILE]" - # Increment the error count - (("ERRORS_FOUND_$FILE_TYPE++")) - else - ########### - # Success # - ########### - echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" - fi - else - ####################################### - # File status = bad, this should fail # - ####################################### - ############################## - # Check the shell for errors # - ############################## - if [ $ERROR_CODE -eq 0 ]; then - ######### - # Error # - ######### - echo "ERROR! Found errors in [$LINTER_NAME] linter!" - echo "ERROR! This file should have failed test case!" - echo "ERROR:[$LINT_CMD]" - echo "ERROR: Linter CMD:[$LINTER_COMMAND $FILE]" - # Increment the error count - (("ERRORS_FOUND_$FILE_TYPE++")) - else - ########### - # Success # - ########### - echo " - File:[$FILE_NAME] failed test case with [$LINTER_NAME] successfully" - fi - fi - done -} -################################################################################ #### Function Footer ########################################################### Footer() { @@ -2324,7 +665,6 @@ Footer() [ "$ERRORS_FOUND_PERL" -ne 0 ] || \ [ "$ERRORS_FOUND_PHP" -ne 0 ] || \ [ "$ERRORS_FOUND_PYTHON" -ne 0 ] || \ - [ "$ERRORS_FOUND_CFN" -ne 0 ] || \ [ "$ERRORS_FOUND_COFFEESCRIPT" -ne 0 ] || \ [ "$ERRORS_FOUND_ANSIBLE" -ne 0 ] || \ [ "$ERRORS_FOUND_JAVASCRIPT_ES" -ne 0 ] || \ @@ -2339,6 +679,7 @@ Footer() [ "$ERRORS_FOUND_CSS" -ne 0 ] || \ [ "$ERRORS_FOUND_ENV" -ne 0 ] || \ [ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || \ + [ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || \ [ "$ERRORS_FOUND_CLOJURE" -ne 0 ] || \ [ "$ERRORS_FOUND_KOTLIN" -ne 0 ]; then # Failed exit @@ -2357,63 +698,6 @@ Footer() fi } ################################################################################ -#### Function RunTestCases ##################################################### -RunTestCases() -{ - # This loop will run the test cases and exclude user code - # This is called from the automation process to validate new code - # When a PR is opened, the new code is validated with the default branch - # version of linter.sh, and a new container is built with the latest codebase - # for testing. That container is spun up, and ran, - # with the flag: TEST_CASE_RUN=true - # So that the new code can be validated against the test cases - - ################# - # Header prints # - ################# - echo "" - echo "----------------------------------------------" - echo "-------------- TEST CASE RUN -----------------" - echo "----------------------------------------------" - echo "" - - ####################### - # Test case languages # - ####################### - TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$" - TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" - TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$" - TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$" - TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$" - TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES -E" ".*\.\(py\)\$" - TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$" - TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$" - TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$" - TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$" - TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" - TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" - 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 -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\)\$" - TestCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" - - ################# - # Footer prints # - ################# - # Call the footer to display run information - # and exit with error code - Footer -} -################################################################################ ############################### MAIN ########################################### ################################################################################ @@ -2443,8 +727,6 @@ GetLinterRules "$YAML_FILE_NAME" "$YAML_LINTER_RULES" GetLinterRules "$MD_FILE_NAME" "$MD_LINTER_RULES" # Get Python rules GetLinterRules "$PYTHON_FILE_NAME" "$PYTHON_LINTER_RULES" -# Get CloudFormation rules -GetLinterRules "$CFN_FILE_NAME" "$CFN_LINTER_RULES" # Get Ruby rules GetLinterRules "$RUBY_FILE_NAME" "$RUBY_LINTER_RULES" # Get Coffeescript rules @@ -2486,7 +768,6 @@ if [[ "$TEST_CASE_RUN" != "false" ]]; then # Code will exit from inside this loop RunTestCases fi - ############################################# # check flag for validation of all codebase # ############################################# @@ -2560,7 +841,7 @@ if [ "$VALIDATE_PYTHON" == "true" ]; then # Lint the python files # ######################### # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" - LintCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES -E" ".*\.\(py\)\$" "${FILE_ARRAY_PYTHON[@]}" + LintCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" "${FILE_ARRAY_PYTHON[@]}" fi ############### @@ -2735,7 +1016,7 @@ if [ "$VALIDATE_KOTLIN" == "true" ]; then # Lint the Kotlin files # ####################### # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" - LintCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "${FILE_ARRAY_ENV[@]}" + LintCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "${FILE_ARRAY_KOTLIN[@]}" fi ################## @@ -2763,6 +1044,17 @@ if [ "$VALIDATE_CLOJURE" == "true" ]; then LintCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "${FILE_ARRAY_CLOJURE[@]}" fi +################## +# PROTOBUF LINTING # +################## +if [ "$VALIDATE_PROTOBUF" == "true" ]; then + ####################### + # Lint the Protocol Buffers files # + ####################### + # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" + LintCodebase "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$" "${FILE_ARRAY_PROTOBUF[@]}" +fi + ###################### # POWERSHELL LINTING # ###################### diff --git a/lib/validation.sh b/lib/validation.sh new file mode 100755 index 00000000..97f85a38 --- /dev/null +++ b/lib/validation.sh @@ -0,0 +1,669 @@ +#!/usr/bin/env bash + +################################################################################ +################################################################################ +########### Super-Linter Validation Functions @admiralawkbar ################### +################################################################################ +################################################################################ +########################## FUNCTION CALLS BELOW ################################ +################################################################################ +################################################################################ +#### Function GetValidationInfo ################################################ +function GetValidationInfo() +{ + ############################################ + # Print headers for user provided env vars # + ############################################ + echo "" + echo "--------------------------------------------" + echo "Gathering user validation information..." + + ########################################### + # Skip validation if were running locally # + ########################################### + if [[ "$RUN_LOCAL" != "true" ]]; then + ############################### + # Convert string to lowercase # + ############################### + VALIDATE_ALL_CODEBASE=$(echo "$VALIDATE_ALL_CODEBASE" | awk '{print tolower($0)}') + ###################################### + # Validate we should check all files # + ###################################### + if [[ "$VALIDATE_ALL_CODEBASE" != "false" ]]; then + # Set to true + VALIDATE_ALL_CODEBASE="$DEFAULT_VALIDATE_ALL_CODEBASE" + echo "- Validating ALL files in code base..." + else + # Its false + echo "- Only validating [new], or [edited] files in code base..." + fi + fi + + ###################### + # Create Print Array # + ###################### + PRINT_ARRAY=() + + ################################ + # Convert strings to lowercase # + ################################ + VALIDATE_YAML=$(echo "$VALIDATE_YAML" | awk '{print tolower($0)}') + VALIDATE_JSON=$(echo "$VALIDATE_JSON" | awk '{print tolower($0)}') + VALIDATE_XML=$(echo "$VALIDATE_XML" | awk '{print tolower($0)}') + VALIDATE_MD=$(echo "$VALIDATE_MD" | awk '{print tolower($0)}') + VALIDATE_BASH=$(echo "$VALIDATE_BASH" | awk '{print tolower($0)}') + VALIDATE_PERL=$(echo "$VALIDATE_PERL" | awk '{print tolower($0)}') + VALIDATE_PHP=$(echo "$VALIDATE_PHP" | awk '{print tolower($0)}') + VALIDATE_PYTHON=$(echo "$VALIDATE_PYTHON" | awk '{print tolower($0)}') + VALIDATE_RUBY=$(echo "$VALIDATE_RUBY" | awk '{print tolower($0)}') + VALIDATE_COFFEE=$(echo "$VALIDATE_COFFEE" | awk '{print tolower($0)}') + VALIDATE_ANSIBLE=$(echo "$VALIDATE_ANSIBLE" | awk '{print tolower($0)}') + VALIDATE_JAVASCRIPT_ES=$(echo "$VALIDATE_JAVASCRIPT_ES" | awk '{print tolower($0)}') + VALIDATE_JAVASCRIPT_STANDARD=$(echo "$VALIDATE_JAVASCRIPT_STANDARD" | awk '{print tolower($0)}') + VALIDATE_TYPESCRIPT_ES=$(echo "$VALIDATE_TYPESCRIPT_ES" | awk '{print tolower($0)}') + VALIDATE_TYPESCRIPT_STANDARD=$(echo "$VALIDATE_TYPESCRIPT_STANDARD" | awk '{print tolower($0)}') + VALIDATE_DOCKER=$(echo "$VALIDATE_DOCKER" | awk '{print tolower($0)}') + VALIDATE_GO=$(echo "$VALIDATE_GO" | awk '{print tolower($0)}') + VALIDATE_TERRAFORM=$(echo "$VALIDATE_TERRAFORM" | awk '{print tolower($0)}') + 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_PROTOBUF=$(echo "$VALIDATE_PROTOBUF" | awk '{print tolower($0)}') + VALIDATE_OPENAPI=$(echo "$VALIDATE_OPENAPI" | awk '{print tolower($0)}') + + ################################################ + # Determine if any linters were explicitly set # + ################################################ + ANY_SET="false" + if [[ -n "$VALIDATE_YAML" || \ + -n "$VALIDATE_JSON" || \ + -n "$VALIDATE_XML" || \ + -n "$VALIDATE_MD" || \ + -n "$VALIDATE_BASH" || \ + -n "$VALIDATE_PERL" || \ + -n "$VALIDATE_PHP" || \ + -n "$VALIDATE_PYTHON" || \ + -n "$VALIDATE_RUBY" || \ + -n "$VALIDATE_COFFEE" || \ + -n "$VALIDATE_ANSIBLE" || \ + -n "$VALIDATE_JAVASCRIPT_ES" || \ + -n "$VALIDATE_JAVASCRIPT_STANDARD" || \ + -n "$VALIDATE_TYPESCRIPT_ES" || \ + -n "$VALIDATE_TYPESCRIPT_STANDARD" || \ + -n "$VALIDATE_DOCKER" || \ + -n "$VALIDATE_GO" || \ + -n "$VALIDATE_TERRAFORM" || \ + -n "$VALIDATE_POWERSHELL" || \ + -n "$VALIDATE_CSS" || \ + -n "$VALIDATE_ENV" || \ + -n "$VALIDATE_CLOJURE" || \ + -n "$VALIDATE_PROTOBUF" || \ + -n "$VALIDATE_OPENAPI" || \ + -n "$VALIDATE_KOTLIN" ]]; then + ANY_SET="true" + fi + + #################################### + # Validate if we should check YAML # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_YAML" ]]; then + # YAML flag was not set - default to false + VALIDATE_YAML="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_YAML="true" + fi + + #################################### + # Validate if we should check JSON # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_JSON" ]]; then + # JSON flag was not set - default to false + VALIDATE_JSON="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_JSON="true" + fi + + ################################### + # Validate if we should check XML # + ################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_XML" ]]; then + # XML flag was not set - default to false + VALIDATE_XML="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_XML="true" + fi + + ######################################## + # Validate if we should check MARKDOWN # + ######################################## + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_MD" ]]; then + # MD flag was not set - default to false + VALIDATE_MD="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_MD="true" + fi + + #################################### + # Validate if we should check BASH # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_BASH" ]]; then + # BASH flag was not set - default to false + VALIDATE_BASH="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_BASH="true" + fi + + #################################### + # Validate if we should check PERL # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_PERL" ]]; then + # PERL flag was not set - default to false + VALIDATE_PERL="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_PERL="true" + fi + + #################################### + # Validate if we should check PHP # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_PHP" ]]; then + # PHP flag was not set - default to false + VALIDATE_PHP="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_PHP="true" + fi + + ###################################### + # Validate if we should check PYTHON # + ###################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_PYTHON" ]]; then + # PYTHON flag was not set - default to false + VALIDATE_PYTHON="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_PYTHON="true" + fi + + #################################### + # Validate if we should check RUBY # + #################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_RUBY" ]]; then + # RUBY flag was not set - default to false + VALIDATE_RUBY="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_RUBY="true" + fi + + ###################################### + # Validate if we should check COFFEE # + ###################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_COFFEE" ]]; then + # COFFEE flag was not set - default to false + VALIDATE_COFFEE="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_COFFEE="true" + fi + + ####################################### + # Validate if we should check ANSIBLE # + ####################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_ANSIBLE" ]]; then + # ANSIBLE flag was not set - default to false + VALIDATE_ANSIBLE="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_ANSIBLE="true" + fi + + ############################################# + # Validate if we should check JAVASCRIPT_ES # + ############################################# + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_JAVASCRIPT_ES" ]]; then + # JAVASCRIPT_ES flag was not set - default to false + VALIDATE_JAVASCRIPT_ES="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_JAVASCRIPT_ES="true" + fi + + ################################################### + # Validate if we should check JAVASCRIPT_STANDARD # + ################################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_JAVASCRIPT_STANDARD" ]]; then + # JAVASCRIPT_STANDARD flag was not set - default to false + VALIDATE_JAVASCRIPT_STANDARD="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_JAVASCRIPT_STANDARD="true" + fi + + ############################################# + # Validate if we should check TYPESCRIPT_ES # + ############################################# + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_TYPESCRIPT_ES" ]]; then + # TYPESCRIPT_ES flag was not set - default to false + VALIDATE_TYPESCRIPT_ES="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_TYPESCRIPT_ES="true" + fi + + ################################################### + # Validate if we should check TYPESCRIPT_STANDARD # + ################################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_TYPESCRIPT_STANDARD" ]]; then + # TYPESCRIPT_STANDARD flag was not set - default to false + VALIDATE_TYPESCRIPT_STANDARD="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_TYPESCRIPT_STANDARD="true" + fi + + ###################################### + # Validate if we should check DOCKER # + ###################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_DOCKER" ]]; then + # DOCKER flag was not set - default to false + VALIDATE_DOCKER="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_DOCKER="true" + fi + + ################################## + # Validate if we should check GO # + ################################## + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_GO" ]]; then + # GO flag was not set - default to false + VALIDATE_GO="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_GO="true" + fi + + ######################################### + # Validate if we should check TERRAFORM # + ######################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_TERRAFORM" ]]; then + # TERRAFORM flag was not set - default to false + VALIDATE_TERRAFORM="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_TERRAFORM="true" + fi + + ######################################### + # Validate if we should check POWERSHELL # + ######################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_POWERSHELL" ]]; then + # POWERSHELL flag was not set - default to false + VALIDATE_POWERSHELL="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_POWERSHELL="true" + fi + + ################################### + # Validate if we should check CSS # + ################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_CSS" ]]; then + # CSS flag was not set - default to false + VALIDATE_CSS="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_CSS="true" + fi + + ################################### + # Validate if we should check ENV # + ################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_ENV" ]]; then + # ENV flag was not set - default to false + VALIDATE_ENV="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_ENV="true" + fi + + ###################################### + # Validate if we should check KOTLIN # + ###################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_KOTLIN" ]]; then + # ENV flag was not set - default to false + VALIDATE_KOTLIN="false" + fi + else + # No linter flags were set - default all to true + 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 PROTOBUF # + ####################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_PROTOBUF" ]]; then + # PROTOBUF flag was not set - default to false + VALIDATE_PROTOBUF="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_PROTOBUF="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 # + ####################################### + if [[ "$VALIDATE_YAML" == "true" ]]; then + PRINT_ARRAY+=("- Validating [YAML] files in code base...") + else + PRINT_ARRAY+=("- Excluding [YAML] files in code base...") + fi + if [[ "$VALIDATE_JSON" == "true" ]]; then + PRINT_ARRAY+=("- Validating [JSON] files in code base...") + else + PRINT_ARRAY+=("- Excluding [JSON] files in code base...") + fi + if [[ "$VALIDATE_XML" == "true" ]]; then + PRINT_ARRAY+=("- Validating [XML] files in code base...") + else + PRINT_ARRAY+=("- Excluding [XML] files in code base...") + fi + if [[ "$VALIDATE_MD" == "true" ]]; then + PRINT_ARRAY+=("- Validating [MARKDOWN] files in code base...") + else + PRINT_ARRAY+=("- Excluding [MARKDOWN] files in code base...") + fi + if [[ "$VALIDATE_BASH" == "true" ]]; then + PRINT_ARRAY+=("- Validating [BASH] files in code base...") + else + PRINT_ARRAY+=("- Excluding [BASH] files in code base...") + fi + if [[ "$VALIDATE_PERL" == "true" ]]; then + PRINT_ARRAY+=("- Validating [PERL] files in code base...") + else + PRINT_ARRAY+=("- Excluding [PERL] files in code base...") + fi + if [[ "$VALIDATE_PHP" == "true" ]]; then + PRINT_ARRAY+=("- Validating [PHP] files in code base...") + else + PRINT_ARRAY+=("- Excluding [PHP] files in code base...") + fi + if [[ "$VALIDATE_PYTHON" == "true" ]]; then + PRINT_ARRAY+=("- Validating [PYTHON] files in code base...") + else + PRINT_ARRAY+=("- Excluding [PYTHON] files in code base...") + fi + if [[ "$VALIDATE_RUBY" == "true" ]]; then + PRINT_ARRAY+=("- Validating [RUBY] files in code base...") + else + PRINT_ARRAY+=("- Excluding [RUBY] files in code base...") + fi + if [[ "$VALIDATE_COFFEE" == "true" ]]; then + PRINT_ARRAY+=("- Validating [COFFEE] files in code base...") + else + PRINT_ARRAY+=("- Excluding [COFFEE] files in code base...") + fi + if [[ "$VALIDATE_ANSIBLE" == "true" ]]; then + PRINT_ARRAY+=("- Validating [ANSIBLE] files in code base...") + else + PRINT_ARRAY+=("- Excluding [ANSIBLE] files in code base...") + fi + if [[ "$VALIDATE_JAVASCRIPT_ES" == "true" ]]; then + PRINT_ARRAY+=("- Validating [JAVASCRIPT(eslint)] files in code base...") + else + PRINT_ARRAY+=("- Excluding [JAVASCRIPT(eslint)] files in code base...") + fi + if [[ "$VALIDATE_JAVASCRIPT_STANDARD" == "true" ]]; then + PRINT_ARRAY+=("- Validating [JAVASCRIPT(standard)] files in code base...") + else + PRINT_ARRAY+=("- Excluding [JAVASCRIPT(standard)] files in code base...") + fi + if [[ "$VALIDATE_TYPESCRIPT_ES" == "true" ]]; then + PRINT_ARRAY+=("- Validating [TYPESCRIPT(eslint)] files in code base...") + else + PRINT_ARRAY+=("- Excluding [TYPESCRIPT(eslint)] files in code base...") + fi + if [[ "$VALIDATE_TYPESCRIPT_STANDARD" == "true" ]]; then + PRINT_ARRAY+=("- Validating [TYPESCRIPT(standard)] files in code base...") + else + PRINT_ARRAY+=("- Excluding [TYPESCRIPT(standard)] files in code base...") + fi + if [[ "$VALIDATE_DOCKER" == "true" ]]; then + PRINT_ARRAY+=("- Validating [DOCKER] files in code base...") + else + PRINT_ARRAY+=("- Excluding [DOCKER] files in code base...") + fi + if [[ "$VALIDATE_GO" == "true" ]]; then + PRINT_ARRAY+=("- Validating [GOLANG] files in code base...") + else + PRINT_ARRAY+=("- Excluding [GOLANG] files in code base...") + fi + if [[ "$VALIDATE_TERRAFORM" == "true" ]]; then + PRINT_ARRAY+=("- Validating [TERRAFORM] files in code base...") + else + PRINT_ARRAY+=("- Excluding [TERRAFORM] files in code base...") + fi + if [[ "$VALIDATE_POWERSHELL" == "true" ]]; then + PRINT_ARRAY+=("- Validating [POWERSHELL] files in code base...") + else + PRINT_ARRAY+=("- Excluding [POWERSHELL] files in code base...") + fi + if [[ "$VALIDATE_CSS" == "true" ]]; then + PRINT_ARRAY+=("- Validating [CSS] files in code base...") + 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 + PRINT_ARRAY+=("- Excluding [ENV] files in code base...") + fi + if [[ "$VALIDATE_KOTLIN" == "true" ]]; then + PRINT_ARRAY+=("- Validating [KOTLIN] files in code base...") + 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 + if [[ "$VALIDATE_PROTOBUF" == "true" ]]; then + PRINT_ARRAY+=("- Validating [PROTOBUF] files in code base...") + else + PRINT_ARRAY+=("- Excluding [PROTOBUF] files in code base...") + fi + + ############################## + # Validate Ansible Directory # + ############################## + if [ -z "$ANSIBLE_DIRECTORY" ]; then + # No Value, need to default + ANSIBLE_DIRECTORY="$DEFAULT_ANSIBLE_DIRECTORY" + else + # Check if first char is '/' + if [[ ${ANSIBLE_DIRECTORY:0:1} == "/" ]]; then + # Remove first char + ANSIBLE_DIRECTORY="${ANSIBLE_DIRECTORY:1}" + fi + # Need to give it full path + TEMP_ANSIBLE_DIRECTORY="$GITHUB_WORKSPACE/$ANSIBLE_DIRECTORY" + # Set the value + ANSIBLE_DIRECTORY="$TEMP_ANSIBLE_DIRECTORY" + fi + + ############################### + # Get the disable errors flag # + ############################### + if [ -z "$DISABLE_ERRORS" ]; then + ################################## + # No flag passed, set to default # + ################################## + DISABLE_ERRORS="$DEFAULT_DISABLE_ERRORS" + fi + + ############################### + # Convert string to lowercase # + ############################### + DISABLE_ERRORS=$(echo "$DISABLE_ERRORS" | awk '{print tolower($0)}') + + ############################ + # Set to false if not true # + ############################ + if [ "$DISABLE_ERRORS" != "true" ]; then + DISABLE_ERRORS="false" + fi + + ############################ + # Get the run verbose flag # + ############################ + if [ -z "$ACTIONS_RUNNER_DEBUG" ]; then + ################################## + # No flag passed, set to default # + ################################## + ACTIONS_RUNNER_DEBUG="$DEFAULT_ACTIONS_RUNNER_DEBUG" + fi + + ############################### + # Convert string to lowercase # + ############################### + ACTIONS_RUNNER_DEBUG=$(echo "$ACTIONS_RUNNER_DEBUG" | awk '{print tolower($0)}') + + ############################ + # Set to true if not false # + ############################ + if [ "$ACTIONS_RUNNER_DEBUG" != "false" ]; then + ACTIONS_RUNNER_DEBUG="true" + fi + + ################### + # Debug on runner # + ################### + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + ########################### + # Print the validate info # + ########################### + for LINE in "${PRINT_ARRAY[@]}" + do + echo "$LINE" + done + + echo "--- DEBUG INFO ---" + echo "---------------------------------------------" + RUNNER=$(whoami) + echo "Runner:[$RUNNER]" + echo "ENV:" + printenv + echo "---------------------------------------------" + fi +} diff --git a/lib/worker.sh b/lib/worker.sh new file mode 100755 index 00000000..1b879768 --- /dev/null +++ b/lib/worker.sh @@ -0,0 +1,658 @@ +#!/usr/bin/env bash + +################################################################################ +################################################################################ +########### Super-Linter linting Functions @admiralawkbar ###################### +################################################################################ +################################################################################ +########################## FUNCTION CALLS BELOW ################################ +################################################################################ +################################################################################ +#### Function LintCodebase ##################################################### +function LintCodebase() +{ + #################### + # Pull in the vars # + #################### + FILE_TYPE="$1" && shift # Pull the variable and remove from array path (Example: JSON) + LINTER_NAME="$1" && shift # Pull the variable and remove from array path (Example: jsonlint) + LINTER_COMMAND="$1" && shift # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file) + FILE_EXTENSIONS="$1" && shift # Pull the variable and remove from array path (Example: *.json) + FILE_ARRAY=("$@") # Array of files to validate (Example: $FILE_ARRAY_JSON) + + ###################### + # Create Print Array # + ###################### + PRINT_ARRAY=() + + ################ + # print header # + ################ + PRINT_ARRAY+=("") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("Linting [$FILE_TYPE] files...") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("----------------------------------------------") + + ####################################### + # Validate we have jsonlint installed # + ####################################### + # shellcheck disable=SC2230 + VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Failed + echo "ERROR! Failed to find [$LINTER_NAME] in system!" + echo "ERROR:[$VALIDATE_INSTALL_CMD]" + exit 1 + else + # Success + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + echo "Successfully found binary in system" + echo "Location:[$VALIDATE_INSTALL_CMD]" + fi + fi + + ########################## + # Initialize empty Array # + ########################## + LIST_FILES=() + + ################ + # Set the flag # + ################ + SKIP_FLAG=0 + + ############################################################ + # Check to see if we need to go through array or all files # + ############################################################ + if [ ${#FILE_ARRAY[@]} -eq 0 ] && [ "$VALIDATE_ALL_CODEBASE" == "false" ]; then + # No files found in commit and user has asked to not validate code base + SKIP_FLAG=1 + # echo " - No files found in changeset to lint for language:[$FILE_TYPE]" + elif [ ${#FILE_ARRAY[@]} -ne 0 ]; then + # 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 # + ############################################################ + if [ ${#LIST_FILES[@]} -lt 1 ]; then + ###################### + # Set to empty array # + ###################### + LIST_FILES=() + ############################# + # Skip as we found no files # + ############################# + SKIP_FLAG=1 + fi + fi + + ############################### + # Check if any data was found # + ############################### + if [ $SKIP_FLAG -eq 0 ]; then + ###################### + # Print Header array # + ###################### + for LINE in "${PRINT_ARRAY[@]}" + do + ######################### + # Print the header info # + ######################### + echo "$LINE" + done + + ################## + # Lint the files # + ################## + for FILE in "${LIST_FILES[@]}" + do + ##################### + # Get the file name # + ##################### + FILE_NAME=$(basename "$FILE" 2>&1) + + ##################################################### + # Make sure we dont lint node modules or test cases # + ##################################################### + if [[ $FILE == *"node_modules"* ]]; then + # This is a node modules file + continue + elif [[ $FILE == *"$TEST_CASE_FOLDER"* ]]; then + # This is the test cases, we should always skip + continue + fi + + ############## + # File print # + ############## + echo "---------------------------" + echo "File:[$FILE]" + + #################### + # Set the base Var # + #################### + LINT_CMD='' + + ####################################### + # Corner case for Powershell subshell # + ####################################### + if [[ "$FILE_TYPE" == "POWERSHELL" ]]; then + ################################ + # Lint the file with the rules # + ################################ + # Need to append "'" to make the pwsh call syntax correct, also exit with exit code from inner subshell + LINT_CMD=$(cd "$GITHUB_WORKSPACE" || exit; $LINTER_COMMAND "$FILE"; exit $? 2>&1) + else + ################################ + # Lint the file with the rules # + ################################ + LINT_CMD=$(cd "$GITHUB_WORKSPACE" || exit; $LINTER_COMMAND "$FILE" 2>&1) + fi + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + ######### + # Error # + ######### + echo "ERROR! Found errors in [$LINTER_NAME] linter!" + echo "ERROR:[$LINT_CMD]" + # Increment the error count + (("ERRORS_FOUND_$FILE_TYPE++")) + else + ########### + # Success # + ########### + echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" + fi + done + fi +} +################################################################################ +#### Function TestCodebase ##################################################### +function TestCodebase() +{ + #################### + # Pull in the vars # + #################### + FILE_TYPE="$1" # Pull the variable and remove from array path (Example: JSON) + LINTER_NAME="$2" # Pull the variable and remove from array path (Example: jsonlint) + LINTER_COMMAND="$3" # Pull the variable and remove from array path (Example: jsonlint -c ConfigFile /path/to/file) + FILE_EXTENSIONS="$4" # Pull the variable and remove from array path (Example: *.json) + + ################ + # print header # + ################ + echo "" + echo "----------------------------------------------" + echo "----------------------------------------------" + echo "Testing Codebase [$FILE_TYPE] files..." + echo "----------------------------------------------" + echo "----------------------------------------------" + echo "" + + ##################################### + # Validate we have linter installed # + ##################################### + # shellcheck disable=SC2230 + VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Failed + echo "ERROR! Failed to find [$LINTER_NAME] in system!" + echo "ERROR:[$VALIDATE_INSTALL_CMD]" + exit 1 + else + # Success + echo "Successfully found binary in system" + echo "Location:[$VALIDATE_INSTALL_CMD]" + fi + + ########################## + # Initialize empty Array # + ########################## + LIST_FILES=() + + ############################################ + # Check if its ansible, as its the outlier # + ############################################ + if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then + ################################# + # Get list of all files to lint # + ################################# + # 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 + + ################## + # Lint the files # + ################## + for FILE in "${LIST_FILES[@]}" + do + ##################### + # Get the file name # + ##################### + FILE_NAME=$(basename "$FILE" 2>&1) + + ############################ + # Get the file pass status # + ############################ + # Example: markdown_good_1.md -> good + FILE_STATUS=$(echo "$FILE_NAME" |cut -f2 -d'_') + + ######################################################### + # If not found, assume it should be linted successfully # + ######################################################### + if [ -z "$FILE_STATUS" ] || [[ "$FILE" == *"README"* ]]; then + ################################## + # Set to good for proper linting # + ################################## + FILE_STATUS="good" + fi + + ############## + # File print # + ############## + echo "---------------------------" + echo "File:[$FILE]" + + ######################## + # Set the lint command # + ######################## + LINT_CMD='' + + ####################################### + # Check if docker and get folder name # + ####################################### + if [[ "$FILE_TYPE" == "DOCKER" ]]; then + if [[ "$FILE" == *"good"* ]]; then + ############# + # Good file # + ############# + FILE_STATUS='good' + else + ############ + # Bad file # + ############ + FILE_STATUS='bad' + fi + fi + + ##################### + # Check for ansible # + ##################### + if [[ "$FILE_TYPE" == "ANSIBLE" ]]; then + ######################################## + # Make sure we dont lint certain files # + ######################################## + if [[ $FILE == *"vault.yml"* ]] || [[ $FILE == *"galaxy.yml"* ]]; then + # This is a file we dont look at + continue + fi + + ################################ + # Lint the file with the rules # + ################################ + LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/ansible" || exit; $LINTER_COMMAND "$FILE" 2>&1) + elif [[ "$FILE_TYPE" == "POWERSHELL" ]]; then + ################################ + # Lint the file with the rules # + ################################ + # Need to append "'" to make the pwsh call syntax correct, also exit with exit code from inner subshell + LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; $LINTER_COMMAND "$FILE"; exit $? 2>&1) + else + ################################ + # Lint the file with the rules # + ################################ + LINT_CMD=$(cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit; $LINTER_COMMAND "$FILE" 2>&1) + fi + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ######################################## + # Check for if it was supposed to pass # + ######################################## + if [[ "$FILE_STATUS" == "good" ]]; then + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + ######### + # Error # + ######### + echo "ERROR! Found errors in [$LINTER_NAME] linter!" + echo "ERROR:[$LINT_CMD]" + echo "ERROR: Linter CMD:[$LINTER_COMMAND $FILE]" + # Increment the error count + (("ERRORS_FOUND_$FILE_TYPE++")) + else + ########### + # Success # + ########### + echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" + fi + else + ####################################### + # File status = bad, this should fail # + ####################################### + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -eq 0 ]; then + ######### + # Error # + ######### + echo "ERROR! Found errors in [$LINTER_NAME] linter!" + echo "ERROR! This file should have failed test case!" + echo "ERROR:[$LINT_CMD]" + echo "ERROR: Linter CMD:[$LINTER_COMMAND $FILE]" + # Increment the error count + (("ERRORS_FOUND_$FILE_TYPE++")) + else + ########### + # Success # + ########### + echo " - File:[$FILE_NAME] failed test case with [$LINTER_NAME] successfully" + fi + fi + done +} +################################################################################ +#### Function RunTestCases ##################################################### +function RunTestCases() +{ + # This loop will run the test cases and exclude user code + # This is called from the automation process to validate new code + # When a PR is opened, the new code is validated with the default branch + # version of linter.sh, and a new container is built with the latest codebase + # for testing. That container is spun up, and ran, + # with the flag: TEST_CASE_RUN=true + # So that the new code can be validated against the test cases + + ################# + # Header prints # + ################# + echo "" + echo "----------------------------------------------" + echo "-------------- TEST CASE RUN -----------------" + echo "----------------------------------------------" + echo "" + + ####################### + # Test case languages # + ####################### + TestCodebase "YML" "yamllint" "yamllint -c $YAML_LINTER_RULES" ".*\.\(yml\|yaml\)\$" + TestCodebase "JSON" "jsonlint" "jsonlint" ".*\.\(json\)\$" + TestCodebase "XML" "xmllint" "xmllint" ".*\.\(xml\)\$" + TestCodebase "MARKDOWN" "markdownlint" "markdownlint -c $MD_LINTER_RULES" ".*\.\(md\)\$" + TestCodebase "BASH" "shellcheck" "shellcheck" ".*\.\(sh\)\$" + TestCodebase "PYTHON" "pylint" "pylint --rcfile $PYTHON_LINTER_RULES" ".*\.\(py\)\$" + TestCodebase "PERL" "perl" "perl -Mstrict -cw" ".*\.\(pl\)\$" + TestCodebase "PHP" "php" "php -l" ".*\.\(php\)\$" + TestCodebase "RUBY" "rubocop" "rubocop -c $RUBY_LINTER_RULES" ".*\.\(rb\)\$" + TestCodebase "GO" "golangci-lint" "golangci-lint run -c $GO_LINTER_RULES" ".*\.\(go\)\$" + TestCodebase "COFFEESCRIPT" "coffeelint" "coffeelint -f $COFFEESCRIPT_LINTER_RULES" ".*\.\(coffee\)\$" + TestCodebase "JAVASCRIPT_ES" "eslint" "eslint --no-eslintrc -c $JAVASCRIPT_LINTER_RULES" ".*\.\(js\)\$" + 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 -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 "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$" + TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" + + ################# + # Footer prints # + ################# + # Call the footer to display run information + # and exit with error code + Footer +} +################################################################################ +#### Function LintAnsibleFiles ################################################# +function LintAnsibleFiles() +{ + ###################### + # Create Print Array # + ###################### + PRINT_ARRAY=() + + ################ + # print header # + ################ + PRINT_ARRAY+=("") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("Linting [Ansible] files...") + PRINT_ARRAY+=("----------------------------------------------") + PRINT_ARRAY+=("----------------------------------------------") + + ###################### + # Name of the linter # + ###################### + LINTER_NAME="ansible-lint" + + ########################################### + # Validate we have ansible-lint installed # + ########################################### + # shellcheck disable=SC2230 + VALIDATE_INSTALL_CMD=$(command -v "$LINTER_NAME" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + # Failed + echo "ERROR! Failed to find $LINTER_NAME in system!" + echo "ERROR:[$VALIDATE_INSTALL_CMD]" + exit 1 + else + # Success + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + # Success + echo "Successfully found binary in system" + echo "Location:[$VALIDATE_INSTALL_CMD]" + fi + fi + + ########################## + # Initialize empty Array # + ########################## + LIST_FILES=() + + ####################### + # Create flag to skip # + ####################### + SKIP_FLAG=0 + + ###################################################### + # Only go into ansible linter if we have base folder # + ###################################################### + if [ -d "$ANSIBLE_DIRECTORY" ]; then + + ############################################################ + # Check to see if we need to go through array or all files # + ############################################################ + if [ "$VALIDATE_ALL_CODEBASE" == "false" ]; then + # We need to only check the ansible playbooks that have updates + #LIST_FILES=("${ANSIBLE_ARRAY[@]}") + # shellcheck disable=SC2164,SC2010,SC2207 + LIST_FILES=($(cd "$ANSIBLE_DIRECTORY"; ls | grep ".yml" 2>&1)) + else + ################################# + # Get list of all files to lint # + ################################# + # shellcheck disable=SC2164,SC2010,SC2207 + LIST_FILES=($(cd "$ANSIBLE_DIRECTORY"; ls | grep ".yml" 2>&1)) + fi + + ############################################################### + # Set the list to empty if only MD and TXT files were changed # + ############################################################### + # No need to run the full ansible checks on read only file changes + if [ "$READ_ONLY_CHANGE_FLAG" -eq 0 ]; then + ########################## + # Set the array to empty # + ########################## + LIST_FILES=() + ################################### + # Send message that were skipping # + ################################### + #echo "- Skipping Ansible lint run as file(s) that were modified were read only..." + ############################ + # Create flag to skip loop # + ############################ + SKIP_FLAG=1 + fi + + #################################### + # Check if we have data to look at # + #################################### + if [ $SKIP_FLAG -eq 0 ]; then + for LINE in "${PRINT_ARRAY[@]}" + do + ######################### + # Print the header line # + ######################### + echo "$LINE" + done + fi + + ################## + # Lint the files # + ################## + for FILE in "${LIST_FILES[@]}" + do + + ######################################## + # Make sure we dont lint certain files # + ######################################## + if [[ $FILE == *"vault.yml"* ]] || [[ $FILE == *"galaxy.yml"* ]]; then + # This is a file we dont look at + continue + fi + + #################### + # Get the filename # + #################### + FILE_NAME=$(basename "$ANSIBLE_DIRECTORY/$FILE" 2>&1) + + ############## + # File print # + ############## + echo "---------------------------" + echo "File:[$FILE]" + + ################################ + # Lint the file with the rules # + ################################ + LINT_CMD=$("$LINTER_NAME" -v -c "$ANSIBLE_LINTER_RULES" "$ANSIBLE_DIRECTORY/$FILE" 2>&1) + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -ne 0 ]; then + ######### + # Error # + ######### + echo "ERROR! Found errors in [$LINTER_NAME] linter!" + echo "ERROR:[$LINT_CMD]" + # Increment error count + ((ERRORS_FOUND_ANSIBLE++)) + else + ########### + # Success # + ########### + echo " - File:[$FILE_NAME] was linted with [$LINTER_NAME] successfully" + fi + done + else # No ansible directory found in path + ############################### + # Check to see if debug is on # + ############################### + if [[ "$ACTIONS_RUNNER_DEBUG" == "true" ]]; then + ######################## + # No Ansible dir found # + ######################## + echo "WARN! No Ansible base directory found at:[$ANSIBLE_DIRECTORY]" + echo "skipping ansible lint" + fi + fi +}