Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: update pre-commit hooks #212

Merged
merged 7 commits into from
Nov 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions .github/actions/check-links/check_links.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import os
import shlex
import subprocess
Expand All @@ -6,13 +8,13 @@
from glob import glob


def log(*outputs, **kwargs):
def log(*outputs: str, **kwargs: t.Any) -> None:
"""Log an output to stderr"""
kwargs.setdefault("file", sys.stderr)
print(*outputs, **kwargs)


def check_links(ignore_glob, ignore_links, links_expire):
def check_links(ignore_glob: list[str], ignore_links: list[str], links_expire: str) -> None:
"""Check URLs for HTML-containing files."""
python = sys.executable.replace(os.sep, "/")
cmd = f"{python} -m pytest --noconftest --check-links --check-links-cache "
Expand Down Expand Up @@ -44,7 +46,7 @@ def check_links(ignore_glob, ignore_links, links_expire):
cmd += " --ignore-glob node_modules"

# Gather all of the markdown, RST, and ipynb files
files: t.List[str] = []
files: list[str] = []
for ext in [".md", ".rst", ".ipynb"]:
matched = glob(f"**/*{ext}", recursive=True)
files.extend(m for m in matched if m not in ignored and "node_modules" not in m)
Expand All @@ -55,8 +57,8 @@ def check_links(ignore_glob, ignore_links, links_expire):

fails = 0
for f in files:
file_cmd = cmd + f' "{f}"'
file_cmd = shlex.split(file_cmd)
file_cmd_str = cmd + f' "{f}"'
file_cmd = shlex.split(file_cmd_str)
try:
log(f"{separator}{f}...")
subprocess.check_output(file_cmd, shell=False) # noqa S603
Expand All @@ -78,9 +80,9 @@ def check_links(ignore_glob, ignore_links, links_expire):


if __name__ == "__main__":
ignore_glob = os.environ.get("IGNORE_GLOB", "")
ignore_glob = ignore_glob.strip().split(" ") if ignore_glob else []
ignore_links = os.environ.get("IGNORE_LINKS", "")
ignore_links = ignore_links.split(" ") if ignore_links else []
ignore_glob_str = os.environ.get("IGNORE_GLOB", "")
ignore_glob = ignore_glob_str.strip().split(" ") if ignore_glob_str else []
ignore_links_str = os.environ.get("IGNORE_LINKS", "")
ignore_links = ignore_links_str.split(" ") if ignore_links_str else []
links_expire = os.environ.get("LINKS_EXPIRE") or "604800"
check_links(ignore_glob, ignore_links, links_expire)
4 changes: 2 additions & 2 deletions .github/actions/install-minimums/create_constraints_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
spec = spec.replace(">", "==")
constraints[r.name] = spec

constraints = [f"{key}{value}\n" for (key, value) in constraints.items()]
constraints_list = [f"{key}{value}\n" for (key, value) in constraints.items()]

# Write the constraints to to a pip constraints file.
with open(output_file, "w") as fid:
fid.writelines(constraints)
fid.writelines(constraints_list)
23 changes: 12 additions & 11 deletions .github/actions/pr-script/pr_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
import os
import shlex
import shutil
import typing as t
from pathlib import Path
from subprocess import PIPE, CalledProcessError, check_output

from ghapi.core import GhApi
from ghapi.core import GhApi # type:ignore[import-not-found]


def run(cmd, **kwargs):
def run(cmd: str, **kwargs: t.Any) -> str:
"""Run a command as a subprocess and get the output as a string"""
if not kwargs.pop("quiet", False):
print(f"+ {cmd}")
Expand All @@ -17,7 +18,7 @@ def run(cmd, **kwargs):

dry_run = os.environ.get("DRY_RUN", "").lower() == "true"
if dry_run:
return
return ""

parts = shlex.split(cmd)
if "/" not in parts[0]:
Expand All @@ -28,15 +29,15 @@ def run(cmd, **kwargs):
parts[0] = executable

try:
return check_output(parts, **kwargs).decode("utf-8").strip() # noqa S603
return str(check_output(parts, **kwargs).decode("utf-8").strip()) # noqa S603
except CalledProcessError as e:
print("output:", e.output.decode("utf-8").strip())
if e.stderr:
print("stderr:", e.stderr.decode("utf-8").strip())
raise e


def run_script(): # noqa
def run_script() -> None: # noqa
"""Run a script on the target pull request URL"""
# e.g. https://github.com/foo/bar/pull/81

