Skip to content

Commit

Permalink
Add help_short field for Python tools and use it to generate the he…
Browse files Browse the repository at this point in the history
…lp text (#20921)

Closes #20912.

This actually wasn't too bad! I didn't realize the trick with
`classproperty` would work as I intended, but it did. Looking at the
individual commits should help separate out the repetitive work
(changing `help` to `help_short`) from the more substantive changes.
  • Loading branch information
krishnan-chandra authored May 16, 2024
1 parent 9e02d42 commit 40e8bc9
Show file tree
Hide file tree
Showing 33 changed files with 56 additions and 35 deletions.
4 changes: 3 additions & 1 deletion docs/notes/2.22.x.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ Default module mappings were added for more modules:

The deprecation for the `platforms` field for the `pex_binary` and `pex_binaries` targets has expired, and so has been removed. The `resolve_local_platforms` field is now meaningless and is thus deprecated.

The option help text for the `install_from_resolve` field for Python tools now contains the default version of the tool, along with instructions on how to override this version using a custom lockfile.
Python tool subsystem docs and help text now include the default version of the tool, along with instructions on how to override this version using a custom lockfile. Additionally, the help text for the `install_from_resolve` option for Python tools now includes this same information.

#### Semgrep

Expand All @@ -82,6 +82,8 @@ Setting [the `orphan_files_behaviour = "ignore"` option](https://www.pantsbuild.

### Plugin API changes

The `PythonToolRequirementsBase` and `PythonToolBase` classes now have a new `help_short` field. Subclasses should now use `help_short` instead of the `help` field. The `help` field will be automatically generated using `help_short`, and will include the tool's default package version and provide instructions on how to override this version using a custom lockfile.

## Full Changelog

For the full changelog, see the individual GitHub Releases for this series: https://github.com/pantsbuild/pants/releases
2 changes: 1 addition & 1 deletion src/python/pants/backend/cc/lint/clangformat/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
class ClangFormat(PythonToolBase):
options_scope = "clang-format"
name = "ClangFormat"
help = help_text(
help_short = help_text(
"""
The clang-format utility for formatting C/C++ (and others) code
(https://clang.llvm.org/docs/ClangFormat.html). The clang-format binaries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class PythonProtobufSubsystem(Subsystem):

class PythonProtobufMypyPlugin(PythonToolRequirementsBase):
options_scope = "mypy-protobuf"
help = "Configuration of the mypy-protobuf type stub generation plugin."
help_short = "Configuration of the mypy-protobuf type stub generation plugin."

default_requirements = ["mypy-protobuf>=3.4.0,<4"]

Expand All @@ -104,7 +104,7 @@ class PythonProtobufMypyPlugin(PythonToolRequirementsBase):

class PythonProtobufGrpclibPlugin(PythonToolRequirementsBase):
options_scope = "python-grpclib-protobuf"
help = "Configuration of the grpclib plugin."
help_short = "Configuration of the grpclib plugin."

default_requirements = ["grpclib[protobuf]>=0.4,<1"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

class DockerfileParser(PythonToolRequirementsBase):
options_scope = "dockerfile-parser"
help = "Used to parse Dockerfile build specs to infer their dependencies."
help_short = "Used to parse Dockerfile build specs to infer their dependencies."

default_requirements = ["dockerfile>=3.2.0,<4"]

Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/helm/subsystems/k8s_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

class HelmKubeParserSubsystem(PythonToolRequirementsBase):
options_scope = "helm-k8s-parser"
help = "Analyses K8S manifests rendered by Helm."
help_short = "Analyses K8S manifests rendered by Helm."

default_requirements = [
"hikaru>=1.1.0",
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/helm/subsystems/post_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

class HelmPostRendererSubsystem(PythonToolRequirementsBase):
options_scope = "helm-post-renderer"
help = "Used perform modifications to the final output produced by Helm charts when they've been fully rendered."
help_short = "Used perform modifications to the final output produced by Helm charts when they've been fully rendered."

default_requirements = [
"yamlpath>=3.6.0,<4",
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/goals/coverage_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def value(self) -> str:

class CoverageSubsystem(PythonToolBase):
options_scope = "coverage-py"
help = "Configuration for Python test coverage measurement."
help_short = "Configuration for Python test coverage measurement."

default_main = ConsoleScript("coverage")
default_requirements = ["coverage[toml]>=6.5,<8"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class AddTrailingComma(PythonToolBase):
options_scope = "add-trailing-comma"
name = "add-trailing-comma"
help = "The add-trailing-comma Python code formatter (https://github.com/asottile/add-trailing-comma)."
help_short = "The add-trailing-comma Python code formatter (https://github.com/asottile/add-trailing-comma)."

default_main = ConsoleScript("add-trailing-comma")
default_requirements = ["add-trailing-comma>=2.2.3,<3"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class Autoflake(PythonToolBase):
options_scope = "autoflake"
name = "Autoflake"
help = "The Autoflake Python code formatter (https://github.com/myint/autoflake)."
help_short = "The Autoflake Python code formatter (https://github.com/myint/autoflake)."

default_main = ConsoleScript("autoflake")
default_requirements = ["autoflake>=1.4,<3"]
Expand Down
4 changes: 3 additions & 1 deletion src/python/pants/backend/python/lint/bandit/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ def opt_out(cls, tgt: Target) -> bool:
class Bandit(PythonToolBase):
options_scope = "bandit"
name = "Bandit"
help = "A tool for finding security issues in Python code (https://bandit.readthedocs.io)."
help_short = (
"A tool for finding security issues in Python code (https://bandit.readthedocs.io)."
)

default_main = ConsoleScript("bandit")
default_requirements = [
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/black/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def opt_out(cls, tgt: Target) -> bool:
class Black(PythonToolBase):
options_scope = "black"
name = "Black"
help = "The Black Python code formatter (https://black.readthedocs.io/)."
help_short = "The Black Python code formatter (https://black.readthedocs.io/)."

default_main = ConsoleScript("black")
default_requirements = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class Docformatter(PythonToolBase):
options_scope = "docformatter"
name = "docformatter"
help = "The Python docformatter tool (https://github.com/myint/docformatter)."
help_short = "The Python docformatter tool (https://github.com/myint/docformatter)."

default_main = ConsoleScript("docformatter")
default_requirements = ["docformatter>=1.4,<1.5"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/flake8/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def opt_out(cls, tgt: Target) -> bool:
class Flake8(PythonToolBase):
options_scope = "flake8"
name = "Flake8"
help = "The Flake8 Python linter (https://flake8.pycqa.org/)."
help_short = "The Flake8 Python linter (https://flake8.pycqa.org/)."

default_main = ConsoleScript("flake8")
default_requirements = ["flake8>=5.0.4,<7"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/isort/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class Isort(PythonToolBase):
options_scope = "isort"
name = "isort"
help = "The Python import sorter tool (https://pycqa.github.io/isort/)."
help_short = "The Python import sorter tool (https://pycqa.github.io/isort/)."

default_main = ConsoleScript("isort")
default_requirements = ["isort[pyproject,colors]>=5.9.3,<6.0"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def opt_out(cls, tgt: Target) -> bool:
class Pydocstyle(PythonToolBase):
options_scope = "pydocstyle"
name = "Pydocstyle"
help = "A tool for checking compliance with Python docstring conventions (http://www.pydocstyle.org/en/stable/)."
help_short = "A tool for checking compliance with Python docstring conventions (http://www.pydocstyle.org/en/stable/)."

default_main = ConsoleScript("pydocstyle")
default_requirements = ["pydocstyle[toml]>=6.1.1,<7.0"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/pylint/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def opt_out(cls, tgt: Target) -> bool:
class Pylint(PythonToolBase):
options_scope = "pylint"
name = "Pylint"
help = "The Pylint linter for Python code (https://www.pylint.org/)."
help_short = "The Pylint linter for Python code (https://www.pylint.org/)."

default_main = ConsoleScript("pylint")
default_requirements = ["pylint>=2.13.0,<3"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
class PyUpgrade(PythonToolBase):
options_scope = "pyupgrade"
name = "pyupgrade"
help = (
help_short = (
"Upgrade syntax for newer versions of the language (https://github.com/asottile/pyupgrade)."
)

Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/ruff/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class RuffMode(str, Enum):
class Ruff(PythonToolBase):
options_scope = "ruff"
name = "Ruff"
help = "The Ruff Python formatter (https://github.com/astral-sh/ruff)."
help_short = "The Ruff Python formatter (https://github.com/astral-sh/ruff)."

default_main = ConsoleScript("ruff")
default_requirements = ["ruff>=0.1.2,<1"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/lint/yapf/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class Yapf(PythonToolBase):
options_scope = "yapf"
name = "yapf"
help = "A formatter for Python files (https://github.com/google/yapf)."
help_short = "A formatter for Python files (https://github.com/google/yapf)."

default_main = ConsoleScript("yapf")
default_requirements = ["yapf>=0.32.0,<1", "toml"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
class PyOxidizer(PythonToolBase):
options_scope = "pyoxidizer"
name = "PyOxidizer"
help = help_text(
help_short = help_text(
"""
The PyOxidizer utility for packaging Python code in a Rust binary
(https://pyoxidizer.readthedocs.io/en/stable/pyoxidizer.html).
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/subsystems/debugpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class DebugPy(PythonToolBase):
options_scope = "debugpy"
name = options_scope
help = "An implementation of the Debug Adapter Protocol for Python (https://github.com/microsoft/debugpy)."
help_short = "An implementation of the Debug Adapter Protocol for Python (https://github.com/microsoft/debugpy)."

default_main = EntryPoint("debugpy")
default_requirements = ["debugpy>=1.6.5,<1.7"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/subsystems/ipython.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

class IPython(PythonToolBase):
options_scope = "ipython"
help = "The IPython enhanced REPL (https://ipython.org/)."
help_short = "The IPython enhanced REPL (https://ipython.org/)."

default_main = ConsoleScript("ipython")
default_requirements = ["ipython>=7.34,<9"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/subsystems/pytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def opt_out(cls, tgt: Target) -> bool:
class PyTest(PythonToolBase):
options_scope = "pytest"
name = "Pytest"
help = "The pytest Python test framework (https://docs.pytest.org/)."
help_short = "The pytest Python test framework (https://docs.pytest.org/)."

# Pytest 7.1.0 introduced a significant bug that is apparently not fixed as of 7.1.1 (the most
# recent release at the time of writing). see https://github.com/pantsbuild/pants/issues/14990.
Expand Down
19 changes: 17 additions & 2 deletions src/python/pants/backend/python/subsystems/python_tool_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import os
from dataclasses import dataclass
from functools import cache
from typing import ClassVar, Iterable, Optional, Sequence
from typing import Callable, ClassVar, Iterable, Optional, Sequence
from urllib.parse import urlparse

from pants.backend.python.target_types import ConsoleScript, EntryPoint, MainSpecification
Expand All @@ -34,7 +34,7 @@
from pants.util.docutil import doc_url, git_url
from pants.util.meta import classproperty
from pants.util.pip_requirement import PipRequirement
from pants.util.strutil import softwrap
from pants.util.strutil import softwrap, strval

logger = logging.getLogger(__name__)

Expand All @@ -50,6 +50,8 @@ class PythonToolRequirementsBase(Subsystem, ExportableTool):

# Subclasses must set.
default_version: ClassVar[str]
# Must be set by subclasses - will be used to set the help text in this class.
help_short: ClassVar[str | Callable[[], str]]
# Subclasses do not need to override.
default_extra_requirements: ClassVar[Sequence[str]] = []

Expand All @@ -65,6 +67,19 @@ class PythonToolRequirementsBase(Subsystem, ExportableTool):

default_lockfile_resource: ClassVar[tuple[str, str] | None] = None

@classmethod
def _help_extended(cls) -> str:
base_help = strval(cls.help_short)
help_paragraphs = [base_help]
package_and_version = cls._default_package_name_and_version()
if package_and_version:
new_paragraph = f"This version of Pants uses `{package_and_version.name}` version {package_and_version.version} by default. Use a dedicated lockfile and the `install_from_resolve` option to control this."
help_paragraphs.append(new_paragraph)

return "\n\n".join(help_paragraphs)

help = classproperty(_help_extended)

@classmethod
def _install_from_resolve_help(cls) -> str:
package_and_version = cls._default_package_name_and_version()
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/python/subsystems/setuptools.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PythonDistributionFieldSet(PackageFieldSet):

class Setuptools(PythonToolRequirementsBase):
options_scope = "setuptools"
help = "Python setuptools, used to package `python_distribution` targets."
help_short = "Python setuptools, used to package `python_distribution` targets."

default_requirements = ["setuptools>=63.1.0,<64.0", "wheel>=0.35.1,<0.38"]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

class SetuptoolsSCM(PythonToolBase):
options_scope = "setuptools-scm"
help = (
help_short = (
"A tool for generating versions from VCS metadata (https://github.com/pypa/setuptools_scm)."
)

Expand Down
4 changes: 3 additions & 1 deletion src/python/pants/backend/python/subsystems/twine.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
class TwineSubsystem(PythonToolBase):
options_scope = "twine"
name = "Twine"
help = "The utility for publishing Python distributions to PyPI and other Python repositories."
help_short = (
"The utility for publishing Python distributions to PyPI and other Python repositories."
)

default_version = "twine>=4,<5"
default_main = ConsoleScript("twine")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def opt_out(cls, tgt: Target) -> bool:
class MyPy(PythonToolBase):
options_scope = "mypy"
name = "MyPy"
help = "The MyPy Python type checker (http://mypy-lang.org/)."
help_short = "The MyPy Python type checker (http://mypy-lang.org/)."

default_main = ConsoleScript("mypy")
default_requirements = ["mypy>=0.961,<2"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class Pytype(PythonToolBase):
options_scope = "pytype"
name = "Pytype"
help = help_text(
help_short = help_text(
"""
The Pytype utility for typechecking Python code
(https://github.com/google/pytype).
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/sql/lint/sqlfluff/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class SqlfluffMode(str, Enum):
class Sqlfluff(PythonToolBase):
options_scope = "sqlfluff"
name = "Sqlfluff"
help = "The Sqlfluff SQL linter (https://github.com/sqlfluff/sqlfluff)."
help_short = "The Sqlfluff SQL linter (https://github.com/sqlfluff/sqlfluff)."

default_main = ConsoleScript("sqlfluff")
default_requirements = ["sqlfluff>=2.3.5,<3"]
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/terraform/dependency_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@

class TerraformHcl2Parser(PythonToolRequirementsBase):
options_scope = "terraform-hcl2-parser"
help = "Used to parse Terraform modules to infer their dependencies."
help_short = "Used to parse Terraform modules to infer their dependencies."

default_requirements = ["python-hcl2>=3.0.5,<5"]

Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/tools/semgrep/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def opt_out(cls, tgt: Target) -> bool:
class SemgrepSubsystem(PythonToolBase):
name = "Semgrep"
options_scope = "semgrep"
help = softwrap(
help_short = softwrap(
"""
Lightweight static analysis for many languages. Find bug variants with patterns that look
like source code. (https://semgrep.dev/)
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/backend/tools/yamllint/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class Yamllint(PythonToolBase):
name = "Yamllint"
options_scope = "yamllint"
help = "A linter for YAML files (https://yamllint.readthedocs.io)"
help_short = "A linter for YAML files (https://yamllint.readthedocs.io)"

default_main = ConsoleScript("yamllint")
default_requirements = ["yamllint>=1.28.0,<2"]
Expand Down

0 comments on commit 40e8bc9

Please sign in to comment.