diff --git a/.automation/test/dart/README.md b/.automation/test/dart/README.md new file mode 100644 index 00000000..21299b50 --- /dev/null +++ b/.automation/test/dart/README.md @@ -0,0 +1,13 @@ +# Dart Test Cases +This folder holds the test cases for **Dart**. + +## 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/dart/dart_bad_1.dart b/.automation/test/dart/dart_bad_1.dart new file mode 100644 index 00000000..c8e4746e --- /dev/null +++ b/.automation/test/dart/dart_bad_1.dart @@ -0,0 +1,5 @@ +// empty_constructor_bodies bad {} +class Point { + int x, y; + Point(this.x, this.y) {} +} diff --git a/.automation/test/dart/dart_good_1.dart b/.automation/test/dart/dart_good_1.dart new file mode 100644 index 00000000..ba9c09c5 --- /dev/null +++ b/.automation/test/dart/dart_good_1.dart @@ -0,0 +1,5 @@ +// empty_constructor_bodies good ; +class Point { + int x, y; + Point(this.x, this.y); +} diff --git a/.github/linters/analysis_options.yaml b/.github/linters/analysis_options.yaml new file mode 100644 index 00000000..0c444f44 --- /dev/null +++ b/.github/linters/analysis_options.yaml @@ -0,0 +1,57 @@ +--- +########################## +########################## +## Dart Linter rules ## +########################## +########################## + +# Pedantic Rules +# https://github.com/dart-lang/pedantic + +linter: + rules: + - always_declare_return_types + - always_require_non_null_named_parameters + - annotate_overrides + - avoid_empty_else + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_relative_lib_imports + - avoid_return_types_on_setters + - avoid_shadowing_type_parameters + - avoid_types_as_parameter_names + - camel_case_extensions + - curly_braces_in_flow_control_structures + - empty_catches + - empty_constructor_bodies + - library_names + - library_prefixes + - no_duplicate_case_values + - null_closures + - omit_local_variable_types + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_contains + - prefer_equal_for_default_values + - prefer_final_fields + - prefer_for_elements_to_map_fromIterable + - prefer_generic_function_type_aliases + - prefer_if_null_operators + - prefer_is_empty + - prefer_is_not_empty + - prefer_iterable_whereType + - prefer_single_quotes + - prefer_spread_collections + - recursive_getters + - slash_for_doc_comments + - type_init_formals + - unawaited_futures + - unnecessary_const + - unnecessary_new + - unnecessary_null_in_if_null_operators + - unnecessary_this + - unrelated_type_equality_checks + - use_function_type_syntax_for_parameters + - use_rethrow_when_possible + - valid_regexps diff --git a/Dockerfile b/Dockerfile index 9b50bb40..494e97ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,6 +33,11 @@ ARG ARM_TTK_DIRECTORY='/opt/microsoft' ARG RAKU_VER="2020.06" ARG RAKU_INSTALL_PATH=/usr ARG RAKUBREW_HOME=/tmp/rakubrew +# Dart Linter +## stable dart sdk: https://dart.dev/get-dart#release-channels +ARG DART_VERSION='2.8.4' +## install alpine-pkg-glibc (glibc compatibility layer package for Alpine Linux) +ARG GLIBC_VERSION='2.31-r0' #################### # Run APK installs # @@ -159,6 +164,17 @@ COPY --from=borkdude/clj-kondo:2020.06.21 /usr/local/bin/clj-kondo /usr/bin/ RUN curl -sSLO https://github.com/pinterest/ktlint/releases/latest/download/ktlint && chmod a+x ktlint \ && mv "ktlint" /usr/bin/ +#################### +# Install dart-sdk # +#################### +RUN wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub +RUN wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/${GLIBC_VERSION}/glibc-${GLIBC_VERSION}.apk +RUN apk add --no-cache glibc-${GLIBC_VERSION}.apk +RUN wget https://storage.googleapis.com/dart-archive/channels/stable/release/${DART_VERSION}/sdk/dartsdk-linux-x64-release.zip -O - -q | unzip -q - \ + && chmod +x dart-sdk/bin/dart* \ + && mv dart-sdk/bin/* /usr/bin/ && mv dart-sdk/lib/* /usr/lib/ && mv dart-sdk/include/* /usr/include/ \ + && rm -r dart-sdk/ + ################ # Install Raku # ################ @@ -212,6 +228,7 @@ ENV GITHUB_SHA=${GITHUB_SHA} \ VALIDATE_HTML=${VALIDATE_HTML} \ VALIDATE_CLOJURE=${VALIDATE_CLOJURE} \ VALIDATE_KOTLIN=${VALIDATE_KOTLIN} \ + VALIDATE_DART=${VALIDATE_DART} \ VALIDATE_POWERSHELL=${VALIDATE_POWERSHELL} \ VALIDATE_ARM=${VALIDATE_ARM} \ VALIDATE_OPENAPI=${VALIDATE_OPENAPI} \ diff --git a/README.md b/README.md index 7f92eb13..14396934 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | **CSS** | [stylelint](https://stylelint.io/) | | **Clojure** | [clj-kondo](https://github.com/borkdude/clj-kondo) | | **CoffeeScript** | [coffeelint](https://coffeelint.github.io/) | +| **Dart** | [dartanalyzer](https://dart.dev/guides/language/analysis-options) | | **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) | @@ -184,6 +185,7 @@ and won't run anything unexpected. | **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_DART** | `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. | diff --git a/docs/disabling-linters.md b/docs/disabling-linters.md index fb622005..5620860d 100644 --- a/docs/disabling-linters.md +++ b/docs/disabling-linters.md @@ -678,6 +678,35 @@ import package.b.* -------------------------------------------------------------------------------- +## Dart +- [dartanalyzer](https://dart.dev/tools/dartanalyzer) + +### dartanalyzer standard Config file +- `.github/linters/.dart-lint.yml` +- You can pass multiple rules and overwrite default rules +- File should be located at: `.github/linters/.dart-lint.yml` + +### dartanalyzer disable single line +```dart +int x = ''; // ignore: invalid_assignment +``` + +### dartanalyzer disable code block +- You can make [rule exceptions](https://dart.dev/guides/language/analysis-options#excluding-code-from-analysis) for the entire file. +```dart +// ignore_for_file: unused_import, unused_local_variable +``` + +### dartanalyzer disable entire file +- You can disable entire files with the `analyzer.exclude` property in `.dart-lint.yml` +```dart +analyzer: + exclude: + - file +``` + +-------------------------------------------------------------------------------- + ## OpenAPI - [spectral](https://github.com/stoplightio/spectral) diff --git a/lib/buildFileList.sh b/lib/buildFileList.sh index 06f0110f..ea152a4b 100755 --- a/lib/buildFileList.sh +++ b/lib/buildFileList.sh @@ -385,6 +385,15 @@ function BuildFileList() { ############################ # Get the Protocol Buffers files # ############################ + elif [ "$FILE_TYPE" == "dart" ]; then + ################################ + # Append the file to the array # + ################################ + FILE_ARRAY_DART+=("$FILE") + ########################################################## + # Set the READ_ONLY_CHANGE_FLAG since this could be exec # + ########################################################## + READ_ONLY_CHANGE_FLAG=1 elif [ "$FILE_TYPE" == "proto" ]; then ################################ # Append the file to the array # diff --git a/lib/linter.sh b/lib/linter.sh index 03a601c0..451fec90 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -80,6 +80,9 @@ PROTOBUF_LINTER_RULES="$DEFAULT_RULES_LOCATION/$PROTOBUF_FILE_NAME" # Path t # Clojure Vars 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 +# Dart Vars +DART_FILE_NAME='analysis_options.yaml' # Name of the file +DART_LINTER_RULES="$DEFAULT_RULES_LOCATION/$DART_FILE_NAME" # Path to the DART 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 @@ -91,7 +94,7 @@ LINTER_ARRAY=("jsonlint" "yamllint" "xmllint" "markdownlint" "shellcheck" "pylint" "perl" "raku" "rubocop" "coffeelint" "eslint" "standard" "ansible-lint" "dockerfilelint" "golangci-lint" "tflint" "stylelint" "dotenv-linter" "pwsh" "arm-ttk" "ktlint" "protolint" "clj-kondo" - "spectral" "cfn-lint" "htmlhint") + "spectral" "cfn-lint" "dart" "htmlhint") ############################# # Language array for prints # @@ -100,7 +103,7 @@ LANGUAGE_ARRAY=('YML' 'JSON' 'XML' 'MARKDOWN' 'BASH' 'PERL' 'RAKU' 'PHP' 'RUBY' 'COFFEESCRIPT' 'ANSIBLE' 'JAVASCRIPT_STANDARD' 'JAVASCRIPT_ES' 'JSX' 'TSX' 'TYPESCRIPT_STANDARD' 'TYPESCRIPT_ES' 'DOCKER' 'GO' 'TERRAFORM' 'CSS' 'ENV' 'POWERSHELL' 'ARM' 'KOTLIN' 'PROTOBUF' 'CLOJURE' 'OPENAPI' - 'CFN' 'HTML') + 'CFN' 'DART' 'HTML') ################### # GitHub ENV Vars # @@ -140,6 +143,7 @@ VALIDATE_POWERSHELL="${VALIDATE_POWERSHELL}" # Boolean to vali 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_DART="${VALIDATE_DART}" # 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 @@ -214,6 +218,7 @@ 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_DART=() # Array of files to check FILE_ARRAY_HTML=() # Array of files to check ############ @@ -249,6 +254,7 @@ 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_DART=0 # Count of errors found ERRORS_FOUND_HTML=0 # Count of errors found ################################################################################ @@ -817,6 +823,7 @@ Footer() { [ "$ERRORS_FOUND_PROTOBUF" -ne 0 ] || [ "$ERRORS_FOUND_CLOJURE" -ne 0 ] || [ "$ERRORS_FOUND_KOTLIN" -ne 0 ] || + [ "$ERRORS_FOUND_DART" -ne 0 ] || [ "$ERRORS_FOUND_HTML" -ne 0 ]; then # Failed exit echo -e "${NC}${F[R]}Exiting with errors found!${NC}" @@ -899,6 +906,8 @@ GetLinterRules "ARM" GetLinterRules "CSS" # Get CFN rules GetLinterRules "CFN" +# Get DART rules +GetLinterRules "DART" # Get HTML rules GetLinterRules "HTML" @@ -1222,6 +1231,17 @@ if [ "$VALIDATE_EDITORCONFIG" == "true" ]; then LintCodebase "EDITORCONFIG" "editorconfig-checker" "editorconfig-checker" "^.*$" "${FILE_ARRAY_ENV[@]}" fi +################## +# DART LINTING # +################## +if [ "$VALIDATE_DART" == "true" ]; then + ####################### + # Lint the Dart files # + ####################### + # LintCodebase "FILE_TYPE" "LINTER_NAME" "LINTER_CMD" "FILE_TYPES_REGEX" "FILE_ARRAY" + LintCodebase "DART" "dart" "pub get || true && dartanalyzer --fatal-infos --fatal-warnings --options $DART_LINTER_RULES" ".*\.\(dart\)\$" "${FILE_ARRAY_DART[@]}" +fi + ################## # DOCKER LINTING # ################## diff --git a/lib/validation.sh b/lib/validation.sh index 8782e326..cc25f430 100755 --- a/lib/validation.sh +++ b/lib/validation.sh @@ -76,6 +76,7 @@ function GetValidationInfo() { 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_DART=$(echo "$VALIDATE_DART" | awk '{print tolower($0)}') VALIDATE_HTML=$(echo "$VALIDATE_HTML" | awk '{print tolower($0)}') ################################################ @@ -109,6 +110,7 @@ function GetValidationInfo() { $VALIDATE_PROTOBUF || -n \ $VALIDATE_OPENAPI || -n \ $VALIDATE_KOTLIN || -n \ + $VALIDATE_DART || -n \ $VALIDATE_EDITORCONFIG || -n \ $VALIDATE_HTML ]]; then ANY_SET="true" @@ -478,6 +480,20 @@ function GetValidationInfo() { VALIDATE_KOTLIN="true" fi + #################################### + # Validate if we should check DART # + #################################### + if [[ $ANY_SET == "true" ]]; then + # Some linter flags were set - only run those set to true + if [[ -z $VALIDATE_DART ]]; then + # ENV flag was not set - default to false + VALIDATE_DART="false" + fi + else + # No linter flags were set - default all to true + VALIDATE_DART="true" + fi + ####################################### # Validate if we should check OPENAPI # ####################################### @@ -689,6 +705,11 @@ function GetValidationInfo() { else PRINT_ARRAY+=("- Excluding [PROTOBUF] files in code base...") fi + if [[ $VALIDATE_DART == "true" ]]; then + PRINT_ARRAY+=("- Validating [DART] files in code base...") + else + PRINT_ARRAY+=("- Excluding [DART] files in code base...") + fi if [[ $VALIDATE_EDITORCONFIG == "true" ]]; then PRINT_ARRAY+=("- Validating [EDITORCONFIG] files in code base...") else diff --git a/lib/worker.sh b/lib/worker.sh index 72bc735b..6310891b 100755 --- a/lib/worker.sh +++ b/lib/worker.sh @@ -526,6 +526,7 @@ function RunTestCases() { 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 "DART" "dart" "dartanalyzer --fatal-infos --fatal-warnings --options $DART_LINTER_RULES" ".*\.\(dart\)\$" "dart" TestCodebase "HTML" "htmlhint" "htmlhint --config $HTML_LINTER_RULES" ".*\.\(html\)\$" "html" #################