Skip to content

Commit

Permalink
Add use_pyproject input to GitHub Action
Browse files Browse the repository at this point in the history
Closes: psf#4285
  • Loading branch information
srittau committed Mar 30, 2024
1 parent 836acad commit 278c40d
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 6 deletions.
5 changes: 5 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ inputs:
description: 'Python Version specifier (PEP440) - e.g. "21.5b1"'
required: false
default: ""
use_pyproject:
description: Read black version specifier from pyproject.toml if `true`.
required: false
default: "false"
summary:
description: "Whether to add the output to the workflow summary"
required: false
Expand Down Expand Up @@ -70,5 +74,6 @@ runs:
INPUT_JUPYTER: ${{ inputs.jupyter }}
INPUT_BLACK_ARGS: ${{ inputs.black_args }}
INPUT_VERSION: ${{ inputs.version }}
INPUT_USE_PYPROJECT: ${{ inputs.use_pyproject }}
pythonioencoding: utf-8
shell: bash
85 changes: 82 additions & 3 deletions action/main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import os
import re
import shlex
import shutil
import sys
Expand All @@ -13,12 +14,90 @@
JUPYTER = os.getenv("INPUT_JUPYTER") == "true"
BLACK_ARGS = os.getenv("INPUT_BLACK_ARGS", default="")
VERSION = os.getenv("INPUT_VERSION", default="")
USE_PYPROJECT = os.getenv("INPUT_USE_PYPROJECT") == "true"

BLACK_VERSION_RE = re.compile(r"^black([^A-Z0-9._-]+)", re.IGNORECASE)
EXTRAS_RE = re.compile(r"\[.*\]")


def determine_version_specifier() -> str:
"""Determine the version of Black to install.
The version can be specified either via the `with.version` input or via the
pyproject.toml file if `with.use_pyproject` is set to `true`.
"""
if USE_PYPROJECT and VERSION:
print(
"::error::'with.version' and 'with.use_pyproject' inputs are mutually exclusive.",
file=sys.stderr,
flush=True,
)
sys.exit(1)
if USE_PYPROJECT:
return read_version_specifier_from_pyproject()
elif VERSION and VERSION[0] in "0123456789":
return f"=={VERSION}"
else:
return VERSION


def read_version_specifier_from_pyproject() -> str:
if sys.version_info < (3, 11):
print(
"::error::'with.use_pyproject' input requires Python 3.11 or later.",
file=sys.stderr,
flush=True,
)
sys.exit(1)

import tomllib

try:
with Path("pyproject.toml").open("rb") as fp:
pyproject = tomllib.load(fp)
except FileNotFoundError:
print(
"::error::'with.use_pyproject' input requires a pyproject.toml file.",
file=sys.stderr,
flush=True,
)
sys.exit(1)

try:
deps = pyproject["project"]["dependencies"]
if not isinstance(deps, list):
raise TypeError()
except (KeyError, TypeError):
print(
"::error::'project.dependencies' table missing from pyproject.toml.",
file=sys.stderr,
flush=True,
)
sys.exit(1)

try:
for item in deps:
# Rudimentary PEP 508 parsing.
item = item.split(";")[0]
item = EXTRAS_RE.sub("", item).strip()
if item == "black":
return ""
elif m := BLACK_VERSION_RE.match(item):
return m.group(1).strip()
except TypeError:
pass

print(
"::error::'black' dependency missing from pyproject.toml.",
file=sys.stderr,
flush=True,
)
sys.exit(1)


run([sys.executable, "-m", "venv", str(ENV_PATH)], check=True)

version_specifier = VERSION
if VERSION and VERSION[0] in "0123456789":
version_specifier = f"=={VERSION}"
version_specifier = determine_version_specifier()
if JUPYTER:
extra_deps = "[colorama,jupyter]"
else:
Expand Down
17 changes: 14 additions & 3 deletions docs/integrations/github_actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ We recommend the use of the `@stable` tag, but per version tags also exist if yo
that. Note that the action's version you select is independent of the version of _Black_
the action will use.

The version of _Black_ the action will use can be configured via `version`. This can be
any
The version of _Black_ the action will use can be configured via `version` or read from
the pyproject.toml file. `version` can be any
[valid version specifier](https://packaging.python.org/en/latest/glossary/#term-Version-Specifier)
or just the version number if you want an exact version. The action defaults to the
or just the version number if you want an exact version. To read the version from the
pyproject.toml file instead, set `use_pyproject` to `true`. The action defaults to the
latest release available on PyPI. Only versions available from PyPI are supported, so no
commit SHAs or branch names.

Expand Down Expand Up @@ -70,3 +71,13 @@ If you want to match versions covered by Black's
src: "./src"
version: "~= 22.0"
```

If you want to read the version from pyproject.toml, set `use_pyproject` to `true`:

```yaml
- uses: psf/black@stable
with:
options: "--check --verbose"
src: "./src"
use_pyproject: true
```

0 comments on commit 278c40d

Please sign in to comment.