Skip to content

Commit

Permalink
fix: support deno.jsonc
Browse files Browse the repository at this point in the history
Also fixes a problem with trailing slashes in JSON files
  • Loading branch information
hasundue committed Mar 6, 2024
1 parent b280f3c commit 7219979
Show file tree
Hide file tree
Showing 12 changed files with 486 additions and 65 deletions.
2 changes: 2 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 4 additions & 10 deletions lib/file.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { detectEOL, EOL, formatEOL } from "./std/fs.ts";
import { detectEOL, EOL } from "./std/fs.ts";
import { toUrl } from "./dependency.ts";
import { type DependencyUpdate } from "./update.ts";
import { parseImportMapJson } from "./import_map.ts";

/**
* Write the given array of DependencyUpdate to files.
Expand Down Expand Up @@ -127,14 +126,9 @@ async function writeToImportMap(
/** The dependency update to apply. */
update: FileUpdate<"import_map">,
) {
const content = await Deno.readTextFile(update.path);
const json = parseImportMapJson(content);
let content = await Deno.readTextFile(update.path);
for (const dependency of update.dependencies) {
json.imports[dependency.map.key] = toUrl(dependency.to);
content = content.replaceAll(toUrl(dependency.from), toUrl(dependency.to));
}
const eol = detectEOL(content) ?? EOL;
await Deno.writeTextFile(
update.path,
formatEOL(JSON.stringify(json, null, 2), eol) + eol,
);
await Deno.writeTextFile(update.path, content);
}
43 changes: 27 additions & 16 deletions lib/file_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ReadTextFileStub,
WriteTextFileStub,
} from "./testing.ts";
import { assertInstanceOf } from "./std/assert.ts";
import { assertSnapshot } from "./testing.ts";
import * as DependencyUpdate from "./update.ts";
import { associateByFile, type FileUpdate, write } from "./file.ts";
Expand All @@ -15,7 +16,9 @@ LatestSemVerStub.create(LATEST);

function toName(path: string) {
const base = basename(path);
return base === "mod.ts" ? `${basename(dirname(path))}/mod.ts` : base;
return base === "mod.ts" || base.endsWith(".json") || base.endsWith(".jsonc")
? basename(dirname(path)) + "/" + base
: base;
}

