]> jfr.im git - yt-dlp.git/commitdiff
[devscripts] `install_deps`: Add script and migrate to it
authorbashonly <redacted>
Sun, 11 Feb 2024 14:17:08 +0000 (15:17 +0100)
committerSimon Sawicki <redacted>
Sun, 11 Feb 2024 18:09:03 +0000 (19:09 +0100)
Authored by: bashonly

.github/workflows/build.yml
.github/workflows/core.yml
.github/workflows/download.yml
.github/workflows/quick-test.yml
.github/workflows/release.yml
README.md
devscripts/install_deps.py [new file with mode: 0755]
requirements.txt [deleted file]

index 4b05e7cf93f80ec8b01a0f751b9dccd861d75983..082164c9e8cbaceb92f6baa731735fb5f8f3b9b4 100644 (file)
@@ -121,16 +121,14 @@ jobs:
       - name: Install Requirements
         run: |
           sudo apt -y install zip pandoc man sed
-          reqs=$(mktemp)
-          cat > "$reqs" << EOF
+          cat > ./requirements.txt << EOF
           python=3.10.*
-          pyinstaller
-          cffi
           brotli-python
-          secretstorage
           EOF
-          sed -E '/^(brotli|secretstorage).*/d' requirements.txt >> "$reqs"
-          mamba create -n build --file "$reqs"
+          python devscripts/install_deps.py --print \
+            --exclude brotli --exclude brotlicffi \
+            --include secretstorage --include pyinstaller >> ./requirements.txt
+          mamba create -n build --file ./requirements.txt
 
       - name: Prepare
         run: |
@@ -203,12 +201,13 @@ jobs:
             apt update
             apt -y install zlib1g-dev python3.8 python3.8-dev python3.8-distutils python3-pip
             python3.8 -m pip install -U pip setuptools wheel
-            # Cannot access requirements.txt from the repo directory at this stage
+            # Cannot access any files from the repo directory at this stage
             python3.8 -m pip install -U Pyinstaller mutagen pycryptodomex websockets brotli certifi secretstorage
 
           run: |
             cd repo
-            python3.8 -m pip install -U Pyinstaller secretstorage -r requirements.txt  # Cached version may be out of date
+            python3.8 devscripts/install_deps.py -o --include build
+            python3.8 devscripts/install_deps.py --include pyinstaller --include secretstorage  # Cached version may be out of date
             python3.8 devscripts/update-version.py -c "${{ inputs.channel }}" -r "${{ needs.process.outputs.origin }}" "${{ inputs.version }}"
             python3.8 devscripts/make_lazy_extractors.py
             python3.8 -m bundle.pyinstaller
@@ -240,9 +239,10 @@ jobs:
       - name: Install Requirements
         run: |
           brew install coreutils
-          python3 -m pip install -U --user pip setuptools wheel
+          python3 devscripts/install_deps.py --user -o --include build
+          python3 devscripts/install_deps.py --print --include pyinstaller > requirements.txt
           # We need to ignore wheels otherwise we break universal2 builds
-          python3 -m pip install -U --user --no-binary :all: Pyinstaller -r requirements.txt
+          python3 -m pip install -U --user --no-binary :all: -r requirements.txt
 
       - name: Prepare
         run: |
@@ -293,8 +293,8 @@ jobs:
       - name: Install Requirements
         run: |
           brew install coreutils
-          python3 -m pip install -U --user pip setuptools wheel
-          python3 -m pip install -U --user Pyinstaller -r requirements.txt
+          python3 devscripts/install_deps.py --user -o --include build
+          python3 devscripts/install_deps.py --user --include pyinstaller
 
       - name: Prepare
         run: |
@@ -333,8 +333,9 @@ jobs:
           python-version: "3.8"
       - name: Install Requirements
         run: | # Custom pyinstaller built with https://github.com/yt-dlp/pyinstaller-builds
-          python -m pip install -U pip setuptools wheel py2exe
-          pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/x86_64/pyinstaller-5.8.0-py3-none-any.whl" -r requirements.txt
+          python devscripts/install_deps.py -o --include build
+          python devscripts/install_deps.py --include py2exe
+          python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/x86_64/pyinstaller-5.8.0-py3-none-any.whl"
 
       - name: Prepare
         run: |
@@ -382,8 +383,9 @@ jobs:
           architecture: "x86"
       - name: Install Requirements
         run: |
-          python -m pip install -U pip setuptools wheel
-          pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-5.8.0-py3-none-any.whl" -r requirements.txt
+          python devscripts/install_deps.py -o --include build
+          python devscripts/install_deps.py
+          python -m pip install -U "https://yt-dlp.github.io/Pyinstaller-Builds/i686/pyinstaller-5.8.0-py3-none-any.whl"
 
       - name: Prepare
         run: |
index eaaf03dee4816f84b76a53ba05dd0851140f03a5..f694c9bdd115d18691bd88f0c5ec259f779ffa3b 100644 (file)
@@ -53,7 +53,7 @@ jobs:
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install test requirements
-      run: pip install pytest -r requirements.txt
+      run: python3 ./devscripts/install_deps.py --include dev
     - name: Run tests
       continue-on-error: False
       run: |
index 9f47d671874e7b003578a94ebb03b34b8b2ae3d5..84339d9700d6aa1c9498e2eaa348596cfad9857f 100644 (file)
@@ -15,7 +15,7 @@ jobs:
       with:
         python-version: 3.9
     - name: Install test requirements
-      run: pip install pytest -r requirements.txt
+      run: python3 ./devscripts/install_deps.py --include dev
     - name: Run tests
       continue-on-error: true
       run: python3 ./devscripts/run_tests.py download
