3 Commits
0.3.1 ... 0.3.2

Author SHA1 Message Date
bashonly
06d71457ef Bump actions/checkout to v6 (#36) 2025-12-07 22:37:46 +00:00
Simon Sawicki
3e76dde153 Use pnpm binary if available (#35) 2025-12-07 19:27:53 +01:00
Simon Sawicki
4f1d91dbb1 Switch to pnpm (#33)
Fixes #29
2025-12-03 23:00:59 +00:00
10 changed files with 1926 additions and 1357 deletions

View File

@@ -23,7 +23,7 @@ jobs:
name: Ruff format check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: astral-sh/ruff-action@v3
with:
args: "check --output-format github"
@@ -32,7 +32,7 @@ jobs:
name: Ruff linting check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- uses: astral-sh/ruff-action@v3
with:
args: "format --check --diff"
@@ -41,33 +41,33 @@ jobs:
name: Prettier check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Deno v2.x (latest)
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Install Deno requirements
- name: Install requirements
run: |
deno install
python pnpm.py install --frozen-lockfile
- name: Run Prettier check
run: |
deno task fmt:check
python pnpm.py fmt:check
eslint:
name: ESLint check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Deno v2.x (latest)
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Install Deno requirements
- name: Install requirements
run: |
deno install
python pnpm.py install --frozen-lockfile
- name: Run ESLint check
run: |
deno task lint
python pnpm.py lint
python_tests:
name: Python tests
@@ -78,7 +78,7 @@ jobs:
runner: [ubuntu-latest, windows-latest]
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Deno v2.x (latest)
@@ -112,17 +112,14 @@ jobs:
name: Prepare JS runtime tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install Deno v2.x (latest)
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Install Deno requirements
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v4 # respects packageManager version in package.json
- name: Install requirements
run: |
deno install
python pnpm.py install --frozen-lockfile
- name: Build control bundle
run: |
deno task bundle
python pnpm.py run bundle
- name: Generate bundle hashes
run: |
pushd dist
@@ -143,6 +140,10 @@ jobs:
path: |
src/yt/solver/test/players
key: test-player-js-${{ hashFiles('src/yt/solver/test/tests.ts') }}
- name: Install Deno v2.x (latest)
uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- name: Download player JS files
run: |
deno run \
@@ -165,7 +166,7 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Deno
@@ -189,7 +190,7 @@ jobs:
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
- name: Install Deno requirements
run: |
deno install
python pnpm.py install --frozen-lockfile
- name: Bundle with Deno
run: |
deno task bundle
@@ -208,14 +209,14 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Deno
uses: denoland/setup-deno@v2
with:
deno-version: "2.0.0" # minimum supported version
- name: Install Deno requirements
run: |
deno install
python pnpm.py install --frozen-lockfile
- name: Download player JS artifact
uses: actions/download-artifact@v5
with:
@@ -232,7 +233,7 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Bun
@@ -256,7 +257,7 @@ jobs:
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
- name: Install Bun requirements
run: |
bun install
python pnpm.py install --frozen-lockfile
- name: Bundle with Bun
run: |
bun --bun run bundle
@@ -275,14 +276,14 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: "1.2.11" # XXX: We support 1.0.31, but test suite requires 1.2.11+
- name: Install Bun requirements
run: |
bun install
python pnpm.py install --frozen-lockfile
- name: Download player JS artifact
uses: actions/download-artifact@v5
with:
@@ -297,7 +298,7 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install Node
@@ -321,7 +322,7 @@ jobs:
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
- name: Install Node requirements
run: |
npm install
python pnpm.py install --frozen-lockfile
- name: Bundle with Node
run: |
npm run bundle
@@ -340,14 +341,14 @@ jobs:
needs: [prepare]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install Node
uses: actions/setup-node@v6
with:
node-version: "22.18" # XXX: We support 20.0, but test suite requires 22.18+
- name: Install Node requirements
run: |
npm install
python pnpm.py install --frozen-lockfile
- name: Download player JS artifact
uses: actions/download-artifact@v5
with:

View File

@@ -12,7 +12,7 @@ jobs:
name: Build artifacts
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: denoland/setup-deno@v2
@@ -37,7 +37,7 @@ jobs:
compression-level: 0
- name: Build JavaScript artifacts
run: |
deno install --frozen
python pnpm.py install --frozen-lockfile
deno task bundle
- name: Upload JavaScript artifacts
uses: actions/upload-artifact@v4
@@ -73,7 +73,7 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
fetch-depth: 0
- uses: actions/download-artifact@v5

1
.gitignore vendored
View File

@@ -3,6 +3,7 @@
/yt_dlp_ejs/_version.py
/node_modules
/bun.lock
/deno.lock
/package-lock.json
/.idea
/.venv

View File

@@ -12,9 +12,13 @@ pip install -U yt-dlp-ejs
## Development
While this project does pin its dependencies,
it only provides a lockfile for building with `deno`.
You may install dependencies using any compatible package manager.
The project uses [`pnpm`](<https://github.com/pnpm/pnpm>) as a package manager with
dependencies pinned through `pnpm-lock.yaml`.
If you only have Python and a JS runtime you may instead invoke `./pnpm.py`,
which will transparently invoke one of the supported JS runtimes to call `pnpm`.
This pure JavaScript approach should be runtime agnostic.
If you notice differences between different runtimes' builds
please open an issue [here](<https://github.com/yt-dlp/ejs/issues/new>).
@@ -26,34 +30,27 @@ The build hook will automatically invoke `deno`, `bun` or `node` as required.
Alternatively, to only build the JavaScript files you can run the `bundle` script manually:
```bash
# Deno:
deno install --frozen
deno task bundle
# Bun:
bun install
bun --bun run bundle
# Node:
npm install
npm run bundle
python pnpm.py install --frozen-lockfile
python pnpm.py run bundle
```
This will automatically select an available runtime and invoke `pnpm` to build it.
### Tests
First, make sure the project's dependencies are installed and download the player JS files:
```bash
# Deno:
deno install --frozen
python pnpm.py install --frozen-lockfile
deno run src/yt/solver/test/download.ts
# Bun:
bun install
python pnpm.py install --frozen-lockfile
bun --bun run src/yt/solver/test/download.ts
# Node 22.6+:
npm install
python pnpm.py install --frozen-lockfile
node --experimental-strip-types src/yt/solver/test/download.ts
```
@@ -74,6 +71,6 @@ node --test
This code is licensed under [Unlicense](<https://unlicense.org/>).
An exception to this are the prebuilt wheels, which contain both
An exception to this is the prebuilt wheels, which contain both
[`meriyah`](<https://github.com/meriyah/meriyah>) and [`astring`](<https://github.com/davidbonnet/astring>),
licensed under [`ISC`](<https://github.com/meriyah/meriyah?tab=ISC-1-ov-file>) and [`MIT`](<https://github.com/davidbonnet/astring?tab=MIT-1-ov-file>), respectively.

1262
deno.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,42 +0,0 @@
import os
import shutil
import subprocess
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
class CustomBuildHook(BuildHookInterface):
def initialize(self, version, build_data):
if shutil.which("deno"):
print("Building with deno...", flush=True)
os.environ["DENO_NO_UPDATE_CHECK"] = "1"
subprocess.run(["deno", "install", "--frozen"], check=True)
subprocess.run(["deno", "task", "bundle"], check=True)
elif shutil.which("bun"):
print("Building with bun...", flush=True)
subprocess.run(["bun", "install"], check=True)
subprocess.run(["bun", "--bun", "run", "bundle"], check=True)
elif shutil.which("npm"):
print("Building with npm...", flush=True)
# npm is a batch file (`npm.cmd`) on windows, which requires `shell=True`
requires_shell = os.name == "nt"
subprocess.run(["npm", "install"], check=True, shell=requires_shell)
subprocess.run(["npm", "run", "bundle"], check=True, shell=requires_shell)
else:
raise RuntimeError(
"One of 'deno', 'bun', or 'npm' could not be found. "
"Please install one of them to proceed with the build."
)
build_data["force_include"].update(
{
"dist/yt.solver.core.min.js": "yt_dlp_ejs/yt/solver/core.min.js",
"dist/yt.solver.lib.min.js": "yt_dlp_ejs/yt/solver/lib.min.js",
}
)
def clean(self, versions):
shutil.rmtree("node_modules", ignore_errors=True)

View File

@@ -25,5 +25,6 @@
"rollup": "4.52.5",
"rollup-plugin-license": "3.6.0",
"typescript-eslint": "8.46.2"
}
},
"packageManager": "pnpm@10.24.0"
}

1782
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

90
pnpm.py Executable file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env python
import json
import os
import pathlib
import shutil
import subprocess
try:
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
except ImportError:
BuildHookInterface = object
class CustomBuildHook(BuildHookInterface):
def initialize(self, version, build_data):
name, pnpm = build_pnpm()
if pnpm is None:
raise RuntimeError(
"One of 'deno', 'bun', or 'npm' could not be found. "
"Please install one of them to proceed with the build."
)
print(f"Building with {name}...")
pnpm(["install", "--frozen-lockfile"])
pnpm(["run", "bundle"])
build_data["force_include"].update(
{
"dist/yt.solver.core.min.js": "yt_dlp_ejs/yt/solver/core.min.js",
"dist/yt.solver.lib.min.js": "yt_dlp_ejs/yt/solver/lib.min.js",
}
)
def clean(self, versions):
shutil.rmtree("node_modules", ignore_errors=True)
def build_pnpm():
package_json = pathlib.Path(__file__).with_name("package.json")
with package_json.open("rb") as file:
data = json.load(file)
package_manager = data["packageManager"]
env = os.environ.copy()
if pnpm := shutil.which("pnpm"):
name = "pnpm binary"
cmd = [pnpm]
elif deno := shutil.which("deno"):
name = "deno"
env["DENO_NO_UPDATE_CHECK"] = "1"
cmd = [
deno,
"run",
"--allow-all",
"--node-modules-dir=none",
f"npm:{package_manager}",
]
elif bun := shutil.which("bun"):
name = "bun"
cmd = [bun, "x", package_manager]
elif npm := shutil.which("npm"):
name = "npm (node)"
cmd = [npm, "exec", "--", package_manager]
else:
return None, None
def run_pnpm(args: list[str]):
return subprocess.check_call([*cmd, *args], env=env)
return name, run_pnpm
if __name__ == "__main__":
import sys
name, pnpm = build_pnpm()
if pnpm is None:
print("ERROR: No suitable JavaScript runtime found", file=sys.stderr)
sys.exit(128)
print(f"Calling {name}...", file=sys.stderr)
try:
pnpm(sys.argv[1:])
except subprocess.CalledProcessError as error:
sys.exit(error.returncode)

View File

@@ -57,6 +57,7 @@ packages = ["yt_dlp_ejs"]
version-file = "yt_dlp_ejs/_version.py"
[tool.hatch.build.targets.wheel.hooks.custom]
path = "pnpm.py"
[tool.ruff.lint]
select = [