Skip to content

Commit

Permalink
Fix regression tests
Browse files Browse the repository at this point in the history
  • Loading branch information
robsimmons committed Apr 15, 2024
1 parent 3968742 commit 82e98de
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 77 deletions.
7 changes: 6 additions & 1 deletion TEST/regression-wiki.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { readdirSync, writeFileSync } from "fs";
import { getImportedPrelude } from "../wiki/elf-wiki-imports.mjs";

/* Only files that are broken *on purpose* (because they're templates
* meant to be filled out as exercises) should be added here.
Expand Down Expand Up @@ -35,7 +36,11 @@ for (const file of readdirSync(WIKI_TWELF_LOC)) {
const base = file.slice(0, file.length - 4);
if (IGNORED_WIKI_FILES.has(base)) continue;
const cfg = base + ".cfg";
writeFileSync(WIKI_TWELF_LOC + cfg, file);
const dependencies = getImportedPrelude(WIKI_TWELF_LOC, file);
writeFileSync(
WIKI_TWELF_LOC + cfg,
dependencies.map(({ file }) => file + "\n") + file
);
cfgs.push(
`test${
UNSAFE_WIKI_FILES.has(base) ? "Unsafe" : ""
Expand Down
79 changes: 3 additions & 76 deletions wiki/elf-watcher.mjs
Original file line number Diff line number Diff line change
@@ -1,87 +1,14 @@
import {
existsSync,
mkdirSync,
readFileSync,
readdirSync,
watch,
writeFileSync,
} from "fs";
import { existsSync, mkdirSync, readdirSync, watch, writeFileSync } from "fs";
import { argv } from "process";
import { elfToMdx } from "./elf-to-mdx.mjs";
import { getImportedPrelude } from "./elf-wiki-imports.mjs";

const DIR_OF_ELF = "pages";
const DIR_OF_MDX = "src/content/docs/wiki";
if (!existsSync(DIR_OF_MDX)) {
mkdirSync("src/content/docs/wiki");
}

/**
* Read the file's header to get all of the imported elf files
* (in reverse order)
*
* @param {string} contents
*/
function getImportedFilenames(contents) {
/**@type {string[]} */
const importStatements = [];

for (const line of contents.split("\n")) {
if (!line.startsWith("%%! ")) break;
if (line.startsWith("%%! import: ")) {
importStatements.push(line.slice(12).trim());
}
}

return importStatements;
}

/**
* Uses a DFS traversal
*
* @param {Set<string>} known
* Avoids double-importing by tracking all the filenames ever added to `accum` in the process of this traversal
* @param {{file: string, contents: string}[]} accum
* Accumulates the files, making sure that files are added after their dependencies
* @param {string} elfname
* Name of an ELF file that is a dependency of the file we're trying to load
*/
function dfsAccumImportedPrelude(known, accum, elfname) {
if (!elfname.match(/^[a-zA-Z.\-_0-9]*[.]elf*$/)) {
throw new Error(
`Imported path ${elfname} invalid: must include only letters, numbers, dashes, and underscores and end in .elf`
);
}
const contents = readFileSync(`${DIR_OF_ELF}/${elfname}`).toString("utf-8");
for (const importElf in getImportedFilenames(contents)) {
if (!known.has(importElf)) {
known.add(importElf);
dfsAccumImportedPrelude(known, accum, importElf);
}
}
accum.push({ file: elfname, contents });
}

/**
*
* @param {string} elfname
*/
function getImportedPrelude(elfname) {
/**@type {Set<string>} */
const known = new Set();

/**@type {{file: string, contents: string}[]} */
const dependencies = [];

for (const file of getImportedFilenames(
readFileSync(elfname).toString("utf-8")
)) {
known.add(file);
dfsAccumImportedPrelude(known, dependencies, file);
}

return dependencies;
}

/**
* Convert and store a Wiki Twelf file as MDX
* @param {string} file
Expand All @@ -93,7 +20,7 @@ async function mdxOfFile(file) {
const mdxname = `${DIR_OF_MDX}/${base}.mdx`;
try {
console.log(`elf->mdx transforming ${file}`);
const prelude = getImportedPrelude(elfname);
const prelude = getImportedPrelude(`${DIR_OF_ELF}/`, file);
const mdxFile = await elfToMdx(
elfname,
prelude.map(({ file, contents }) => `%%! file: ${file}\n${contents}\n`)
Expand Down
72 changes: 72 additions & 0 deletions wiki/elf-wiki-imports.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { readFileSync } from "fs";

/**
* Read the file's header to get all of the imported elf files
* (in reverse order)
*
* @param {string} contents
*/
function getImportedFilenames(contents) {
/**@type {string[]} */
const importStatements = [];

for (const line of contents.split("\n")) {
if (!line.startsWith("%%! ")) break;
if (line.startsWith("%%! import: ")) {
importStatements.push(line.slice(12).trim());
}
}

return importStatements;
}

/**
* Uses a DFS traversal
*
* @param {string} base
* Relative path of elf files
* @param {Set<string>} known
* Avoids double-importing by tracking all the filenames ever added to `accum` in the process of this traversal
* @param {{file: string, contents: string}[]} accum
* Accumulates the files, making sure that files are added after their dependencies
* @param {string} elfname
* Name of an ELF file that is a dependency of the file we're trying to load
*/
function dfsAccumImportedPrelude(base, known, accum, elfname) {
if (!elfname.match(/^[a-zA-Z.\-_0-9]*[.]elf*$/)) {
throw new Error(
`Imported path ${elfname} invalid: must include only letters, numbers, dashes, and underscores and end in .elf`
);
}
const contents = readFileSync(`${base}${elfname}`).toString("utf-8");
for (const importElf in getImportedFilenames(contents)) {
if (!known.has(importElf)) {
known.add(importElf);
dfsAccumImportedPrelude(base, known, accum, importElf);
}
}
accum.push({ file: elfname, contents });
}

/**
*
* @param {string} base
* Relative path of elf files
* @param {string} elfname
*/
export function getImportedPrelude(base, elfname) {
/**@type {Set<string>} */
const known = new Set();

/**@type {{file: string, contents: string}[]} */
const dependencies = [];

for (const file of getImportedFilenames(
readFileSync(`${base}${elfname}`).toString("utf-8")
)) {
known.add(file);
dfsAccumImportedPrelude(base, known, dependencies, file);
}

return dependencies;
}

0 comments on commit 82e98de

Please sign in to comment.