diff --git a/.automation/test/python_black/python_good_1.py b/.automation/test/python_black/python_good_1.py index 8106d8d8..b3b4e7d1 100644 --- a/.automation/test/python_black/python_good_1.py +++ b/.automation/test/python_black/python_good_1.py @@ -1,11 +1,11 @@ import json +import sys from os import getenv, path from pprint import pprint -import sys import click # pylint: disable=import-error -from dotenv import load_dotenv # pylint: disable=import-error import requests # pylint: disable=import-error +from dotenv import load_dotenv # pylint: disable=import-error env = load_dotenv() api_url = getenv("API_URL", default="https://api.github.com/graphql") diff --git a/.automation/test/python_flake8/python_good_1.py b/.automation/test/python_flake8/python_good_1.py index 8106d8d8..b3b4e7d1 100644 --- a/.automation/test/python_flake8/python_good_1.py +++ b/.automation/test/python_flake8/python_good_1.py @@ -1,11 +1,11 @@ import json +import sys from os import getenv, path from pprint import pprint -import sys import click # pylint: disable=import-error -from dotenv import load_dotenv # pylint: disable=import-error import requests # pylint: disable=import-error +from dotenv import load_dotenv # pylint: disable=import-error env = load_dotenv() api_url = getenv("API_URL", default="https://api.github.com/graphql") diff --git a/.automation/test/python_isort/README.md b/.automation/test/python_isort/README.md new file mode 100644 index 00000000..aa9bb375 --- /dev/null +++ b/.automation/test/python_isort/README.md @@ -0,0 +1,19 @@ +# Python Test Cases + +This folder holds the test cases for **Python**. + +## 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/python_isort/python_bad_1.py b/.automation/test/python_isort/python_bad_1.py new file mode 100644 index 00000000..8106d8d8 --- /dev/null +++ b/.automation/test/python_isort/python_bad_1.py @@ -0,0 +1,195 @@ +import json +from os import getenv, path +from pprint import pprint +import sys + +import click # pylint: disable=import-error +from dotenv import load_dotenv # pylint: disable=import-error +import requests # pylint: disable=import-error + +env = load_dotenv() +api_url = getenv("API_URL", default="https://api.github.com/graphql") +github_token = getenv("GITHUB_TOKEN", default=None) + +if github_token is None: + sys.exit( + "GitHub Token is not set." + + "Please set the GITHUB_TOKEN env variable in your system or " + + "the .env file of your project." + ) + +client_id = getenv("CLIENT_ID", default="copy_labels.py") +headers = { + "Authorization": "bearer {github_token}".format(github_token=github_token), + "Accept": "application/vnd.github.bane-preview+json", + "Content-Type": "application/json", +} + + +def create_label(repo_id, label): + """ + Create label in the supplied repo. + + :param repo_id: Unique ID that represents the repo in GitHub + :type repo_id: str + :param label: Object with label information. + :type label: dict + :return: GitHub API request response + """ + + query_variables = { + "createLabelInput": { + "color": label["color"], + "description": label["description"], + "name": label["name"], + "repositoryId": repo_id, + } + } + + with open( + path.join(path.dirname(__file__), "queries/create_label.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + response = requests.post(api_url, data=json.dumps(payload), headers=headers).json() + print("Created label {label}".format(label=label["name"])) + + return response + + +def get_labels(owner, repo): + """ + Gets a list of labels from the supplied repo. + :param owner: Repo owner GitHub login. + :type owner: str + :param repo: Repository name. + :type repo: str + :return: A tuple with the GitHub id for the repository and a list of labels defined in the repository + """ + + query_variables = { + "owner": owner, + "name": repo, + } + + with open( + path.join(path.dirname(__file__), "queries/get_repo_data.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + response = requests.post(api_url, data=json.dumps(payload), headers=headers) + + status_code = response.status_code + result = response.json() + + if status_code >= 200 and status_code <= 300: + repo_id = result["data"]["repository"]["id"] + labels = result["data"]["repository"]["labels"]["nodes"] + + return repo_id, labels + else: + raise Exception( + "[ERROR] getting issue labels. Status Code: {status_code} - Message: {result}".format( + status_code=status_code, result=result["message"] + ) + ) + + +def delete_label(label_id): + """ + Delete the specified label + :param label_id: Label's node id. + :type label_id: str + :return: GitHub API request response. + """ + + query_variables = { + "deleteLabelInput": {"clientMutationId": client_id, "id": label_id} + } + + with open( + path.join(path.dirname(__file__), "queries/delete_label.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + result = requests.post(api_url, data=json.dumps(payload), headers=headers).json() + + return result + + +@click.command() +@click.option("--dry", is_flag=True) +@click.argument("source_repo") +@click.argument("target_repo") +def copy_labels(source_repo, target_repo, dry): + """ + Copy labels from the source repository to the target repository. + \f + :param source: The full name of a GitHub repo from where the labels will be copied from. Eg. github/opensourcefriday + :type source: str + :param target: The full name of a GitHub repo to where the labels will be copied. Eg. github/opensourcefriday + :type target: str + :return: + """ + source_owner, source_repo_name = source_repo.split("/") + target_owner, target_repo_name = target_repo.split("/") + + try: + print( + "Fetching labels for {source_repo_name} repo.".format( + source_repo_name=source_repo_name + ) + ) + _, source_repo_labels = get_labels(source_owner, source_repo_name) + print( + "Fetched labels for {source_repo_name}".format( + source_repo_name=source_repo_name + ) + ) + + print( + "Fetching labels for {target_repo_name} repo.".format( + target_repo_name=target_repo_name + ) + ) + target_repo_id, target_repo_labels = get_labels(target_owner, target_repo_name) + print( + "Fetched labels for {target_repo_name}".format( + target_repo_name=target_repo_name + ) + ) + + filtered_labels = list( + filter(lambda x: x not in target_repo_labels, source_repo_labels) + ) + + if dry: + print("This is just a dry run. No labels will be copied/created.") + print( + "{label_count} labels would have been created.".format( + label_count=len(filtered_labels) + ) + ) + pprint(filtered_labels, indent=4) + else: + print( + "Preparing to created {label_count} labels in {target_repo}".format( + label_count=len(filtered_labels), target_repo=target_repo + ) + ) + + for label in filtered_labels: + create_label(target_repo_id, label) + except Exception as error: + sys.exit(error) + + print("Done") + + +if __name__ == "__main__": + # Pylint doesn't know that @click.command takes care of injecting the + # function parameters. Disabling Pylint error. + copy_labels() # pylint: disable=no-value-for-parameter diff --git a/.automation/test/python_isort/python_good_1.py b/.automation/test/python_isort/python_good_1.py new file mode 100644 index 00000000..b3b4e7d1 --- /dev/null +++ b/.automation/test/python_isort/python_good_1.py @@ -0,0 +1,195 @@ +import json +import sys +from os import getenv, path +from pprint import pprint + +import click # pylint: disable=import-error +import requests # pylint: disable=import-error +from dotenv import load_dotenv # pylint: disable=import-error + +env = load_dotenv() +api_url = getenv("API_URL", default="https://api.github.com/graphql") +github_token = getenv("GITHUB_TOKEN", default=None) + +if github_token is None: + sys.exit( + "GitHub Token is not set." + + "Please set the GITHUB_TOKEN env variable in your system or " + + "the .env file of your project." + ) + +client_id = getenv("CLIENT_ID", default="copy_labels.py") +headers = { + "Authorization": "bearer {github_token}".format(github_token=github_token), + "Accept": "application/vnd.github.bane-preview+json", + "Content-Type": "application/json", +} + + +def create_label(repo_id, label): + """ + Create label in the supplied repo. + + :param repo_id: Unique ID that represents the repo in GitHub + :type repo_id: str + :param label: Object with label information. + :type label: dict + :return: GitHub API request response + """ + + query_variables = { + "createLabelInput": { + "color": label["color"], + "description": label["description"], + "name": label["name"], + "repositoryId": repo_id, + } + } + + with open( + path.join(path.dirname(__file__), "queries/create_label.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + response = requests.post(api_url, data=json.dumps(payload), headers=headers).json() + print("Created label {label}".format(label=label["name"])) + + return response + + +def get_labels(owner, repo): + """ + Gets a list of labels from the supplied repo. + :param owner: Repo owner GitHub login. + :type owner: str + :param repo: Repository name. + :type repo: str + :return: A tuple with the GitHub id for the repository and a list of labels defined in the repository + """ + + query_variables = { + "owner": owner, + "name": repo, + } + + with open( + path.join(path.dirname(__file__), "queries/get_repo_data.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + response = requests.post(api_url, data=json.dumps(payload), headers=headers) + + status_code = response.status_code + result = response.json() + + if status_code >= 200 and status_code <= 300: + repo_id = result["data"]["repository"]["id"] + labels = result["data"]["repository"]["labels"]["nodes"] + + return repo_id, labels + else: + raise Exception( + "[ERROR] getting issue labels. Status Code: {status_code} - Message: {result}".format( + status_code=status_code, result=result["message"] + ) + ) + + +def delete_label(label_id): + """ + Delete the specified label + :param label_id: Label's node id. + :type label_id: str + :return: GitHub API request response. + """ + + query_variables = { + "deleteLabelInput": {"clientMutationId": client_id, "id": label_id} + } + + with open( + path.join(path.dirname(__file__), "queries/delete_label.gql"), "r" + ) as query_file: + query = "".join(query_file.readlines()) + + payload = {"query": query, "variables": query_variables} + result = requests.post(api_url, data=json.dumps(payload), headers=headers).json() + + return result + + +@click.command() +@click.option("--dry", is_flag=True) +@click.argument("source_repo") +@click.argument("target_repo") +def copy_labels(source_repo, target_repo, dry): + """ + Copy labels from the source repository to the target repository. + \f + :param source: The full name of a GitHub repo from where the labels will be copied from. Eg. github/opensourcefriday + :type source: str + :param target: The full name of a GitHub repo to where the labels will be copied. Eg. github/opensourcefriday + :type target: str + :return: + """ + source_owner, source_repo_name = source_repo.split("/") + target_owner, target_repo_name = target_repo.split("/") + + try: + print( + "Fetching labels for {source_repo_name} repo.".format( + source_repo_name=source_repo_name + ) + ) + _, source_repo_labels = get_labels(source_owner, source_repo_name) + print( + "Fetched labels for {source_repo_name}".format( + source_repo_name=source_repo_name + ) + ) + + print( + "Fetching labels for {target_repo_name} repo.".format( + target_repo_name=target_repo_name + ) + ) + target_repo_id, target_repo_labels = get_labels(target_owner, target_repo_name) + print( + "Fetched labels for {target_repo_name}".format( + target_repo_name=target_repo_name + ) + ) + + filtered_labels = list( + filter(lambda x: x not in target_repo_labels, source_repo_labels) + ) + + if dry: + print("This is just a dry run. No labels will be copied/created.") + print( + "{label_count} labels would have been created.".format( + label_count=len(filtered_labels) + ) + ) + pprint(filtered_labels, indent=4) + else: + print( + "Preparing to created {label_count} labels in {target_repo}".format( + label_count=len(filtered_labels), target_repo=target_repo + ) + ) + + for label in filtered_labels: + create_label(target_repo_id, label) + except Exception as error: + sys.exit(error) + + print("Done") + + +if __name__ == "__main__": + # Pylint doesn't know that @click.command takes care of injecting the + # function parameters. Disabling Pylint error. + copy_labels() # pylint: disable=no-value-for-parameter diff --git a/.automation/test/python_isort/reports/expected-PYTHON.tap.ignored b/.automation/test/python_isort/reports/expected-PYTHON.tap.ignored new file mode 100644 index 00000000..1751d70f --- /dev/null +++ b/.automation/test/python_isort/reports/expected-PYTHON.tap.ignored @@ -0,0 +1,7 @@ +TAP version 13 +1..2 +not ok 1 - python_bad_1.py + --- + message: ************* Module python_bad_1\npython/python_bad_1.py 15 24 E0001 invalid syntax (, line 15) (syntax-error)\n + ... +ok 2 - python_good_1.py diff --git a/.automation/test/python_pylint/python_good_1.py b/.automation/test/python_pylint/python_good_1.py index 8106d8d8..b3b4e7d1 100644 --- a/.automation/test/python_pylint/python_good_1.py +++ b/.automation/test/python_pylint/python_good_1.py @@ -1,11 +1,11 @@ import json +import sys from os import getenv, path from pprint import pprint -import sys import click # pylint: disable=import-error -from dotenv import load_dotenv # pylint: disable=import-error import requests # pylint: disable=import-error +from dotenv import load_dotenv # pylint: disable=import-error env = load_dotenv() api_url = getenv("API_URL", default="https://api.github.com/graphql") diff --git a/README.md b/README.md index 7cab415b..49806ec5 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Developers on **GitHub** can call the **GitHub Action** to lint their code base | **PHP** | [PHP built-in linter](https://www.php.net/) / [PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) / [PHPStan](https://phpstan.org/n) / [Psalm](https://psalm.dev/) | | **PowerShell** | [PSScriptAnalyzer](https://github.com/PowerShell/Psscriptanalyzer) | | **Protocol Buffers** | [protolint](https://github.com/yoheimuta/protolint) | -| **Python3** | [pylint](https://www.pylint.org/) / [flake8](https://flake8.pycqa.org/en/latest/) / [black](https://github.com/psf/black) | +| **Python3** | [pylint](https://www.pylint.org/) / [flake8](https://flake8.pycqa.org/en/latest/) / [black](https://github.com/psf/black) / [isort](https://pypi.org/project/isort/) | | **R** | [lintr](https://github.com/jimhester/lintr) | | **Raku** | [Raku](https://raku.org) | | **Ruby** | [RuboCop](https://github.com/rubocop-hq/rubocop) | @@ -224,9 +224,10 @@ But if you wish to select or exclude specific linters, we give you full control | **OUTPUT_FORMAT** | `none` | The report format to be generated, besides the stdout one. Output format of tap is currently using v13 of the specification. Supported formats: tap | | **OUTPUT_FOLDER** | `super-linter.report` | The location where the output reporting will be generated to. Output folder must not previously exist. | | **OUTPUT_DETAILS** | `simpler` | What level of details to be reported. Supported formats: simpler or detailed. | -| **PYTHON_PYLINT_CONFIG_FILE** | `.python-lint` | Filename for [pylint configuration](https://pylint.pycqa.org/en/latest/user_guide/run.html?highlight=rcfile#command-line-options) (ex: `.python-lint`, `.pylintrc`) | -| **PYTHON_FLAKE8_CONFIG_FILE** | `.flake8` | Filename for [flake8 configuration](https://flake8.pycqa.org/en/latest/user/configuration.html) (ex: `.flake8`, `tox.ini`) | | **PYTHON_BLACK_CONFIG_FILE** | `.python-black` | Filename for [black configuration](https://github.com/psf/black/blob/master/docs/compatible_configs.md) (ex: `.isort.cfg`, `pyproject.toml`) | +| **PYTHON_FLAKE8_CONFIG_FILE** | `.flake8` | Filename for [flake8 configuration](https://flake8.pycqa.org/en/latest/user/configuration.html) (ex: `.flake8`, `tox.ini`) | +| **PYTHON_ISORT_CONFIG_FILE** | `.isort.cfg` | Filename for [isort configuration](https://pycqa.github.io/isort/docs/configuration/config_files/) (ex: `.isort.cfg`, `pyproject.toml`) | +| **PYTHON_PYLINT_CONFIG_FILE** | `.python-lint` | Filename for [pylint configuration](https://pylint.pycqa.org/en/latest/user_guide/run.html?highlight=rcfile#command-line-options) (ex: `.python-lint`, `.pylintrc`) | | **RUBY_CONFIG_FILE** | `.ruby-lint.yml` | Filename for [rubocop configuration](https://docs.rubocop.org/rubocop/configuration.html) (ex: `.ruby-lint.yml`, `.rubocop.yml`) | | **SNAKEMAKE_SNAKEFMT_CONFIG_FILE**| `.snakefmt.toml` | Filename for [Snakemake configuration](https://github.com/snakemake/snakefmt#configuration) (ex: `pyproject.toml`, `.snakefmt.toml`) | | **TYPESCRIPT_ES_CONFIG_FILE** | `.eslintrc.yml` | Filename for [eslint configuration](https://eslint.org/docs/user-guide/configuring#configuration-file-formats) (ex: `.eslintrc.yml`, `.eslintrc.json`) | @@ -237,7 +238,7 @@ But if you wish to select or exclude specific linters, we give you full control | **VALIDATE_BASH_EXEC** | `true` | Flag to enable or disable the linting process of the Bash language to validate if file is stored as executable. | | **VALIDATE_CLOJURE** | `true` | Flag to enable or disable the linting process of the Clojure language. | | **VALIDATE_CLOUDFORMATION** | `true` | Flag to enable or disable the linting process of the AWS Cloud Formation language. | -| **VALIDATE_COFFEE** | `true` | Flag to enable or disable the linting process of the Coffeescript language. | +| **VALIDATE_COFFEE** | `true` | Flag to enable or disable the linting process of the Coffeescript language. | | **VALIDATE_CSHARP** | `true` | Flag to enable or disable the linting process of the C# language. | | **VALIDATE_CSS** | `true` | Flag to enable or disable the linting process of the CSS language. | | **VALIDATE_DART** | `true` | Flag to enable or disable the linting process of the Dart language. | @@ -267,9 +268,10 @@ But if you wish to select or exclude specific linters, we give you full control | **VALIDATE_PHP_PSALM** | `true` | Flag to enable or disable the linting process of the PHP language. (Utilizing: PSalm) | | **VALIDATE_PROTOBUF** | `true` | Flag to enable or disable the linting process of the Protobuf language. | | **VALIDATE_PYTHON** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: pylint) (keep for backward compatibility) | -| **VALIDATE_PYTHON_PYLINT** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: pylint) | -| **VALIDATE_PYTHON_FLAKE8** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: flake8) | | **VALIDATE_PYTHON_BLACK** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: black) | +| **VALIDATE_PYTHON_FLAKE8** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: flake8) | +| **VALIDATE_PYTHON_ISORT** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: isort) | +| **VALIDATE_PYTHON_PYLINT** | `true` | Flag to enable or disable the linting process of the Python language. (Utilizing: pylint) | | **VALIDATE_POWERSHELL** | `true` | Flag to enable or disable the linting process of the Powershell language. | | **VALIDATE_R** | `true` | Flag to enable or disable the linting process of the R language. | | **VALIDATE_RAKU** | `true` | Flag to enable or disable the linting process of the Raku language. | diff --git a/TEMPLATES/.isort.cfg b/TEMPLATES/.isort.cfg new file mode 100644 index 00000000..a865f55c --- /dev/null +++ b/TEMPLATES/.isort.cfg @@ -0,0 +1,2 @@ +[isort] +profile= diff --git a/dependencies/Pipfile b/dependencies/Pipfile index be003acf..67935d25 100644 --- a/dependencies/Pipfile +++ b/dependencies/Pipfile @@ -10,6 +10,7 @@ black = ">=20" cfn-lint = "*" flake8 = "*" pylint = "*" +isort = "*" snakefmt = "*" snakemake = "*" yamllint = "*" diff --git a/lib/buildFileList.sh b/lib/buildFileList.sh index cd3229a4..fb057f16 100755 --- a/lib/buildFileList.sh +++ b/lib/buildFileList.sh @@ -431,6 +431,7 @@ function BuildFileList() { FILE_ARRAY_PYTHON_BLACK+=("${FILE}") FILE_ARRAY_PYTHON_PYLINT+=("${FILE}") FILE_ARRAY_PYTHON_FLAKE8+=("${FILE}") + FILE_ARRAY_PYTHON_ISORT+=("${FILE}") ###################### # Get the RAKU files # diff --git a/lib/linter.sh b/lib/linter.sh index c4d8b941..f63d4756 100755 --- a/lib/linter.sh +++ b/lib/linter.sh @@ -109,6 +109,8 @@ PYTHON_BLACK_FILE_NAME="${PYTHON_BLACK_CONFIG_FILE:-.python-black}" # shellcheck disable=SC2034 # Variable is referenced indirectly PYTHON_FLAKE8_FILE_NAME="${PYTHON_FLAKE8_CONFIG_FILE:-.flake8}" # shellcheck disable=SC2034 # Variable is referenced indirectly +PYTHON_ISORT_FILE_NAME="${PYTHON_ISORT_CONFIG_FILE:-.isort.cfg}" +# shellcheck disable=SC2034 # Variable is referenced indirectly PYTHON_PYLINT_FILE_NAME="${PYTHON_PYLINT_CONFIG_FILE:-.python-lint}" # shellcheck disable=SC2034 # Variable is referenced indirectly R_FILE_NAME=".lintr" @@ -136,7 +138,7 @@ LANGUAGE_ARRAY=('ANSIBLE' 'ARM' 'BASH' 'BASH_EXEC' 'CLOUDFORMATION' 'CLOJURE' 'C 'DART' 'DOCKERFILE' 'DOCKERFILE_HADOLINT' 'EDITORCONFIG' 'ENV' 'GO' 'GROOVY' 'HTML' 'JAVA' 'JAVASCRIPT_ES' 'JAVASCRIPT_STANDARD' 'JSON' 'JSX' 'KUBERNETES_KUBEVAL' 'KOTLIN' 'LATEX' 'LUA' 'MARKDOWN' 'OPENAPI' 'PERL' 'PHP_BUILTIN' 'PHP_PHPCS' 'PHP_PHPSTAN' 'PHP_PSALM' 'POWERSHELL' - 'PROTOBUF' 'PYTHON_BLACK' 'PYTHON_PYLINT' 'PYTHON_FLAKE8' 'R' 'RAKU' 'RUBY' 'SHELL_SHFMT' 'SNAKEMAKE_LINT' 'SNAKEMAKE_SNAKEFMT' 'STATES' 'SQL' + 'PROTOBUF' 'PYTHON_BLACK' 'PYTHON_PYLINT' 'PYTHON_FLAKE8' 'PYTHON_ISORT' 'R' 'RAKU' 'RUBY' 'SHELL_SHFMT' 'SNAKEMAKE_LINT' 'SNAKEMAKE_SNAKEFMT' 'STATES' 'SQL' 'TEKTON' 'TERRAFORM' 'TERRAFORM_TERRASCAN' 'TERRAGRUNT' 'TSX' 'TYPESCRIPT_ES' 'TYPESCRIPT_STANDARD' 'XML' 'YAML') ############################## @@ -181,6 +183,7 @@ LINTER_NAMES_ARRAY['PROTOBUF']="protolint" LINTER_NAMES_ARRAY['PYTHON_BLACK']="black" LINTER_NAMES_ARRAY['PYTHON_PYLINT']="pylint" LINTER_NAMES_ARRAY['PYTHON_FLAKE8']="flake8" +LINTER_NAMES_ARRAY['PYTHON_ISORT']="isort" LINTER_NAMES_ARRAY['R']="R" LINTER_NAMES_ARRAY['RAKU']="raku" LINTER_NAMES_ARRAY['RUBY']="rubocop" @@ -1183,6 +1186,7 @@ LINTER_COMMANDS_ARRAY['PROTOBUF']="protolint lint --config_path ${PROTOBUF_LINTE LINTER_COMMANDS_ARRAY['PYTHON_BLACK']="black --config ${PYTHON_BLACK_LINTER_RULES} --diff --check" LINTER_COMMANDS_ARRAY['PYTHON_PYLINT']="pylint --rcfile ${PYTHON_PYLINT_LINTER_RULES}" LINTER_COMMANDS_ARRAY['PYTHON_FLAKE8']="flake8 --config=${PYTHON_FLAKE8_LINTER_RULES}" +LINTER_COMMANDS_ARRAY['PYTHON_ISORT']="isort --check --diff --sp ${PYTHON_ISORT_LINTER_RULES}" LINTER_COMMANDS_ARRAY['R']="lintr" LINTER_COMMANDS_ARRAY['RAKU']="raku" LINTER_COMMANDS_ARRAY['RUBY']="rubocop -c ${RUBY_LINTER_RULES} --force-exclusion" diff --git a/lib/linterVersions.sh b/lib/linterVersions.sh index d21a2dc3..9046895c 100755 --- a/lib/linterVersions.sh +++ b/lib/linterVersions.sh @@ -23,7 +23,7 @@ ARM_TTK_PSD1='/usr/bin/arm-ttk' # Powershell var ####################################### LINTER_ARRAY=('ansible-lint' 'arm-ttk' 'asl-validator' 'bash-exec' 'black' 'cfn-lint' 'checkstyle' 'chktex' 'clj-kondo' 'coffeelint' 'dotnet-format' 'dart' 'dockerfilelint' 'dotenv-linter' 'editorconfig-checker' 'eslint' 'flake8' 'golangci-lint' - 'hadolint' 'htmlhint' 'jsonlint' 'kubeval' 'ktlint' 'lintr' 'lua' 'markdownlint' 'npm-groovy-lint' 'perl' 'protolint' + 'hadolint' 'htmlhint' 'isort' 'jsonlint' 'kubeval' 'ktlint' 'lintr' 'lua' 'markdownlint' 'npm-groovy-lint' 'perl' 'protolint' 'pwsh' 'pylint' 'raku' 'rubocop' 'shellcheck' 'shfmt' 'spectral' 'standard' 'stylelint' 'sql-lint' 'tekton-lint' 'terrascan' 'tflint' 'xmllint' 'yamllint')