diff --git a/cli/main.ts b/cli/main.ts index e28fdbb2..00dff066 100644 --- a/cli/main.ts +++ b/cli/main.ts @@ -4,7 +4,7 @@ import { collect } from "@molt/core"; import type { Update } from "@molt/core/types"; import { printChangelog } from "./src/changelog.ts"; -import { findConfig, findLock } from "./src/files.ts"; +import { findConfig, findLock, findSource } from "./src/files.ts"; import { runTasks } from "./src/tasks.ts"; import { print, printRefs } from "./src/updates.ts"; @@ -53,6 +53,8 @@ main.action(async function (options, ...source) { ? undefined : options.lock ?? await findLock(); + source = source.length ? source : config ? [] : await findSource(); + if (options.dryRun) { const paths = [config, lock, ...source].filter((it) => it != null); await import("./src/mock.ts").then((m) => m.mock(paths)); diff --git a/cli/main_test.ts b/cli/main_test.ts index 0236bf84..62110775 100644 --- a/cli/main_test.ts +++ b/cli/main_test.ts @@ -69,4 +69,23 @@ describe("CLI", () => { `, ); }); + + it("should find updates in modules with `--no-config`", async () => { + const { stderr, stdout } = await molt("--no-config"); + assertEquals( + stdout, + dedent` + 📦 @conventional-commits/parser 0.4.0 → 0.4.1 + 📦 @luca/flag 1.0.0 → 1.0.1 + 📦 deno.land/std 0.222.0 → 0.224.0 + `, + ); + assertEquals( + stderr, + dedent` + Collecting dependencies + Fetching updates + `, + ); + }); }); diff --git a/cli/src/files.ts b/cli/src/files.ts index ebad4fe8..67826fa2 100644 --- a/cli/src/files.ts +++ b/cli/src/files.ts @@ -1,15 +1,33 @@ import { exists } from "@std/fs"; +import { parse } from "@std/jsonc"; export async function findConfig() { - if (await exists("deno.json")) { + if (await exists("deno.json") && await hasImports("deno.json")) { return "deno.json"; - } else if (await exists("deno.jsonc")) { + } + if (await exists("deno.jsonc") && await hasImports("deno.jsonc")) { return "deno.jsonc"; } } +async function hasImports(config: string): Promise { + if (!config) return false; + const jsonc = parse(await Deno.readTextFile(config)); + return jsonc !== null && typeof jsonc === "object" && "imports" in jsonc; +} + export async function findLock() { if (await exists("deno.lock")) { return "deno.lock"; } } + +export async function findSource() { + const source: string[] = []; + for await (const entry of Deno.readDir(".")) { + if (entry.isFile && entry.name.endsWith(".ts")) { + source.push(entry.name); + } + } + return source; +}; diff --git a/cli/src/updates.ts b/cli/src/updates.ts index 5ce63882..cec5c005 100644 --- a/cli/src/updates.ts +++ b/cli/src/updates.ts @@ -1,5 +1,6 @@ import { colors } from "@cliffy/ansi"; import type { Update } from "@molt/core/types"; +import * as SemVer from "@std/semver"; const { bold, yellow, gray, cyan } = colors; @@ -7,16 +8,25 @@ export function print(update: Update) { const { constraint, lock } = update; let output = `📦 ${bold(update.dep.name)}`; - if (constraint && !lock) { - output += cyan(` ${constraint.from} → ${constraint.to}`); - return output; - } - if (lock) { - output += yellow(` ${lock.from} → ${lock.to}`); + const versions = constraint && SemVer.tryParse(constraint.to) + ? constraint + : lock; + + if (versions) { + output += yellow(` ${versions.from} → ${versions.to}`); } - if (constraint && constraint.to !== lock?.to) { - output += cyan(` (${constraint.from} → ${constraint.to})`); + + const ranges = constraint && !SemVer.tryParse(constraint.to) + ? constraint + : undefined; + + if (ranges) { + output += " "; + if (versions) output += cyan("("); + output += cyan(`${ranges.from} → ${ranges.to}`); + if (versions) output += cyan(")"); } + console.log(output); } diff --git a/core/bumps_test.ts b/core/bumps_test.ts index 840d024d..1258919e 100644 --- a/core/bumps_test.ts +++ b/core/bumps_test.ts @@ -4,7 +4,7 @@ import { get } from "./bumps.ts"; import { parse } from "./specs.ts"; describe("bump", () => { - it("should determine the version bump for a package", () => { + it("should bump a constrianted jsr dep with a lock", () => { assertEquals( get( { ...parse("jsr:@std/jsonc@^0.222.1"), locked: "0.222.1" }, @@ -13,4 +13,34 @@ describe("bump", () => { { constraint: "^0.224.0", lock: "0.224.3" }, ); }); + + it("should bump a constrianted jsr dep without a lock", () => { + assertEquals( + get( + parse("jsr:@std/jsonc@^0.222.1"), + { latest: "1.0.0-rc.3", released: "0.224.3" }, + ), + { constraint: "^0.224.0" }, + ); + }); + + it("should bump a fixed jsr dep with a lock", () => { + assertEquals( + get( + { ...parse("jsr:@std/jsonc@0.222.1"), locked: "0.222.1" }, + { latest: "1.0.0-rc.3", released: "0.224.3" }, + ), + { constraint: "0.224.3", lock: "0.224.3" }, + ); + }); + + it("should bump a fixed jsr dep without a lock", () => { + assertEquals( + get( + parse("jsr:@std/jsonc@0.222.1"), + { latest: "1.0.0-rc.3", released: "0.224.3" }, + ), + { constraint: "0.224.3" }, + ); + }); }); diff --git a/core/updates_test.ts b/core/updates_test.ts index 30d251a0..07767f91 100644 --- a/core/updates_test.ts +++ b/core/updates_test.ts @@ -33,6 +33,14 @@ describe("get", () => { }); }); + it("should get an update to a fixed jsr dep", async () => { + const dep = parse("jsr:@molt/core@0.18.0"); + assertEquals(await get(dep), { + released: "0.18.5", + latest, + }); + }); + it("should get an update to a jsr dep", async () => { const dep = parse("jsr:@molt/core@^0.18.0"); assertEquals(await get(dep), {