@codacy/analysis-runner 0.20.0 → 0.22.0

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/dist/index.js +144 -4
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1220,12 +1220,13 @@ async function analyze(options) {
1220
1220
  const adapters = await getRegisteredAdapters(requestedTools);
1221
1221
  logger.info("Pipeline started", { mode, toolCount: adapters.length, parallelTools, toolTimeout });
1222
1222
  const globalDir = import_path4.default.join(import_os2.default.homedir(), ".codacy");
1223
+ const runnerEnv = options.runner ?? "local";
1223
1224
  const baseCtx = {
1224
1225
  repositoryRoot: options.repositoryRoot,
1225
1226
  globalDir,
1226
1227
  platform: { os: import_os2.default.platform(), arch: import_os2.default.arch() },
1227
1228
  logger,
1228
- runner: "local"
1229
+ runner: runnerEnv
1229
1230
  };
1230
1231
  const ready = [];
1231
1232
  const unavailable = [];
@@ -1280,7 +1281,8 @@ async function analyze(options) {
1280
1281
  toolId: adapter.id,
1281
1282
  displayName: adapter.displayName,
1282
1283
  reason: availability.reason || "Tool is not available",
1283
- ...availability.installHint ? { remediation: availability.installHint } : {}
1284
+ ...availability.installHint ? { remediation: availability.installHint } : {},
1285
+ ...availability.staleManagedInstall ? { staleManagedInstall: true } : {}
1284
1286
  }
1285
1287
  };
1286
1288
  } catch (err) {
@@ -1350,6 +1352,20 @@ async function analyze(options) {
1350
1352
  });
1351
1353
  representedIds.add(toolConfig.toolId);
1352
1354
  }
1355
+ if (mode !== "inspect" && runnerEnv !== "container") {
1356
+ const updateStartMs = Date.now();
1357
+ let updatedCount = 0;
1358
+ if (capability.ready.length > 0) {
1359
+ updatedCount += await updateStaleManagedTools(capability, adapters, baseCtx, logger);
1360
+ }
1361
+ if (mode !== "auto-install" && capability.unavailable.length > 0) {
1362
+ updatedCount += await repairMissingManagedTools(capability, adapters, baseCtx, logger);
1363
+ }
1364
+ phaseTimings.toolUpdateMs = Date.now() - updateStartMs;
1365
+ if (updatedCount > 0) {
1366
+ logger.info(`Updated ${updatedCount} managed tool(s) to their pinned versions`);
1367
+ }
1368
+ }
1353
1369
  if (mode === "auto-install" && capability.unavailable.length > 0) {
1354
1370
  const installStartMs = Date.now();
1355
1371
  const installErrors = [];
@@ -1638,6 +1654,124 @@ function makeToolContext(base, adapter, targetFiles) {
1638
1654
  generatedConfigDir: import_path4.default.join(base.repositoryRoot, ".codacy", "generated", adapter.id)
1639
1655
  };
1640
1656
  }
