Skip to main content

Rewrite the pip_compile function as a Python script; bump this repo

ID
58c95c6
date
2025-04-23 06:59:56+00:00
author
Alex Chan <alex@alexwlchan.net>
parent
86d0fde
message
Rewrite the `pip_compile` function as a Python script; bump this repo
changed files
5 files, 101 additions, 88 deletions

Changed files

fish_functions/README.md (4335) → fish_functions/README.md (4117)

diff --git a/fish_functions/README.md b/fish_functions/README.md
index fe58cb9..a60db60 100644
--- a/fish_functions/README.md
+++ b/fish_functions/README.md
@@ -105,15 +105,6 @@ cog_helpers.create_description_table(folder_name=folder_name, scripts=functions)
   </dd>
 
   <dt>
-    <a href="https://github.com/alexwlchan/scripts/blob/main/fish_functions/pip_compile.fish">
-      <code>pip_compile.fish</code>
-    </a>
-  </dt>
-  <dd>
-    Create requirements.txt lock files with uv
-  </dd>
-
-  <dt>
     <a href="https://github.com/alexwlchan/scripts/blob/main/fish_functions/pip_sync.fish">
       <code>pip_sync.fish</code>
     </a>
@@ -158,4 +149,4 @@ cog_helpers.create_description_table(folder_name=folder_name, scripts=functions)
     Create and activate a new virtual environment
   </dd>
 </dl>
-<!-- [[[end]]] (checksum: 67f00a2925833d4359f4ab8087eab838) -->
\ No newline at end of file
+<!-- [[[end]]] (checksum: b2b37beea55a61207649c299f0858d15) -->
\ No newline at end of file

fish_functions/pip_compile.fish (665) → fish_functions/pip_compile.fish (0)

diff --git a/fish_functions/pip_compile.fish b/fish_functions/pip_compile.fish
deleted file mode 100644
index c9ca008..0000000
--- a/fish_functions/pip_compile.fish
+++ /dev/null
@@ -1,13 +0,0 @@
-function pip_compile --description "Create requirements.txt lock files with uv"
-    if test \( -e requirements.in \) -a \( -e overrides.txt \)
-        uv pip compile requirements.in --output-file requirements.txt --override overrides.txt
-    else if test \( -e requirements.in \)
-        uv pip compile requirements.in --output-file requirements.txt
-    end
-
-    if test \( -e dev_requirements.in \) -a \( -e overrides.txt \)
-        uv pip compile dev_requirements.in --output-file dev_requirements.txt --override overrides.txt
-    else if test \( -e dev_requirements.in \)
-        uv pip compile dev_requirements.in --output-file dev_requirements.txt
-    end
-end

python/README.md (778) → python/README.md (1207)

diff --git a/python/README.md b/python/README.md
index 91a4865..091f94e 100644
--- a/python/README.md
+++ b/python/README.md
@@ -21,6 +21,10 @@ scripts = [
         "name": "pyfmt [...PATH]",
         "description": "Format Python files with ruff.",
     },
+    {
+        "name": "pip_compile (--upgrade)",
+        "description": "Compile any `requirements.in` files into a list of exact versions in `requirements.txt`.",
+    },
 ]
 
 cog_helpers.create_description_table(folder_name=folder_name, scripts=scripts)
@@ -35,5 +39,14 @@ cog_helpers.create_description_table(folder_name=folder_name, scripts=scripts)
   <dd>
     Format Python files with ruff.
   </dd>
+
+  <dt>
+    <a href="https://github.com/alexwlchan/scripts/blob/main/python/pip_compile">
+      <code>pip_compile (--upgrade)</code>
+    </a>
+  </dt>
+  <dd>
+    Compile any `requirements.in` files into a list of exact versions in `requirements.txt`.
+  </dd>
 </dl>
-<!-- [[[end]]] (checksum: 4c51b7cdb9a034e48bee58b82c75d99c) -->
+<!-- [[[end]]] (checksum: 3e15017c8de1c144defe8f18a08d38b1) -->

