From c42c0be99b56b8f9e9d0ee23addeda3ddbc5a5e9 Mon Sep 17 00:00:00 2001 From: n1ckyb Date: Sat, 8 Aug 2026 04:19:33 +0100 Subject: [PATCH] fix: repair the four defects that forced 0.0.1 to be pulled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every one of these was invisible to CI and obvious within thirty seconds of installing the published wheel. Nothing in the pipeline ever did that. 1. THE ONE THAT BROKE THE PRODUCT. _TRUSTED_PLUGIN_PACKAGE_NAMES listed "intentumdiff" — the IMPORT name — but entry points report the DISTRIBUTION, which is "intentumdiff-python". So the package failed its own first-party check, treated all 69 built-in parsers as untrusted third-party plugins, and refused them with a security warning naming itself as the culprit. Every invocation printed ~69 error lines about "arbitrary code execution" before returning a result. No repo test could see it: in a source checkout the distribution resolves differently and the check passes. It exists only in an installed wheel. 2. `python -m intentumdiff` failed with "cannot be directly executed" — there was no __main__.py. READMEs reach for `python -m` constantly, and it is what people use when the console script is not on PATH. 3. The plugin error pointed at https://docs.intentumdiff.dev/plugins/metadata, a domain that is not registered — so it failed DNS, not merely 404. Now points at docs/PLUGIN_GUIDE.md, which exists. 4. The README's headline example could not run: `old` and `new` were never defined, so a user copying it got NameError on line 3. It is now a complete, runnable program, and the output shown is its real output. Adds scripts/smoke_published_wheel.py, which installs the published artefact into a clean venv and uses it as a user would: install, import, console script, python -m, a real diff, CLEAN STDERR, and every URL in the output resolving. Run against 0.0.1 it fails three checks — exactly the ones above. That is the point: it reproduces the shipped bugs rather than asserting they are absent. Verified: the README example was extracted from the file and run verbatim against a patched install; it prints the documented output. Co-Authored-By: Claude Opus 4.8 --- README.md | 19 +++ scripts/smoke_published_wheel.py | 171 +++++++++++++++++++++++++++ src/intentumdiff/__main__.py | 12 ++ src/intentumdiff/plugins/registry.py | 14 ++- 4 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 scripts/smoke_published_wheel.py create mode 100644 src/intentumdiff/__main__.py diff --git a/README.md b/README.md index 59daedd..40cf0a3 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,30 @@ does zero functional work. ```python from intentumdiff import SemanticDiffer +old = """def greet(name): + return "hi " + name +""" + +new = """def greet(name): + if not name: + return None + return "hi " + name +""" + diff = SemanticDiffer().diff_strings(old, new, "example.py") for change in diff.changes: print(change.change_type, change.description) ``` +Running that prints one change — the added guard clause: + +```text +ChangeType.ADDITION Insert -> if_statement('if_statement') +``` + +Reformat the same file — change the quotes, rewrap the lines, add blank lines — and +IntentumDiff reports **no changes at all**. That is the point: it compares meaning, not text. + ## Building from source The wheel bundles two provisioned build inputs — the engine and the parser components: diff --git a/scripts/smoke_published_wheel.py b/scripts/smoke_published_wheel.py new file mode 100644 index 0000000..f5163a4 --- /dev/null +++ b/scripts/smoke_published_wheel.py @@ -0,0 +1,171 @@ +"""Install the PUBLISHED wheel into a clean venv and use it as a user would. + +# Why this exists + +IntentumDiff 0.0.1 shipped broken and had to be pulled. Every invocation printed ~69 +"Failed to catalog parser plugin" errors, because the distribution name +(`intentumdiff-python`) was missing from the package's own first-party trust list, so all +69 built-in parsers were refused as untrusted third-party code. + +**No test in the repo could have caught it.** In a source checkout the distribution resolves +differently, so the trust check passed. The bug only exists in an installed wheel — and +nothing in CI ever installed one and ran it. + +That is the gap this closes: CI proves the code builds; this proves the ARTEFACT works. + +# What it checks + +Everything a new user does in their first five minutes, in order: + +1. `pip install` from the index into an empty venv +2. `import intentumdiff` +3. the console script runs +4. `python -m intentumdiff` works +5. a real diff produces a real result +6. **stderr is CLEAN** — the check that would have caught 0.0.1 +7. every URL in the error catalogue actually resolves + +Usage: + python scripts/smoke_published_wheel.py # from PyPI + python scripts/smoke_published_wheel.py --wheel dist/x.whl # a local build, pre-publish +""" + +from __future__ import annotations + +import argparse +import shutil +import subprocess +import sys +import tempfile +import venv +from pathlib import Path + +# A diff with an obvious right answer: a guard clause is added, so exactly one change. +OLD_SRC = "def greet(name):\n return 'hi ' + name\n" +NEW_SRC = "def greet(name):\n if not name:\n return None\n return 'hi ' + name\n" + +USE_SCRIPT = """ +from intentumdiff import SemanticDiffer +old = {old!r} +new = {new!r} +diff = SemanticDiffer().diff_strings(old, new, "example.py") +print("CHANGES", len(diff.changes)) +""" + + +class Smoke: + def __init__(self, root: Path) -> None: + self.root = root + self.py = ( + root / ".venv" / ("Scripts" if sys.platform == "win32" else "bin") + / ("python.exe" if sys.platform == "win32" else "python") + ) + self.failures: list[str] = [] + + def check(self, name: str, ok: bool, detail: str = "") -> None: + print(f" {'PASS' if ok else 'FAIL'} {name}") + if not ok: + if detail: + print(f" {detail.strip()[:400]}") + self.failures.append(name) + + def run(self, *args: str, **kw) -> subprocess.CompletedProcess[str]: + return subprocess.run( + [str(self.py), *args], capture_output=True, text=True, + encoding="utf-8", errors="replace", cwd=self.root, **kw + ) + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--wheel", help="local wheel or sdist; defaults to installing from PyPI") + ap.add_argument("--package", default="intentumdiff-python") + args = ap.parse_args() + + root = Path(tempfile.mkdtemp(prefix="intentumdiff-smoke-")) + print(f" clean environment: {root}\n") + try: + venv.create(root / ".venv", with_pip=True) + s = Smoke(root) + + # 1. Install exactly as a user would. + target = args.wheel or args.package + r = s.run("-m", "pip", "install", "--quiet", target) + s.check(f"pip install {target}", r.returncode == 0, r.stderr) + if r.returncode != 0: + return report(s) + + # 2. Import. + r = s.run("-c", "import intentumdiff; print(intentumdiff.__version__)") + s.check("import intentumdiff", r.returncode == 0, r.stderr) + version = r.stdout.strip() + + # 3. Console script — the documented entry point. + exe = s.py.parent / ("intentumdiff.exe" if sys.platform == "win32" else "intentumdiff") + r2 = subprocess.run([str(exe), "--version"], capture_output=True, text=True, + encoding="utf-8", errors="replace") + s.check("console script `intentumdiff --version`", r2.returncode == 0, r2.stderr) + + # 4. `python -m` — READMEs reach for this constantly, so it must work. + r = s.run("-m", "intentumdiff", "--version") + s.check("python -m intentumdiff", r.returncode == 0, r.stderr) + + # 5. A real diff with a known-correct answer. + script = root / "use.py" + script.write_text(USE_SCRIPT.format(old=OLD_SRC, new=NEW_SRC), encoding="utf-8") + r = s.run(str(script)) + s.check("SemanticDiffer produces a diff", "CHANGES" in r.stdout, r.stderr) + + # 6. THE ONE THAT MATTERS. 0.0.1 emitted ~69 plugin-catalogue errors on every + # invocation while still returning a result, so exit code alone said "fine". + noise = [ + ln for ln in r.stderr.splitlines() + if ln.strip() and "Failed to catalog" in ln + ] + s.check( + "no plugin-catalogue errors on stderr", + not noise, + f"{len(noise)} error line(s), first: {noise[0] if noise else ''}", + ) + + # 7. Every URL the package tells users to visit must resolve. 0.0.1 pointed at + # docs.intentumdiff.dev, which does not exist. + import re + import urllib.error + import urllib.request + + urls = sorted(set(re.findall(r"https?://[^\s'\"<>)\]]+", r.stderr))) + dead = [] + for u in urls: + try: + req = urllib.request.Request(u, method="HEAD", + headers={"User-Agent": "intentumdiff-smoke"}) + with urllib.request.urlopen(req, timeout=10) as resp: + if resp.status >= 400: + dead.append(f"{u} -> {resp.status}") + except urllib.error.HTTPError as e: + dead.append(f"{u} -> {e.code}") + except Exception as e: # DNS failure counts: the domain does not exist + dead.append(f"{u} -> {type(e).__name__}") + s.check( + f"all {len(urls)} URL(s) in output resolve", + not dead, + "; ".join(dead[:3]), + ) + + print(f"\n version under test: {version or '(unknown)'}") + return report(s) + finally: + shutil.rmtree(root, ignore_errors=True) + + +def report(s: Smoke) -> int: + if s.failures: + print(f"\n SMOKE FAILED: {len(s.failures)} check(s) — {', '.join(s.failures)}") + return 1 + print("\n SMOKE PASSED") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/src/intentumdiff/__main__.py b/src/intentumdiff/__main__.py new file mode 100644 index 0000000..ef83b92 --- /dev/null +++ b/src/intentumdiff/__main__.py @@ -0,0 +1,12 @@ +"""Enable `python -m intentumdiff`. + +The console script alone is not enough: `python -m` is what people reach for when the +script is not on PATH (a venv they have not activated, CI, a container), and READMEs use +it constantly. 0.0.1 shipped without this module, so the invocation failed with an +unhelpful "cannot be directly executed". +""" + +from intentumdiff.cli import main + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/intentumdiff/plugins/registry.py b/src/intentumdiff/plugins/registry.py index cfd4bbe..1a8c1b3 100644 --- a/src/intentumdiff/plugins/registry.py +++ b/src/intentumdiff/plugins/registry.py @@ -70,6 +70,18 @@ # trusted plugin metadata. _TRUSTED_PLUGIN_PACKAGE_NAMES: frozenset[str] = frozenset( { + # The DISTRIBUTION name, which is not the import name. The wheel is published as + # `intentumdiff-python` (the polyglot-binding convention) while the import package + # is `intentumdiff`, and entry points report the DISTRIBUTION. + # + # Omitting it made the package fail its own first-party check: all 69 built-in + # parsers were treated as untrusted third-party plugins and refused with a security + # warning naming the package itself as the culprit. Every invocation printed ~69 + # error lines before producing output. Shipped in 0.0.1 and only found by installing + # the published wheel — no test in the repo could see it, because in a source + # checkout the distribution resolves differently. + "intentumdiff-python", + "intentumdiff_python", "intentumdiff", "intentumdiff-dbt", "intentumdiff_dbt", @@ -275,7 +287,7 @@ def _wasm_path_from_ep(ep: importlib.metadata.EntryPoint) -> str: "execute arbitrary code before Wasm sandboxing is in effect. " f"The plugin author must add '{_WASM_PATH_METADATA_FIELD}: ' " "to their package metadata. " - "See: https://docs.intentumdiff.dev/plugins/metadata" + "See: https://github.com/buchochelliq-labs/intentumdiff-python/blob/main/docs/PLUGIN_GUIDE.md" ) # Locate the file via importlib.metadata without importing anything.