1657
+ async function updateStaleManagedTools(capability, adapters, baseCtx, logger) {
1658
+ const adaptersById = new Map(adapters.map((a) => [a.id, a]));
1659
+ let updated = 0;
1660
+ for (const status of capability.ready) {
1661
+ const adapter = adaptersById.get(status.toolId);
1662
+ if (!adapter) continue;
1663
+ if (status.installation === "bundled") continue;
1664
+ if (status.version === adapter.preferredVersion) continue;
1665
+ if (status.installation === "global") {
1666
+ status.expectedVersion = adapter.preferredVersion;
1667
+ logger.debug("System tool version differs from the pinned version", {
1668
+ toolId: adapter.id,
1669
+ version: status.version,
1670
+ expected: adapter.preferredVersion
1671
+ });
1672
+ continue;
1673
+ }
1674
+ const ctx = makeToolContext(baseCtx, adapter, []);
1675
+ logger.info(
1676
+ `Updating ${adapter.displayName} ${status.version} to ${adapter.preferredVersion}...`
1677
+ );
1678
+ try {
1679
+ const installResult = await adapter.install(ctx);
1680
+ if (!installResult.success) {
1681
+ if (installResult.error?.kind === "NotSupported") {
1682
+ status.expectedVersion = adapter.preferredVersion;
1683
+ logger.debug("Tool does not support automated install, leaving as-is", {
1684
+ toolId: adapter.id
1685
+ });
1686
+ } else {
1687
+ status.expectedVersion = adapter.preferredVersion;
1688
+ logger.warn(
1689
+ `Could not update ${adapter.displayName} to ${adapter.preferredVersion}, continuing with ${status.version}: ${installResult.error?.message ?? "install failed"}`,
1690
+ { toolId: adapter.id }
1691
+ );
1692
+ }
1693
+ continue;
1694
+ }
1695
+ const recheck = await adapter.checkAvailability(ctx);
1696
+ if (recheck.available) {
1697
+ status.version = recheck.version ?? installResult.installedVersion ?? status.version;
1698
+ status.installation = recheck.installation ?? status.installation;
1699
+ if (status.version === adapter.preferredVersion) delete status.expectedVersion;
1700
+ else status.expectedVersion = adapter.preferredVersion;
1701
+ updated++;
1702
+ logger.info(`${adapter.displayName} updated to ${status.version}`);
1703
+ } else {
1704
+ status.expectedVersion = adapter.preferredVersion;
1705
+ logger.warn(
1706
+ `${adapter.displayName} is not available after updating: ${recheck.reason ?? "unknown"}`,
1707
+ { toolId: adapter.id }
1708
+ );
1709
+ }
1710
+ } catch (err) {
1711
+ status.expectedVersion = adapter.preferredVersion;
1712
+ logger.warn(
1713
+ `Could not update ${adapter.displayName}, continuing with ${status.version}: ${err instanceof Error ? err.message : String(err)}`,
1714
+ { toolId: adapter.id }
1715
+ );
1716
+ }
1717
+ }
1718
+ return updated;
1719
+ }
1720
+ async function repairMissingManagedTools(capability, adapters, baseCtx, logger) {
1721
+ const adaptersById = new Map(adapters.map((a) => [a.id, a]));
1722
+ let repaired = 0;
1723
+ for (let i = capability.unavailable.length - 1; i >= 0; i--) {
1724
+ const status = capability.unavailable[i];
1725
+ const adapter = adaptersById.get(status.toolId);
1726
+ if (!adapter) continue;
1727
+ const ctx = makeToolContext(baseCtx, adapter, []);
1728
+ const hasPreviousInstall = status.staleManagedInstall === true || await (0, import_tooling3.hasManagedInstall)(ctx.toolInstallDir);
1729
+ if (!hasPreviousInstall) continue;
1730
+ logger.info(
1731
+ `Reinstalling ${adapter.displayName} at the pinned version ${adapter.preferredVersion}...`
1732
+ );
1733
+ try {
1734
+ const installResult = await adapter.install(ctx);
1735
+ if (!installResult.success) {
1736
+ if (installResult.error?.kind === "NotSupported") {
1737
+ logger.debug("Tool does not support automated install, leaving as-is", {
1738
+ toolId: adapter.id
1739
+ });
1740
+ } else {
1741
+ logger.warn(
1742
+ `Could not reinstall ${adapter.displayName} at ${adapter.preferredVersion}, continuing without it: ${installResult.error?.message ?? "install failed"}`,
1743
+ { toolId: adapter.id }
1744
+ );
1745
+ }
1746
+ continue;
1747
+ }
1748
+ const recheck = await adapter.checkAvailability(ctx);
1749
+ if (!recheck.available) {
1750
+ logger.warn(
1751
+ `${adapter.displayName} is still not available after reinstalling: ${recheck.reason ?? "unknown"}`,
1752
+ { toolId: adapter.id }
1753
+ );
1754
+ continue;
1755
+ }
1756
+ capability.ready.push({
1757
+ toolId: adapter.id,
1758
+ displayName: adapter.displayName,
1759
+ version: recheck.version ?? installResult.installedVersion ?? adapter.preferredVersion,
1760
+ installation: recheck.installation ?? "codacy",
1761
+ runner: "local"
1762
+ });
1763
+ capability.unavailable.splice(i, 1);
1764
+ repaired++;
1765
+ logger.info(`${adapter.displayName} reinstalled at ${adapter.preferredVersion}`);
1766
+ } catch (err) {
1767
+ logger.warn(
1768
+ `Could not reinstall ${adapter.displayName}, continuing without it: ${err instanceof Error ? err.message : String(err)}`,
1769
+ { toolId: adapter.id }
1770
+ );
1771
+ }
1772
+ }
1773
+ return repaired;
1774
+ }
1641
1775
  function normalizeIssues(issues) {
1642
1776
  return issues.map((issue) => {
1643
1777
  if (issue.endLine !== void 0 && issue.endLine === issue.line) {
@@ -1908,7 +2042,7 @@ function formatTextSummary(result, isInspect) {
1908
2042
  table.push([
1909
2043
  import_ansis.default.cyan(tool.displayName ?? tool.toolId),
1910
2044
  tool.version,
1911
- tool.installation,
2045
+ formatInstallCell(tool),
1912
2046
  formatConfigCell(tool, result.metadata.repositoryRoot),
1913
2047
  filesCell,
1914
2048
  prereqCell
@@ -1939,7 +2073,7 @@ function formatTextSummary(result, isInspect) {
1939
2073
  table.push([
1940
2074
  import_ansis.default.cyan(tool.displayName ?? tool.toolId),
1941
2075
  tool.version,
1942
- tool.installation,
2076
+ formatInstallCell(tool),
1943
2077
  formatConfigCell(tool, result.metadata.repositoryRoot),
1944
2078
  filesCell,
1945
2079
  issueCount > 0 ? import_ansis.default.bold.red(String(issueCount)) : String(issueCount),
@@ -2099,6 +2233,12 @@ function formatMultilineIssue(output, issue) {
2099
2233
  }
2100
2234
  }
2101
2235
  }
2236
+ function formatInstallCell(tool) {
2237
+ if (!tool.expectedVersion) return tool.installation;
2238
+ const mismatch = (0, import_tooling4.describeVersionMismatch)(tool.version, tool.expectedVersion);
2239
+ if (!mismatch) return tool.installation;
2240
+ return `${tool.installation} ${import_ansis.default.yellow(`(${mismatch})`)}`;
2241
+ }
2102
2242
  function formatFilesCell(filesRouted) {
2103
2243
  if (filesRouted === void 0) return "-";
2104
2244
  if (filesRouted === 0) return import_ansis.default.dim("0");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codacy/analysis-runner",
3
- "version": "0.20.0",
3
+ "version": "0.22.0",
4
4
  "description": "Core orchestration engine for Codacy analysis",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -12,11 +12,11 @@
12
12
  "cli-table3": "^0.6",
13
13
  "minimatch": "10.2.4",
14
14
  "yaml": "^2.6.0",
15
- "@codacy/tooling": "0.20.0"
15
+ "@codacy/tooling": "0.22.0"
16
16
  },
17
17
  "devDependencies": {
18
18
  "@codacy/openapi-typescript-codegen": "0.0.9",
19
- "@codacy/tools-dummy-1": "0.20.0"
19
+ "@codacy/tools-dummy-1": "0.22.0"
20
20
  },
21
21
  "license": "MIT",
22
22
  "author": "Codacy <support@codacy.com> (https://www.codacy.com)",