Browse Source

fix script/update-requirements and gihub workflow

Signed-off-by: Ivan Schaller <ivan@schaller.sh>
pull/1261/head
Ivan Schaller 6 months ago
parent
commit
bd47ae9041
4 changed files with 78 additions and 94 deletions
  1. +1
    -1
      .github/workflows/docs.yml
  2. +2
    -9
      requirements-dev.txt
  3. +1
    -55
      requirements-docs.txt
  4. +74
    -29
      script/update-requirements

+ 1
- 1
.github/workflows/docs.yml View File

@ -6,7 +6,7 @@ on:
- "v*.*.*"
pull_request:
branches: [main, master]
branches: main
workflow_dispatch:


+ 2
- 9
requirements-dev.txt View File

@ -1,5 +1,4 @@
# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update
PyYAML==6.0.2
Pygments==2.19.1
SecretStorage==3.3.3
black==24.10.0
@ -11,11 +10,8 @@ click==8.2.1
cmarkgfm==2024.11.20
coverage==7.9.1
cryptography==45.0.4
dnspython==2.7.0
docutils==0.21.2
fqdn==1.5.1
id==1.5.0
idna==3.10
iniconfig==2.1.0
isort==6.0.1
jaraco.classes==3.4.0
@ -33,7 +29,6 @@ mdit-py-plugins==0.4.2
mdurl==0.1.2
more-itertools==10.7.0
mypy_extensions==1.1.0
natsort==8.4.0
nh3==0.2.21
packaging==25.0
pathspec==0.12.1
@ -47,9 +42,8 @@ pyflakes==3.3.2
pyproject_hooks==1.2.0
pytest-cov==6.2.1
pytest-mock==3.14.1
pytest==8.4.0
pytest==8.4.1
pytest_network==0.0.1
python-dateutil==2.9.0.post0
readme_renderer==44.0
repoze.lru==0.7
requests-toolbelt==1.0.0
@ -58,8 +52,7 @@ rfc3986==2.0.0
rich==14.0.0
ruamel.yaml.clib==0.2.12
ruamel.yaml==0.18.14
six==1.17.0
twine==6.1.0
urllib3==2.4.0
urllib3==2.5.0
wcwidth==0.2.13
wheel==0.45.1

+ 1
- 55
requirements-docs.txt View File

@ -1,74 +1,23 @@
# DO NOT EDIT THIS FILE DIRECTLY - use ./script/update-requirements to update
Jinja2==3.1.6
MarkupSafe==3.0.2
PyYAML==6.0.2
Pygments==2.19.1
SecretStorage==3.3.3
Sphinx==8.2.3
alabaster==1.0.0
babel==2.17.0
beautifulsoup4==4.13.4
black==24.10.0
build==1.2.2.post1
certifi==2025.6.15
cffi==1.17.1
charset-normalizer==3.4.2
click==8.2.1
cmarkgfm==2024.11.20
coverage==7.9.1
cryptography==45.0.4
dnspython==2.7.0
docutils==0.21.2
fqdn==1.5.1
furo==2024.8.6
id==1.5.0
idna==3.10
imagesize==1.4.1
iniconfig==2.1.0
isort==6.0.1
jaraco.classes==3.4.0
jaraco.context==6.0.1
jaraco.functools==4.1.0
jeepney==0.9.0
keyring==25.6.0
markdown-it-py==3.0.0
mdformat==0.7.22
mdformat_footnote==0.1.1
mdformat_frontmatter==2.0.8
mdformat_myst==0.2.1
mdformat_tables==1.0.0
mdit-py-plugins==0.4.2
mdurl==0.1.2
more-itertools==10.7.0
mypy_extensions==1.1.0
myst-parser==4.0.1
natsort==8.4.0
nh3==0.2.21
packaging==25.0
pathspec==0.12.1
platformdirs==4.3.8
pluggy==1.6.0
pprintpp==0.4.0
pycountry-convert==0.7.2
pycountry==24.6.1
pycparser==2.22
pyflakes==3.3.2
pyproject_hooks==1.2.0
pytest-cov==6.2.1
pytest-mock==3.14.1
pytest==8.4.0
pytest_network==0.0.1
python-dateutil==2.9.0.post0
readme_renderer==44.0
repoze.lru==0.7
requests-toolbelt==1.0.0
requests==2.32.4
rfc3986==2.0.0
rich==14.0.0
roman-numerals-py==3.1.0
ruamel.yaml.clib==0.2.12
ruamel.yaml==0.18.14
six==1.17.0
snowballstemmer==3.0.1
soupsieve==2.7
sphinx-basic-ng==1.0.0b2
@ -79,8 +28,5 @@ sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
twine==6.1.0
typing_extensions==4.14.0
urllib3==2.4.0
wcwidth==0.2.13
wheel==0.45.1
urllib3==2.5.0