Expand All @@ -49,15 +50,15 @@ def run_script(): # noqa
if not script:
script = "[]"
try:
script = json.loads(script)
script_obj = json.loads(script)
except Exception: # noqa S110
pass
if not isinstance(script, list):
script = [script]
if not isinstance(script_obj, list):
script_obj = [script_obj]
if os.environ.get("PRE_COMMIT") == "true":
script += ["pre-commit run --all-files"]
script_obj += ["pre-commit run --all-files"]
print(f"Running script on {target}:")
print(f" {script}")
print(f" {script_obj}")

print(f"Finding owner and repo for {target}")
owner, repo = target.replace("https://github.com/", "").split("/")[:2]
Expand All @@ -79,7 +80,7 @@ def run_script(): # noqa
print(f"User is authorized as {association}")

# Give a confirmation message
msg = f'Running script "{script}" on behalf of "{maintainer}"'
msg = f'Running script "{script_obj}" on behalf of "{maintainer}"'
print(msg)
if not dry_run:
gh.issues.create_comment(number, msg)
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ jobs:
- name: Run Linters
run: |
hatch run typing:test
hatch run lint:style
hatch run lint:build
pipx run interrogate -v .

check_links:
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
package_spec: "nbclient[test] ipykernel"
package_download_extra_args: "--use-pep517"
test_command: "echo 'hello'"
extra_test: "pytest --pyargs nbclient"
extra_test: "pytest"
env_values: IPYKERNEL_CELL_NAME=\<IPY-INPUT\>

binder_link:
Expand Down
20 changes: 13 additions & 7 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ci:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-case-conflict
- id: check-ast
Expand All @@ -21,7 +21,7 @@ repos:
- id: trailing-whitespace

- repo: https://github.com/python-jsonschema/check-jsonschema
rev: 0.27.0
rev: 0.27.1
hooks:
- id: check-github-workflows

Expand All @@ -42,10 +42,13 @@ repos:
- id: blacken-docs
additional_dependencies: [black==23.7.0]

- repo: https://github.com/psf/black-pre-commit-mirror
rev: 23.9.1
- repo: https://github.com/pre-commit/mirrors-mypy
rev: "v1.6.1"
hooks:
- id: black
- id: mypy
stages: [manual]
args: ["--install-types", "--non-interactive"]
additional_dependencies: ["packaging"]

- repo: https://github.com/codespell-project/codespell
rev: "v2.2.6"
Expand All @@ -61,13 +64,16 @@ repos:
- id: rst-inline-touching-normal

- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.292
rev: v0.1.5
hooks:
- id: ruff
types_or: [python, jupyter]
args: ["--fix", "--show-fixes"]
- id: ruff-format
types_or: [python, jupyter]

- repo: https://github.com/scientific-python/cookie
rev: "2023.09.21"
rev: "2023.10.27"
hooks:
- id: sp-repo-review
additional_dependencies: ["repo-review[cli]"]
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@jupyterlab/maintainer-tools",
"version": "0.24.2",
"private": true
"name": "@jupyterlab/maintainer-tools",
"version": "0.24.2",
"private": true
}
31 changes: 11 additions & 20 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ authors = [{name = "Sir Robin", email = "robin@camelot.uk"}]
dynamic = ["description", "version"]
readme = "README.md"
dependencies = ["jupyter_core>=4.12,!=5.0.*"]
requires-python = ">=3.8"

[project.optional-dependencies]
test = ["pytest>=7.0"]
Expand All @@ -24,24 +25,18 @@ check_minimum = "python -c 'from jupyter_core import __version__; assert __versi
check_pre = "python -c 'import os; assert os.environ[\"PIP_PRE\"] == \"1\"'"

[tool.hatch.envs.typing]
features = ["test"]
dependencies = ["mypy>=1.5.1"]
dependencies = ["pre-commit"]
detached = true
[tool.hatch.envs.typing.scripts]
test = "mypy --install-types --non-interactive {args}"
test = "pre-commit run --all-files --hook-stage manual mypy"

[tool.hatch.envs.lint]
dependencies = ["black==23.1.0", "mdformat>0.7", "ruff==0.0.270"]
dependencies = ["pre-commit"]
detached = true
[tool.hatch.envs.lint.scripts]
style = [
"ruff {args:.}",
"black --check --diff {args:.}",
"mdformat --check {args:*.md}"
]
fmt = [
"black {args:.}",
"ruff --fix {args:.}",
"mdformat {args:*.md}"
build = [
"pre-commit run --all-files ruff",
"pre-commit run --all-files ruff-format"
]

[tool.pytest.ini_options]
Expand All @@ -63,16 +58,12 @@ show_error_codes = true
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
warn_unreachable = true

[tool.black]
line-length = 100
skip-string-normalization = true
target-version = ["py38"]

[tool.ruff]
target-version = "py38"
line-length = 100

[tool.ruff.lint]
select = [
"A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "ISC", "N",
"A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "N",
"PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP",
"W", "YTT",
]
Expand Down