diff --git a/.automation/test/arm/README.md b/.automation/test/arm/README.md new file mode 100644 index 00000000..e2746d06 --- /dev/null +++ b/.automation/test/arm/README.md @@ -0,0 +1,13 @@ +# ARM Test Cases +This folder holds the test cases for **Azure Resource Manager (ARM)**. + +## 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/arm/arm_bad_1.json b/.automation/test/arm/arm_bad_1.json new file mode 100644 index 00000000..d75ced62 --- /dev/null +++ b/.automation/test/arm/arm_bad_1.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "", + "parameters": { + "Network.Config": { + "type": "object", + "metadata": { + "description": "Properties object for the Virtual Network" + } + } + }, + "variables": { + "Network.Name": "[parameters('Network.Config').name]", + "Network.Location": "[parameters('Network.Config').location]", + "Network.Tags": "[parameters('Network.Config').tags]", + "Network.Properties.AddressSpace.AddressPrefixes": "[parameters('Network.Config').addressPrefixes]", + "Network.Properties.DhcpOptions.DnsServers": "[parameters('Network.Config').dnsServers]", + "copy": [ + { + "name": "Network.Properties.Subnets", + "count": "[length(parameters('Network.Config').subnetConfig)]", + "input": { + "name": "[concat(parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].aksId,'-',parameters('Network.Config').locationId)]", + "properties": "[parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].properties]" + } + } + ], + "Test.Blank.Variable": [] + }, + "resources": [ + { + "name": "[variables('Network.Name')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2019-12-01", + "tags": "[variables('Network.Tags')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[variables('Network.Properties.AddressSpace.AddressPrefixes')]" + }, + "dhcpOptions": { + "dnsServers": "[variables('Network.Properties.DhcpOptions.DnsServers')]" + }, + "subnets": "[variables('Network.Properties.Subnets')]" + } + } + ], + "outputs": { + "state": { + "type": "object", + "value": "[reference(resourceId('Microsoft.Network/virtualNetworks',variables('Network.Name')), '2019-12-01', 'Full')]" + } + } +} \ No newline at end of file diff --git a/.automation/test/arm/arm_good_1.json b/.automation/test/arm/arm_good_1.json new file mode 100644 index 00000000..df09afb7 --- /dev/null +++ b/.automation/test/arm/arm_good_1.json @@ -0,0 +1,53 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "Network.Config": { + "type": "object", + "metadata": { + "description": "Properties object for the Virtual Network" + } + } + }, + "variables": { + "Network.Name": "[parameters('Network.Config').name]", + "Network.Location": "[parameters('Network.Config').location]", + "Network.Tags": "[parameters('Network.Config').tags]", + "Network.Properties.AddressSpace.AddressPrefixes": "[parameters('Network.Config').addressPrefixes]", + "Network.Properties.DhcpOptions.DnsServers": "[parameters('Network.Config').dnsServers]", + "copy": [ + { + "name": "Network.Properties.Subnets", + "count": "[length(parameters('Network.Config').subnetConfig)]", + "input": { + "name": "[concat(parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].aksId,'-',parameters('Network.Config').locationId)]", + "properties": "[parameters('Network.Config').subnetConfig[copyIndex('Network.Properties.Subnets')].properties]" + } + } + ] + }, + "resources": [ + { + "name": "[variables('Network.Name')]", + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2019-12-01", + "location": "[variables('Network.Location')]", + "tags": "[variables('Network.Tags')]", + "properties": { + "addressSpace": { + "addressPrefixes": "[variables('Network.Properties.AddressSpace.AddressPrefixes')]" + }, + "dhcpOptions": { + "dnsServers": "[variables('Network.Properties.DhcpOptions.DnsServers')]" + }, + "subnets": "[variables('Network.Properties.Subnets')]" + } + } + ], + "outputs": { + "state": { + "type": "object", + "value": "[reference(resourceId('Microsoft.Network/virtualNetworks',variables('Network.Name')), '2019-12-01', 'Full')]" + } + } +} \ No newline at end of file diff --git a/.automation/test/editorconfig-checker/.editorconfig b/.automation/test/editorconfig-checker/.editorconfig new file mode 100644 index 00000000..f41c803b --- /dev/null +++ b/.automation/test/editorconfig-checker/.editorconfig @@ -0,0 +1,3 @@ +[*.ext] +indent_style = space +indent_size = 4 diff --git a/.automation/test/editorconfig-checker/README.md b/.automation/test/editorconfig-checker/README.md new file mode 100644 index 00000000..650f9932 --- /dev/null +++ b/.automation/test/editorconfig-checker/README.md @@ -0,0 +1,13 @@ +# EDITORCONFIG_CHECKER Test Cases +This folder holds the test cases for **EDITORCONFIG_CHECKER**. + +## 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/editorconfig-checker/editorconfig-checker_bad_1.ext b/.automation/test/editorconfig-checker/editorconfig-checker_bad_1.ext new file mode 100644 index 00000000..e60d663b --- /dev/null +++ b/.automation/test/editorconfig-checker/editorconfig-checker_bad_1.ext @@ -0,0 +1,3 @@ + some line + some line + some line diff --git a/.automation/test/editorconfig-checker/editorconfig-checker_good_1.ext b/.automation/test/editorconfig-checker/editorconfig-checker_good_1.ext new file mode 100644 index 00000000..30464ecd --- /dev/null +++ b/.automation/test/editorconfig-checker/editorconfig-checker_good_1.ext @@ -0,0 +1,3 @@ +some line + some line + some line diff --git a/.automation/test/html/README.md b/.automation/test/html/README.md new file mode 100644 index 00000000..db11f6fc --- /dev/null +++ b/.automation/test/html/README.md @@ -0,0 +1,13 @@ +# HTML Test Cases +This folder holds the test cases for **HTML**. + +## 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. \ No newline at end of file diff --git a/.automation/test/html/html_bad_01.html b/.automation/test/html/html_bad_01.html new file mode 100644 index 00000000..8252a910 --- /dev/null +++ b/.automation/test/html/html_bad_01.html @@ -0,0 +1,99 @@ + + + + + Document + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+ +
+ + + + + + +
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + + +
+
+
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/.automation/test/html/html_good_01.html b/.automation/test/html/html_good_01.html new file mode 100644 index 00000000..1b10ca4e --- /dev/null +++ b/.automation/test/html/html_good_01.html @@ -0,0 +1,10 @@ + + + + + Document + + + Good HTML! + + \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 75434287..64a37fb3 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -32,7 +32,7 @@ Draft pull requests are also welcome to get feedback early on, or if there is so ## Releasing If you are the current maintainer of this action: 1. If a major version number change: Update `README.md` and the wiki to reflect new version number in the example workflow file sections -2. Draft [Release](https://help.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) with a summarized changelog +2. Draft [Releases](https://help.github.com/en/github/administering-a-repository/managing-releases-in-a-repository) are created automatically. They just need to be checked over for accuracy before making it official. 3. Ensure you check the box for [publishing to the marketplace](https://help.github.com/en/actions/creating-actions/publishing-actions-in-github-marketplace#publishing-an-action) 4. A GitHub Action will Publish the Docker image to GitHub Package Registry once a Release is created 5. A GitHub Action will Publish the Docker image to Docker Hub once a Release is created diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..65dedd3d --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/.github/linters/.ecrc b/.github/linters/.ecrc new file mode 100644 index 00000000..e052a07b --- /dev/null +++ b/.github/linters/.ecrc @@ -0,0 +1,18 @@ +{ + "Verbose": false, + "Debug": false, + "IgnoreDefaults": false, + "SpacesAftertabs": false, + "NoColor": false, + "Exclude": [], + "AllowedContentTypes": [], + "PassedFiles": [], + "Disable": { + "EndOfLine": false, + "Indentation": false, + "InsertFinalNewline": false, + "TrimTrailingWhitespace": false, + "IndentSize": false, + "MaxLineLength": false + } +} diff --git a/.github/linters/.htmlhintrc b/.github/linters/.htmlhintrc new file mode 100644 index 00000000..7fc24f8d --- /dev/null +++ b/.github/linters/.htmlhintrc @@ -0,0 +1,25 @@ +{ + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "attr-value-not-empty": false, + "attr-no-duplication": true, + "doctype-first": true, + "tag-pair": true, + "tag-self-close": false, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "title-require": true, + "alt-require": true, + "doctype-html5": true, + "id-class-value": "dash", + "style-disabled": false, + "inline-style-disabled": false, + "inline-script-disabled": false, + "space-tab-mixed-disabled": "space", + "id-class-ad-disabled": false, + "href-abs-or-rel": false, + "attr-unsafe-chars": true, + "head-script-disabled": true +} \ No newline at end of file diff --git a/.github/pull_request-template.md b/.github/pull_request-template.md new file mode 100644 index 00000000..b6470eb3 --- /dev/null +++ b/.github/pull_request-template.md @@ -0,0 +1,16 @@ + + + +Fixes # + + + +## Proposed Changes + +- +- +- + +## Readiness Checklist +- [ ] Label as `breaking` if this is a large fundamental change +- [ ] Label as either `automation`, `bug`, `documentation`, `enhancement`, `infrastructure`, or `performance` diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000..44d7f26f --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,39 @@ +name-template: 'v$RESOLVED_VERSION' +tag-template: 'v$RESOLVED_VERSION' +template: | + # Changelog + $CHANGES + + See details of [all code changes](https://github.com/github/super-linter/compare/$PREVIOUS_TAG...v$RESOLVED_VERSION) since last release + +categories: + - title: '🚀 Features' + labels: + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + labels: + - 'infrastructure' + - 'automation' + - 'documentation' + - title: '🏎 Performance' + label: 'performance' +change-template: '- $TITLE @$AUTHOR (#$NUMBER)' +version-resolver: + major: + labels: + - 'type: breaking' + minor: + labels: + - 'type: enhancement' + patch: + labels: + - 'type: bug' + - 'type: maintenance' + - 'type: documentation' + default: patch diff --git a/.github/workflows/deploy-DEV.yml b/.github/workflows/deploy-DEV.yml index 2372e17b..ef454467 100644 --- a/.github/workflows/deploy-DEV.yml +++ b/.github/workflows/deploy-DEV.yml @@ -41,7 +41,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v2.3.1 ################################### # Build image locally for testing # diff --git a/.github/workflows/deploy-PROD.yml b/.github/workflows/deploy-PROD.yml index b2306c80..3373f0da 100644 --- a/.github/workflows/deploy-PROD.yml +++ b/.github/workflows/deploy-PROD.yml @@ -35,7 +35,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v2.3.1 ##################### # Run Deploy script # diff --git a/.github/workflows/deploy-RELEASE.yml b/.github/workflows/deploy-RELEASE.yml index 4417ed4b..1a44e903 100644 --- a/.github/workflows/deploy-RELEASE.yml +++ b/.github/workflows/deploy-RELEASE.yml @@ -35,7 +35,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v2.3.1 ################################### # Run Deploy script for Dockerhub # diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml new file mode 100644 index 00000000..2c30bcdb --- /dev/null +++ b/.github/workflows/draft-release.yml @@ -0,0 +1,16 @@ +name: Release Drafter + +on: + push: + # branches to consider in the event; optional, defaults to all + branches: + - master + +jobs: + update_release_draft: + runs-on: ubuntu-latest + steps: + # Drafts your next Release notes as Pull Requests are merged into "master" + - uses: release-drafter/release-drafter@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/stack-linter.yml b/.github/workflows/stack-linter.yml index 71c2b00f..d301d0c4 100644 --- a/.github/workflows/stack-linter.yml +++ b/.github/workflows/stack-linter.yml @@ -35,7 +35,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v2.3.1 ################################ # Run Linter against code base # diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index cff0986d..81d155c9 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -29,7 +29,7 @@ jobs: if: "github.event_name == 'schedule'" steps: - name: Mark issue stale - uses: actions/stale@v3 + uses: actions/stale@v3.0.7 with: repo-token: ${{ secrets.GITHUB_TOKEN }} stale-issue-message: "This issue has been automatically marked as stale because it has not had recent activity.\nIt will be closed in 14 days if no further activity occurs.\nThank you for your contributions.\n\nIf you think this issue should stay open, please remove the `O: stale 🤖` label or comment on the issue." diff --git a/.github/workflows/versioning.yml b/.github/workflows/versioning.yml index c95b118a..37a3ed9e 100644 --- a/.github/workflows/versioning.yml +++ b/.github/workflows/versioning.yml @@ -32,12 +32,12 @@ jobs: ############################# # Check out the latest code # ############################# - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.1 ###################### # Run the tag action # ###################### - - uses: Actions-R-Us/actions-tagger@latest + - uses: Actions-R-Us/actions-tagger@v2.0.1 with: publish_latest_tag: true env: diff --git a/Dockerfile b/Dockerfile index 9aa41e0a..538c4e13 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,23 @@ LABEL com.github.actions.name="GitHub Super-Linter" \ com.github.actions.color="red" \ maintainer="GitHub DevOps " +################################ +# Set ARG values used in Build # +################################ +# PowerShell & PSScriptAnalyzer +ARG PWSH_VERSION='latest' +ARG PWSH_DIRECTORY='/opt/microsoft/powershell' +ARG PSSA_VERSION='latest' +# arm-ttk +ARG ARM_TTK_URI='https://github.com/Azure/arm-ttk.git' +ARG ARM_TTK_DIRECTORY='/opt/microsoft/arm-ttk' +# clj-kondo +ARG CLJ_KONDO_VERSION='2020.06.21' +# Go Linter +ARG GO_VERSION='v1.27.0' +# Raku Linter +ARG RAKU_VER="2020.06" + #################### # Run APK installs # #################### @@ -42,9 +59,6 @@ RUN apk add --no-cache \ # Reference: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell-core-on-linux?view=powershell-7 # Slightly modified to always retrieve latest stable Powershell version # If changing PWSH_VERSION='latest' to a specific version, use format PWSH_VERSION='tags/v7.0.2' -ARG PWSH_VERSION='latest' -ARG PWSH_DIRECTORY='/opt/microsoft/powershell' -ARG PSSA_VERSION='latest' RUN mkdir -p ${PWSH_DIRECTORY} \ && curl -s https://api.github.com/repos/powershell/powershell/releases/${PWSH_VERSION} \ | grep browser_download_url \ @@ -52,9 +66,19 @@ RUN mkdir -p ${PWSH_DIRECTORY} \ | cut -d '"' -f 4 \ | xargs -n 1 wget -O - \ | tar -xzC ${PWSH_DIRECTORY} \ - && ln -s ${PWSH_DIRECTORY}/pwsh /usr/bin/pwsh -f \ + && ln -sf ${PWSH_DIRECTORY}/pwsh /usr/bin/pwsh \ && pwsh -c 'Install-Module -Name PSScriptAnalyzer -RequiredVersion ${PSSA_VERSION} -Scope AllUsers -Force' +############################################################# +# Install Azure Resource Manager Template Toolkit (arm-ttk) # +############################################################# +# Depends on PowerShell +# Reference https://github.com/Azure/arm-ttk +# Reference https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-toolkit +ENV ARM_TTK_PSD1="${ARM_TTK_DIRECTORY}/arm-ttk/arm-ttk.psd1" +RUN git clone "${ARM_TTK_URI}" "${ARM_TTK_DIRECTORY}" \ + && ln -sTf "$ARM_TTK_PSD1" /usr/bin/arm-ttk + ##################### # Run Pip3 Installs # ##################### @@ -79,6 +103,7 @@ RUN npm config set package-lock false \ stylelint \ stylelint-config-standard \ @stoplight/spectral \ + htmlhint \ && npm --no-cache install \ markdownlint-cli \ jsonlint prettyjson \ @@ -92,7 +117,8 @@ RUN npm config set package-lock false \ @typescript-eslint/parser \ eslint-plugin-jest \ stylelint \ - stylelint-config-standard + stylelint-config-standard \ + htmlhint #################################### # Install dockerfilelint from repo # @@ -123,7 +149,6 @@ RUN wget -qO- "https://github.com/koalaman/shellcheck/releases/download/stable/s ##################### # Install Go Linter # ##################### -ARG GO_VERSION='v1.27.0' RUN wget -O- -nvq https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s "$GO_VERSION" ################## @@ -149,7 +174,6 @@ RUN wget "https://github.com/dotenv-linter/dotenv-linter/releases/latest/downloa ##################### # Install clj-kondo # ##################### -ARG CLJ_KONDO_VERSION='2020.06.21' RUN curl -sLO https://github.com/borkdude/clj-kondo/releases/download/v${CLJ_KONDO_VERSION}/clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ && unzip clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ && rm clj-kondo-${CLJ_KONDO_VERSION}-linux-static-amd64.zip \ @@ -164,7 +188,6 @@ RUN curl -sSLO https://github.com/pinterest/ktlint/releases/latest/download/ktli ################ # Install Raku # ################ -ARG RAKU_VER="2020.06" # Environment ENV PATH="/root/raku-install/bin:/root/raku-install/share/perl6/site/bin:/root/.rakudobrew/bin:${PATH}" \ @@ -180,7 +203,11 @@ RUN git clone https://github.com/tadzik/rakudobrew ~/.rakudobrew \ && rakudobrew build-zef \ && rm -rf /root/.rakudobrew - +################################ +# Install editorconfig-checker # +################################ +RUN wget -qO- "https://github.com/editorconfig-checker/editorconfig-checker/releases/latest/download/ec-linux-amd64.tar.gz" | tar -xzf - \ + && mv "bin/ec-linux-amd64" /usr/bin/editorconfig-checker ########################################### # Load GitHub Env Vars for GitHub Actions # @@ -215,8 +242,10 @@ ENV GITHUB_SHA=${GITHUB_SHA} \ VALIDATE_CLOJURE=${VALIDATE_CLOJURE} \ VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \ VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \ + VALIDATE_ARM=${VALIDATE_ARM} \ VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \ VALIDATE_PROTOBUF=${VALIDATE_PROTOBUF} \ + VALIDATE_EDITORCONFIG=${VALIDATE_EDITORCONFIG} \ ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \ RUN_LOCAL=${RUN_LOCAL} \ TEST_CASE_RUN=${TEST_CASE_RUN} \ diff --git a/README.md b/README.md index 127db501..798b512a 100644 --- a/README.md +++ b/README.md @@ -34,13 +34,16 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | *Language* | *Linter* | | --- | --- | | **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) | +| **Azure Resource Manager (ARM)** | [arm-ttk](https://github.com/azure/arm-ttk) | | **AWS CloudFormation templates** | [cfn-lint](https://github.com/aws-cloudformation/cfn-python-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) | +| **EDITORCONFIG** | [editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker) | | **ENV** | [dotenv-linter](https://github.com/dotenv-linter/dotenv-linter) | | **Golang** | [golangci-lint](https://github.com/golangci/golangci-lint) | +| **HTMLHint** | [HTMLHint](https://github.com/htmlhint/HTMLHint) | | **JavaScript** | [eslint](https://eslint.org/) [standard js](https://standardjs.com/) | | **JSON** | [jsonlint](https://github.com/zaach/jsonlint) | | **Kotlin** | [ktlint](https://github.com/pinterest/ktlint) | @@ -173,14 +176,17 @@ and won't run anything unexpected. | **VALIDATE_DOCKER** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_GO** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_POWERSHELL** | `true` | Flag to enable or disable the linting process of the language. | +| **VALIDATE_ARM** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_TERRAFORM** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_CSS** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_ENV** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_CLOJURE** | `true` | Flag to enable or disable the linting process of the language. | +| **VALIDATE_HTML** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_KOTLIN** | `true` | Flag to enable or disable the linting process of the language. | | **VALIDATE_OPENAPI** | `true` | Flag to enable or disable the linting process of the language. | | **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. | +| **VALIDATE_EDITORCONFIG** | `true` | Flag to enable or disable the linting process with the editorconfig. | | **ANSIBLE_DIRECTORY** | `/ansible` | Flag to set the root directory for Ansible file location(s). | | **ACTIONS_RUNNER_DEBUG** | `false` | Flag to enable additional information about the linter, versions, and additional output. | | **DISABLE_ERRORS** | `false` | Flag to have the linter complete with exit code 0 even if errors were detected. | diff --git a/TEMPLATES/.arm-ttk.psd1 b/TEMPLATES/.arm-ttk.psd1 new file mode 100644 index 00000000..bcddce85 --- /dev/null +++ b/TEMPLATES/.arm-ttk.psd1 @@ -0,0 +1,30 @@ +# Documentation: +# - Test Parameters: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-toolkit#test-parameters +# - Test Cases: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/test-cases +@{ + # Test = @( + # 'Parameters Property Must Exist', + # 'Parameters Must Be Referenced', + # 'Secure String Parameters Cannot Have Default', + # 'Location Should Not Be Hardcoded', + # 'Resources Should Have Location', + # 'VM Size Should Be A Parameter', + # 'Min And Max Value Are Numbers', + # 'artifacts-parameter', + # 'Variables Must Be Referenced', + # 'Dynamic Variable References Should Not Use Concat', + # 'apiVersions Should Be Recent', + # 'Providers apiVersions Is Not Permitted', + # 'Template Should Not Contain Blanks', + # 'IDs Should Be Derived From ResourceIDs', + # 'ResourceIds should not contain', + # 'DependsOn Must Not Be Conditional', + # 'Deployment Resources Must Not Be Debug', + # 'adminUsername Should Not Be A Literal', + # 'VM Images Should Use Latest Version', + # 'Virtual-Machines-Should-Not-Be-Preview', + # 'ManagedIdentityExtension must not be used', + # 'Outputs Must Not Contain Secrets' + # ) + # Skip = @() +} diff --git a/TEMPLATES/.htmlhintrc b/TEMPLATES/.htmlhintrc new file mode 100644 index 00000000..7fc24f8d --- /dev/null +++ b/TEMPLATES/.htmlhintrc @@ -0,0 +1,25 @@ +{ + "tagname-lowercase": true, + "attr-lowercase": true, + "attr-value-double-quotes": true, + "attr-value-not-empty": false, + "attr-no-duplication": true, + "doctype-first": true, + "tag-pair": true, + "tag-self-close": false, + "spec-char-escape": true, + "id-unique": true, + "src-not-empty": true, + "title-require": true, + "alt-require": true, + "doctype-html5": true, + "id-class-value": "dash", + "style-disabled": false, + "inline-style-disabled": false, + "inline-script-disabled": false, + "space-tab-mixed-disabled": "space", + "id-class-ad-disabled": false, + "href-abs-or-rel": false, + "attr-unsafe-chars": true, + "head-script-disabled": true +} \ No newline at end of file diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index 0dace390..9c6eb445 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -37,6 +37,8 @@ For some linters it is also possible to override rules on a case by case level w - [Kotlin](#kotlin) - [OpenAPI](#openapi) - [Protocol Buffers](#protocol-buffers) +- [EDITORCONFIG-CHECKER](#editorconfig-checker) +- [HTML](#html) @@ -761,4 +763,51 @@ lint: ### clj-kondo disable entire file ```clojure {:output {:exclude-files ["path/to/file"]}} + +## EDITORCONFIG-CHECKER +- [editorconfig-checker](https://github.com/editorconfig-checker/editorconfig-checker) + +-------------------------------------------------------------------------------- + +### editorconfig-checker Config file +- `.github/linters/.ecrc` +- This linter will also use the [`.editorconfig`](https://editorconfig.org/) of your project + +### editorconfig-checker disable single line +- +```js + // editorconfig-checker-disable-line ``` + +### editorconfig-checker disable code block +- There is currently **No** way to disable rules inline of the file(s) + +### editorconfig-checker disable entire file +- +```js +// editorconfig-checker-disable-file +``` +- You can disable entire files with the `Exclude` property in `.ecrc` +```json +{ + "Exclude": [ + "path/to/file", + "^regular\\/expression\\.ext$" + ] +} +``` + +## HTML +- [htmlhint](https://htmlhint.com/) + +### htmlhint standard Config file +- `.github/linters/.htmlhintrc` + +### htmlhint disable single line +- There is currently **No** way to disable rules in a single line + +### htmlhint disable code block +- There is currently **No** way to disable rules in a code block + +### htmlhint disable entire file +- There is currently **No** way to disable rules in an entire file \ No newline at end of file diff --git a/lib/buildFileList.sh b/lib/buildFileList.sh index 4e1c6196..4cda6582 100755 --- a/lib/buildFileList.sh +++ b/lib/buildFileList.sh @@ -81,11 +81,6 @@ function BuildFileList() { 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 # ########################### @@ -93,6 +88,11 @@ function BuildFileList() { # reverse it back, substitute to lowercase FILE_TYPE=$(basename "$FILE" | rev | cut -f1 -d'.' | rev | awk '{print tolower($0)}') + ############## + # Print file # + ############## + echo "File:[$FILE], File_type:[$FILE_TYPE]" + ######### # DEBUG # ######### @@ -142,7 +142,15 @@ function BuildFileList() { ################################ FILE_ARRAY_OPENAPI+=("$FILE") fi - + ############################ + # Check if file is ARM # + ############################ + if DetectARMFile "$FILE"; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_ARM+=("$FILE") + fi ##################################### # Check if the file is CFN template # ##################################### @@ -359,7 +367,7 @@ function BuildFileList() { # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## READ_ONLY_CHANGE_FLAG=1 - elif [ "$FILE" == "dockerfile" ]; then + elif [ "$FILE" == "dockerfile" ] || [ "$FILE_TYPE" == "dockerfile" ]; then ################################ # Append the file to the array # ################################ @@ -377,6 +385,15 @@ function BuildFileList() { # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## READ_ONLY_CHANGE_FLAG=1 + elif [ "$FILE_TYPE" == "html" ]; then + ################################ + # Append the file to the array # + ##############################p## + FILE_ARRAY_HTML+=("$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 # diff --git a/lib/linter.sh b/lib/linter.sh index 0ce860d6..70006186 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -22,26 +22,26 @@ source /action/lib/worker.sh # Source the function script(s) # GLOBALS # ########### # Default Vars -DEFAULT_RULES_LOCATION='/action/lib/.automation' # Default rules files location -LINTER_RULES_PATH="${LINTER_RULES_PATH:-.github/linters}" # Linter Path Directory +DEFAULT_RULES_LOCATION='/action/lib/.automation' # Default rules files location +LINTER_RULES_PATH="${LINTER_RULES_PATH:-.github/linters}" # Linter Path Directory # YAML Vars -YAML_FILE_NAME='.yaml-lint.yml' # Name of the file -YAML_LINTER_RULES="$DEFAULT_RULES_LOCATION/$YAML_FILE_NAME" # Path to the yaml lint rules +YAML_FILE_NAME='.yaml-lint.yml' # Name of the file +YAML_LINTER_RULES="$DEFAULT_RULES_LOCATION/$YAML_FILE_NAME" # Path to the yaml lint rules # MD Vars -MD_FILE_NAME='.markdown-lint.yml' # Name of the file -MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to the markdown lint rules +MD_FILE_NAME='.markdown-lint.yml' # Name of the file +MD_LINTER_RULES="$DEFAULT_RULES_LOCATION/$MD_FILE_NAME" # Path to the markdown lint rules # Python Vars -PYTHON_FILE_NAME='.python-lint' # Name of the file -PYTHON_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PYTHON_FILE_NAME" # Path to the python lint rules +PYTHON_FILE_NAME='.python-lint' # Name of the file +PYTHON_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PYTHON_FILE_NAME" # Path to the python lint rules # Cloudformation Vars -CFN_FILE_NAME='.cfnlintrc.yml' # Name of the file -CFN_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CFN_FILE_NAME" # Path to the python lint rules +CFN_FILE_NAME='.cfnlintrc.yml' # Name of the file +CFN_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CFN_FILE_NAME" # Path to the cloudformation lint rules # Ruby Vars -RUBY_FILE_NAME="${RUBY_CONFIG_FILE:-.ruby-lint.yml}" # Name of the file -RUBY_LINTER_RULES="$DEFAULT_RULES_LOCATION/$RUBY_FILE_NAME" # Path to the ruby lint rules +RUBY_FILE_NAME="${RUBY_CONFIG_FILE:-.ruby-lint.yml}" # Name of the file +RUBY_LINTER_RULES="$DEFAULT_RULES_LOCATION/$RUBY_FILE_NAME" # Path to the ruby lint rules # Coffee Vars -COFFEESCRIPT_FILE_NAME='.coffee-lint.json' # Name of the file -COFFEESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEESCRIPT_FILE_NAME" # Path to the coffeescript lint rules +COFFEE_FILE_NAME='.coffee-lint.json' # Name of the file +COFFEESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$COFFEE_FILE_NAME" # Path to the coffeescript lint rules # Javascript Vars JAVASCRIPT_FILE_NAME="${JAVASCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # Name of the file JAVASCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$JAVASCRIPT_FILE_NAME" # Path to the Javascript lint rules @@ -51,32 +51,38 @@ TYPESCRIPT_FILE_NAME="${TYPESCRIPT_ES_CONFIG_FILE:-.eslintrc.yml}" # Name o TYPESCRIPT_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TYPESCRIPT_FILE_NAME" # Path to the Typescript lint rules TYPESCRIPT_STANDARD_LINTER_RULES='' # ENV string to pass when running js standard # Ansible Vars -ANSIBLE_FILE_NAME='.ansible-lint.yml' # Name of the file -ANSIBLE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ANSIBLE_FILE_NAME" # Path to the Ansible lint rules +ANSIBLE_FILE_NAME='.ansible-lint.yml' # Name of the file +ANSIBLE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ANSIBLE_FILE_NAME" # Path to the Ansible lint rules # Docker Vars -DOCKER_FILE_NAME='.dockerfilelintrc' # Name of the file -DOCKER_LINTER_RULES="$DEFAULT_RULES_LOCATION/$DOCKER_FILE_NAME" # Path to the Docker lint rules +DOCKER_FILE_NAME='.dockerfilelintrc' # Name of the file +DOCKER_LINTER_RULES="$DEFAULT_RULES_LOCATION/$DOCKER_FILE_NAME" # Path to the Docker lint rules # Golang Vars -GO_FILE_NAME='.golangci.yml' # Name of the file -GO_LINTER_RULES="$DEFAULT_RULES_LOCATION/$GO_FILE_NAME" # Path to the Go lint rules +GO_FILE_NAME='.golangci.yml' # Name of the file +GO_LINTER_RULES="$DEFAULT_RULES_LOCATION/$GO_FILE_NAME" # Path to the Go lint rules # Terraform Vars -TERRAFORM_FILE_NAME='.tflint.hcl' # Name of the file -TERRAFORM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TERRAFORM_FILE_NAME" # Path to the Terraform lint rules +TERRAFORM_FILE_NAME='.tflint.hcl' # Name of the file +TERRAFORM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$TERRAFORM_FILE_NAME" # Path to the Terraform lint rules # Powershell Vars POWERSHELL_FILE_NAME='.powershell-psscriptanalyzer.psd1' # Name of the file POWERSHELL_LINTER_RULES="$DEFAULT_RULES_LOCATION/$POWERSHELL_FILE_NAME" # Path to the Powershell lint rules +# Azure Resource Manager Vars +ARM_FILE_NAME='.arm-ttk.psd1' # Name of the file +ARM_LINTER_RULES="$DEFAULT_RULES_LOCATION/$ARM_FILE_NAME" # Path to the ARM lint rules # CSS Vars -CSS_FILE_NAME='.stylelintrc.json' # Name of the file -CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to the CSS lint rules +CSS_FILE_NAME='.stylelintrc.json' # Name of the file +CSS_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CSS_FILE_NAME" # Path to the CSS lint rules # OpenAPI Vars -OPENAPI_FILE_NAME='.openapirc.yml' # Name of the file -OPENAPI_LINTER_RULES="$DEFAULT_RULES_LOCATION/$OPENAPI_FILE_NAME" # Path to the OpenAPI lint rules +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 +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" +CLOJURE_FILE_NAME='.clj-kondo/config.edn' # Name of the file +CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" # Path to the Clojure lint rules +# HTML Vars +HTML_FILE_NAME='.htmlhintrc' # Name of the file +HTML_LINTER_RULES="$DEFAULT_RULES_LOCATION/$HTML_FILE_NAME" # Path to the CSS lint rules ####################################### # Linter array for information prints # @@ -84,8 +90,8 @@ CLOJURE_LINTER_RULES="$DEFAULT_RULES_LOCATION/$CLOJURE_FILE_NAME" LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" "pylint" "perl" "raku" "rubocop" "coffeelint" "eslint" "standard" "ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint" - "stylelint" "dotenv-linter" "pwsh" "ktlint" "protolint" "clj-kondo" - "spectral" "cfn-lint") + "stylelint" "dotenv-linter" "pwsh" "arm-ttk" "ktlint" "protolint" "clj-kondo" + "spectral" "cfn-lint" "htmlhint") ############################# # Language array for prints # @@ -93,7 +99,8 @@ LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'RAKU' 'PHP' 'RUBY' 'PYTHON' 'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES' 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM' - 'CSS' 'ENV' 'POWERSHELL' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' 'CFN') + 'CSS' 'ENV' 'POWERSHELL' 'ARM' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' + 'CFN' 'HTML') ################### # GitHub ENV Vars # @@ -128,10 +135,13 @@ VALIDATE_ENV="${VALIDATE_ENV}" # Boolean to vali VALIDATE_CLOJURE="${VALIDATE_CLOJURE}" # Boolean to validate language VALIDATE_TERRAFORM="${VALIDATE_TERRAFORM}" # Boolean to validate language VALIDATE_POWERSHELL="${VALIDATE_POWERSHELL}" # Boolean to validate language +VALIDATE_ARM="${VALIDATE_ARM}" # Boolean to validate language VALIDATE_KOTLIN="${VALIDATE_KOTLIN}" # Boolean to validate language VALIDATE_OPENAPI="${VALIDATE_OPENAPI}" # Boolean to validate language +VALIDATE_EDITORCONFIG="${VALIDATE_EDITORCONFIG}" # Boolean to validate files with editorconfig TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases DISABLE_ERRORS="${DISABLE_ERRORS}" # Boolean to enable warning-only output without throwing errors +VALIDATE_HTML="${VALIDATE_HTML}" # Boolean to validate language ############## # Debug Vars # @@ -185,12 +195,14 @@ FILE_ARRAY_DOCKER=() # Array of files to check FILE_ARRAY_GO=() # Array of files to check FILE_ARRAY_TERRAFORM=() # Array of files to check FILE_ARRAY_POWERSHELL=() # Array of files to check +FILE_ARRAY_ARM=() # Array of files to check FILE_ARRAY_CSS=() # Array of files to check FILE_ARRAY_ENV=() # Array of files to check FILE_ARRAY_CLOJURE=() # Array of files to check FILE_ARRAY_KOTLIN=() # Array of files to check FILE_ARRAY_PROTOBUF=() # Array of files to check FILE_ARRAY_OPENAPI=() # Array of files to check +FILE_ARRAY_HTML=() # Array of files to check ############ # Counters # @@ -216,12 +228,14 @@ ERRORS_FOUND_DOCKER=0 # Count of errors found ERRORS_FOUND_GO=0 # Count of errors found ERRORS_FOUND_TERRAFORM=0 # Count of errors found ERRORS_FOUND_POWERSHELL=0 # Count of errors found +ERRORS_FOUND_ARM=0 # Count of errors found ERRORS_FOUND_CSS=0 # Count of errors found ERRORS_FOUND_ENV=0 # Count of errors found ERRORS_FOUND_CLOJURE=0 # Count of errors found ERRORS_FOUND_KOTLIN=0 # Count of errors found ERRORS_FOUND_PROTOBUF=0 # Count of errors found ERRORS_FOUND_OPENAPI=0 # Count of errors found +ERRORS_FOUND_HTML=0 # Count of errors found ################################################################################ ########################## FUNCTIONS BELOW ##################################### @@ -256,19 +270,24 @@ GetLinterVersions() { echo "" echo "---------------------------------------------" echo "Linter Version Info:" - echo "---------------------------------------------" - echo "" ########################################################## # Go through the array of linters and print version info # ########################################################## for LINTER in "${LINTER_ARRAY[@]}"; do - echo "---------------------------------------------" - echo "[$LINTER]:" ################### # Get the version # ################### - mapfile -t GET_VERSION_CMD < <("$LINTER" --version 2>&1) + if [[ "$LINTER" == "arm-ttk" ]]; then + # Need specific command for ARM + mapfile -t GET_VERSION_CMD < <(grep -iE 'version' "$ARM_TTK_PSD1" | xargs 2>&1) + elif [[ "$LINTER" == "protolint" ]]; then + # Need specific command for Protolint + mapfile -t GET_VERSION_CMD < <(echo "--version not supported") + else + # Standard version command + mapfile -t GET_VERSION_CMD < <("$LINTER" --version 2>&1) + fi ####################### # Load the error code # @@ -279,16 +298,20 @@ GetLinterVersions() { # Check the shell for errors # ############################## if [ $ERROR_CODE -ne 0 ] || [ -z "${GET_VERSION_CMD[*]}" ]; then - echo -e "${NC}${F[Y]}WARN!${NC} Failed to get version info for:[$LINTER]${NC}" - echo "---------------------------------------------" + echo -e "${NC}[$LINTER]: ${F[Y]}WARN!${NC} Failed to get version info for:${NC}" else ########################## # Print the version info # ########################## - echo "${GET_VERSION_CMD[*]}" - echo "---------------------------------------------" + echo -e "${NC}${F[B]}Successfully found version for ${F[W]}[$LINTER]${F[B]}: ${F[W]}${GET_VERSION_CMD[*]}${NC}" fi done + + ######################### + # Print version footers # + ######################### + echo "---------------------------------------------" + echo "" } ################################################################################ #### Function GetLinterRules ################################################### @@ -438,6 +461,39 @@ DetectOpenAPIFile() { fi } ################################################################################ +#### Function DetectARMFile #################################################### +DetectARMFile() { + ################ + # Pull in vars # + ################ + FILE="$1" # Name of the file/path we are validating + + ############################### + # Check the file for keywords # + ############################### + grep -E 'schema.management.azure.com' "$FILE" > /dev/null + + ####################### + # Load the error code # + ####################### + ERROR_CODE=$? + + ############################## + # Check the shell for errors # + ############################## + if [ $ERROR_CODE -eq 0 ]; then + ######################## + # Found string in file # + ######################## + return 0 + else + ################### + # No string match # + ################### + return 1 + fi +} +################################################################################ #### Function DetectCloudFormationFile ######################################### DetectCloudFormationFile() { ################ @@ -724,6 +780,7 @@ Footer() { [ "$ERRORS_FOUND_GO" -ne 0 ] || [ "$ERRORS_FOUND_TERRAFORM" -ne 0 ] || [ "$ERRORS_FOUND_POWERSHELL" -ne 0 ] || + [ "$ERRORS_FOUND_ARM" -ne 0 ] || [ "$ERRORS_FOUND_RUBY" -ne 0 ] || [ "$ERRORS_FOUND_CSS" -ne 0 ] || [ "$ERRORS_FOUND_CFN" -ne 0 ] || @@ -731,7 +788,8 @@ Footer() { [ "$ERRORS_FOUND_OPENAPI" -ne 0 ] || [ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || [ "$ERRORS_FOUND_CLOJURE" -ne 0 ] || - [ "$ERRORS_FOUND_KOTLIN" -ne 0 ]; then + [ "$ERRORS_FOUND_KOTLIN" -ne 0 ] || + [ "$ERRORS_FOUND_HTML" -ne 0 ]; then # Failed exit echo -e "${NC}${F[R]}Exiting with errors found!${NC}" exit 1 @@ -747,6 +805,7 @@ Footer() { exit 0 fi } + ################################################################################ ############################### MAIN ########################################### ################################################################################ @@ -795,10 +854,14 @@ GetLinterRules "DOCKER" GetLinterRules "TERRAFORM" # Get PowerShell rules GetLinterRules "POWERSHELL" +# Get ARM rules +GetLinterRules "ARM" # Get CSS rules GetLinterRules "CSS" # Get CFN rules GetLinterRules "CFN" +# Get HTML rules +GetLinterRules "HTML" ################################# # Check if were in verbose mode # @@ -1088,6 +1151,18 @@ if [ "$VALIDATE_KOTLIN" == "true" ]; then LintCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "${FILE_ARRAY_KOTLIN[@]}" fi +######################## +# EDITORCONFIG LINTING # +######################## +echo ed: "$VALIDATE_EDITORCONFIG" +if [ "$VALIDATE_EDITORCONFIG" == "true" ]; then + #################################### + # Lint the files with editorconfig # + #################################### + # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" + LintCodebase "EDITORCONFIG" "editorconfig-checker" "editorconfig-checker" "^.*$" "${FILE_ARRAY_ENV[@]}" +fi + ################## # DOCKER LINTING # ################## @@ -1140,6 +1215,17 @@ if [ "$VALIDATE_POWERSHELL" == "true" ]; then LintCodebase "POWERSHELL" "pwsh" "Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "${FILE_ARRAY_POWERSHELL[@]}" fi +######################## +# ARM Template LINTING # +######################## +if [ "$VALIDATE_ARM" == "true" ]; then + ############################### + # Lint the ARM Template files # + ############################### + # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" + LintCodebase "ARM" "arm-ttk" "Import-Module $ARM_TTK_PSD1 ; \$config = \$(Import-PowerShellDataFile -Path $ARM_LINTER_RULES) ; Test-AzTemplate @config -TemplatePath" ".*\.\(json\)\$" "${FILE_ARRAY_ARM[@]}" +fi + ################### # OPENAPI LINTING # ################### @@ -1171,6 +1257,20 @@ if [ "$VALIDATE_OPENAPI" == "true" ]; then LintCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" "disabledfileext" "${FILE_ARRAY_OPENAPI[@]}" fi +################ +# HTML LINTING # +################ +if [ "$VALIDATE_HTML" == "true" ]; then + ################################# + # Get HTML standard rules # + ################################# + GetStandardRules "htmlhint" + ############################# + # Lint the HTML files # + ############################# + LintCodebase "HTML" "htmlhint" "htmlhint --config $HTML_LINTER_RULES" ".*\.\(html\)\$" "${FILE_ARRAY_HTML[@]}" +fi + ########## # Footer # ########## diff --git a/lib/validation.sh b/lib/validation.sh index 1e83e0a9..17f53a3d 100755 --- a/lib/validation.sh +++ b/lib/validation.sh @@ -66,12 +66,15 @@ function GetValidationInfo() { 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_ARM=$(echo "$VALIDATE_ARM" | 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)}') + VALIDATE_EDITORCONFIG=$(echo "$VALIDATE_EDITORCONFIG" | awk '{print tolower($0)}') + VALIDATE_HTML=$(echo "$VALIDATE_HTML" | awk '{print tolower($0)}') ################################################ # Determine if any linters were explicitly set # @@ -97,12 +100,15 @@ function GetValidationInfo() { $VALIDATE_GO || -n \ $VALIDATE_TERRAFORM || -n \ $VALIDATE_POWERSHELL || -n \ + $VALIDATE_ARM || -n \ $VALIDATE_CSS || -n \ $VALIDATE_ENV || -n \ $VALIDATE_CLOJURE || -n \ $VALIDATE_PROTOBUF || -n \ $VALIDATE_OPENAPI || -n \ - $VALIDATE_KOTLIN ]]; then + $VALIDATE_KOTLIN || -n \ + $VALIDATE_EDITORCONFIG || -n \ + $VALIDATE_HTML ]]; then ANY_SET="true" fi @@ -386,6 +392,20 @@ function GetValidationInfo() { VALIDATE_POWERSHELL="true" fi + ################################### + # Validate if we should check ARM # + ################################### + if [[ "$ANY_SET" == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z "$VALIDATE_ARM" ]]; then + # ARM flag was not set - default to false + VALIDATE_ARM="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_ARM="true" + fi + ################################### # Validate if we should check CSS # ################################### @@ -470,6 +490,34 @@ function GetValidationInfo() { VALIDATE_CLOJURE="true" fi + ############################################ + # Validate if we should check editorconfig # + ############################################ + if [[ $ANY_SET == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z $VALIDATE_EDITORCONFIG ]]; then + # EDITORCONFIG flag was not set - default to false + VALIDATE_EDITORCONFIG="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_EDITORCONFIG="true" + fi + + #################################### + # Validate if we should check HTML # + #################################### + if [[ $ANY_SET == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z $VALIDATE_HTML ]]; then + # HTML flag was not set - default to false + VALIDATE_HTML="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_HTML="true" + fi + ####################################### # Print which linters we are enabling # ####################################### @@ -573,6 +621,11 @@ function GetValidationInfo() { else PRINT_ARRAY+=("- Excluding [POWERSHELL] files in code base...") fi + if [[ $VALIDATE_ARM == "true" ]]; then + PRINT_ARRAY+=("- Validating [ARM] files in code base...") + else + PRINT_ARRAY+=("- Excluding [ARM] files in code base...") + fi if [[ $VALIDATE_CSS == "true" ]]; then PRINT_ARRAY+=("- Validating [CSS] files in code base...") else @@ -603,6 +656,16 @@ function GetValidationInfo() { else PRINT_ARRAY+=("- Excluding [PROTOBUF] files in code base...") fi + if [[ $VALIDATE_EDITORCONFIG == "true" ]]; then + PRINT_ARRAY+=("- Validating [EDITORCONFIG] files in code base...") + else + PRINT_ARRAY+=("- Excluding [EDITORCONFIG] files in code base...") + fi + if [[ $VALIDATE_HTML == "true" ]]; then + PRINT_ARRAY+=("- Validating [HTML] files in code base...") + else + PRINT_ARRAY+=("- Excluding [HTML] files in code base...") + fi ############################## # Validate Ansible Directory # diff --git a/lib/worker.sh b/lib/worker.sh index a485e250..2c9bf4d0 100755 --- a/lib/worker.sh +++ b/lib/worker.sh @@ -55,8 +55,7 @@ function LintCodebase() { else # Success if [[ $ACTIONS_RUNNER_DEBUG == "true" ]]; then - echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system${NC}" - echo "Location:[$VALIDATE_INSTALL_CMD]" + echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system location: ${F[W]}[$VALIDATE_INSTALL_CMD]${NC}" fi fi @@ -156,17 +155,19 @@ function LintCodebase() { #################### LINT_CMD='' - ####################################### - # Corner case for Powershell subshell # - ####################################### - if [[ $FILE_TYPE == "POWERSHELL" ]]; then + #################################### + # Corner case for pwsh subshell # + # - PowerShell (PSScriptAnalyzer) # + # - ARM (arm-ttk) # + #################################### + if [[ $FILE_TYPE == "POWERSHELL" ]] || [[ $FILE_TYPE == "ARM" ]]; then ################################ # Lint the file with the rules # ################################ # Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell LINT_CMD=$( cd "$GITHUB_WORKSPACE" || exit - pwsh -c "($LINTER_COMMAND $FILE)" + pwsh -NoProfile -NoLogo -Command "$LINTER_COMMAND $FILE; if (\$Error.Count) { exit 1 }" exit $? 2>&1 ) else @@ -248,8 +249,7 @@ function TestCodebase() { exit 1 else # Success - echo -e "${NC}${F[B]}Successfully found binary in system${NC}" - echo "Location:[$VALIDATE_INSTALL_CMD]" + echo -e "${NC}${F[B]}Successfully found binary for ${F[W]}[$LINTER_NAME]${F[B]} in system location: ${F[W]}[$VALIDATE_INSTALL_CMD]${NC}" fi ########################## @@ -334,14 +334,14 @@ function TestCodebase() { cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER/$INDVIDUAL_TEST_FOLDER" || exit $LINTER_COMMAND "$FILE" 2>&1 ) - elif [[ $FILE_TYPE == "POWERSHELL" ]]; then + elif [[ $FILE_TYPE == "POWERSHELL" ]] || [[ $FILE_TYPE == "ARM" ]]; then ################################ # Lint the file with the rules # ################################ # Need to run PowerShell commands using pwsh -c, also exit with exit code from inner subshell LINT_CMD=$( cd "$GITHUB_WORKSPACE/$TEST_CASE_FOLDER" || exit - pwsh -c "($LINTER_COMMAND $FILE)" + pwsh -NoProfile -NoLogo -Command "$LINTER_COMMAND $FILE; if (\$Error.Count) { exit 1 }" exit $? 2>&1 ) else @@ -471,13 +471,15 @@ function RunTestCases() { TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" ".*\.\(yml\|yaml\)\$" "ansible" TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" "terraform" TestCodebase "CFN" "cfn-lint" "cfn-lint --config-file $CFN_LINTER_RULES" ".*\.\(json\|yml\|yaml\)\$" "cfn" - TestCodebase "POWERSHELL" "pwsh" "pwsh -c Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "powershell" + TestCodebase "POWERSHELL" "pwsh" "Invoke-ScriptAnalyzer -EnableExit -Settings $POWERSHELL_LINTER_RULES -Path" ".*\.\(ps1\|psm1\|psd1\|ps1xml\|pssc\|psrc\|cdxml\)\$" "powershell" + TestCodebase "ARM" "arm-ttk" "Import-Module $ARM_TTK_PSD1 ; \$config = \$(Import-PowerShellDataFile -Path $ARM_LINTER_RULES) ; Test-AzTemplate @config -TemplatePath" ".*\.\(json\)\$" "arm" TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "css" TestCodebase "ENV" "dotenv-linter" "dotenv-linter" ".*\.\(env\)\$" "env" TestCodebase "CLOJURE" "clj-kondo" "clj-kondo --config $CLOJURE_LINTER_RULES --lint" ".*\.\(clj\|cljs\|cljc\|edn\)\$" "clojure" TestCodebase "KOTLIN" "ktlint" "ktlint" ".*\.\(kt\|kts\)\$" "kotlin" TestCodebase "PROTOBUF" "protolint" "protolint lint --config_path $PROTOBUF_LINTER_RULES" ".*\.\(proto\)\$" "protobuf" TestCodebase "OPENAPI" "spectral" "spectral lint -r $OPENAPI_LINTER_RULES" ".*\.\(ymlopenapi\|jsonopenapi\)\$" "openapi" + TestCodebase "HTML" "htmlhint" "htmlhint --config $HTML_LINTER_RULES" ".*\.\(html\)\$" "html" ################# # Footer prints # diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..33b3caa3 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,545 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "ajv": { + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + }, + "aws4": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + }, + "chalk": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-base": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", + "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "requires": { + "glob-parent": "^2.0.0", + "is-glob": "^2.0.0" + } + }, + "glob-parent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", + "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "requires": { + "is-glob": "^2.0.0" + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "htmlhint": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/htmlhint/-/htmlhint-0.14.1.tgz", + "integrity": "sha512-VWKrljlwF8tEKH48YPfC30zYKhrsMqm70d7vXswivEqd3DSva8ZlIzfeCa3YWFEFRIIhiXKgKurlqEpCtYMCAA==", + "dev": true, + "requires": { + "async": "3.2.0", + "chalk": "4.0.0", + "commander": "5.1.0", + "glob": "7.1.6", + "parse-glob": "3.0.4", + "request": "2.88.2", + "strip-json-comments": "3.1.0", + "xml": "1.0.1" + } + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "is-dotfile": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", + "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=" + }, + "is-extglob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + }, + "is-glob": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", + "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "requires": { + "is-extglob": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "requires": { + "mime-db": "1.44.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "parse-glob": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", + "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "requires": { + "glob-base": "^0.3.0", + "is-dotfile": "^1.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + }, + "psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "strip-json-comments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==" + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "requires": { + "has-flag": "^4.0.0" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=" + } + } +}