greenbump 0.2.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 (116) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +125 -0
  3. package/README.zh-CN.md +213 -0
  4. package/action-dist/index.cjs +19695 -0
  5. package/action.yml +76 -0
  6. package/dist/action/github.js +70 -0
  7. package/dist/action/github.js.map +1 -0
  8. package/dist/action/main.js +99 -0
  9. package/dist/action/main.js.map +1 -0
  10. package/dist/agent/factory.js +72 -0
  11. package/dist/agent/factory.js.map +1 -0
  12. package/dist/agent/fixer.js +307 -0
  13. package/dist/agent/fixer.js.map +1 -0
  14. package/dist/agent/fixer.test.js +224 -0
  15. package/dist/agent/fixer.test.js.map +1 -0
  16. package/dist/agent/provider-anthropic.js +59 -0
  17. package/dist/agent/provider-anthropic.js.map +1 -0
  18. package/dist/agent/provider-openai.js +65 -0
  19. package/dist/agent/provider-openai.js.map +1 -0
  20. package/dist/agent/provider.js +4 -0
  21. package/dist/agent/provider.js.map +1 -0
  22. package/dist/cli.js +138 -0
  23. package/dist/cli.js.map +1 -0
  24. package/dist/engine/batch.js +246 -0
  25. package/dist/engine/batch.js.map +1 -0
  26. package/dist/engine/batch.test.js +59 -0
  27. package/dist/engine/batch.test.js.map +1 -0
  28. package/dist/engine/changelog.js +66 -0
  29. package/dist/engine/changelog.js.map +1 -0
  30. package/dist/engine/checks.js +41 -0
  31. package/dist/engine/checks.js.map +1 -0
  32. package/dist/engine/checks.test.js +92 -0
  33. package/dist/engine/checks.test.js.map +1 -0
  34. package/dist/engine/detect.js +5 -0
  35. package/dist/engine/detect.js.map +1 -0
  36. package/dist/engine/ecosystems/bundler.js +59 -0
  37. package/dist/engine/ecosystems/bundler.js.map +1 -0
  38. package/dist/engine/ecosystems/cargo.js +83 -0
  39. package/dist/engine/ecosystems/cargo.js.map +1 -0
  40. package/dist/engine/ecosystems/cocoapods.js +47 -0
  41. package/dist/engine/ecosystems/cocoapods.js.map +1 -0
  42. package/dist/engine/ecosystems/composer.js +32 -0
  43. package/dist/engine/ecosystems/composer.js.map +1 -0
  44. package/dist/engine/ecosystems/conan.js +106 -0
  45. package/dist/engine/ecosystems/conan.js.map +1 -0
  46. package/dist/engine/ecosystems/elm.js +77 -0
  47. package/dist/engine/ecosystems/elm.js.map +1 -0
  48. package/dist/engine/ecosystems/go.js +72 -0
  49. package/dist/engine/ecosystems/go.js.map +1 -0
  50. package/dist/engine/ecosystems/gradle.js +90 -0
  51. package/dist/engine/ecosystems/gradle.js.map +1 -0
  52. package/dist/engine/ecosystems/index.js +67 -0
  53. package/dist/engine/ecosystems/index.js.map +1 -0
  54. package/dist/engine/ecosystems/maven.js +77 -0
  55. package/dist/engine/ecosystems/maven.js.map +1 -0
  56. package/dist/engine/ecosystems/mix.js +64 -0
  57. package/dist/engine/ecosystems/mix.js.map +1 -0
  58. package/dist/engine/ecosystems/npm.js +47 -0
  59. package/dist/engine/ecosystems/npm.js.map +1 -0
  60. package/dist/engine/ecosystems/nuget.js +50 -0
  61. package/dist/engine/ecosystems/nuget.js.map +1 -0
  62. package/dist/engine/ecosystems/parsers.test.js +255 -0
  63. package/dist/engine/ecosystems/parsers.test.js.map +1 -0
  64. package/dist/engine/ecosystems/pip.js +61 -0
  65. package/dist/engine/ecosystems/pip.js.map +1 -0
  66. package/dist/engine/ecosystems/pipenv.js +37 -0
  67. package/dist/engine/ecosystems/pipenv.js.map +1 -0
  68. package/dist/engine/ecosystems/pnpm.js +48 -0
  69. package/dist/engine/ecosystems/pnpm.js.map +1 -0
  70. package/dist/engine/ecosystems/poetry.js +42 -0
  71. package/dist/engine/ecosystems/poetry.js.map +1 -0
  72. package/dist/engine/ecosystems/pub.js +32 -0
  73. package/dist/engine/ecosystems/pub.js.map +1 -0
  74. package/dist/engine/ecosystems/python-shared.js +29 -0
  75. package/dist/engine/ecosystems/python-shared.js.map +1 -0
  76. package/dist/engine/ecosystems/swiftpm.js +102 -0
  77. package/dist/engine/ecosystems/swiftpm.js.map +1 -0
  78. package/dist/engine/ecosystems/types.js +19 -0
  79. package/dist/engine/ecosystems/types.js.map +1 -0
  80. package/dist/engine/ecosystems/uv.js +36 -0
  81. package/dist/engine/ecosystems/uv.js.map +1 -0
  82. package/dist/engine/ecosystems/yarn.js +62 -0
  83. package/dist/engine/ecosystems/yarn.js.map +1 -0
  84. package/dist/engine/exec.js +47 -0
  85. package/dist/engine/exec.js.map +1 -0
  86. package/dist/engine/git.js +42 -0
  87. package/dist/engine/git.js.map +1 -0
  88. package/dist/engine/git.test.js +111 -0
  89. package/dist/engine/git.test.js.map +1 -0
  90. package/dist/engine/pm.js +14 -0
  91. package/dist/engine/pm.js.map +1 -0
  92. package/dist/engine/run.js +167 -0
  93. package/dist/engine/run.js.map +1 -0
  94. package/dist/engine/run.test.js +47 -0
  95. package/dist/engine/run.test.js.map +1 -0
  96. package/dist/engine/upgrade.js +10 -0
  97. package/dist/engine/upgrade.js.map +1 -0
  98. package/dist/engine/workspace.js +155 -0
  99. package/dist/engine/workspace.js.map +1 -0
  100. package/dist/engine/workspace.test.js +95 -0
  101. package/dist/engine/workspace.test.js.map +1 -0
  102. package/dist/exitcode.js +51 -0
  103. package/dist/exitcode.js.map +1 -0
  104. package/dist/exitcode.test.js +62 -0
  105. package/dist/exitcode.test.js.map +1 -0
  106. package/dist/format.js +101 -0
  107. package/dist/format.js.map +1 -0
  108. package/dist/pr.js +63 -0
  109. package/dist/pr.js.map +1 -0
  110. package/dist/report.js +13 -0
  111. package/dist/report.js.map +1 -0
  112. package/dist/report.test.js +56 -0
  113. package/dist/report.test.js.map +1 -0
  114. package/dist/test-utils.js +36 -0
  115. package/dist/test-utils.js.map +1 -0
  116. package/package.json +56 -0
