From b629ab89c592557312121086c40f28025fbcaedc Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sat, 13 Jul 2024 13:29:21 -0400 Subject: [PATCH] Set absolute URLs prior to uploading to PyPI (#5038) ## Summary Closes https://github.com/astral-sh/uv/issues/5030. --- .github/workflows/ci.yml | 7 ++++ README.md | 4 +-- scripts/bench/__main__.py | 4 +-- scripts/check_cache_compat.py | 2 +- scripts/check_embedded_python.py | 1 - .../python/deptry_reproducer/__init__.py | 1 - scripts/scenarios/generate.py | 2 +- scripts/transform_readme.py | 32 +++++++++++++++++-- 8 files changed, 43 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc9b3d4b7..fc3c536a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,10 @@ jobs: steps: - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: "Install Rustfmt" run: rustup component add rustfmt @@ -60,6 +64,9 @@ jobs: - name: "Ruff check" run: pipx run ruff check . + - name: "README check" + run: python scripts/transform_readme.py --target pypi + cargo-clippy: needs: determine_changes if: ${{ github.repository == 'astral-sh/uv' && (needs.determine_changes.outputs.code == 'true' || github.ref == 'refs/heads/main') }} diff --git a/README.md b/README.md index d6045aa16..4c138ef08 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,7 @@ Although we generally recommend using virtual environments for dependency manage `--system` is appropriate in continuous integration and containerized environments. The `--system` flag is also used to opt in to mutating system environments. For example, the -the `--python` argument can be used to request a Python version (e.g., `--python 3.12`), and uv will +`--python` argument can be used to request a Python version (e.g., `--python 3.12`), and uv will search for an interpreter that meets the request. If uv finds a system interpreter (e.g., `/usr/lib/python3.12`), then the `--system` flag is required to allow modification of this non-virtual Python environment. Without the `--system` flag, uv will ignore any interpreters that are not in virtual environments. @@ -282,7 +282,7 @@ Using a password or token: When using a GitHub personal access token, the username is arbitrary. GitHub does not support logging in with password directly, although other hosts may. If a username is provided without credentials, you will be prompted to enter them. -If there are no credentials present in the URL and authentication is needed, the [Git credential helper](https://git-scm.com/doc/credential-helpers) will be queried. +If there are no credentials present in the URL and authentication is needed, uv will query the [Git credential helper](https://git-scm.com/doc/credential-helpers). ### HTTP authentication diff --git a/scripts/bench/__main__.py b/scripts/bench/__main__.py index 8e87c262f..ac46434bf 100644 --- a/scripts/bench/__main__.py +++ b/scripts/bench/__main__.py @@ -1089,9 +1089,9 @@ def main(): else list(Benchmark) ) - logging.info("Reading requirements from: {}".format(requirements_file)) + logging.info(f"Reading requirements from: {requirements_file}") logging.info("```") - with open(args.file, "r") as f: + with open(args.file) as f: for line in f: logging.info(line.rstrip()) logging.info("```") diff --git a/scripts/check_cache_compat.py b/scripts/check_cache_compat.py index 47a72911c..5bcf7fd44 100755 --- a/scripts/check_cache_compat.py +++ b/scripts/check_cache_compat.py @@ -9,8 +9,8 @@ from __future__ import annotations import argparse import logging import os -import sys import subprocess +import sys import tempfile DEFAULT_TEST_PACKAGES = [ diff --git a/scripts/check_embedded_python.py b/scripts/check_embedded_python.py index ec9d9358f..674da3b96 100755 --- a/scripts/check_embedded_python.py +++ b/scripts/check_embedded_python.py @@ -9,7 +9,6 @@ import subprocess import sys import tempfile - if __name__ == "__main__": logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") diff --git a/scripts/packages/deptry_reproducer/python/deptry_reproducer/__init__.py b/scripts/packages/deptry_reproducer/python/deptry_reproducer/__init__.py index a95c6b977..7f58ec345 100644 --- a/scripts/packages/deptry_reproducer/python/deptry_reproducer/__init__.py +++ b/scripts/packages/deptry_reproducer/python/deptry_reproducer/__init__.py @@ -1,6 +1,5 @@ from .deptry_reproducer import * - __doc__ = deptry_reproducer.__doc__ if hasattr(deptry_reproducer, "__all__"): __all__ = deptry_reproducer.__all__ diff --git a/scripts/scenarios/generate.py b/scripts/scenarios/generate.py index 173eaa288..8634aeafb 100755 --- a/scripts/scenarios/generate.py +++ b/scripts/scenarios/generate.py @@ -207,7 +207,7 @@ def main(scenarios: list[Path], snapshot_update: bool = True): logging.info( f"Updating test file at `{tests.relative_to(PROJECT_ROOT)}`...", ) - with open(tests, "wt") as test_file: + with open(tests, "w") as test_file: test_file.write(output) # Format diff --git a/scripts/transform_readme.py b/scripts/transform_readme.py index 6708c1725..f3511a77f 100644 --- a/scripts/transform_readme.py +++ b/scripts/transform_readme.py @@ -8,8 +8,12 @@ adjusts the images in the README.md to support the given target. from __future__ import annotations import argparse +import re +import urllib.parse from pathlib import Path +import tomllib + URL = "https://github.com/astral-sh/uv/assets/1309177/{}" URL_LIGHT = URL.format("629e59c0-9c6e-4013-9ad4-adb2bcf5080d") URL_DARK = URL.format("03aa9163-1c79-4a87-a31d-7a9311ed9310") @@ -35,6 +39,8 @@ PYPI = f""" def main(target: str) -> None: """Modify the README.md to support the given target.""" + + # Replace the benchmark images based on the target. with Path("README.md").open(encoding="utf8") as fp: content = fp.read() if GITHUB not in content: @@ -42,12 +48,34 @@ def main(target: str) -> None: raise ValueError(msg) if target == "pypi": - with Path("README.md").open("w", encoding="utf8") as fp: - fp.write(content.replace(GITHUB, PYPI)) + content = content.replace(GITHUB, PYPI) else: msg = f"Unknown target: {target}" raise ValueError(msg) + # Read the current version from the `pyproject.toml`. + with Path("pyproject.toml").open(mode="rb") as fp: + # Parse the TOML. + pyproject = tomllib.load(fp) + if "project" in pyproject and "version" in pyproject["project"]: + version = pyproject["project"]["version"] + else: + raise ValueError("Version not found in pyproject.toml") + + # Replace any relative URLs with absolute URLs. + def replace(match: re.Match) -> str: + url = match.group(1) + if not url.startswith("http"): + url = urllib.parse.urljoin( + f"https://github.com/astral-sh/uv/blob/{version}/README.md", url + ) + return f"]({url})" + + content = re.sub(r"]\(([^)]+)\)", replace, content) + + with Path("README.md").open("w", encoding="utf8") as fp: + fp.write(content) + if __name__ == "__main__": parser = argparse.ArgumentParser(