From 4208cf66bea84c8c00c28dbd495c85087be3e49c Mon Sep 17 00:00:00 2001 From: vsoch Date: Fri, 9 Jul 2021 21:32:38 -0600 Subject: `spack style`: automatically bootstrap dependencies This uses our bootstrapping logic to automatically install dependencies for `spack style`. Users should no longer have to pre-install all of the tools (`isort`, `mypy`, `black`, `flake8`). The command will do it for them. - [x] add logic to bootstrap specs with specific version requirements in `spack style` - [x] remove style tools from CI requirements (to ensure we test bootstrapping) - [x] rework dependencies for `mypy` and `py-typed-ast` - `py-typed-ast` needs to be a link dependency - it needs to be at 1.4.1 or higher to work with python 3.9 Signed-off-by: vsoch --- lib/spack/docs/developer_guide.rst | 23 +++++++++++++++++++++++ lib/spack/spack/cmd/style.py | 28 ++++++++++++++++++++-------- 2 files changed, 43 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/spack/docs/developer_guide.rst b/lib/spack/docs/developer_guide.rst index 31311e87f7..71aac1fd93 100644 --- a/lib/spack/docs/developer_guide.rst +++ b/lib/spack/docs/developer_guide.rst @@ -818,6 +818,29 @@ Developer commands ``spack doc`` ^^^^^^^^^^^^^ +.. _cmd-spack-style: + +^^^^^^^^^^^^^^^ +``spack style`` +^^^^^^^^^^^^^^^ + +spack style exists to help the developer user to check imports and style with +mypy, flake8, isort, and (soon) black. To run all style checks, simply do: + +.. code-block:: console + + $ spack style + +To run automatic fixes for isort you can do: + +.. code-block:: console + + $ spack style --fix + +You do not need any of these Python packages installed on your system for +the checks to work! Spack will bootstrap install them from packages for +your use. + ^^^^^^^^^^^^^^^^^^^ ``spack unit-test`` ^^^^^^^^^^^^^^^^^^^ diff --git a/lib/spack/spack/cmd/style.py b/lib/spack/spack/cmd/style.py index 0eceb4dc2d..2841a4af0f 100644 --- a/lib/spack/spack/cmd/style.py +++ b/lib/spack/spack/cmd/style.py @@ -14,6 +14,7 @@ import llnl.util.tty as tty import llnl.util.tty.color as color from llnl.util.filesystem import working_dir +import spack.bootstrap import spack.paths from spack.util.executable import which @@ -44,9 +45,15 @@ initial_working_dir = None #: List of directories to exclude from checks. exclude_directories = [spack.paths.external_path] -#: order in which tools should be run. flake8 is last so that it can +#: Order in which tools should be run. flake8 is last so that it can #: double-check the results of other tools (if, e.g., --fix was provided) -tool_order = ["isort", "mypy", "black", "flake8"] +#: The list maps an executable name to a spack spec needed to install it. +tool_order = [ + ("isort", "py-isort@4.3.5:"), + ("mypy", "py-mypy@0.900:"), + ("black", "py-black"), + ("flake8", "py-flake8"), +] #: tools we run in spack style tools = {} @@ -210,7 +217,7 @@ def rewrite_and_print_output( def print_style_header(file_list, args): - tools = [tool for tool in tool_order if getattr(args, tool)] + tools = [tool for tool, _ in tool_order if getattr(args, tool)] tty.msg("Running style checks on spack:", "selected: " + ", ".join(tools)) # translate modified paths to cwd_relative if needed @@ -338,15 +345,20 @@ def style(parser, args): # run tools in order defined in tool_order returncode = 0 - for tool_name in tool_order: + for tool_name, tool_spec in tool_order: if getattr(args, tool_name): run_function, required = tools[tool_name] print_tool_header(tool_name) - cmd = which(tool_name, required=required) - if not cmd: - color.cprint(" @y{%s not in PATH, skipped}" % tool_name) - continue + # Bootstrap tools so we don't need to require install + with spack.bootstrap.ensure_bootstrap_configuration(): + spec = spack.spec.Spec(tool_spec) + cmd = spack.bootstrap.get_executable( + tool_name, spec=spec, install=True + ) + if not cmd: + color.cprint(" @y{%s not in PATH, skipped}" % tool_name) + continue returncode |= run_function(cmd, file_list, args) -- cgit v1.2.3-60-g2f50