diff --git a/.automation/test/css/README.md b/.automation/test/css/README.md new file mode 100644 index 00000000..04c7121a --- /dev/null +++ b/.automation/test/css/README.md @@ -0,0 +1,13 @@ +# CSS Test Cases +This folder holds the test cases for **CSS**. + +## 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/css/css_bad_01.css b/.automation/test/css/css_bad_01.css new file mode 100644 index 00000000..3c600b36 --- /dev/null +++ b/.automation/test/css/css_bad_01.css @@ -0,0 +1,9 @@ +/* Bad */ +/* Multiline */ +/* Comment */ +.selector-3[type="text"] { + background: linear-gradient(#FFFFFF, rgba(0, 0, 0, 0.8)); + box-sizing: border-box; + display: block; + color: #AAAAAA; +} diff --git a/.automation/test/css/css_good_01.css b/.automation/test/css/css_good_01.css new file mode 100644 index 00000000..a126e5b2 --- /dev/null +++ b/.automation/test/css/css_good_01.css @@ -0,0 +1,22 @@ +/** + * Multi-line comment + */ + +.selector-1, +.selector-2, +.selector-3[type="text"] { + background: linear-gradient(#fff, rgba(0, 0, 0, 0.8)); + box-sizing: border-box; + display: block; + color: #333; +} + +.selector-a, +.selector-b:not(:first-child) { + padding: 10px !important; + top: calc(calc(1em * 2) / 3); +} + +.selector-x { width: 10%; } +.selector-y { width: 20%; } +.selector-z { width: 30%; } diff --git a/.github/linters/.stylelintrc.json b/.github/linters/.stylelintrc.json new file mode 100644 index 00000000..40db42c6 --- /dev/null +++ b/.github/linters/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-standard" +} diff --git a/Dockerfile b/Dockerfile index 943ae78b..7f655c31 100644 --- a/Dockerfile +++ b/Dockerfile @@ -50,6 +50,8 @@ RUN npm config set package-lock false \ @typescript-eslint/eslint-plugin \ @typescript-eslint/parser \ eslint-plugin-jest \ + stylelint \ + stylelint-config-standard \ && npm --no-cache install \ markdownlint-cli \ jsonlint prettyjson \ @@ -61,7 +63,9 @@ RUN npm config set package-lock false \ eslint-config-prettier \ @typescript-eslint/eslint-plugin \ @typescript-eslint/parser \ - eslint-plugin-jest + eslint-plugin-jest \ + stylelint \ + stylelint-config-standard #################################### # Install dockerfilelint from repo # @@ -123,6 +127,7 @@ ENV GITHUB_SHA=${GITHUB_SHA} \ VALIDATE_TYPESCRIPT_STANDARD=${VALIDATE_TYPESCRIPT_STANDARD} \ VALIDATE_GO=${VALIDATE_GO} \ VALIDATE_TERRAFORM=${VALIDATE_TERRAFORM} \ + VALIDATE_CSS=${VALIDATE_CSS} \ ANSIBLE_DIRECTORY=${ANSIBLE_DIRECTORY} \ RUN_LOCAL=${RUN_LOCAL} \ TEST_CASE_RUN=${TEST_CASE_RUN} \ diff --git a/README.md b/README.md index 541937e2..b0074dc7 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | *Language* | *Linter* | | --- | --- | | **Ansible** | [ansible-lint](https://github.com/ansible/ansible-lint) | -| **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | +| **CSS** | [stylelint](https://stylelint.io/) | +| **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/) | @@ -131,6 +132,7 @@ 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_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. | | **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. | | **DEFAULT_WORKSPACE** | `/tmp/lint` | The location containing files to lint if you are running locally. | diff --git a/TEMPLATES/.stylelintrc.json b/TEMPLATES/.stylelintrc.json new file mode 100644 index 00000000..40db42c6 --- /dev/null +++ b/TEMPLATES/.stylelintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "stylelint-config-standard" +} diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index 16811f06..92187192 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -20,6 +20,7 @@ Below is examples and documentation for each language and the various methods to - [Golang](#golang) - [Dockerfile](#dockerfile) - [Terraform](#terraform) +- [CSS](#stylelint) @@ -511,3 +512,35 @@ alert('foo') - There is currently **No** way to disable rules inline of the file(s) -------------------------------------------------------------------------------- + +## CSS +- [stylelint](https://stylelint.io/) + +### stylelint standard Config file +- `.github/linters/.stylelintrc.json` + +### stylelint disable single line +```css +#id { + /* stylelint-disable-next-line declaration-no-important */ + color: pink !important; +} +``` + +### stylelint disable code block +```css +/* stylelint-disable */ +a {} +/* stylelint-enable */ +``` + +### stylelint disable entire file +- You can disable entire files with the `ignoreFiles` property in `.stylelintrc.json` +```json +{ + "ignoreFiles": [ + "styles/ignored/wildcards/*.css", + "styles/ignored/specific-file.css" + ] +} +``` diff --git a/lib/linter.sh b/lib/linter.sh index 9d51a5ea..b96f44ec 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -48,20 +48,25 @@ GO_LINTER_RULES="$DEFAULT_RULES_LOCATION/$GO_FILE_NAME" # Path to th # 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 +# 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 + ####################################### # Linter array for information prints # ####################################### LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" "pylint" "perl" "rubocop" "coffeelint" "eslint" "standard" - "ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint") + "ansible-lint" "/dockerfilelint/bin/dockerfilelint" "golangci-lint" "tflint" + "stylelint") ############################# # Language array for prints # ############################# LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'RUBY' 'PYTHON' 'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES' - 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM') + 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM' 'CSS') ################### # GitHub ENV Vars # @@ -89,6 +94,7 @@ VALIDATE_TYPESCRIPT_STANDARD="${VALIDATE_TYPESCRIPT_STANDARD}" # Boolean to val VALIDATE_DOCKER="${VALIDATE_DOCKER}" # Boolean to validate language VALIDATE_GO="${VALIDATE_GO}" # Boolean to validate language VALIDATE_TERRAFORM="${VALIDATE_TERRAFORM}" # Boolean to validate language +VALIDATE_CSS="${VALIDATE_CSS}" # Boolean to validate language TEST_CASE_RUN="${TEST_CASE_RUN}" # Boolean to validate only test cases ############## @@ -129,6 +135,7 @@ FILE_ARRAY_TYPESCRIPT_STANDARD=() # Array of files to check 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_CSS=() # Array of files to check ############ # Counters # @@ -150,6 +157,7 @@ ERRORS_FOUND_TYPESCRIPT_ES=0 # Count of errors found 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_CSS=0 # Count of errors found ################################################################################ ########################## FUNCTIONS BELOW ##################################### @@ -726,6 +734,7 @@ GetValidationInfo() 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_CSS=$(echo "$VALIDATE_CSS" | awk '{print tolower($0)') ################################################ # Determine if any linters were explicitly set # @@ -747,7 +756,8 @@ GetValidationInfo() -n "$VALIDATE_TYPESCRIPT_STANDARD" || \ -n "$VALIDATE_DOCKER" || \ -n "$VALIDATE_GO" || \ - -n "$VALIDATE_TERRAFORM" ]]; then + -n "$VALIDATE_TERRAFORM" || \ + -n "$VALIDATE_CSS" ]]; then ANY_SET="true" fi @@ -989,6 +999,20 @@ GetValidationInfo() VALIDATE_TERRAFORM="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 + ####################################### # Print which linters we are enabling # ####################################### @@ -1077,6 +1101,11 @@ GetValidationInfo() else PRINT_ARRAY+=("- Excluding [TERRAFORM] 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 ############################## # Validate Ansible Directory # @@ -1384,6 +1413,15 @@ BuildFileList() # Set the READ_ONLY_CHANGE_FLAG since this could be exec # ########################################################## READ_ONLY_CHANGE_FLAG=1 + 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" == "Dockerfile" ]; then ################################ # Append the file to the array # @@ -1889,7 +1927,8 @@ Footer() [ "$ERRORS_FOUND_DOCKER" -ne 0 ] || \ [ "$ERRORS_FOUND_GO" -ne 0 ] || \ [ "$ERRORS_FOUND_TERRAFORM" -ne 0 ] || \ - [ "$ERRORS_FOUND_RUBY" -ne 0 ]; then + [ "$ERRORS_FOUND_RUBY" -ne 0 ] || \ + [ "$ERRORS_FOUND_CSS" -ne 0 ]; then # Failed exit echo "Exiting with errors found!" exit 1 @@ -1946,6 +1985,7 @@ RunTestCases() TestCodebase "DOCKER" "/dockerfilelint/bin/dockerfilelint" "/dockerfilelint/bin/dockerfilelint" ".*\(Dockerfile\)\$" TestCodebase "ANSIBLE" "ansible-lint" "ansible-lint -v -c $ANSIBLE_LINTER_RULES" "ansible-lint" TestCodebase "TERRAFORM" "tflint" "tflint -c $TERRAFORM_LINTER_RULES" ".*\.\(tf\)\$" + TestCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" ################# # Footer prints # @@ -2000,6 +2040,8 @@ GetLinterRules "$GO_FILE_NAME" "$GO_LINTER_RULES" GetLinterRules "$DOCKER_FILE_NAME" "$DOCKER_LINTER_RULES" # Get Terraform rules GetLinterRules "$TERRAFORM_FILE_NAME" "$TERRAFORM_LINTER_RULES" +# Get CSS rules +GetLinterRules "$CSS_FILE_NAME" "$CSS_LINTER_RULES" ################################# # Check if were in verbose mode # @@ -2215,6 +2257,20 @@ if [ "$VALIDATE_TYPESCRIPT_STANDARD" == "true" ]; then LintCodebase "TYPESCRIPT_STANDARD" "standard" "standard --parser @typescript-eslint/parser --plugin @typescript-eslint/eslint-plugin $TYPESCRIPT_STANDARD_LINTER_RULES" ".*\.\(ts\)\$" "${FILE_ARRAY_TYPESCRIPT_STANDARD[@]}" fi +############### +# CSS LINTING # +############### +if [ "$VALIDATE_CSS" == "true" ]; then + ################################# + # Get CSS standard rules # + ################################# + GetStandardRules "stylelint" + ############################# + # Lint the CSS files # + ############################# + LintCodebase "CSS" "stylelint" "stylelint --config $CSS_LINTER_RULES" ".*\.\(css\)\$" "${FILE_ARRAY_CSS[@]}" +fi + ################## # DOCKER LINTING # ##################