async function assertFileUpdateSnapshot(
Expand Down Expand Up @@ -56,21 +59,26 @@ ReadTextFileStub.create(fs, { readThrough: true });
WriteTextFileStub.create(fs);

async function test(path: string, name = toName(path)) {
const updates = await DependencyUpdate.collect(
new URL(path, import.meta.url),
{ cwd: new URL(dirname(path), import.meta.url) },
);
const results = associateByFile(updates);
try {
const updates = await DependencyUpdate.collect(
new URL(path, import.meta.url),
{ cwd: new URL(dirname(path), import.meta.url) },
);
const results = associateByFile(updates);

Deno.test("associateByFile - " + name, async (t) => {
await assertFileUpdateSnapshot(t, results);
});
Deno.test("associateByFile - " + name, async (t) => {
await assertFileUpdateSnapshot(t, results);
});

Deno.test("write - " + name, async (t) => {
fs.clear();
await write(results);
await assertFileSystemSnapshot(t, fs);
});
Deno.test("write - " + name, async (t) => {
fs.clear();
await write(results);
await assertFileSystemSnapshot(t, fs);
});
} catch (error) {
// import_map_reffered/deno.json just reffers to another import_map.json
assertInstanceOf(error, SyntaxError);
}
}

// Test the all cases in test/data
Expand All @@ -86,8 +94,11 @@ for await (
new URL("../test/data/" + testCase.name, import.meta.url),
)
) {
if (entry.isFile && entry.name === "mod.ts") {
await test(`../test/data/${testCase.name}/mod.ts`);
if (
entry.isFile && entry.name === "mod.ts" ||
entry.name.endsWith(".json") || entry.name.endsWith(".jsonc")
) {
await test(`../test/data/${testCase.name}/${entry.name}`);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions lib/std/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export { assertObjectMatch } from "https://deno.land/std@0.218.2/assert/assert_o
export { assertThrows } from "https://deno.land/std@0.218.2/assert/assert_throws.ts";
export { AssertionError } from "https://deno.land/std@0.218.2/assert/assertion_error.ts";
export { assertRejects } from "https://deno.land/std@0.218.2/assert/assert_rejects.ts";
export { assertInstanceOf } from "https://deno.land/std@0.218.2/assert/assert_instance_of.ts";
1 change: 1 addition & 0 deletions lib/std/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { maxBy } from "https://deno.land/std@0.218.2/collections/max_by.ts";
export { filterKeys } from "https://deno.land/std@0.218.2/collections/filter_keys.ts";
export { filterEntries } from "https://deno.land/std@0.218.2/collections/filter_entries.ts";
export { mapEntries } from "https://deno.land/std@0.218.2/collections/map_entries.ts";
export { partition } from "https://deno.land/std@0.218.2/collections/partition.ts";
19 changes: 11 additions & 8 deletions lib/update.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { distinct } from "./std/collections.ts";
import { distinct, partition } from "./std/collections.ts";
import { fromFileUrl } from "./std/path.ts";
import {
createGraph,
Expand Down Expand Up @@ -152,8 +152,10 @@ export async function collect(
? await tryReadFromJson(toUrl(importMapPath))
: undefined;

const [jsons, esms] = partition(urls, isJsonPath);

await DenoGraph.ensureInit();
const graph = await createGraph(urls, {
const graph = await createGraph(esms, {
load,
resolve: importMap?.resolveInner,
});
Expand All @@ -172,16 +174,17 @@ export async function collect(
return update ? updates.push(update) : undefined;
})
),
...graph.modules
.filter((m) => m.kind === "asserted" && m.mediaType === "Json")
.map(async (m) => {
const results = await _collectFromImportMap(m.specifier, options);
updates.push(...results);
}),
...jsons.map(async (url) => {
const results = await _collectFromImportMap(url, options);
updates.push(...results);
}),
]);
return updates.sort((a, b) => a.to.name.localeCompare(b.to.name));
}

const isJsonPath = (path: string) =>
path.endsWith(".json") || path.endsWith(".jsonc");

const load: NonNullable<CreateGraphOptions["load"]> = async (
specifier,
) => {
Expand Down
52 changes: 21 additions & 31 deletions lib/update_test.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { dirname } from "./std/path.ts";
import { assertEquals, assertThrows } from "./std/assert.ts";
import { assertEquals, assertInstanceOf, assertThrows } from "./std/assert.ts";
import { filterKeys } from "./std/collections.ts";
import { basename } from "./std/path.ts";
import { assertSnapshot } from "./testing.ts";
import { LatestSemVerStub } from "./testing.ts";
import { readImportMapJson } from "./import_map.ts";
import { collect, DependencyUpdate, getVersionChange } from "./update.ts";

function test(
async function test(
path: string,
name = basename(path),
variation?: string,
) {
Deno.test(
"collect - " + (variation ? `${name} - ${variation}` : name),
async (t) => {
const updates = await collect(new URL(path, import.meta.url), {
cwd: new URL(dirname(path), import.meta.url),
});
for (const update of updates) {
await assertUpdateSnapshot(t, update);
}
},
);
try {
const updates = await collect(new URL(path, import.meta.url), {
cwd: new URL(dirname(path), import.meta.url),
});
Deno.test(
"collect - " + (variation ? `${name} - ${variation}` : name),
async (t) => {
for (const update of updates) {
await assertUpdateSnapshot(t, update);
}
},
);
} catch (error) {
// import_map_reffered/deno.json just reffers to another import_map.json
assertInstanceOf(error, SyntaxError);
}
}

async function assertUpdateSnapshot(
Expand All @@ -39,15 +43,6 @@ async function assertUpdateSnapshot(
);
}

async function hasImportMap(url: URL) {
try {
await readImportMapJson(url);
return true;
} catch {
return false;
}
}

const LATEST = "123.456.789";
LatestSemVerStub.create(LATEST);

Expand All @@ -56,7 +51,7 @@ for await (
const testCase of Deno.readDir(new URL("../test/data", import.meta.url))
) {
if (testCase.isFile && testCase.name.endsWith(".ts")) {
test(`../test/data/${testCase.name}`);
await test(`../test/data/${testCase.name}`);
}
if (testCase.isDirectory) {
for await (
Expand All @@ -66,14 +61,9 @@ for await (
) {
if (
entry.isFile && entry.name === "mod.ts" ||
entry.name.endsWith(".json") && await hasImportMap(
new URL(
`../test/data/${testCase.name}/${entry.name}`,
import.meta.url,
),
)
entry.name.endsWith(".json") || entry.name.endsWith("jsonc")
) {
test(
await test(
`../test/data/${testCase.name}/${entry.name}`,
testCase.name,
entry.name,
Expand Down
10 changes: 10 additions & 0 deletions test/data/jsonc/deno.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"imports": {
"std/": "https://deno.land/std@0.200.0/",
"deno_graph": "https://deno.land/x/deno_graph@0.50.0/mod.ts",
"node-emoji": "npm:node-emoji@1.0.0",
"flag": "jsr:@luca/flag@1.0.0",
// map root to the project root
"/": "./"
}
}
5 changes: 5 additions & 0 deletions test/integration/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ molt("deno.json", { cwd: "import_map" });
molt("deno.json --write", { cwd: "import_map" });
molt("deno.json --commit --prefix :package:", { cwd: "import_map" });

// deno.jsonc
molt("deno.jsonc", { cwd: "jsonc" });
molt("deno.jsonc --write", { cwd: "jsonc" });
molt("deno.jsonc --commit --prefix :package:", { cwd: "jsonc" });

//-----------------------
// Test implementation
//-----------------------
Expand Down
46 changes: 46 additions & 0 deletions test/snapshots/cli.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -421,3 +421,49 @@ snapshot[`cli - import_map - "molt deno.json --commit --prefix :package:" 2`] =
"Checking for updates
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc" 1`] = `
"πŸ“¦ @luca/flag 1.0.0 => 123.456.789
πŸ“¦ deno.land/std 0.200.0 => 123.456.789
πŸ“¦ deno.land/x/deno_graph 0.50.0 => 123.456.789
πŸ“¦ node-emoji 1.0.0 => 123.456.789
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc" 2`] = `
"Checking for updates
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc --write" 1`] = `
"πŸ“¦ @luca/flag 1.0.0 => 123.456.789
πŸ“¦ deno.land/std 0.200.0 => 123.456.789
πŸ“¦ deno.land/x/deno_graph 0.50.0 => 123.456.789
πŸ“¦ node-emoji 1.0.0 => 123.456.789
πŸ’Ύ deno.jsonc
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc --write" 2`] = `
"Checking for updates
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc --commit --prefix :package:" 1`] = `
"πŸ“¦ @luca/flag 1.0.0 => 123.456.789
πŸ“¦ deno.land/std 0.200.0 => 123.456.789
πŸ“¦ deno.land/x/deno_graph 0.50.0 => 123.456.789
πŸ“¦ node-emoji 1.0.0 => 123.456.789
πŸ“ :package: bump @luca/flag from 1.0.0 to 123.456.789
πŸ“ :package: bump deno.land/std from 0.200.0 to 123.456.789
πŸ“ :package: bump deno.land/x/deno_graph from 0.50.0 to 123.456.789
πŸ“ :package: bump node-emoji from 1.0.0 to 123.456.789
"
`;
snapshot[`cli - jsonc - "molt deno.jsonc --commit --prefix :package:" 2`] = `
"Checking for updates
"
`;
Loading

0 comments on commit 7219979

Please sign in to comment.