+ 74
- 29
script/update-requirements View File

@ -1,12 +1,14 @@
#!/usr/bin/env python3
import re
from os.path import join
from subprocess import check_call, check_output
import subprocess
from pathlib import Path
from sys import argv
from tempfile import TemporaryDirectory
TARGETS = ['', 'dev', 'docs'] # the empty string is used for the project itself
SCRIPT = argv[0]
TARGETS = ('', 'dev', 'docs') # empty string is used for the base requirements
FILE_HEADER = f'# DO NOT EDIT THIS FILE DIRECTLY - use {SCRIPT} to update\n'
def print_packages(packages, heading):
@ -15,40 +17,83 @@ def print_packages(packages, heading):
print('\n '.join(packages))
# would be nice if there was a cleaner way to get this, but I've not found a
# more reliable one.
with open('setup.py') as fh:
match = re.search(r"name='(?P<pkg>[\w-]+)',", fh.read())
def get_package_name() -> str:
match = re.search(
r"name='(?P<pkg>[\w-]+)',", Path('setup.py').read_text(encoding='utf8')
)
if not match:
raise Exception('failed to determine our package name')
our_package_name = match.group('pkg')
print(f'our_package_name: {our_package_name}')
with TemporaryDirectory() as tmpdir:
check_call(['python3', '-m', 'venv', tmpdir])
return our_package_name
for target in TARGETS:
to_install = f'.[{target}]' if target else '.'
check_call([join(tmpdir, 'bin', 'pip'), 'install', to_install])
frozen = check_output([join(tmpdir, 'bin', 'pip'), 'freeze'])
frozen = set(frozen.decode('utf-8').strip().split('\n'))
# pip installs the module itself along with deps so we need to get that out of
# our list by finding the thing that was file installed during dev
frozen = sorted(
[p for p in frozen if not p.startswith(our_package_name)]
def run_command(command: str) -> tuple[str, str, int]:
try:
proc = subprocess.run(
command.split(),
check=True,
capture_output=True,
encoding='utf8',
timeout=30,
)
except Exception as exc:
print(f"can't run command='{command}'")
raise exc
return proc.stdout.strip(), proc.stderr.strip(), proc.returncode
def save_base_reqs(our_package_name: str, tmpdir: str) -> list[str]:
print('installing base')
run_command(f'python3 -m venv {tmpdir}')
run_command(f'{tmpdir}/bin/pip install .')
stdout, _, _ = run_command(f'{tmpdir}/bin/pip freeze')
frozen = [*{*stdout.splitlines()}] # dedup items
frozen = sorted([p for p in frozen if not p.startswith(our_package_name)])
print_packages(frozen, 'base-frozen')
Path('requirements.txt').write_text(
FILE_HEADER + '\n'.join(frozen) + '\n', encoding='utf8'
)
return frozen
print_packages(frozen, f'{target}-frozen')
script = argv[0]
def save_extra_reqs(
our_package_name: str, tmpdir: str, base_frozen: list[str], extra: str
) -> None:
print(f'installing extra: {extra}')
run_command(f'{tmpdir}/bin/pip install .[{extra}]')
stdout, _, _ = run_command(f'{tmpdir}/bin/pip freeze')
frozen = [*{*stdout.splitlines()} - {*base_frozen}] # remove base deps
frozen = sorted([p for p in frozen if not p.startswith(our_package_name)])
print_packages(frozen, f'{extra}-frozen')
Path(f'requirements-{extra}.txt').write_text(
FILE_HEADER + '\n'.join(frozen) + '\n', encoding='utf8'
)
def main() -> None:
our_package_name = get_package_name()
# install all extra dependencies in a new venv, so we don't get duplicate/unwanted deps
for target in TARGETS:
with TemporaryDirectory() as tmpdir:
print(f'using tmpdir={tmpdir}')
base_frozen = save_base_reqs(our_package_name, tmpdir)
if not target:
continue # skip extra requirements for base package
save_extra_reqs(our_package_name, tmpdir, base_frozen, target)
with open(
f'requirements{"-" + target if target else ""}.txt', 'w'
) as fh:
fh.write(
f'# DO NOT EDIT THIS FILE DIRECTLY - use {script} to update\n'
)
fh.write('\n'.join(frozen))
fh.write('\n')
if __name__ == '__main__':
main()

Loading…
Cancel
Save