python/pip_compile (0) → python/pip_compile (1278)

diff --git a/python/pip_compile b/python/pip_compile
new file mode 100755
index 0000000..ef18e0e
--- /dev/null
+++ b/python/pip_compile
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+"""
+Compile any `requirements.in` files into a list of exact versions
+in `requirements.txt`.
+
+* If you pass the `--upgrade` flag, it will upgrade all the requirements
+  to the latest version.
+
+"""
+
+from pathlib import Path
+import shlex
+import subprocess
+import sys
+
+
+def compile_requirements_file(in_file: str, *, upgrade: bool) -> None:
+    """
+    Compile a single requirements file.
+    """
+    assert in_file.endswith(".in")
+    txt_file = in_file.replace(".in", ".txt")
+    assert in_file != txt_file
+
+    # If this `.in` file doesn't exist.
+    if not Path(in_file).exists():
+        return
+
+    # Construct the `uv pip compile` command.
+    cmd = ["uv", "pip", "compile", in_file, "--output-file", txt_file]
+
+    if upgrade:
+        cmd.append("--upgrade")
+
+    # Actually run the command, and print a debug entry for it
+    subprocess.check_call(
+        ["/Users/alexwlchan/repos/scripts/debug/print_info", f"-> {shlex.join(cmd)}"]
+    )
+    subprocess.check_call(cmd)
+
+
+if __name__ == "__main__":
+    upgrade = "--upgrade" in sys.argv
+
+    compile_requirements_file("requirements.in", upgrade=upgrade)
+    compile_requirements_file("script_requirements.in", upgrade=upgrade)
+    compile_requirements_file("dev_requirements.in", upgrade=upgrade)

requirements.txt (3792) → requirements.txt (3360)

diff --git a/requirements.txt b/requirements.txt
index fbe01f0..1b10f9b 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,34 +1,30 @@
 # This file was autogenerated by uv via the following command:
 #    uv pip compile requirements.in --output-file requirements.txt
-aiofiles==23.2.1
+aiofiles==24.1.0
     # via datasette
-anyio==4.1.0
+anyio==4.9.0
     # via httpx
-argcomplete==3.2.3
+argcomplete==3.6.2
     # via pipx
-asgi-csrf==0.9
+asgi-csrf==0.11
     # via datasette
-asgiref==3.7.2
+asgiref==3.8.1
     # via datasette
 attrs==25.3.0
     # via -r requirements.in
-backports-tarfile==1.2.0
-    # via jaraco-context
 beautifulsoup4==4.13.4
     # via -r requirements.in
-boto3==1.35.26
+boto3==1.38.0
     # via -r requirements.in
-botocore==1.35.26
+botocore==1.38.0
     # via
     #   boto3
     #   s3transfer
-certifi==2023.11.17
+certifi==2025.1.31
     # via
     #   httpcore
     #   httpx
-cffi==1.16.0
-    # via cryptography
-click==8.1.7
+click==8.1.8
     # via
     #   click-default-group
     #   datasette
@@ -41,27 +37,21 @@ click-default-group==1.2.4
     #   sqlite-utils
 cogapp==3.4.1
     # via -r requirements.in
-cryptography==42.0.7
-    # via secretstorage
 datasette==0.65.1
     # via
     #   -r requirements.in
     #   datasette-render-image-tags
 datasette-render-image-tags==0.1
     # via -r requirements.in
-exceptiongroup==1.2.2
-    # via
-    #   anyio
-    #   pytest
 flexcache==0.3
     # via datasette
-flexparser==0.3.1
+flexparser==0.4
     # via datasette
 h11==0.14.0
     # via
     #   httpcore
     #   uvicorn
-httpcore==1.0.2
+httpcore==1.0.8
     # via httpx
 httpx==0.28.1
     # via
@@ -69,36 +59,30 @@ httpx==0.28.1
     #   datasette
 humanize==4.12.2
     # via -r requirements.in
-hupper==1.12
+hupper==1.12.1
     # via datasette
 hyperlink==21.0.0
     # via -r requirements.in
