From f0a9c1b0c64b77b6c137c23e753755b6dc0850ea Mon Sep 17 00:00:00 2001 From: oxura Date: Sun, 11 Oct 2026 21:37:14 +0600 Subject: [PATCH 1/4] fix(cli): stop checkup at the end of the import header --- README.md | 2 ++ bend2/main.ts | 9 ++++++++- gates/ping.ts | 12 ++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 02737ec3e7..f3f7a0bd75 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,8 @@ def add_zero(x): - Formatter: [bend-fmt-lsp](tools/bend-fmt-lsp), a formatting-only Bend 2 language server. - Community language server: [bend2-lsp](https://github.com/don2e4/bend2-lsp), with formatting, diagnostics, and hover. - Community workshop: [Bend 2 pocket workshop](https://np.github.io/bend-workshop/), the checker and JS compiler in one HTML page, with goals and proof tools, phone first. +- `--checkup` checks and runs the initial import header independently; + definitions and multiline string bodies do not add imports. # Community diff --git a/bend2/main.ts b/bend2/main.ts index f262925086..9e53e002c2 100755 --- a/bend2/main.ts +++ b/bend2/main.ts @@ -331,8 +331,15 @@ async function cli_checkup(file: string): Promise { const base = await book_read(BASE); let bad = false; for (const raw of fs.readFileSync(file, "utf8").split("\n")) { + const line = raw.trim(); + if (line === "" || line.startsWith("#")) { + continue; + } + if (!/^import(\s|$)/.test(line)) { + break; + } const m = /^import\s+(\S+)\s+as\s+[A-Za-z_][A-Za-z0-9_]*\s*$/ - .exec(raw.trim()); + .exec(line); if (m === null) { continue; } diff --git a/gates/ping.ts b/gates/ping.ts index a72189e0ac..411dd0c8f7 100644 --- a/gates/ping.ts +++ b/gates/ping.ts @@ -289,6 +289,18 @@ try { check("guide, base and a program run through the executable", guide.out.startsWith("# Bend") && base.out.startsWith("type Map") && sum5.code === 0 && sum5.out === "5n\n"); + const header_source = path.join(TMP, "literal-checkup.bend"); + fs.writeFileSync(header_source, + "import Base\nimport ./sum.bend as Sum\n" + + "def text() -> String:\n \"body text\n" + + "import ./absent.bend as Hidden\nmore text\"\n"); + const header_check = await bend([header_source, "--check-only"], + { BEND_NO_TELEMETRY: "1" }); + const header_run = await bend([header_source, "--checkup"], + { BEND_NO_TELEMETRY: "1" }); + check("valid body literal text does not add an independent import", + header_check.code === 0 && header_run.code === 0 + && header_run.out.endsWith("5n\n")); fs.writeFileSync(path.join(TMP, "page.html"), "\n"); fs.writeFileSync(path.join(TMP, "page.ts"), "import \"./none.ts\";\n"); From 7a9060066eca32bf53dd23a140a00d028a1961bf Mon Sep 17 00:00:00 2001 From: Lorenzobattistela Date: Mon, 12 Oct 2026 10:49:01 -0300 Subject: [PATCH 2/4] Drop the README line --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index f3f7a0bd75..02737ec3e7 100644 --- a/README.md +++ b/README.md @@ -208,8 +208,6 @@ def add_zero(x): - Formatter: [bend-fmt-lsp](tools/bend-fmt-lsp), a formatting-only Bend 2 language server. - Community language server: [bend2-lsp](https://github.com/don2e4/bend2-lsp), with formatting, diagnostics, and hover. - Community workshop: [Bend 2 pocket workshop](https://np.github.io/bend-workshop/), the checker and JS compiler in one HTML page, with goals and proof tools, phone first. -- `--checkup` checks and runs the initial import header independently; - definitions and multiline string bodies do not add imports. # Community From 454957a93749e4ea0fbc2f586b379095b12fcafe Mon Sep 17 00:00:00 2001 From: Lorenzobattistela Date: Mon, 12 Oct 2026 10:54:05 -0300 Subject: [PATCH 3/4] test: the checkup header test has a comment and a blank line --- gates/ping.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gates/ping.ts b/gates/ping.ts index 5940fc8eb4..2df552b65c 100644 --- a/gates/ping.ts +++ b/gates/ping.ts @@ -295,7 +295,7 @@ try { && sum5.code === 0 && sum5.out === "5n\n"); const header_source = path.join(TMP, "literal-checkup.bend"); fs.writeFileSync(header_source, - "import Base\nimport ./sum.bend as Sum\n" + "# a header\nimport Base\n\nimport ./sum.bend as Sum\n" + "def text() -> String:\n \"body text\n" + "import ./absent.bend as Hidden\nmore text\"\n"); const header_check = await bend([header_source, "--check-only"], From 179ed12efcbfb294d6870d6ef3c95efbd16e845a Mon Sep 17 00:00:00 2001 From: Lorenzobattistela Date: Mon, 12 Oct 2026 10:54:13 -0300 Subject: [PATCH 4/4] fix(cli): --checkup gives Base only to a module whose header imports it --- bend2/main.ts | 3 ++- gates/ping.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/bend2/main.ts b/bend2/main.ts index b0cf08dd78..6fd7998bf5 100755 --- a/bend2/main.ts +++ b/bend2/main.ts @@ -350,7 +350,8 @@ async function cli_checkup(file: string): Promise { cli_say(1, "--- " + m[1] + " ---\n"); let code = 1; try { - const own = /^import Base\s*(?:#.*)?$/m.test(fs.readFileSync(at, "utf8")); + const own = /^(?:[\t\r ]*(?:(?:#|import )[^\n]*)?\n)*[\t ]*import Base\s/ + .test(fs.readFileSync(at, "utf8")); code = book_run(await book_read(at, own ? base : undefined), [at]); } catch (e) { cli_say(2, book_err(e) + "\n"); diff --git a/gates/ping.ts b/gates/ping.ts index 2df552b65c..6d9b62840c 100644 --- a/gates/ping.ts +++ b/gates/ping.ts @@ -305,6 +305,14 @@ try { check("valid body literal text does not add an independent import", header_check.code === 0 && header_run.code === 0 && header_run.out.endsWith("5n\n")); + const no_base = path.join(TMP, "no-base.bend"); + fs.writeFileSync(no_base, + "def main() -> String:\n \"body\nimport Base\n\"\n"); + fs.writeFileSync(header_source, "import ./no-base.bend as NoBase\n"); + const base_run = await bend([header_source, "--checkup"], + { BEND_NO_TELEMETRY: "1" }); + check("--checkup gives Base only to a module that imports it", + base_run.code === 1); fs.writeFileSync(path.join(TMP, "page.html"), "\n"); fs.writeFileSync(path.join(TMP, "page.ts"), "import \"./none.ts\";\n");