Skip to content

Commit

Permalink
fix(core,cli): TypeError on non-locked dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
hasundue committed Jul 31, 2024
1 parent f03f02f commit 28782d9
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 10 deletions.
8 changes: 5 additions & 3 deletions core/locks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ async function getJsrDependencies(
export async function extract(
lockfile: LockfileJson,
dependency: DependencySpec,
): Promise<LockfileJson> {
): Promise<LockfileJson | undefined> {
return isRemote(dependency)
? await extractRemote(lockfile, dependency)
: extractPackage(lockfile, dependency as DependencySpec<"jsr" | "npm">);
Expand All @@ -257,14 +257,15 @@ export async function extract(
async function extractRemote(
lock: LockfileJson,
dep: DependencySpec<"http" | "https">,
): Promise<LockfileJson> {
): Promise<LockfileJson | undefined> {
const reqs = Object.keys(lock.remote).filter((req) =>
req.startsWith(stringify(dep))
);
const deps = (await Promise.all(reqs.map(async (req) => {
const graph = await createGraph(req);
return graph.modules.map((mod) => mod.specifier);
}))).flat();
if (!deps.length) return;
return {
version: VERSION,
remote: filterValues(
Expand All @@ -277,11 +278,12 @@ async function extractRemote(
function extractPackage(
lock: LockfileJson,
dep: DependencySpec<"jsr" | "npm">,
): LockfileJson {
): LockfileJson | undefined {
const name = stringify(dep, "kind", "name", "constraint");
const lockfile = parseFromJson("", lock);
lockfile.setWorkspaceConfig({ dependencies: [name] });
const json = lockfile.toJson();
if (!json.packages) return;
json.remote = {};
return json;
}
Expand Down
6 changes: 6 additions & 0 deletions core/locks_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,12 @@ describe("extract", () => {
beforeEach(() => fs.mock());
afterEach(() => fs.dispose());

it("should return undefined for an unlocked package", async () => {
const dep = parse("jsr:@std/testing@^0.222.0");
const lock = await extract(LOCKFILE, dep);
assertEquals(lock, undefined);
});

it("should extract the partial lock for a jsr package from a lockfile", async () => {
const dep = parse("jsr:@std/assert@^0.222.0");
const lock = await extract(LOCKFILE, dep);
Expand Down
14 changes: 7 additions & 7 deletions core/mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class LockContext {

get merged(): LockfileJson {
return this.reqs.map((req) =>
this.created.get(req) ?? this.extracted.get(req)!
this.created.get(req) ?? this.extracted.get(req) ?? {} as LockfileJson
// @ts-ignore allow passing concrete types to deepMerge
).reduce((prev, curr) => deepMerge(prev, curr), Lock.empty);
}
Expand Down Expand Up @@ -159,7 +159,7 @@ export async function collect(
const lockfile = Lock.parse(await Deno.readTextFile(options.lock!));
for (const req of reqs) {
const lock = await Lock.extract(lockfile, parse(req));
locks.extracted.set(req, lock);
if (lock) locks.extracted.set(req, lock);
}
}
const ctx = new Context(reqs, refs, locks);
Expand Down Expand Up @@ -217,11 +217,11 @@ class Update implements UpdateI {
const bumped = bump.constraint
? { ...dep, constraint: bump.constraint }
: dep;

const locked = this.#ctx.locks.extracted.get(req)!;
const lock = await Lock.create(bumped, bump.lock, locked);
this.#ctx.locks.created.set(req, lock);

const locked = this.#ctx.locks.extracted.get(req);
if (locked) {
const lock = await Lock.create(bumped, bump.lock, locked);
this.#ctx.locks.created.set(req, lock);
}
await Deno.writeTextFile(
this.#ctx.locks.source,
Lock.format(this.#ctx.locks.merged),
Expand Down
44 changes: 44 additions & 0 deletions core/mod_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,48 @@ describe("core", () => {
lock: "deno.lock",
});
});

it("should handle an non-locked dependency", async () => {
await Deno.writeTextFile(
"deno.json",
dedent`
{
"imports": {
"@conventional-commits/parser": "npm:@conventional-commits/parser@^0.3.0",
"@luca/flag": "jsr:@luca/flag@^1.0.0"
}
}
`,
);
const deps = await collect({ config: "deno.json", lock: "deno.lock" });
assertEquals(deps.length, 2);
const [dep] = deps;
const update = await dep.check();
assertExists(update);
assertEquals(update.dep.name, "@conventional-commits/parser");
await update.write();
assertEquals(await Deno.readTextFile("mod.ts"), MOD_TS);
assertEquals(
await Deno.readTextFile("deno.json"),
dedent`
{
"imports": {
"@conventional-commits/parser": "npm:@conventional-commits/parser@^0.4.0",
"@luca/flag": "jsr:@luca/flag@^1.0.0"
}
}
`,
);
assertEquals(await Deno.readTextFile("deno.lock"), DENO_LOCK);
await update.commit();
assertSpyCallArg(git, 0, 1, {
args: [
"commit",
"-m",
"bump @conventional-commits/parser to ^0.4.0",
"deno.json",
],
lock: undefined,
});
});
});

0 comments on commit 28782d9

Please sign in to comment.