108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
export interface OutputInfo {
|
|
path: string;
|
|
hashAlgo: string;
|
|
hash: string;
|
|
}
|
|
|
|
export interface DerivationData {
|
|
name: string;
|
|
outputs: Map<string, OutputInfo>;
|
|
inputDrvs: Map<string, Set<string>>;
|
|
inputSrcs: Set<string>;
|
|
platform: string;
|
|
builder: string;
|
|
args: string[];
|
|
env: Map<string, string>;
|
|
}
|
|
|
|
export const escapeString = (s: string): string => {
|
|
let result = "";
|
|
for (const char of s) {
|
|
switch (char) {
|
|
case '"':
|
|
result += '\\"';
|
|
break;
|
|
case "\\":
|
|
result += "\\\\";
|
|
break;
|
|
case "\n":
|
|
result += "\\n";
|
|
break;
|
|
case "\r":
|
|
result += "\\r";
|
|
break;
|
|
case "\t":
|
|
result += "\\t";
|
|
break;
|
|
default:
|
|
result += char;
|
|
}
|
|
}
|
|
return `"${result}"`;
|
|
};
|
|
|
|
const quoteString = (s: string): string => `"${s}"`;
|
|
|
|
const cmpByKey = <T>(a: [string, T], b: [string, T]): number =>
|
|
a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0;
|
|
|
|
export const generateAterm = (drv: DerivationData): string => {
|
|
const outputEntries: string[] = [];
|
|
const sortedOutputs = Array.from(drv.outputs.entries()).sort(cmpByKey);
|
|
for (const [name, info] of sortedOutputs) {
|
|
outputEntries.push(
|
|
`(${quoteString(name)},${quoteString(info.path)},${quoteString(info.hashAlgo)},${quoteString(info.hash)})`,
|
|
);
|
|
}
|
|
const outputs = outputEntries.join(",");
|
|
|
|
const inputDrvEntries: string[] = [];
|
|
const sortedInputDrvs = Array.from(drv.inputDrvs.entries()).sort(cmpByKey);
|
|
for (const [drvPath, outputs] of sortedInputDrvs) {
|
|
const sortedOuts = Array.from(outputs).sort();
|
|
const outList = `[${sortedOuts.map(quoteString).join(",")}]`;
|
|
inputDrvEntries.push(`(${quoteString(drvPath)},${outList})`);
|
|
}
|
|
const inputDrvs = inputDrvEntries.join(",");
|
|
|
|
const sortedInputSrcs = Array.from(drv.inputSrcs).sort();
|
|
const inputSrcs = sortedInputSrcs.map(quoteString).join(",");
|
|
|
|
const args = drv.args.map(escapeString).join(",");
|
|
const envs = Array.from(drv.env.entries())
|
|
.sort(cmpByKey)
|
|
.map(([k, v]) => `(${escapeString(k)},${escapeString(v)})`);
|
|
|
|
return `Derive([${outputs}],[${inputDrvs}],[${inputSrcs}],${quoteString(drv.platform)},${escapeString(drv.builder)},[${args}],[${envs}])`;
|
|
};
|
|
|
|
export const generateAtermModulo = (drv: DerivationData, inputDrvHashes: Map<string, string>): string => {
|
|
const outputEntries: string[] = [];
|
|
const sortedOutputs = Array.from(drv.outputs.entries()).sort(cmpByKey);
|
|
for (const [name, info] of sortedOutputs) {
|
|
outputEntries.push(
|
|
`(${quoteString(name)},${quoteString(info.path)},${quoteString(info.hashAlgo)},${quoteString(info.hash)})`,
|
|
);
|
|
}
|
|
const outputs = outputEntries.join(",");
|
|
|
|
const inputDrvEntries: string[] = [];
|
|
const sortedInputDrvHashes = Array.from(inputDrvHashes.entries()).sort(cmpByKey);
|
|
for (const [drvHash, outputs] of sortedInputDrvHashes) {
|
|
const sortedOuts = outputs.split(",").sort();
|
|
const outList = `[${sortedOuts.map(quoteString).join(",")}]`;
|
|
inputDrvEntries.push(`(${quoteString(drvHash)},${outList})`);
|
|
}
|
|
const inputDrvs = inputDrvEntries.join(",");
|
|
|
|
const sortedInputSrcs = Array.from(drv.inputSrcs).sort();
|
|
const inputSrcs = sortedInputSrcs.map(quoteString).join(",");
|
|
|
|
const args = drv.args.map(escapeString).join(",");
|
|
const envs = Array.from(drv.env.entries())
|
|
.sort(cmpByKey)
|
|
.map(([k, v]) => `(${escapeString(k)},${escapeString(v)})`);
|
|
|
|
return `Derive([${outputs}],[${inputDrvs}],[${inputSrcs}],${quoteString(drv.platform)},${escapeString(drv.builder)},[${args}],[${envs}])`;
|
|
};
|