diff --git a/crates/puffin-cli/tests/pip_install_scenarios.rs b/crates/puffin-cli/tests/pip_install_scenarios.rs index be319b4f1..57aa26015 100644 --- a/crates/puffin-cli/tests/pip_install_scenarios.rs +++ b/crates/puffin-cli/tests/pip_install_scenarios.rs @@ -1,6 +1,6 @@ #![cfg(all(feature = "python", feature = "pypi"))] -/// Generated by `scripts/scenarios/generate.py` +/// Generated by `./scripts/scenarios/update.py` use std::process::Command; use anyhow::Result; diff --git a/scripts/scenarios/generate.py b/scripts/scenarios/generate.py deleted file mode 100644 index 70ada520b..000000000 --- a/scripts/scenarios/generate.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/env python3 -# -# Generates snapshot test cases from packse scenarios. -# -# Usage: -# $ scripts/scenarios/generate.py > crates/puffin-cli/tests/pip_install_scenarios.rs - -try: - import packse -except ImportError: - print("packse must be installed") - exit(1) - - -try: - import chevron_blue -except ImportError: - print("chevron-blue must be installed") - exit(1) - - -import sys -import subprocess -import json -from pathlib import Path - -__dir__ = Path(__file__).parent - -TEMPLATE = __dir__ / "template.mustache" -DATA = __dir__ / "data.json" - -data = json.loads( - subprocess.check_output( - [ - "packse", - "inspect", - str(packse.__development_base_path__ / "scenarios"), - ], - ) -) - -# Add a generated -data["generated_by"] = f"Generated by `{' '.join(sys.argv)}`" - -# Add normalized names for tests -for scenario in data["scenarios"]: - scenario["normalized_name"] = scenario["name"].replace("-", "_") - -# Drop the example scenario -for index, scenario in enumerate(data["scenarios"]): - if scenario["name"] == "example": - data["scenarios"].pop(index) - -output = chevron_blue.render(template=TEMPLATE.read_text(), data=data, no_escape=True) - -print(output) diff --git a/scripts/scenarios/requirements.txt b/scripts/scenarios/requirements.txt new file mode 100644 index 000000000..33dd676c3 --- /dev/null +++ b/scripts/scenarios/requirements.txt @@ -0,0 +1,2 @@ +chevron-blue==0.2.1 +packse @ git+https://github.com/zanieb/packse diff --git a/scripts/scenarios/update.py b/scripts/scenarios/update.py new file mode 100755 index 000000000..6981cae39 --- /dev/null +++ b/scripts/scenarios/update.py @@ -0,0 +1,143 @@ +#!/usr/bin/env python3 +# +# Generates and updates snapshot test cases from packse scenarios. +# +# Usage: +# +# $ scripts/scenarios/update.py +# +# Requirements: +# +# Requires `packse` and `chevron-blue`. +# +# $ pip install -r scripts/scenarios/requirements.txt +# +# Also supports a local, editable requirement on `packse`. +# +# Uses `git`, `rustfmt`, and `cargo insta test` requirements from the project. + +import json +import shutil +import subprocess +import sys +from pathlib import Path + +TOOL_ROOT = Path(__file__).parent +TEMPLATE = TOOL_ROOT / "template.mustache" +PACKSE = TOOL_ROOT / "packse-scenarios" +REQUIREMENTS = TOOL_ROOT / "requirements.txt" +PROJECT_ROOT = TOOL_ROOT.parent.parent +TARGET = PROJECT_ROOT / "crates" / "puffin-cli" / "tests" / "pip_install_scenarios.rs" + +try: + import packse +except ImportError: + print( + f"missing requirement `packse`: install the requirements at {REQUIREMENTS.relative_to(PROJECT_ROOT)}", + file=sys.stderr, + ) + exit(1) + + +try: + import chevron_blue +except ImportError: + print( + f"missing requirement `chevron-blue`: install the requirements at {REQUIREMENTS.relative_to(PROJECT_ROOT)}", + file=sys.stderr, + ) + exit(1) + + +if packse.__development_base_path__.name != "packse": + # Not a local editable installation, download latest scenarios + if PACKSE.exists(): + shutil.rmtree(PACKSE) + + print("Downloading scenarios from packse repository...", file=sys.stderr) + # Perform a sparse checkout where we only grab the `scenarios` folder + subprocess.check_call( + [ + "git", + "clone", + "-n", + "--depth=1", + "--filter=tree:0", + "https://github.com/zanieb/packse", + str(PACKSE), + ], + cwd=TOOL_ROOT, + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT, + ) + subprocess.check_call( + ["git", "sparse-checkout", "set", "--no-cone", "scenarios"], + cwd=PACKSE, + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT, + ) + subprocess.check_call( + ["git", "checkout"], + cwd=PACKSE, + stdout=subprocess.DEVNULL, + stderr=subprocess.STDOUT, + ) + scenarios_path = str(PACKSE / "scenarios") +else: + print("Using local packse scenarios...", file=sys.stderr) + scenarios_path = str(packse.__development_base_path__ / "scenarios") + + +print("Loading scenario metadata...", file=sys.stderr) +data = json.loads( + subprocess.check_output( + [ + "packse", + "inspect", + scenarios_path, + ], + ) +) + +# Add a generated note +data["generated_by"] = f"Generated by `{' '.join(sys.argv)}`" + +# Add normalized names for tests +for scenario in data["scenarios"]: + scenario["normalized_name"] = scenario["name"].replace("-", "_") + +# Drop the example scenario +for index, scenario in enumerate(data["scenarios"]): + if scenario["name"] == "example": + data["scenarios"].pop(index) + +# Render the template +print("Rendering template...", file=sys.stderr) +output = chevron_blue.render(template=TEMPLATE.read_text(), data=data, no_escape=True) + +# Update the test file +print(f"Updating test file at `{TARGET.relative_to(PROJECT_ROOT)}`...", file=sys.stderr) +with open(TARGET, "wt") as target_file: + target_file.write(output) + +# Format +print("Formatting test file...", file=sys.stderr) +subprocess.check_call(["rustfmt", str(TARGET)]) + +# Update snapshots +print("Updating snapshots...\n", file=sys.stderr) +subprocess.call( + [ + "cargo", + "insta", + "test", + "--accept", + "--test", + TARGET.with_suffix("").name, + "--features", + "pypi,python", + ], + cwd=PROJECT_ROOT, +) + +print("\nDone!", file=sys.stderr)