@@ -42,7 +42,7 @@ jobs:
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install test requirements
-      run: pip install pytest -r requirements.txt
+      run: python3 ./devscripts/install_deps.py --include dev
     - name: Run tests
       continue-on-error: true
       run: python3 ./devscripts/run_tests.py download
index 84fca62d4ddb0eec0441d56ba10f853a48274f34..4e9616926e8c8c9668ca5f8b91b2021e2f73f463 100644 (file)
@@ -15,7 +15,7 @@ jobs:
       with:
         python-version: '3.8'
     - name: Install test requirements
-      run: pip install pytest -r requirements.txt
+      run: python3 ./devscripts/install_deps.py --include dev
     - name: Run tests
       run: |
         python3 -m yt_dlp -v || true
@@ -28,8 +28,8 @@ jobs:
     - uses: actions/checkout@v4
     - uses: actions/setup-python@v4
     - name: Install flake8
-      run: pip install flake8
+      run: python3 ./devscripts/install_deps.py -o --include dev
     - name: Make lazy extractors
-      run: python devscripts/make_lazy_extractors.py
+      run: python3 ./devscripts/make_lazy_extractors.py
     - name: Run flake8
       run: flake8 .
index d1508e5e6ce0d6dd3feda57b7691c7e7f91e6ab6..1653add4f09e16859a54d1470c50cc6724196a85 100644 (file)
@@ -253,8 +253,7 @@ jobs:
       - name: Install Requirements
         run: |
           sudo apt -y install pandoc man
-          python -m pip install -U pip setuptools wheel twine
-          python -m pip install -U -r requirements.txt
+          python devscripts/install_deps.py -o --include build
 
       - name: Prepare
         env:
index c74777d2f56e2cb65a863a8d9beebeee84cea092..2fcb099176bc1feeeb1b925da192273076097c64 100644 (file)
--- a/README.md
+++ b/README.md
@@ -324,7 +324,7 @@ ### Standalone PyInstaller Builds
 To build the standalone executable, you must have Python and `pyinstaller` (plus any of yt-dlp's [optional dependencies](#dependencies) if needed). The executable will be built for the same architecture (x86/ARM, 32/64 bit) as the Python used. You can run the following commands:
 
 ```
-python3 -m pip install -U pyinstaller -r requirements.txt
+python3 devscripts/install_deps.py --include pyinstaller
 python3 devscripts/make_lazy_extractors.py
 python3 -m bundle.pyinstaller
 ```
@@ -351,13 +351,14 @@ ### Standalone Py2Exe Builds (Windows)
 If you wish to build it anyway, install Python (if it is not already installed) and you can run the following commands:
 
 ```
-py -m pip install -U py2exe -r requirements.txt
+py devscripts/install_deps.py --include py2exe
 py devscripts/make_lazy_extractors.py
 py -m bundle.py2exe
 ```
 
 ### Related scripts
 
+* **`devscripts/install_deps.py`** - Install dependencies for yt-dlp.
 * **`devscripts/update-version.py`** - Update the version number based on current date.
 * **`devscripts/set-variant.py`** - Set the build variant of the executable.
 * **`devscripts/make_changelog.py`** - Create a markdown changelog using short commit messages and update `CONTRIBUTORS` file.
diff --git a/devscripts/install_deps.py b/devscripts/install_deps.py
new file mode 100755 (executable)
index 0000000..715e5b0
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+# Allow execution from anywhere
+import os
+import sys
+
+sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+
+import argparse
+import re
+import subprocess
+
+from devscripts.tomlparse import parse_toml
+from devscripts.utils import read_file
+
+
+def parse_args():
+    parser = argparse.ArgumentParser(description='Install dependencies for yt-dlp')
+    parser.add_argument(
+        'input', nargs='?', metavar='TOMLFILE', default='pyproject.toml', help='Input file (default: %(default)s)')
+    parser.add_argument(
+        '-e', '--exclude', metavar='REQUIREMENT', action='append', help='Exclude a required dependency')
+    parser.add_argument(
+        '-i', '--include', metavar='GROUP', action='append', help='Include an optional dependency group')
+    parser.add_argument(
+        '-o', '--only-optional', action='store_true', help='Only install optional dependencies')
+    parser.add_argument(
+        '-p', '--print', action='store_true', help='Only print a requirements.txt to stdout')
+    parser.add_argument(
+        '-u', '--user', action='store_true', help='Install with pip as --user')
+    return parser.parse_args()
+
+
+def main():
+    args = parse_args()
+    toml_data = parse_toml(read_file(args.input))
+    deps = toml_data['project']['dependencies']
+    targets = deps.copy() if not args.only_optional else []
+
+    for exclude in args.exclude or []:
+        for dep in deps:
+            simplified_dep = re.match(r'[\w-]+', dep)[0]
+            if dep in targets and (exclude.lower() == simplified_dep.lower() or exclude == dep):
+                targets.remove(dep)
+
+    optional_deps = toml_data['project']['optional-dependencies']
+    for include in args.include or []:
+        group = optional_deps.get(include)
+        if group:
+            targets.extend(group)
+
+    if args.print:
+        for target in targets:
+            print(target)
+        return
+
+    pip_args = [sys.executable, '-m', 'pip', 'install', '-U']
+    if args.user:
+        pip_args.append('--user')
+    pip_args.extend(targets)
+
+    return subprocess.call(pip_args)
+
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644 (file)
index 06ff82a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-mutagen
-pycryptodomex
-brotli; implementation_name=='cpython'
-brotlicffi; implementation_name!='cpython'
-certifi
-requests>=2.31.0,<3
-urllib3>=1.26.17,<3
-websockets>=12.0