-idna==3.6
+idna==3.10
     # via
     #   anyio
     #   httpx
     #   hyperlink
-importlib-metadata==8.6.1
-    # via keyring
-iniconfig==2.0.0
+iniconfig==2.1.0
     # via pytest
-itsdangerous==2.1.2
+itsdangerous==2.2.0
     # via
     #   asgi-csrf
     #   datasette
-janus==1.0.0
+janus==2.0.0
     # via datasette
-jaraco-classes==3.3.0
+jaraco-classes==3.4.0
     # via keyring
-jaraco-context==5.3.0
+jaraco-context==6.0.1
     # via keyring
-jaraco-functools==4.0.1
+jaraco-functools==4.1.0
     # via keyring
-jeepney==0.8.0
-    # via
-    #   keyring
-    #   secretstorage
-jinja2==3.1.3
+jinja2==3.1.6
     # via datasette
 jmespath==1.0.1
     # via
@@ -106,17 +90,17 @@ jmespath==1.0.1
     #   botocore
 keyring==25.6.0
     # via -r requirements.in
-markupsafe==2.1.3
+markupsafe==3.0.2
     # via jinja2
 mergedeep==1.3.4
     # via datasette
-more-itertools==10.1.0
+more-itertools==10.7.0
     # via
     #   jaraco-classes
     #   jaraco-functools
 naturalsort==1.5.1
     # via -r requirements.in
-packaging==23.2
+packaging==25.0
     # via
     #   pipx
     #   pytest
@@ -126,9 +110,11 @@ pillow==11.2.1
     #   pillow-heif
 pillow-heif==0.22.0
     # via -r requirements.in
+pip==25.0.1
+    # via datasette
 pipx==1.7.1
     # via -r requirements.in
-platformdirs==4.1.0
+platformdirs==4.3.7
     # via
     #   datasette
     #   pipx
@@ -137,33 +123,31 @@ pluggy==1.5.0
     #   datasette
     #   pytest
     #   sqlite-utils
-pycparser==2.22
-    # via cffi
 pygments==2.19.1
     # via -r requirements.in
 pypdf==5.4.0
     # via -r requirements.in
 pytest==8.3.5
     # via -r requirements.in
-python-dateutil==2.8.2
+python-dateutil==2.9.0.post0
     # via
     #   botocore
     #   sqlite-utils
-python-multipart==0.0.6
+python-multipart==0.0.20
     # via asgi-csrf
-pyyaml==6.0.1
+pyyaml==6.0.2
     # via datasette
 ruff==0.11.6
     # via -r requirements.in
-s3transfer==0.10.2
+s3transfer==0.12.0
     # via boto3
-secretstorage==3.3.3
-    # via keyring
-six==1.16.0
+setuptools==79.0.0
+    # via datasette
+six==1.17.0
     # via python-dateutil
-sniffio==1.3.0
+sniffio==1.3.1
     # via anyio
-soupsieve==2.5
+soupsieve==2.7
     # via beautifulsoup4
 sqlite-fts4==1.0.3
     # via sqlite-utils
@@ -173,29 +157,20 @@ tabulate==0.9.0
     # via sqlite-utils
 termcolor==3.0.1
     # via -r requirements.in
-tomli==2.2.1
-    # via
-    #   pipx
-    #   pytest
 tqdm==4.67.1
     # via -r requirements.in
-typing-extensions==4.9.0
+typing-extensions==4.13.2
     # via
-    #   asgiref
+    #   anyio
     #   beautifulsoup4
     #   datasette
     #   flexcache
     #   flexparser
-    #   janus
-    #   pypdf
-    #   uvicorn
-urllib3==1.26.20
+urllib3==2.4.0
     # via botocore
 userpath==1.9.2
     # via pipx
-uvicorn==0.25.0
+uvicorn==0.34.2
     # via datasette
 yt-dlp==2025.3.31
     # via -r requirements.in
-zipp==3.21.0
-    # via importlib-metadata