@@ -0,0 +1,77 @@
1
+ import { join } from "node:path";
2
+ import { readFile } from "node:fs/promises";
3
+ import { pathExists } from "./types.js";
4
+ const DEP_BLOCK = /<dependency>\s*<groupId>([^<]+)<\/groupId>\s*<artifactId>([^<]+)<\/artifactId>\s*<version>([^<]+)<\/version>/g;
5
+ export function parsePomXml(raw) {
6
+ const deps = [];
7
+ for (const m of raw.matchAll(DEP_BLOCK)) {
8
+ deps.push({ name: `${m[1]}:${m[2]}`, version: m[3] });
9
+ }
10
+ return deps;
11
+ }
12
+ async function directDeps(cwd) {
13
+ try {
14
+ const raw = await readFile(join(cwd, "pom.xml"), "utf8");
15
+ return parsePomXml(raw);
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ async function latestOnMavenCentral(groupArtifact) {
22
+ const [g, a] = groupArtifact.split(":");
23
+ try {
24
+ const url = `https://search.maven.org/solrsearch/select?q=g:${encodeURIComponent(g)}+AND+a:${encodeURIComponent(a)}&core=gav&rows=1&sort=v+desc&wt=json`;
25
+ const res = await fetch(url);
26
+ if (!res.ok)
27
+ return null;
28
+ const data = (await res.json());
29
+ return data.response?.docs?.[0]?.v ?? null;
30
+ }
31
+ catch {
32
+ return null;
33
+ }
34
+ }
35
+ /** Maven has no per-dependency pin CLI — versions live inline in pom.xml. */
36
+ export const mavenAdapter = {
37
+ id: "maven",
38
+ displayName: "Maven",
39
+ manifestFiles: ["pom.xml"],
40
+ lockFiles: [],
41
+ verified: true,
42
+ async detect(cwd) {
43
+ return pathExists(join(cwd, "pom.xml"));
44
+ },
45
+ async outdated(cwd) {
46
+ const deps = await directDeps(cwd);
47
+ const out = [];
48
+ for (const d of deps) {
49
+ const latest = await latestOnMavenCentral(d.name);
50
+ if (latest && latest !== d.version)
51
+ out.push({ name: d.name, current: d.version, wanted: "", latest });
52
+ }
53
+ return out;
54
+ },
55
+ async install(cwd, name, version) {
56
+ const { readFile: rf, writeFile } = await import("node:fs/promises");
57
+ const path = join(cwd, "pom.xml");
58
+ const [, artifactId] = name.split(":");
59
+ const raw = await rf(path, "utf8");
60
+ const re = new RegExp(`(<artifactId>${escapeRegExp(artifactId)}<\\/artifactId>\\s*<version>)([^<]+)(<\\/version>)`);
61
+ if (!re.test(raw)) {
62
+ return { code: 1, stdout: "", stderr: `could not find ${name} in pom.xml`, combined: `could not find ${name} in pom.xml` };
63
+ }
64
+ await writeFile(path, raw.replace(re, `$1${version}$3`), "utf8");
65
+ return { code: 0, stdout: `pinned ${name} to ${version} in pom.xml`, stderr: "", combined: "" };
66
+ },
67
+ async defaultCheckCommands() {
68
+ return {
69
+ build: { cmd: "mvn", args: ["-q", "compile"] },
70
+ test: { cmd: "mvn", args: ["-q", "test"] },
71
+ };
72
+ },
73
+ };
74
+ function escapeRegExp(s) {
75
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
76
+ }
77
+ //# sourceMappingURL=maven.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maven.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/maven.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { join } from "node:path";
2
+ import { exec } from "../exec.js";
3
+ import { pathExists } from "./types.js";
4
+ // `mix hex.outdated` prints a fixed-width table: "Dependency Only Current Latest Status".
5
+ // The "Only" cell is blank for deps with no `only:` restriction, so a plain
6
+ // whitespace-split misreads columns (e.g. a "dev"-only dep shifts every
7
+ // later field left by one). Slice by the header's column start offsets instead.
8
+ const HEADER = /^Dependency\s+Only\s+Current\s+Latest\s+Status/;
9
+ export function parseMixOutdated(stdout) {
10
+ const lines = stdout.split("\n");
11
+ const headerIdx = lines.findIndex((l) => HEADER.test(l));
12
+ if (headerIdx < 0)
13
+ return [];
14
+ const header = lines[headerIdx];
15
+ const idxOnly = header.indexOf("Only");
16
+ const idxCurrent = header.indexOf("Current");
17
+ const idxLatest = header.indexOf("Latest");
18
+ const idxStatus = header.indexOf("Status");
19
+ const out = [];
20
+ for (const line of lines.slice(headerIdx + 1)) {
21
+ if (!line.trim())
22
+ break; // blank line ends the table
23
+ const name = line.slice(0, idxOnly).trim();
24
+ const current = line.slice(idxCurrent, idxLatest).trim();
25
+ const latest = line.slice(idxLatest, idxStatus).trim();
26
+ if (name && current && latest && current !== latest)
27
+ out.push({ name, current, wanted: "", latest });
28
+ }
29
+ return out;
30
+ }
31
+ export const mixAdapter = {
32
+ id: "mix",
33
+ displayName: "Mix (Hex)",
34
+ manifestFiles: ["mix.exs"],
35
+ lockFiles: ["mix.lock"],
36
+ verified: true,
37
+ async detect(cwd) {
38
+ return pathExists(join(cwd, "mix.exs"));
39
+ },
40
+ async outdated(cwd) {
41
+ const r = await exec("mix", ["hex.outdated"], { cwd, timeout: 120_000 });
42
+ return parseMixOutdated(r.stdout);
43
+ },
44
+ async install(cwd, name, version) {
45
+ // mix.exs deps are declared as Elixir code (`{:name, "~> 1.0"}`); no
46
+ // official CLI pins a single dep version, so we edit the source line.
47
+ const { readFile, writeFile } = await import("node:fs/promises");
48
+ const path = join(cwd, "mix.exs");
49
+ const raw = await readFile(path, "utf8");
50
+ const re = new RegExp(`(\\{:${name},\\s*)"[^"]+"`);
51
+ if (!re.test(raw)) {
52
+ return { code: 1, stdout: "", stderr: `could not find :${name} in mix.exs`, combined: `could not find :${name} in mix.exs` };
53
+ }
54
+ await writeFile(path, raw.replace(re, `$1"== ${version}"`), "utf8");
55
+ return { code: 0, stdout: `pinned ${name} to ${version} in mix.exs`, stderr: "", combined: "" };
56
+ },
57
+ async defaultCheckCommands() {
58
+ return {
59
+ build: { cmd: "mix", args: ["compile"] },
60
+ test: { cmd: "mix", args: ["test"] },
61
+ };
62
+ },
63
+ };
64
+ //# sourceMappingURL=mix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mix.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/mix.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { join } from "node:path";
2
+ import { exec } from "../exec.js";
3
+ import { pathExists, safeJson } from "./types.js";
4
+ async function readScripts(cwd) {
5
+ try {
6
+ const { readFile } = await import("node:fs/promises");
7
+ const raw = await readFile(join(cwd, "package.json"), "utf8");
8
+ const pkg = JSON.parse(raw);
9
+ return { build: pkg.scripts?.build, test: pkg.scripts?.test };
10
+ }
11
+ catch {
12
+ return {};
13
+ }
14
+ }
15
+ export function parseNpmOutdated(data) {
16
+ if (!data)
17
+ return [];
18
+ return Object.entries(data)
19
+ .map(([name, v]) => ({ name, current: v.current ?? "", wanted: "", latest: v.latest ?? "" }))
20
+ .filter((o) => o.latest && o.current !== o.latest);
21
+ }
22
+ export const npmAdapter = {
23
+ id: "npm",
24
+ displayName: "npm",
25
+ manifestFiles: ["package.json"],
26
+ lockFiles: ["package-lock.json"],
27
+ verified: true,
28
+ async detect(cwd) {
29
+ return pathExists(join(cwd, "package.json"));
30
+ },
31
+ async outdated(cwd) {
32
+ const r = await exec("npm", ["outdated", "--json"], { cwd, timeout: 120_000 });
33
+ const data = safeJson(r.stdout);
34
+ return parseNpmOutdated(data);
35
+ },
36
+ async install(cwd, name, version) {
37
+ return exec("npm", ["install", `${name}@${version}`, "--save-exact"], { cwd, timeout: 300_000 });
38
+ },
39
+ async defaultCheckCommands(cwd) {
40
+ const scripts = await readScripts(cwd);
41
+ return {
42
+ build: scripts.build ? { cmd: "npm", args: ["run", "build"] } : undefined,
43
+ test: scripts.test ? { cmd: "npm", args: ["test"] } : undefined,
44
+ };
45
+ },
46
+ };
47
+ //# sourceMappingURL=npm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/npm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAwC,MAAM,YAAY,CAAC;AAExF,KAAK,UAAU,WAAW,CAAC,GAAW;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyC,CAAC;QACpE,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC;IAChE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAkE;IACjG,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IACrB,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;SAC5F,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAqB;IAC1C,EAAE,EAAE,KAAK;IACT,WAAW,EAAE,KAAK;IAClB,aAAa,EAAE,CAAC,cAAc,CAAC;IAC/B,SAAS,EAAE,CAAC,mBAAmB,CAAC;IAChC,QAAQ,EAAE,IAAI;IAEd,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAG;QAChB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,QAAQ,CAAwD,CAAC,CAAC,MAAM,CAAC,CAAC;QACvF,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO;QAC9B,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,OAAO,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,GAAG;QAC5B,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QACvC,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;YACzE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;SAChE,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,50 @@
1
+ import { readdir } from "node:fs/promises";
2
+ import { pathExists } from "./types.js";
3
+ import { exec } from "../exec.js";
4
+ // `dotnet list package --outdated` prints whitespace-aligned columns, no
5
+ // arrow: " > Newtonsoft.Json 13.0.1 13.0.1 13.0.3"
6
+ // (Package Requested Resolved Latest) — current version is "Resolved".
7
+ const OUTDATED_LINE = /^\s*>\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/;
8
+ export function parseNugetOutdated(stdout) {
9
+ const out = [];
10
+ for (const line of stdout.split("\n")) {
11
+ const m = OUTDATED_LINE.exec(line);
12
+ if (m)
13
+ out.push({ name: m[1], current: m[3], wanted: m[2], latest: m[4] });
14
+ }
15
+ return out;
16
+ }
17
+ async function hasCsproj(cwd) {
18
+ try {
19
+ const entries = await readdir(cwd);
20
+ return entries.some((e) => e.endsWith(".csproj") || e.endsWith(".sln"));
21
+ }
22
+ catch {
23
+ return false;
24
+ }
25
+ }
26
+ export const nugetAdapter = {
27
+ id: "nuget",
28
+ displayName: "NuGet (.NET)",
29
+ manifestFiles: ["*.csproj"],
30
+ lockFiles: ["packages.lock.json"],
31
+ verified: true,
32
+ async detect(cwd) {
33
+ return hasCsproj(cwd);
34
+ },
35
+ async outdated(cwd) {
36
+ const r = await exec("dotnet", ["list", "package", "--outdated"], { cwd, timeout: 180_000 });
37
+ return parseNugetOutdated(r.stdout);
38
+ },
39
+ async install(cwd, name, version) {
40
+ return exec("dotnet", ["add", "package", name, "--version", version], { cwd, timeout: 300_000 });
41
+ },
42
+ async defaultCheckCommands() {
43
+ return {
44
+ build: { cmd: "dotnet", args: ["build"] },
45
+ test: { cmd: "dotnet", args: ["test"] },
46
+ };
47
+ },
48
+ };
49
+ void pathExists;
50
+ //# sourceMappingURL=nuget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuget.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/nuget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAwC,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,yEAAyE;AACzE,mEAAmE;AACnE,0EAA0E;AAC1E,MAAM,aAAa,GAAG,uCAAuC,CAAC;AAE9D,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,GAAG,GAAe,EAAE,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;QACnC,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,EAAE,EAAE,OAAO;IACX,WAAW,EAAE,cAAc;IAC3B,aAAa,EAAE,CAAC,UAAU,CAAC;IAC3B,SAAS,EAAE,CAAC,oBAAoB,CAAC;IACjC,QAAQ,EAAE,IAAI;IAEd,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAG;QAChB,MAAM,CAAC,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,YAAY,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC7F,OAAO,kBAAkB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO;QAC9B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IACnG,CAAC;IAED,KAAK,CAAC,oBAAoB;QACxB,OAAO;YACL,KAAK,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;YACzC,IAAI,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE;SACxC,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,KAAK,UAAU,CAAC"}
@@ -0,0 +1,255 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { parseYarnOutdated } from "./yarn.js";
4
+ import { parseGoListOutdated } from "./go.js";
5
+ import { parseComposerOutdated } from "./composer.js";
6
+ import { parsePubOutdated } from "./pub.js";
7
+ import { parseNugetOutdated } from "./nuget.js";
8
+ import { parseCargoToml } from "./cargo.js";
9
+ import { parsePomXml } from "./maven.js";
10
+ import { parseGradleBuildFile } from "./gradle.js";
11
+ import { parseBundlerOutdated } from "./bundler.js";
12
+ import { parsePoetryOutdated } from "./poetry.js";
13
+ import { parseCocoapodsOutdated } from "./cocoapods.js";
14
+ import { parseMixOutdated } from "./mix.js";
15
+ import { parseConanfileTxt } from "./conan.js";
16
+ import { parseNpmOutdated } from "./npm.js";
17
+ import { parsePnpmOutdated } from "./pnpm.js";
18
+ import { parsePipOutdated } from "./pip.js";
19
+ import { parseUvOutdated } from "./uv.js";
20
+ import { parsePipenvOutdated } from "./pipenv.js";
21
+ import { parseElmDirectDeps } from "./elm.js";
22
+ import { parsePackageResolved, parsePackageSwiftDeps } from "./swiftpm.js";
23
+ test("yarn: parses the ndjson table row, skips non-table lines", () => {
24
+ const stdout = [
25
+ JSON.stringify({ type: "info", data: "unrelated" }),
26
+ JSON.stringify({
27
+ type: "table",
28
+ data: {
29
+ head: ["Package", "Current", "Wanted", "Latest", "Package Type", "URL"],
30
+ body: [
31
+ ["lodash", "4.17.20", "4.17.21", "4.17.21", "dependencies", ""],
32
+ ["left-pad", "1.0.0", "1.0.0", "1.0.0", "dependencies", ""],
33
+ ],
34
+ },
35
+ }),
36
+ ].join("\n");
37
+ const result = parseYarnOutdated(stdout);
38
+ assert.deepEqual(result, [{ name: "lodash", current: "4.17.20", wanted: "", latest: "4.17.21" }]);
39
+ });
40
+ test("go: parses ndjson module stream, skips main/indirect/no-update", () => {
41
+ const stdout = [
42
+ JSON.stringify({ Path: "example.com/app", Main: true }),
43
+ JSON.stringify({ Path: "example.com/indirect", Version: "v1.0.0", Indirect: true, Update: { Version: "v1.1.0" } }),
44
+ JSON.stringify({ Path: "example.com/nodiff", Version: "v1.0.0", Update: { Version: "v1.0.0" } }),
45
+ JSON.stringify({ Path: "example.com/direct", Version: "v1.0.0", Update: { Version: "v1.2.0" } }),
46
+ ].join("\n");
47
+ const result = parseGoListOutdated(stdout);
48
+ assert.deepEqual(result, [{ name: "example.com/direct", current: "v1.0.0", wanted: "", latest: "v1.2.0" }]);
49
+ });
50
+ test("composer: parses `composer outdated --format json`", () => {
51
+ const stdout = JSON.stringify({
52
+ installed: [
53
+ { name: "monolog/monolog", version: "2.0.0", latest: "3.5.0" },
54
+ { name: "psr/log", version: "1.1.4", latest: "1.1.4" },
55
+ ],
56
+ });
57
+ const result = parseComposerOutdated(stdout);
58
+ assert.deepEqual(result, [{ name: "monolog/monolog", current: "2.0.0", wanted: "", latest: "3.5.0" }]);
59
+ });
60
+ test("pub: parses `dart pub outdated --json`", () => {
61
+ const stdout = JSON.stringify({
62
+ packages: [
63
+ { package: "http", current: { version: "0.13.0" }, latest: { version: "1.2.0" } },
64
+ { package: "path", current: { version: "1.8.0" }, latest: { version: "1.8.0" } },
65
+ ],
66
+ });
67
+ const result = parsePubOutdated(stdout);
68
+ assert.deepEqual(result, [{ name: "http", current: "0.13.0", wanted: "", latest: "1.2.0" }]);
69
+ });
70
+ test("nuget: parses `dotnet list package --outdated` table", () => {
71
+ const stdout = [
72
+ "Project 'App' has the following updates to its packages",
73
+ " [net8.0]:",
74
+ " Top-level Package Requested Resolved Latest",
75
+ " > Newtonsoft.Json 13.0.1 13.0.1 13.0.3",
76
+ ].join("\n");
77
+ const result = parseNugetOutdated(stdout);
78
+ assert.deepEqual(result, [{ name: "Newtonsoft.Json", current: "13.0.1", wanted: "13.0.1", latest: "13.0.3" }]);
79
+ });
80
+ test("cargo: parses [dependencies] section of Cargo.toml", () => {
81
+ const raw = [
82
+ "[package]",
83
+ 'name = "app"',
84
+ "",
85
+ "[dependencies]",
86
+ 'serde = "1.0"',
87
+ 'tokio = "^1.28"',
88
+ "",
89
+ "[dev-dependencies]",
90
+ 'criterion = "0.5"',
91
+ ].join("\n");
92
+ const result = parseCargoToml(raw);
93
+ assert.deepEqual([...result.entries()], [["serde", "1.0"], ["tokio", "1.28"]]);
94
+ });
95
+ test("maven: parses <dependency> blocks from pom.xml", () => {
96
+ const raw = `<project>
97
+ <dependencies>
98
+ <dependency>
99
+ <groupId>org.apache.commons</groupId>
100
+ <artifactId>commons-lang3</artifactId>
101
+ <version>3.12.0</version>
102
+ </dependency>
103
+ </dependencies>
104
+ </project>`;
105
+ const result = parsePomXml(raw);
106
+ assert.deepEqual(result, [{ name: "org.apache.commons:commons-lang3", version: "3.12.0" }]);
107
+ });
108
+ test("gradle: parses implementation(...) dependency declarations", () => {
109
+ const raw = `dependencies {
110
+ implementation("com.google.guava:guava:31.1-jre")
111
+ testImplementation 'junit:junit:4.13.2'
112
+ }`;
113
+ const result = parseGradleBuildFile(raw);
114
+ assert.deepEqual(result, [
115
+ { group: "com.google.guava", artifact: "guava", version: "31.1-jre" },
116
+ { group: "junit", artifact: "junit", version: "4.13.2" },
117
+ ]);
118
+ });
119
+ test("bundler: parses `bundle outdated` gem lines", () => {
120
+ const stdout = [
121
+ "Fetching gem metadata...",
122
+ "Gem Current Latest Requested Groups",
123
+ "* rails (newest 7.1.2, installed 7.0.4, requested ~> 7.0) in groups \"default\"",
124
+ "* rake (newest 13.1.0, installed 13.1.0)",
125
+ ].join("\n");
126
+ const result = parseBundlerOutdated(stdout);
127
+ assert.deepEqual(result, [{ name: "rails", current: "7.0.4", wanted: "", latest: "7.1.2" }]);
128
+ });
129
+ test("poetry: parses `poetry show -o` plain-text table", () => {
130
+ const stdout = ["requests 2.28.0 2.31.0 HTTP library", "click 8.1.3 8.1.3 CLI toolkit"].join("\n");
131
+ const result = parsePoetryOutdated(stdout);
132
+ assert.deepEqual(result, [{ name: "requests", current: "2.28.0", wanted: "", latest: "2.31.0" }]);
133
+ });
134
+ test("cocoapods: parses `pod outdated` list lines, using the (latest version) suffix", () => {
135
+ // The value after "->" is only what the Podfile's constraint resolves
136
+ // to (often == current for an exact pin, as with AFNetworking below) —
137
+ // the true latest is only in the "(latest version X)" suffix.
138
+ const stdout = [
139
+ "The following pod updates are available:",
140
+ "- AFNetworking 3.2.1 -> 3.2.1 (latest version 4.0.1)",
141
+ "- Alamofire 5.6.0 -> 5.6.0 (latest version 5.6.0)",
142
+ ].join("\n");
143
+ const result = parseCocoapodsOutdated(stdout);
144
+ assert.deepEqual(result, [{ name: "AFNetworking", current: "3.2.1", wanted: "", latest: "4.0.1" }]);
145
+ });
146
+ test("mix: parses `mix hex.outdated` table rows, including the Only column", () => {
147
+ // Real `mix hex.outdated` output always has the "Only" column; it's blank
148
+ // for deps with no `only:` restriction (e.g. jason below).
149
+ const stdout = [
150
+ "Dependency Only Current Latest Status ",
151
+ "ex_doc dev 0.29.0 0.40.3 Update not possible ",
152
+ "jason 1.2.0 1.4.5 Update not possible ",
153
+ "",
154
+ "Run `mix hex.outdated APP` to see requirements for a specific dependency.",
155
+ ].join("\n");
156
+ const result = parseMixOutdated(stdout);
157
+ assert.deepEqual(result, [
158
+ { name: "ex_doc", current: "0.29.0", wanted: "", latest: "0.40.3" },
159
+ { name: "jason", current: "1.2.0", wanted: "", latest: "1.4.5" },
160
+ ]);
161
+ });
162
+ test("conan: parses [requires] section of conanfile.txt", () => {
163
+ const raw = ["[requires]", "zlib/1.2.13", "boost/1.83.0", "", "[generators]", "CMakeDeps"].join("\n");
164
+ const result = parseConanfileTxt(raw);
165
+ assert.deepEqual(result, [
166
+ { name: "zlib", version: "1.2.13" },
167
+ { name: "boost", version: "1.83.0" },
168
+ ]);
169
+ });
170
+ test("npm: parses `npm outdated --json` output, dropping entries already at latest", () => {
171
+ const data = {
172
+ lodash: { current: "4.17.20", latest: "4.17.21" },
173
+ axios: { current: "1.3.0", latest: "1.3.0" },
174
+ };
175
+ const result = parseNpmOutdated(data);
176
+ assert.deepEqual(result, [{ name: "lodash", current: "4.17.20", wanted: "", latest: "4.17.21" }]);
177
+ });
178
+ test("npm: null data (non-JSON stdout) yields empty result", () => {
179
+ assert.deepEqual(parseNpmOutdated(null), []);
180
+ });
181
+ test("pnpm: parses `pnpm outdated --format json`, tolerating missing current/latest", () => {
182
+ const data = {
183
+ lodash: { current: "4.17.20", latest: "4.17.21" },
184
+ // pnpm can omit fields for workspace-linked packages; guard against undefined.
185
+ weird: {},
186
+ };
187
+ const result = parsePnpmOutdated(data);
188
+ assert.deepEqual(result, [{ name: "lodash", current: "4.17.20", wanted: "", latest: "4.17.21" }]);
189
+ });
190
+ test("pnpm: null data yields empty result", () => {
191
+ assert.deepEqual(parsePnpmOutdated(null), []);
192
+ });
193
+ test("pip: parses `pip list --outdated --format json`", () => {
194
+ const data = [
195
+ { name: "requests", version: "2.28.0", latest_version: "2.31.0" },
196
+ { name: "flask", version: "2.0.0", latest_version: "2.3.3" },
197
+ ];
198
+ const result = parsePipOutdated(data);
199
+ assert.deepEqual(result, [
200
+ { name: "requests", current: "2.28.0", wanted: "", latest: "2.31.0" },
201
+ { name: "flask", current: "2.0.0", wanted: "", latest: "2.3.3" },
202
+ ]);
203
+ });
204
+ test("pip: null data yields empty result", () => {
205
+ assert.deepEqual(parsePipOutdated(null), []);
206
+ });
207
+ test("uv: parses `uv pip list --outdated --format json` (same shape as pip)", () => {
208
+ const data = [{ name: "requests", version: "2.28.0", latest_version: "2.31.0" }];
209
+ const result = parseUvOutdated(data);
210
+ assert.deepEqual(result, [{ name: "requests", current: "2.28.0", wanted: "", latest: "2.31.0" }]);
211
+ });
212
+ test("uv: null data yields empty result", () => {
213
+ assert.deepEqual(parseUvOutdated(null), []);
214
+ });
215
+ test("pipenv: parses `pipenv run pip list --outdated --format json`", () => {
216
+ const data = [{ name: "django", version: "4.0.0", latest_version: "4.2.5" }];
217
+ const result = parsePipenvOutdated(data);
218
+ assert.deepEqual(result, [{ name: "django", current: "4.0.0", wanted: "", latest: "4.2.5" }]);
219
+ });
220
+ test("pipenv: null data yields empty result", () => {
221
+ assert.deepEqual(parsePipenvOutdated(null), []);
222
+ });
223
+ test("elm: extracts direct dependencies from elm.json, ignoring indirect deps", () => {
224
+ const json = {
225
+ dependencies: {
226
+ direct: { "elm/core": "1.0.5", "elm/json": "1.1.3" },
227
+ indirect: { "elm/bytes": "1.0.8" },
228
+ },
229
+ };
230
+ assert.deepEqual(parseElmDirectDeps(json), { "elm/core": "1.0.5", "elm/json": "1.1.3" });
231
+ });
232
+ test("elm: missing dependencies field yields empty object", () => {
233
+ assert.deepEqual(parseElmDirectDeps({}), {});
234
+ });
235
+ test("swiftpm: parses Package.resolved pins into a name-to-version map", () => {
236
+ const raw = JSON.stringify({
237
+ pins: [
238
+ { identity: "swift-log", state: { version: "1.5.3" } },
239
+ { identity: "no-version-pin", state: {} },
240
+ ],
241
+ });
242
+ assert.deepEqual(parsePackageResolved(raw), { "swift-log": "1.5.3" });
243
+ });
244
+ test("swiftpm: extracts .package(url:, from:) declarations and joins with resolved versions", () => {
245
+ const manifest = [
246
+ ".package(url: \"https://github.com/apple/swift-log.git\", from: \"1.4.0\")",
247
+ ".package(url: \"https://github.com/apple/swift-nio.git\", from: \"2.0.0\")",
248
+ ].join("\n");
249
+ const resolved = { "swift-log": "1.5.3" }; // swift-nio has no resolved pin (e.g. not yet fetched)
250
+ const result = parsePackageSwiftDeps(manifest, resolved);
251
+ assert.deepEqual(result, [
252
+ { name: "swift-log", current: "1.5.3", url: "https://github.com/apple/swift-log.git" },
253
+ ]);
254
+ });
255
+ //# sourceMappingURL=parsers.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parsers.test.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/parsers.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ import { join } from "node:path";
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { exec } from "../exec.js";
4
+ import { pathExists, safeJson } from "./types.js";
5
+ import { guessPythonTestCommand } from "./python-shared.js";
6
+ const REQ_FILE = "requirements.txt";
7
+ /**
8
+ * pip has no per-project isolation of its own — `pip list` reports whatever
9
+ * is installed in the active interpreter/venv. We assume the caller has
10
+ * already activated the right venv (same assumption `pip install` itself
11
+ * makes). This is a known limitation vs. lockfile-based ecosystems.
12
+ */
13
+ export function parsePipOutdated(data) {
14
+ if (!data)
15
+ return [];
16
+ return data.map((d) => ({ name: d.name, current: d.version, wanted: "", latest: d.latest_version }));
17
+ }
18
+ export const pipAdapter = {
19
+ id: "pip",
20
+ displayName: "pip",
21
+ manifestFiles: [REQ_FILE],
22
+ lockFiles: [],
23
+ verified: true,
24
+ async detect(cwd) {
25
+ return pathExists(join(cwd, REQ_FILE));
26
+ },
27
+ async outdated(cwd) {
28
+ const r = await exec("pip3", ["list", "--outdated", "--format", "json"], { cwd, timeout: 120_000 });
29
+ const data = safeJson(r.stdout);
30
+ return parsePipOutdated(data);
31
+ },
32
+ async install(cwd, name, version) {
33
+ const r = await exec("pip3", ["install", `${name}==${version}`], { cwd, timeout: 300_000 });
34
+ if (r.code !== 0)
35
+ return r;
36
+ await pinInRequirements(cwd, name, version);
37
+ return r;
38
+ },
39
+ async defaultCheckCommands(cwd) {
40
+ const test = await guessPythonTestCommand(cwd);
41
+ return { test };
42
+ },
43
+ };
44
+ /** `pip install` doesn't touch requirements.txt, so we pin the version ourselves. */
45
+ async function pinInRequirements(cwd, name, version) {
46
+ const path = join(cwd, REQ_FILE);
47
+ try {
48
+ const raw = await readFile(path, "utf8");
49
+ const re = new RegExp(`^${escapeRegExp(name)}\\s*(==|>=|<=|~=|>|<)?.*$`, "im");
50
+ const line = `${name}==${version}`;
51
+ const next = re.test(raw) ? raw.replace(re, line) : raw.trimEnd() + `\n${line}\n`;
52
+ await writeFile(path, next, "utf8");
53
+ }
54
+ catch {
55
+ // no requirements.txt to update; the pip install itself already ran.
56
+ }
57
+ }
58
+ function escapeRegExp(s) {
59
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
60
+ }
61
+ //# sourceMappingURL=pip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pip.js","sourceRoot":"","sources":["../../../src/engine/ecosystems/pip.ts"],"names":[],"mappings":"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"}