@codacy/verity-cli 0.34.0-experimental.675f6d2 → 0.34.0-experimental.7e3f52d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/verity.js +72 -27
  2. package/package.json +1 -1
package/bin/verity.js CHANGED
@@ -17221,7 +17221,7 @@ function readConfigFile(path) {
17221
17221
  return {
17222
17222
  git_moments: [...new Set(moments)],
17223
17223
  ...source2 ? { git_moments_source: source2 } : {},
17224
- ...raw.formal === "push" ? { formal: "push" } : {}
17224
+ ...raw.formal === "push" || raw.formal === "off" ? { formal: raw.formal } : {}
17225
17225
  };
17226
17226
  } catch {
17227
17227
  return DEFAULTS;
@@ -24152,7 +24152,7 @@ function registerConfigCommands(program2) {
24152
24152
  config.command("formal [state]").description('Get or set formal verification at push: "push" or "off" (needs Lean \u2014 verity lean status)').action((state) => {
24153
24153
  if (state === void 0) {
24154
24154
  const cfg = readProjectConfig();
24155
- process.stdout.write((cfg.formal ?? "off") + "\n");
24155
+ process.stdout.write((cfg.formal === "push" ? "push" : "off") + "\n");
24156
24156
  if (cfg.formal_refused) printWarn(formalRefusalMessage(cfg.formal_refused));
24157
24157
  return;
24158
24158
  }
@@ -24160,7 +24160,7 @@ function registerConfigCommands(program2) {
24160
24160
  printError(`Unrecognised state: ${state}. Use "push" or "off".`);
24161
24161
  process.exit(1);
24162
24162
  }
24163
- writeProjectConfig({ formal: state === "push" ? "push" : void 0 });
24163
+ writeProjectConfig({ formal: state === "push" ? "push" : "off" });
24164
24164
  const refused2 = state === "push" ? readProjectConfig().formal_refused : void 0;
24165
24165
  if (refused2) {
24166
24166
  printWarn(`Formal verification at push: still off \u2014 ${formalRefusalMessage(refused2)}`);
@@ -27073,7 +27073,7 @@ function channelSilence(input) {
27073
27073
  // src/lib/cli-version.ts
27074
27074
  function cliVersion() {
27075
27075
  try {
27076
- return true ? "0.34.0-experimental.675f6d2" : "dev";
27076
+ return true ? "0.34.0-experimental.7e3f52d" : "dev";
27077
27077
  } catch {
27078
27078
  return "dev";
27079
27079
  }
@@ -34873,10 +34873,10 @@ function parseReplayOutput(output) {
34873
34873
  }
34874
34874
  return { claim, shellCalls, executedCalls, shellTexts, outputTexts };
34875
34875
  }
34876
- var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/;
34876
+ var RESULT_LINE = /REPLAY_RESULT=(reproduced|diverged)\b/g;
34877
34877
  function printedResult(outputTexts) {
34878
34878
  let last = null;
34879
- for (const t of outputTexts) for (const m of t.matchAll(new RegExp(RESULT_LINE.source, "g"))) last = m[1];
34879
+ for (const t of outputTexts) for (const m of t.matchAll(RESULT_LINE)) last = m[1];
34880
34880
  return last;
34881
34881
  }
34882
34882
  var RESULT_MISSING = "the harness never printed REPLAY_RESULT=reproduced on its own stdout \u2014 the verdict was the model's word, not the run's";
@@ -35910,9 +35910,10 @@ function verityLeanHome(env = process.env) {
35910
35910
  function findToolchain(env = process.env) {
35911
35911
  const managedBin = (0, import_node_path43.join)(verityLeanHome(env), LEAN_TOOLCHAIN.replace(/^leanprover\/lean4:/, ""), "bin");
35912
35912
  const elanBin = (0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "bin");
35913
- const path = [managedBin, elanBin, env.PATH ?? ""].filter(Boolean).join(import_node_path43.delimiter);
35914
- const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
35915
35913
  const elanHas = (0, import_node_fs58.existsSync)((0, import_node_path43.join)(env.HOME ?? (0, import_node_os9.homedir)(), ".elan", "toolchains", LEAN_TOOLCHAIN.replace("/", "--").replace(":", "---")));
35914
+ const userPath = (env.PATH ?? "").split(import_node_path43.delimiter).filter((d) => d && (elanHas || (0, import_node_path43.resolve)(d) !== (0, import_node_path43.resolve)(elanBin)));
35915
+ const path = [managedBin, ...elanHas ? [elanBin] : [], ...userPath].join(import_node_path43.delimiter);
35916
+ const merged = { ...env, PATH: path, ELAN_TOOLCHAIN: env.ELAN_TOOLCHAIN ?? LEAN_TOOLCHAIN };
35916
35917
  const exe = process.platform === "win32" ? "lake.exe" : "lake";
35917
35918
  const candidates2 = [(0, import_node_path43.join)(managedBin, exe), ...elanHas ? [(0, import_node_path43.join)(elanBin, exe)] : [], exe];
35918
35919
  for (const candidate of candidates2) {
@@ -38802,6 +38803,22 @@ var import_promises18 = require("node:stream/promises");
38802
38803
  var import_node_stream = require("node:stream");
38803
38804
  var RELEASES = "https://releases.lean-lang.org/lean4";
38804
38805
  var LEAN_DOWNLOAD_SIZE = "\u2248800 MB download, 2.7 GB on disk";
38806
+ var DOWNLOAD_STALL_MS = 6e4;
38807
+ var LEAN_DISK_NEEDED_BYTES = 3.75 * 1024 ** 3;
38808
+ function freeBytes(dir) {
38809
+ let d = dir;
38810
+ for (let i2 = 0; i2 < 64; i2++) {
38811
+ try {
38812
+ const st = (0, import_node_fs63.statfsSync)(d);
38813
+ return Number(st.bavail) * Number(st.bsize);
38814
+ } catch {
38815
+ const up = (0, import_node_path47.join)(d, "..");
38816
+ if (up === d) return null;
38817
+ d = up;
38818
+ }
38819
+ }
38820
+ return null;
38821
+ }
38805
38822
  var LEAN_ASSET_SHA256 = {
38806
38823
  "v4.34.0": {
38807
38824
  "lean-4.34.0-darwin.zip": "75a2a4b8e3d35680e8f51fae5a42c79702f463dd73ee1520fb61e5a9143e336c",
@@ -38860,17 +38877,32 @@ function unzip(zip, dest) {
38860
38877
  }
38861
38878
  return { ok: false, error: errors.join("; ") };
38862
38879
  }
38863
- async function download(url, dest, onProgress) {
38864
- const res = await fetch(url, { redirect: "follow" });
38865
- if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status}`);
38866
- const total = Number(res.headers.get("content-length")) || null;
38867
- let seen = 0;
38868
- const stream = import_node_stream.Readable.fromWeb(res.body);
38869
- stream.on("data", (chunk) => {
38870
- seen += chunk.length;
38871
- onProgress(seen, total);
38872
- });
38873
- await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest));
38880
+ async function download(url, dest, onProgress, stallMs = DOWNLOAD_STALL_MS) {
38881
+ const ctrl = new AbortController();
38882
+ let timer;
38883
+ const arm = () => {
38884
+ clearTimeout(timer);
38885
+ timer = setTimeout(() => ctrl.abort(), stallMs);
38886
+ };
38887
+ arm();
38888
+ try {
38889
+ const res = await fetch(url, { redirect: "follow", signal: ctrl.signal });
38890
+ if (!res.ok || !res.body) throw new Error(`download failed: HTTP ${res.status}`);
38891
+ const total = Number(res.headers.get("content-length")) || null;
38892
+ let seen = 0;
38893
+ const stream = import_node_stream.Readable.fromWeb(res.body);
38894
+ stream.on("data", (chunk) => {
38895
+ arm();
38896
+ seen += chunk.length;
38897
+ onProgress(seen, total);
38898
+ });
38899
+ await (0, import_promises18.pipeline)(stream, (0, import_node_fs63.createWriteStream)(dest), { signal: ctrl.signal });
38900
+ } catch (err2) {
38901
+ if (ctrl.signal.aborted) throw new Error(`download stalled: nothing received for ${Math.round(stallMs / 1e3)} s`);
38902
+ throw err2;
38903
+ } finally {
38904
+ clearTimeout(timer);
38905
+ }
38874
38906
  }
38875
38907
  function inPlaceProgress(label2, write = (s) => process.stderr.write(s)) {
38876
38908
  let active = false;
@@ -38908,6 +38940,12 @@ async function installLean(opts = {}) {
38908
38940
  const dir = pinnedVersionDir(env);
38909
38941
  const url = `${RELEASES}/${pinnedVersion()}/${asset}`;
38910
38942
  const home = verityLeanHome(env);
38943
+ const free = freeBytes(home);
38944
+ const needed = opts.minFreeBytes ?? LEAN_DISK_NEEDED_BYTES;
38945
+ if (free !== null && free < needed) {
38946
+ const gb = (n) => (n / 1024 ** 3).toFixed(1);
38947
+ return { ok: false, error: `not enough disk space for Lean: ${gb(free)} GB free where ${home} lives, needs about ${gb(needed)} GB` };
38948
+ }
38911
38949
  const tmp = (0, import_node_path47.join)(home, ".tmp");
38912
38950
  (0, import_node_fs63.rmSync)(tmp, { recursive: true, force: true });
38913
38951
  (0, import_node_fs63.mkdirSync)(tmp, { recursive: true });
@@ -39216,8 +39254,10 @@ var INTENSITY_CHOICES = [
39216
39254
  { id: "thorough", label: "thorough", hint: "all tools, all rules (~15s)" }
39217
39255
  ];
39218
39256
  var FORMAL_CHOICES = [
39219
- { id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample", recommended: true },
39220
- { id: "no", label: "no", hint: "enable later with: verity config formal push" }
39257
+ { id: "yes", label: "yes", hint: "a Lean model of the riskiest changed function; blocks only on a REPRODUCED counterexample" },
39258
+ // No is the default (review of #255): "yes" downloads ≈800 MB and unpacks
39259
+ // 2.7 GB, and a bare Enter must never do that.
39260
+ { id: "no", label: "no", hint: "enable later with: verity config formal push", recommended: true }
39221
39261
  ];
39222
39262
  var MOMENT_CHOICES = [
39223
39263
  { id: "stop", label: "On stop", hint: "after every agent turn \u2014 fast feedback while you work", recommended: true },
@@ -39623,16 +39663,20 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
39623
39663
  printWarn(` Formal verification: off \u2014 ${formalRefusalMessage(cfg.formal_refused)}`);
39624
39664
  return;
39625
39665
  }
39626
- const toolchain = findToolchain();
39627
39666
  if (cfg.formal === "push") {
39628
- if (toolchain) printInfo(" Formal verification at push \u2713");
39667
+ if (findToolchain()) printInfo(" Formal verification at push \u2713");
39629
39668
  else printWarn(" Formal verification is on but Lean is missing \u2014 run: verity lean install");
39630
39669
  return;
39631
39670
  }
39671
+ if (cfg.formal === "off") {
39672
+ printInfo(" Formal verification: off (enable with: verity config formal push)");
39673
+ return;
39674
+ }
39632
39675
  if (defaultsOnly || !interactive()) {
39633
39676
  printInfo(" Formal verification (a model-based bug finder at push): off \u2014 enable with: verity config formal push");
39634
39677
  return;
39635
39678
  }
39679
+ const toolchain = findToolchain();
39636
39680
  console.log("");
39637
39681
  console.log(" Formal verification review \u2014 a model-based bug finder for your riskiest code.");
39638
39682
  console.log(" At push, Verity picks the riskiest changed function, checks a small model of");
@@ -39640,9 +39684,10 @@ async function offerFormalVerification(defaultsOnly, pluginMode) {
39640
39684
  console.log(" Verity for that). Only a reproduced bug can block; most pushes get no model.");
39641
39685
  console.log(` Adds /verity-prove <worry> to check any code on demand.${toolchain ? "" : ` Needs to install Lean 4 (${LEAN_DOWNLOAD_SIZE}) on "yes".`}`);
39642
39686
  console.log("");
39643
- const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "yes");
39687
+ const wants = await promptChoice("Formal verification at push?", FORMAL_CHOICES, "no");
39644
39688
  if (wants === "yes" && pluginMode) printInfo(" Plugin: the push check works now; /verity:verity-prove arrives with the plugin's next release.");
39645
39689
  if (wants !== "yes") {
39690
+ writeProjectConfig({ formal: "off" });
39646
39691
  printInfo(" Formal verification: off (enable later with: verity config formal push)");
39647
39692
  return;
39648
39693
  }
@@ -39901,7 +39946,7 @@ function registerInitCommand(program2) {
39901
39946
  ...telemetryChoice ? { telemetry: telemetryChoice } : {},
39902
39947
  init: {
39903
39948
  completed_at: (/* @__PURE__ */ new Date()).toISOString(),
39904
- cli_version: true ? "0.34.0-experimental.675f6d2" : "dev"
39949
+ cli_version: true ? "0.34.0-experimental.7e3f52d" : "dev"
39905
39950
  }
39906
39951
  });
39907
39952
  } catch (err2) {
@@ -41374,8 +41419,8 @@ function registerLeanCommand(program2) {
41374
41419
  }
41375
41420
 
41376
41421
  // src/cli.ts
41377
- program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.675f6d2").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41378
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.675f6d2");
41422
+ program.name("verity").description("CLI for Verity quality gate service").version("0.34.0-experimental.7e3f52d").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
41423
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.34.0-experimental.7e3f52d");
41379
41424
  setUserNamedServiceUrl(program.opts().serviceUrl);
41380
41425
  try {
41381
41426
  await foldLegacyLocalCredential();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codacy/verity-cli",
3
- "version": "0.34.0-experimental.675f6d2",
3
+ "version": "0.34.0-experimental.7e3f52d",
4
4
  "description": "CLI for Verity quality gate service",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://verity.md",