Format authored monorepo code with pinned language formatters
This commit is contained in:
+51
-59
@@ -1,24 +1,11 @@
|
||||
import { lstat, readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import {
|
||||
parseQuixosLockDocument,
|
||||
type QuixosLockDiagnostic,
|
||||
type QuixosLockParseResult,
|
||||
} from "./parser.js";
|
||||
import type {
|
||||
LockedResource,
|
||||
QuixosLockDocument,
|
||||
QuixosRepositoryLock,
|
||||
} from "./types.js";
|
||||
import { parseQuixosLockDocument, type QuixosLockDiagnostic, type QuixosLockParseResult } from "./parser.js";
|
||||
import type { LockedResource, QuixosLockDocument, QuixosRepositoryLock } from "./types.js";
|
||||
|
||||
export type QuixosLockSourceReader = (relativePath: string) => Promise<string>;
|
||||
|
||||
const diagnostic = (
|
||||
code: string,
|
||||
message: string,
|
||||
fileName: string,
|
||||
path?: string,
|
||||
): QuixosLockDiagnostic => ({
|
||||
const diagnostic = (code: string, message: string, fileName: string, path?: string): QuixosLockDiagnostic => ({
|
||||
phase: "resolution",
|
||||
code,
|
||||
message,
|
||||
@@ -38,11 +25,9 @@ export const resolveQuixosLock = async (
|
||||
if (root.document.kind !== "root") {
|
||||
return {
|
||||
ok: false,
|
||||
diagnostics: [diagnostic(
|
||||
"expected-root-lock",
|
||||
"The entrypoint must be a root Quixos lock, not a fragment",
|
||||
rootFileName,
|
||||
)],
|
||||
diagnostics: [
|
||||
diagnostic("expected-root-lock", "The entrypoint must be a root Quixos lock, not a fragment", rootFileName),
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
@@ -54,15 +39,16 @@ export const resolveQuixosLock = async (
|
||||
|
||||
const addResources = (document: QuixosLockDocument, fileName: string) => {
|
||||
for (const resource of document.resources) {
|
||||
const duplicate = resources.find((entry) =>
|
||||
entry.kind === resource.kind && entry.binding === resource.binding);
|
||||
const duplicate = resources.find((entry) => entry.kind === resource.kind && entry.binding === resource.binding);
|
||||
if (duplicate) {
|
||||
diagnostics.push(diagnostic(
|
||||
"duplicate-resource-binding",
|
||||
`Duplicate ${resource.kind} binding ${resource.binding} across imported lock files`,
|
||||
fileName,
|
||||
`${resource.kind}.${resource.binding}`,
|
||||
));
|
||||
diagnostics.push(
|
||||
diagnostic(
|
||||
"duplicate-resource-binding",
|
||||
`Duplicate ${resource.kind} binding ${resource.binding} across imported lock files`,
|
||||
fileName,
|
||||
`${resource.kind}.${resource.binding}`,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
resources.push(resource);
|
||||
}
|
||||
@@ -71,11 +57,9 @@ export const resolveQuixosLock = async (
|
||||
|
||||
const visit = async (importPath: string) => {
|
||||
if (active.includes(importPath)) {
|
||||
diagnostics.push(diagnostic(
|
||||
"import-cycle",
|
||||
`Lock import cycle: ${[...active, importPath].join(" -> ")}`,
|
||||
importPath,
|
||||
));
|
||||
diagnostics.push(
|
||||
diagnostic("import-cycle", `Lock import cycle: ${[...active, importPath].join(" -> ")}`, importPath),
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (visited.has(importPath)) return;
|
||||
@@ -84,11 +68,13 @@ export const resolveQuixosLock = async (
|
||||
try {
|
||||
source = await readSource(importPath);
|
||||
} catch (cause) {
|
||||
diagnostics.push(diagnostic(
|
||||
"import-read-failed",
|
||||
`Could not read lock import ${importPath}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
||||
importPath,
|
||||
));
|
||||
diagnostics.push(
|
||||
diagnostic(
|
||||
"import-read-failed",
|
||||
`Could not read lock import ${importPath}: ${cause instanceof Error ? cause.message : String(cause)}`,
|
||||
importPath,
|
||||
),
|
||||
);
|
||||
active.pop();
|
||||
return;
|
||||
}
|
||||
@@ -99,11 +85,13 @@ export const resolveQuixosLock = async (
|
||||
return;
|
||||
}
|
||||
if (parsed.document.kind !== "fragment") {
|
||||
diagnostics.push(diagnostic(
|
||||
"imported-root-lock",
|
||||
`Imported file ${importPath} must begin with "quixos-lock fragment"`,
|
||||
importPath,
|
||||
));
|
||||
diagnostics.push(
|
||||
diagnostic(
|
||||
"imported-root-lock",
|
||||
`Imported file ${importPath} must begin with "quixos-lock fragment"`,
|
||||
importPath,
|
||||
),
|
||||
);
|
||||
active.pop();
|
||||
return;
|
||||
}
|
||||
@@ -131,20 +119,24 @@ export const loadQuixosLock = async (fileName: string): Promise<QuixosLockParseR
|
||||
const repositoryRoot = path.dirname(absoluteRoot);
|
||||
const rootName = path.basename(absoluteRoot);
|
||||
const rootSource = await readFile(absoluteRoot, "utf8");
|
||||
return await resolveQuixosLock(rootSource, async (relativePath) => {
|
||||
let absoluteImport = repositoryRoot;
|
||||
const segments = relativePath.split("/");
|
||||
for (const [index, segment] of segments.entries()) {
|
||||
absoluteImport = path.join(absoluteImport, segment);
|
||||
const metadata = await lstat(absoluteImport);
|
||||
if (metadata.isSymbolicLink()) {
|
||||
throw new Error("imports must not traverse symbolic links");
|
||||
return await resolveQuixosLock(
|
||||
rootSource,
|
||||
async (relativePath) => {
|
||||
let absoluteImport = repositoryRoot;
|
||||
const segments = relativePath.split("/");
|
||||
for (const [index, segment] of segments.entries()) {
|
||||
absoluteImport = path.join(absoluteImport, segment);
|
||||
const metadata = await lstat(absoluteImport);
|
||||
if (metadata.isSymbolicLink()) {
|
||||
throw new Error("imports must not traverse symbolic links");
|
||||
}
|
||||
const final = index === segments.length - 1;
|
||||
if ((!final && !metadata.isDirectory()) || (final && !metadata.isFile())) {
|
||||
throw new Error("imports must be ordinary files beneath ordinary directories");
|
||||
}
|
||||
}
|
||||
const final = index === segments.length - 1;
|
||||
if ((!final && !metadata.isDirectory()) || (final && !metadata.isFile())) {
|
||||
throw new Error("imports must be ordinary files beneath ordinary directories");
|
||||
}
|
||||
}
|
||||
return await readFile(absoluteImport, "utf8");
|
||||
}, rootName);
|
||||
return await readFile(absoluteImport, "utf8");
|
||||
},
|
||||
rootName,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user