From 1b65a13b9a8f87fb08d4ed834e9fcea03422c166 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:07:36 -0500 Subject: [PATCH 01/17] Update params.py --- azdev/params.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/azdev/params.py b/azdev/params.py index d49d66508..6fc528aed 100644 --- a/azdev/params.py +++ b/azdev/params.py @@ -66,6 +66,9 @@ def load_arguments(self, _): c.argument('report', action='store_true', help='Display results as a report.') c.argument('untested_params', nargs='+', help='Space-separated list of param dest values to search for (OR logic)') + with ArgumentsContext(self, 'format') as c: + c.positional('modules', modules_type) + with ArgumentsContext(self, 'style') as c: c.positional('modules', modules_type) c.argument('pylint', action='store_true', help='Run pylint.') From 6dffd05f56bf9cd70b3665c2abc63ab6f9997eec Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:09:04 -0500 Subject: [PATCH 02/17] Update help.py --- azdev/help.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/azdev/help.py b/azdev/help.py index 39569df01..9b8e62e0e 100644 --- a/azdev/help.py +++ b/azdev/help.py @@ -99,6 +99,14 @@ """ +helps['format'] = """ + short-summary: Autoformat Python code (black). + examples: + - name: Autoformat Python code using Black. + text: azdev format +""" + + helps['style'] = """ short-summary: Check code style (pylint and PEP8). examples: From f755a8c65cb96c24d89c18c73959fec0b52104b5 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:10:28 -0500 Subject: [PATCH 03/17] Update commands.py --- azdev/commands.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/azdev/commands.py b/azdev/commands.py index 045a0d81b..0ba6da62f 100644 --- a/azdev/commands.py +++ b/azdev/commands.py @@ -21,6 +21,9 @@ def operation_group(name): with CommandGroup(self, '', operation_group('testtool')) as g: g.command('test', 'run_tests') + with CommandGroup(self, '', operation_group('format')) as g: + g.command('format', 'auto_format') + with CommandGroup(self, '', operation_group('style')) as g: g.command('style', 'check_style') From 4ce8ffa6cb8ad3173047856ee7368d3f1d6c1046 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:12:15 -0500 Subject: [PATCH 04/17] Create --- azdev/operations/format.py | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 azdev/operations/format.py diff --git a/azdev/operations/format.py b/azdev/operations/format.py new file mode 100644 index 000000000..6b860eb3d --- /dev/null +++ b/azdev/operations/format.py @@ -0,0 +1,95 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ----------------------------------------------------------------------------- + +from glob import glob +import multiprocessing +import os +import sys + +from knack.log import get_logger +from knack.util import CLIError, CommandResultItem + +from azdev.utilities import ( + display, heading, py_cmd, get_path_table, EXTENSION_PREFIX, + get_azdev_config, get_azdev_config_dir, require_azure_cli, filter_by_git_diff) + + +logger = get_logger(__name__) + + +# pylint: disable=too-many-statements +def auto_format(modules=None, git_source=None, git_target=None, git_repo=None): + + heading('Style Check') + + # allow user to run only on CLI or extensions + cli_only = modules == ['CLI'] + ext_only = modules == ['EXT'] + if cli_only or ext_only: + modules = None + + selected_modules = get_path_table(include_only=modules) + + # remove these two non-modules + selected_modules['core'].pop('azure-cli-nspkg', None) + selected_modules['core'].pop('azure-cli-command_modules-nspkg', None) + + black_result = None + + if cli_only: + ext_names = None + selected_modules['ext'] = {} + if ext_only: + mod_names = None + selected_modules['mod'] = {} + selected_modules['core'] = {} + + # filter down to only modules that have changed based on git diff + selected_modules = filter_by_git_diff(selected_modules, git_source, git_target, git_repo) + + if not any(selected_modules.values()): + raise CLIError('No modules selected.') + + mod_names = list(selected_modules['mod'].keys()) + list(selected_modules['core'].keys()) + ext_names = list(selected_modules['ext'].keys()) + + if mod_names: + display('Modules: {}\n'.format(', '.join(mod_names))) + if ext_names: + display('Extensions: {}\n'.format(', '.join(ext_names))) + + exit_code_sum = 0 + black_result = _run_black(selected_modules) + exit_code_sum += black_result.exit_code + + if black_result.error: + logger.error(black_result.error.output.decode('utf-8')) + logger.error('Black: FAILED\n') + else: + display('Black: PASSED\n') + + sys.exit(exit_code_sum) + + +def _run_black(modules): + + cli_paths = list(modules["core"].values()) + list(modules["mod"].values()) + ext_paths = list(modules["ext"].values()) + + def run(paths, rcfile, desc): + if not paths: + return None + logger.debug("Running on %s:\n%s", desc, "\n".join(paths)) + command = "black -l 120 {}".format( + " ".join(paths) + ) + return py_cmd(command, message="Running black on {}...".format(desc)) + + cli_config, ext_config = _config_file_path("black") + + cli_result = run(cli_paths, cli_config, "modules") + ext_result = run(ext_paths, ext_config, "extensions") + return _combine_command_result(cli_result, ext_result) From 62d468133fc95f389a05e0750e0c50b016d86bd5 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:14:17 -0500 Subject: [PATCH 05/17] Update __init__.py --- azdev/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdev/__init__.py b/azdev/__init__.py index 19ef82112..c52cb838c 100644 --- a/azdev/__init__.py +++ b/azdev/__init__.py @@ -4,4 +4,4 @@ # license information. # ----------------------------------------------------------------------------- -__VERSION__ = '0.1.40' +__VERSION__ = '0.1.41' From e3405ed9e2ecbbfc5f6ebff5516bd911e80d0244 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:16:15 -0500 Subject: [PATCH 06/17] Update format.py --- azdev/operations/format.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/azdev/operations/format.py b/azdev/operations/format.py index 6b860eb3d..9dc3784c7 100644 --- a/azdev/operations/format.py +++ b/azdev/operations/format.py @@ -23,7 +23,7 @@ # pylint: disable=too-many-statements def auto_format(modules=None, git_source=None, git_target=None, git_repo=None): - heading('Style Check') + heading('Autoformat') # allow user to run only on CLI or extensions cli_only = modules == ['CLI'] @@ -79,7 +79,7 @@ def _run_black(modules): cli_paths = list(modules["core"].values()) + list(modules["mod"].values()) ext_paths = list(modules["ext"].values()) - def run(paths, rcfile, desc): + def run(paths, desc): if not paths: return None logger.debug("Running on %s:\n%s", desc, "\n".join(paths)) @@ -88,8 +88,6 @@ def run(paths, rcfile, desc): ) return py_cmd(command, message="Running black on {}...".format(desc)) - cli_config, ext_config = _config_file_path("black") - - cli_result = run(cli_paths, cli_config, "modules") - ext_result = run(ext_paths, ext_config, "extensions") + cli_result = run(cli_paths, "modules") + ext_result = run(ext_paths, "extensions") return _combine_command_result(cli_result, ext_result) From a99a940fb7b3758e788d721266da9dec7c0d81e5 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:16:27 -0500 Subject: [PATCH 07/17] Update __init__.py --- azdev/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdev/__init__.py b/azdev/__init__.py index c52cb838c..7ee84e146 100644 --- a/azdev/__init__.py +++ b/azdev/__init__.py @@ -4,4 +4,4 @@ # license information. # ----------------------------------------------------------------------------- -__VERSION__ = '0.1.41' +__VERSION__ = '0.1.42' From bfaff3384fa3d78d236afead08b4fbdedc7bca57 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:18:18 -0500 Subject: [PATCH 08/17] Update format.py --- azdev/operations/format.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/azdev/operations/format.py b/azdev/operations/format.py index 9dc3784c7..0420dc04f 100644 --- a/azdev/operations/format.py +++ b/azdev/operations/format.py @@ -74,6 +74,33 @@ def auto_format(modules=None, git_source=None, git_target=None, git_repo=None): sys.exit(exit_code_sum) +def _combine_command_result(cli_result, ext_result): + + final_result = CommandResultItem(None) + + def apply_result(item): + if item: + final_result.exit_code += item.exit_code + if item.error: + if final_result.error: + try: + final_result.error.message += item.error.message + except AttributeError: + final_result.error.message += str(item.error) + else: + final_result.error = item.error + setattr(final_result.error, 'message', '') + if item.result: + if final_result.result: + final_result.result += item.result + else: + final_result.result = item.result + + apply_result(cli_result) + apply_result(ext_result) + return final_result + + def _run_black(modules): cli_paths = list(modules["core"].values()) + list(modules["mod"].values()) From 0e8ac4a46307014acdec532025ea9b52fa0e8e1f Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:18:27 -0500 Subject: [PATCH 09/17] Update __init__.py --- azdev/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdev/__init__.py b/azdev/__init__.py index 7ee84e146..29471e3f3 100644 --- a/azdev/__init__.py +++ b/azdev/__init__.py @@ -4,4 +4,4 @@ # license information. # ----------------------------------------------------------------------------- -__VERSION__ = '0.1.42' +__VERSION__ = '0.1.43' From 831139147ba0a842204997e23b5c65c8bfb1e514 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:19:54 -0500 Subject: [PATCH 10/17] Update format.py --- azdev/operations/format.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdev/operations/format.py b/azdev/operations/format.py index 0420dc04f..79281e9f5 100644 --- a/azdev/operations/format.py +++ b/azdev/operations/format.py @@ -69,7 +69,7 @@ def auto_format(modules=None, git_source=None, git_target=None, git_repo=None): logger.error(black_result.error.output.decode('utf-8')) logger.error('Black: FAILED\n') else: - display('Black: PASSED\n') + display('Black: COMPLETE\n') sys.exit(exit_code_sum) From 6b87b3d7665d1d1718fa434a44a78dfcce6fabf1 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:24:56 -0500 Subject: [PATCH 11/17] Update README.md --- README.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d2b5eb105..e519b1af7 100644 --- a/README.md +++ b/README.md @@ -133,15 +133,19 @@ For instructions on manually writing the commands and tests, see more in - [Authoring Tests](https://github.com/Azure/azure-cli/blob/dev/doc/authoring_tests.md) ## Style, linter check and testing -1. Check code style (Pylint and PEP8): +1. Auto format code (Black): + ``` + azdev format + ``` +2. Check code style (Pylint and PEP8): ``` azdev style ``` -2. Run static code checks of the CLI command table: +3. Run static code checks of the CLI command table: ``` azdev linter ``` -3. Record or replay CLI tests: +4. Record or replay CLI tests: ``` azdev test ``` From 08f65e8544989655236676bf9010eb03aa9c4675 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:28:56 -0500 Subject: [PATCH 12/17] Update __init__.py --- azdev/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azdev/__init__.py b/azdev/__init__.py index 29471e3f3..c52cb838c 100644 --- a/azdev/__init__.py +++ b/azdev/__init__.py @@ -4,4 +4,4 @@ # license information. # ----------------------------------------------------------------------------- -__VERSION__ = '0.1.43' +__VERSION__ = '0.1.41' From c7fe502893f60d3486418014f9dbd44bb4a65918 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:31:49 -0500 Subject: [PATCH 13/17] Create --- azdev/operations/tests/test_format.py | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 azdev/operations/tests/test_format.py diff --git a/azdev/operations/tests/test_format.py b/azdev/operations/tests/test_format.py new file mode 100644 index 000000000..95105414d --- /dev/null +++ b/azdev/operations/tests/test_format.py @@ -0,0 +1,42 @@ +# ----------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for +# license information. +# ----------------------------------------------------------------------------- + +import configparser +import unittest +from unittest import mock + +from azdev.operations.style import _config_file_path + + +class TestConfigFilePath(unittest.TestCase): + def test_unsupported_code_style_checker(self): + with self.assertRaises(ValueError): + _config_file_path(style_type="unknown") + + def test_black_config_without_setup(self): + mocked_config = configparser.ConfigParser() + mocked_config.add_section("cli") + mocked_config.set("cli", "repo_path", "") + mocked_config.add_section("ext") + mocked_config.set("ext", "repo_paths", "") + + + def test_black_config_with_partially_setup(self): + cli_repo_path = "~/Azure/azure-cli" + mocked_config = configparser.ConfigParser() + mocked_config.add_section("cli") + mocked_config.set("cli", "repo_path", cli_repo_path) + mocked_config.add_section("ext") + mocked_config.set("ext", "repo_paths", "") + + def test_black_config_with_all_setup(self): + cli_repo_path = "~/Azure/azure-cli" + ext_repo_path = "~/Azure/azure-cli-extensions" + mocked_config = configparser.ConfigParser() + mocked_config.add_section("cli") + mocked_config.set("cli", "repo_path", cli_repo_path) + mocked_config.add_section("ext") + mocked_config.set("ext", "repo_paths", ext_repo_path) From 7e2a7c80d640e9c381e87e62e7b71cda77f427cf Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:41:39 -0500 Subject: [PATCH 14/17] Update test_format.py --- azdev/operations/tests/test_format.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/azdev/operations/tests/test_format.py b/azdev/operations/tests/test_format.py index 95105414d..374be1f6c 100644 --- a/azdev/operations/tests/test_format.py +++ b/azdev/operations/tests/test_format.py @@ -8,8 +8,6 @@ import unittest from unittest import mock -from azdev.operations.style import _config_file_path - class TestConfigFilePath(unittest.TestCase): def test_unsupported_code_style_checker(self): From b984a275992ccbf7a26308cddfd68c40b7799308 Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:41:47 -0500 Subject: [PATCH 15/17] Update test_format.py --- azdev/operations/tests/test_format.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/azdev/operations/tests/test_format.py b/azdev/operations/tests/test_format.py index 374be1f6c..33d66733e 100644 --- a/azdev/operations/tests/test_format.py +++ b/azdev/operations/tests/test_format.py @@ -10,10 +10,6 @@ class TestConfigFilePath(unittest.TestCase): - def test_unsupported_code_style_checker(self): - with self.assertRaises(ValueError): - _config_file_path(style_type="unknown") - def test_black_config_without_setup(self): mocked_config = configparser.ConfigParser() mocked_config.add_section("cli") From cc14affaff4629ae17c87fef17469a87a31437ab Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Thu, 9 Mar 2023 18:45:00 -0500 Subject: [PATCH 16/17] Update format.py --- azdev/operations/format.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/azdev/operations/format.py b/azdev/operations/format.py index 79281e9f5..6945fa662 100644 --- a/azdev/operations/format.py +++ b/azdev/operations/format.py @@ -13,8 +13,7 @@ from knack.util import CLIError, CommandResultItem from azdev.utilities import ( - display, heading, py_cmd, get_path_table, EXTENSION_PREFIX, - get_azdev_config, get_azdev_config_dir, require_azure_cli, filter_by_git_diff) + display, heading, py_cmd, get_path_table, filter_by_git_diff) logger = get_logger(__name__) From 61dae44cb03130caddce868182de72bf3c7e54ca Mon Sep 17 00:00:00 2001 From: Daniel Ciborowski Date: Fri, 10 Mar 2023 13:05:19 -0500 Subject: [PATCH 17/17] Update setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index e7bb18394..59c42d203 100644 --- a/setup.py +++ b/setup.py @@ -65,6 +65,7 @@ ], install_requires=[ 'azure-multiapi-storage', + 'black', 'docutils', 'flake8', 'gitpython',