From 3e75e7df599d9546a159963ecdcc0658b130eeff Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 1 Oct 2026 00:28:45 +0000 Subject: [PATCH] Transpile the originals against the open-abap-core the runtime was built with scripts/originals.mjs cloned open-abap-core from HEAD, unpinned, so the differential test transpiled the ABAP originals against whatever open-abap-core was that day, while the translation runs on the one @abap2ui5/node-runtime was built against. A change in open-abap-core would have shown up as a difference between original and translation that is neither's. Today HEAD is c677145 and the runtime's commit b2d219d. The runtime records that commit in its package.json since 1.146.0 (abap2ui5.openAbapCore), next to the transpiler version the script already reads. Fetch exactly that commit - git init, fetch --depth 1 , checkout FETCH_HEAD, as node-runtime's README shows - and replace a .deps checkout that sits at another commit, so a stale clone from before this change is not kept. A runtime that does not record it (1.145.0) still gets the HEAD clone, with a warning that says why. Checked: npm run differential with abap2UI5/samples at the pin - 71 samples, 239 roundtrips, no difference - plus the fallback and the replacement of a stale checkout by hand. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01D4ictE8drLTLYcvFQ7tn9u --- CHANGELOG.md | 6 ++++++ README.md | 7 +++++-- scripts/originals.mjs | 26 ++++++++++++++++++++++---- 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05b2d42..67222b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ versions [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +- The differential test transpiles the originals against open-abap-core at the + commit `@abap2ui5/node-runtime` records in its `package.json` + (`abap2ui5.openAbapCore`) instead of HEAD, so the original runs on the + open-abap-core the translation runs on; a runtime that does not record it + (1.145.0) still gets HEAD, with a warning. + ## [0.2.0] - 2026-09-30 For `@cap2ui5/cds-plugin` 0.4.0, whose model carries only the fields an app diff --git a/README.md b/README.md index 2636241..9b0a010 100644 --- a/README.md +++ b/README.md @@ -176,8 +176,11 @@ sends, every other action and which app has the screen - today 71 samples in `Z2UI5_CL_SMP_APP_122` prints a number with `CONV string( )`, which keeps ABAP's trailing sign position (`"0 "`) and JavaScript's `String( )` does not. -It needs the network once (open-abap-core is cloned into `.deps/`) and -`@abaplint/transpiler-cli` at the runtime's version, a devDependency. +It needs the network once (open-abap-core is fetched into `.deps/` at the +commit @abap2ui5/node-runtime was built against - its `package.json` records +it as `abap2ui5.openAbapCore` - so that the original runs on the open-abap-core +the translation runs on) and `@abaplint/transpiler-cli` at the runtime's +version, a devDependency. ## What a translated sample looks like diff --git a/scripts/originals.mjs b/scripts/originals.mjs index 69e2b49..a52d895 100644 --- a/scripts/originals.mjs +++ b/scripts/originals.mjs @@ -12,7 +12,8 @@ // The runtime's own transpiler output is what cap2UI5 hosts, so the original // runs on exactly the framework the translation runs on. // -// Needs the network once: open-abap-core is cloned into .deps/. +// Needs the network once: open-abap-core is fetched into .deps/ - at the commit +// @abap2ui5/node-runtime was built against, which its package.json records. import { execFileSync } from "node:child_process"; import fs from "node:fs"; import { createRequire } from "node:module"; @@ -34,16 +35,33 @@ if (head !== pin) throw new Error(`${checkout} is at ${head}, ABAP2UI5_SAMPLES_P // the transpiler the runtime was built with: its output is tied to the runtime const runtimeDir = path.dirname(require.resolve("@abap2ui5/node-runtime/package.json", { paths: [require.resolve("@cap2ui5/cds-plugin")] })); -const wanted = JSON.parse(fs.readFileSync(path.join(runtimeDir, "package.json"), "utf8")).abap2ui5?.transpiler; +const built = JSON.parse(fs.readFileSync(path.join(runtimeDir, "package.json"), "utf8")).abap2ui5 ?? {}; +const wanted = built.transpiler; const have = JSON.parse(fs.readFileSync(require.resolve("@abaplint/transpiler-cli/package.json"), "utf8")).version; if (wanted && wanted !== have) { throw new Error(`@abaplint/transpiler-cli ${have} is installed, @abap2ui5/node-runtime was built with ${wanted} - ` + `npm i -D --save-exact @abaplint/transpiler-cli@${wanted}`); } +// open-abap-core at the commit the runtime was built against (abap2ui5.openAbapCore), +// so that the original is transpiled against the open-abap-core the runtime hosts +// it on - a clone of HEAD would run the original on a newer one than the translation. +// git clone takes no commit, so: init, fetch the one commit, check it out. const deps = path.join(ROOT, ".deps", "open-abap-core"); -if (!fs.existsSync(deps)) { - execFileSync("git", ["clone", "--depth", "1", "https://github.com/open-abap/open-abap-core", deps], { stdio: "inherit" }); +const core = "https://github.com/open-abap/open-abap-core"; +const checkedOut = fs.existsSync(deps) ? execFileSync("git", ["-C", deps, "rev-parse", "HEAD"], { encoding: "utf8" }).trim() : null; +if (built.openAbapCore) { + if (checkedOut !== built.openAbapCore) { + fs.rmSync(deps, { recursive: true, force: true }); + fs.mkdirSync(deps, { recursive: true }); + execFileSync("git", ["init", "-q", deps], { stdio: "inherit" }); + execFileSync("git", ["-C", deps, "fetch", "-q", "--depth", "1", core, built.openAbapCore], { stdio: "inherit" }); + execFileSync("git", ["-C", deps, "checkout", "-q", "FETCH_HEAD"], { stdio: "inherit" }); + } +} else if (!checkedOut) { + // node-runtime 1.145.0 and older did not record the commit + console.warn("originals: @abap2ui5/node-runtime does not record its open-abap-core commit (abap2ui5.openAbapCore) - cloning HEAD"); + execFileSync("git", ["clone", "--depth", "1", core, deps], { stdio: "inherit" }); } const work = fs.mkdtempSync(path.join(os.tmpdir(), "originals-"));