Initial boiler plate project

This commit is contained in:
2024-09-24 03:52:46 +00:00
parent 6120b2d6c3
commit 154b93e267
10034 changed files with 2079352 additions and 2 deletions

View File

@ -0,0 +1,25 @@
/**
* Proxy the environment to track environment variables keys that
* are accessed during the build.
*
* @param envVars A set to track environment variable keys that are accessed.
* @returns A function that restores the original environment.
*/ export function envProxy(envVars) {
const newEnv = new Proxy(process.env, {
get: (target, key, receiver)=>{
envVars.add(key);
return Reflect.get(target, key, receiver);
},
set: (target, key, value)=>{
return Reflect.set(target, key, value);
}
});
const oldEnv = process.env;
process.env = newEnv;
// Return a function that restores the original environment.
return ()=>{
process.env = oldEnv;
};
}
//# sourceMappingURL=env.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/env.ts"],"names":["envProxy","envVars","newEnv","Proxy","process","env","get","target","key","receiver","add","Reflect","set","value","oldEnv"],"mappings":"AAEA;;;;;;CAMC,GACD,OAAO,SAASA,SAASC,OAAgB;IACvC,MAAMC,SAAS,IAAIC,MAAMC,QAAQC,GAAG,EAAE;QACpCC,KAAK,CAACC,QAAQC,KAAKC;YACjBR,QAAQS,GAAG,CAACF;YACZ,OAAOG,QAAQL,GAAG,CAACC,QAAQC,KAAKC;QAClC;QACAG,KAAK,CAACL,QAAQC,KAAKK;YACjB,OAAOF,QAAQC,GAAG,CAACL,QAAQC,KAAKK;QAClC;IACF;IAEA,MAAMC,SAASV,QAAQC,GAAG;IAC1BD,QAAQC,GAAG,GAAGH;IAEd,4DAA4D;IAC5D,OAAO;QACLE,QAAQC,GAAG,GAAGS;IAChB;AACF"}

View File

@ -0,0 +1,85 @@
import fs from "fs/promises";
import path from "path";
import { envProxy } from "./env";
import { tcpProxy } from "./tcp";
import { TurborepoAccessTraceResult } from "./result";
/**
* Trace access to the filesystem (TODO), environment variables, and TCP addresses and
* merge the results into the parent `TurborepoAccessTraceResult`.
*
* @param f the function to trace
* @param parent the `TurborepoAccessTraceResult` to merge the results into
* @returns the result of the function
*/ export function turborepoTraceAccess(f, parent) {
// If the trace file is not set, don't trace and instead just call the
// function.
if (!process.env.TURBOREPO_TRACE_FILE) return f();
// Otherwise, trace the function and merge the results into the parent. Using
// `then` instead of `await` here to avoid creating a new async context when
// tracing is disabled.
return withTurborepoTraceAccess(f).then(([result, proxy])=>{
parent.merge(proxy);
// Return the result of the function.
return result;
});
}
/**
* Write the access trace to the trace file.
*
* @param distDir the directory to write the trace file to
* @param traces an array of traces to merge and write to the trace file
*/ export async function writeTurborepoAccessTraceResult({ distDir, traces }) {
const configTraceFile = process.env.TURBOREPO_TRACE_FILE;
if (!configTraceFile || traces.length === 0) return;
// merge traces
const [accessTrace, ...otherTraces] = traces;
for (const trace of otherTraces){
accessTrace.merge(trace);
}
try {
// make sure the directory exists
await fs.mkdir(path.dirname(configTraceFile), {
recursive: true
});
await fs.writeFile(configTraceFile, JSON.stringify({
outputs: [
`${distDir}/**`,
`!${distDir}/cache/**`
],
accessed: accessTrace.toPublicTrace()
}));
} catch (err) {
// if we can't write this file, we should bail out here to avoid
// the possibility of incorrect turborepo cache hits.
throw new Error(`Failed to write turborepo access trace file`, {
cause: err
});
}
}
async function withTurborepoTraceAccess(f) {
const envVars = new Set([]);
// addresses is an array of objects, so a set is useless
const addresses = [];
// TODO: watch fsPaths (removed from this implementation for now)
const fsPaths = new Set();
// setup proxies
const restoreTCP = tcpProxy(addresses);
const restoreEnv = envProxy(envVars);
let functionResult;
// NOTE: we intentionally don't catch errors here so the calling function can handle them
try {
// call the wrapped function
functionResult = await f();
} finally{
// remove proxies
restoreTCP();
restoreEnv();
}
const traceResult = new TurborepoAccessTraceResult(envVars, addresses, fsPaths);
return [
functionResult,
traceResult
];
}
//# sourceMappingURL=helpers.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/helpers.ts"],"names":["fs","path","envProxy","tcpProxy","TurborepoAccessTraceResult","turborepoTraceAccess","f","parent","process","env","TURBOREPO_TRACE_FILE","withTurborepoTraceAccess","then","result","proxy","merge","writeTurborepoAccessTraceResult","distDir","traces","configTraceFile","length","accessTrace","otherTraces","trace","mkdir","dirname","recursive","writeFile","JSON","stringify","outputs","accessed","toPublicTrace","err","Error","cause","envVars","Set","addresses","fsPaths","restoreTCP","restoreEnv","functionResult","traceResult"],"mappings":"AAAA,OAAOA,QAAQ,cAAa;AAC5B,OAAOC,UAAU,OAAM;AAEvB,SAASC,QAAQ,QAAQ,QAAO;AAChC,SAASC,QAAQ,QAAQ,QAAO;AAChC,SAASC,0BAA0B,QAAQ,WAAU;AAErD;;;;;;;CAOC,GACD,OAAO,SAASC,qBACdC,CAAuB,EACvBC,MAAkC;IAElC,sEAAsE;IACtE,YAAY;IACZ,IAAI,CAACC,QAAQC,GAAG,CAACC,oBAAoB,EAAE,OAAOJ;IAE9C,6EAA6E;IAC7E,4EAA4E;IAC5E,uBAAuB;IACvB,OAAOK,yBAAyBL,GAAGM,IAAI,CAAC,CAAC,CAACC,QAAQC,MAAM;QACtDP,OAAOQ,KAAK,CAACD;QAEb,qCAAqC;QACrC,OAAOD;IACT;AACF;AAEA;;;;;CAKC,GACD,OAAO,eAAeG,gCAAgC,EACpDC,OAAO,EACPC,MAAM,EAIP;IACC,MAAMC,kBAAkBX,QAAQC,GAAG,CAACC,oBAAoB;IAExD,IAAI,CAACS,mBAAmBD,OAAOE,MAAM,KAAK,GAAG;IAE7C,eAAe;IACf,MAAM,CAACC,aAAa,GAAGC,YAAY,GAAGJ;IACtC,KAAK,MAAMK,SAASD,YAAa;QAC/BD,YAAYN,KAAK,CAACQ;IACpB;IAEA,IAAI;QACF,iCAAiC;QACjC,MAAMvB,GAAGwB,KAAK,CAACvB,KAAKwB,OAAO,CAACN,kBAAkB;YAAEO,WAAW;QAAK;QAChE,MAAM1B,GAAG2B,SAAS,CAChBR,iBACAS,KAAKC,SAAS,CAAC;YACbC,SAAS;gBAAC,CAAC,EAAEb,QAAQ,GAAG,CAAC;gBAAE,CAAC,CAAC,EAAEA,QAAQ,SAAS,CAAC;aAAC;YAClDc,UAAUV,YAAYW,aAAa;QACrC;IAEJ,EAAE,OAAOC,KAAK;QACZ,gEAAgE;QAChE,qDAAqD;QACrD,MAAM,IAAIC,MAAM,CAAC,2CAA2C,CAAC,EAAE;YAC7DC,OAAOF;QACT;IACF;AACF;AAEA,eAAetB,yBACbL,CAAuB;IAEvB,MAAM8B,UAAmB,IAAIC,IAAI,EAAE;IACnC,wDAAwD;IACxD,MAAMC,YAAuB,EAAE;IAC/B,iEAAiE;IACjE,MAAMC,UAAc,IAAIF;IAExB,gBAAgB;IAChB,MAAMG,aAAarC,SAASmC;IAC5B,MAAMG,aAAavC,SAASkC;IAE5B,IAAIM;IAEJ,yFAAyF;IACzF,IAAI;QACF,4BAA4B;QAC5BA,iBAAiB,MAAMpC;IACzB,SAAU;QACR,iBAAiB;QACjBkC;QACAC;IACF;IAEA,MAAME,cAAc,IAAIvC,2BACtBgC,SACAE,WACAC;IAGF,OAAO;QAACG;QAAgBC;KAAY;AACtC"}

View File

@ -0,0 +1,4 @@
export { turborepoTraceAccess, writeTurborepoAccessTraceResult } from "./helpers";
export { TurborepoAccessTraceResult } from "./result";
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/index.ts"],"names":["turborepoTraceAccess","writeTurborepoAccessTraceResult","TurborepoAccessTraceResult"],"mappings":"AACA,SACEA,oBAAoB,EACpBC,+BAA+B,QAC1B,YAAW;AAClB,SAASC,0BAA0B,QAAQ,WAAU"}

View File

@ -0,0 +1,41 @@
export class TurborepoAccessTraceResult {
constructor(envVars = new Set([]), addresses = [], fsPaths = new Set([])){
this.envVars = envVars;
this.addresses = addresses;
this.fsPaths = fsPaths;
}
/**
* Merge another `TurborepoAccessTraceResult` into this one, mutating this `TurborepoAccessTraceResult`.
*/ merge(other) {
other.envVars.forEach((envVar)=>this.envVars.add(envVar));
other.fsPaths.forEach((path)=>this.fsPaths.add(path));
this.addresses.push(...other.addresses);
return this;
}
/**
* Serialize this `TurborepoAccessTraceResult` into a serializable object. Used for passing
* the `TurborepoAccessTraceResult` between workers where Sets are not serializable.
*/ serialize() {
return {
fs: Array.from(this.fsPaths).map(String),
addresses: this.addresses,
envVars: Array.from(this.envVars).map(String)
};
}
/**
* Squash this `TurborepoAccessTraceResult` into a public trace object that can be written to a file
*/ toPublicTrace() {
return {
network: this.addresses.length > 0,
envVarKeys: Array.from(this.envVars).map(String),
filePaths: Array.from(this.fsPaths).map(String)
};
}
/**
* Create an `TurborepoAccessTraceResult` from a serialized `SerializableTurborepoAccessTraceResult`
*/ static fromSerialized(serialized) {
return new TurborepoAccessTraceResult(new Set(serialized.envVars), serialized.addresses, new Set(serialized.fs));
}
}
//# sourceMappingURL=result.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/result.ts"],"names":["TurborepoAccessTraceResult","constructor","envVars","Set","addresses","fsPaths","merge","other","forEach","envVar","add","path","push","serialize","fs","Array","from","map","String","toPublicTrace","network","length","envVarKeys","filePaths","fromSerialized","serialized"],"mappings":"AAQA,OAAO,MAAMA;IACXC,YACE,AAAQC,UAAmB,IAAIC,IAAI,EAAE,CAAC,EACtC,AAAQC,YAAuB,EAAE,EACjC,AAAQC,UAAc,IAAIF,IAAI,EAAE,CAAC,CACjC;aAHQD,UAAAA;aACAE,YAAAA;aACAC,UAAAA;IACP;IAEH;;GAEC,GACD,AAAOC,MAAMC,KAAiC,EAAE;QAC9CA,MAAML,OAAO,CAACM,OAAO,CAAC,CAACC,SAAW,IAAI,CAACP,OAAO,CAACQ,GAAG,CAACD;QACnDF,MAAMF,OAAO,CAACG,OAAO,CAAC,CAACG,OAAS,IAAI,CAACN,OAAO,CAACK,GAAG,CAACC;QACjD,IAAI,CAACP,SAAS,CAACQ,IAAI,IAAIL,MAAMH,SAAS;QAEtC,OAAO,IAAI;IACb;IAEA;;;GAGC,GACD,AAAOS,YAAoD;QACzD,OAAO;YACLC,IAAIC,MAAMC,IAAI,CAAC,IAAI,CAACX,OAAO,EAAEY,GAAG,CAACC;YACjCd,WAAW,IAAI,CAACA,SAAS;YACzBF,SAASa,MAAMC,IAAI,CAAC,IAAI,CAACd,OAAO,EAAEe,GAAG,CAACC;QACxC;IACF;IAEA;;GAEC,GACD,AAAOC,gBAAkD;QACvD,OAAO;YACLC,SAAS,IAAI,CAAChB,SAAS,CAACiB,MAAM,GAAG;YACjCC,YAAYP,MAAMC,IAAI,CAAC,IAAI,CAACd,OAAO,EAAEe,GAAG,CAACC;YACzCK,WAAWR,MAAMC,IAAI,CAAC,IAAI,CAACX,OAAO,EAAEY,GAAG,CAACC;QAC1C;IACF;IAEA;;GAEC,GACD,OAAcM,eACZC,UAAkD,EAClD;QACA,OAAO,IAAIzB,2BACT,IAAIG,IAAIsB,WAAWvB,OAAO,GAC1BuB,WAAWrB,SAAS,EACpB,IAAID,IAAIsB,WAAWX,EAAE;IAEzB;AACF"}

View File

@ -0,0 +1,31 @@
import net from "net";
/**
* Proxy the TCP connect method to determine if any network access is made during the build
*
* @param addresses An array to track the addresses that are accessed.
* @returns A function that restores the original connect method.
*/ export function tcpProxy(addresses) {
// net.Socket docs https://nodejs.org/api/net.html#class-netsocket
const originalConnect = net.Socket.prototype.connect;
// Override the connect method
net.Socket.prototype.connect = function(...args) {
// First, check if the first argument is an object and not null
if (typeof args[0] === "object" && args[0] !== null) {
const options = args[0];
// check if the options has what we need
if ("port" in options && options.port !== undefined && "host" in options && options.host !== undefined) {
addresses.push({
addr: options.host,
port: options.port.toString()
});
}
}
return originalConnect.apply(this, args);
};
return ()=>{
// Restore the original connect method
net.Socket.prototype.connect = originalConnect;
};
}
//# sourceMappingURL=tcp.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/tcp.ts"],"names":["net","tcpProxy","addresses","originalConnect","Socket","prototype","connect","args","options","port","undefined","host","push","addr","toString","apply"],"mappings":"AAAA,OAAOA,SAAS,MAAK;AAGrB;;;;;CAKC,GACD,OAAO,SAASC,SAASC,SAAoB;IAC3C,kEAAkE;IAClE,MAAMC,kBAAkBH,IAAII,MAAM,CAACC,SAAS,CAACC,OAAO;IAEpD,8BAA8B;IAC9BN,IAAII,MAAM,CAACC,SAAS,CAACC,OAAO,GAAG,SAAU,GAAGC,IAAS;QACnD,+DAA+D;QAC/D,IAAI,OAAOA,IAAI,CAAC,EAAE,KAAK,YAAYA,IAAI,CAAC,EAAE,KAAK,MAAM;YACnD,MAAMC,UAAUD,IAAI,CAAC,EAAE;YAEvB,wCAAwC;YACxC,IACE,UAAUC,WACVA,QAAQC,IAAI,KAAKC,aACjB,UAAUF,WACVA,QAAQG,IAAI,KAAKD,WACjB;gBACAR,UAAUU,IAAI,CAAC;oBAAEC,MAAML,QAAQG,IAAI;oBAAEF,MAAMD,QAAQC,IAAI,CAACK,QAAQ;gBAAG;YACrE;QACF;QAEA,OAAOX,gBAAgBY,KAAK,CAAC,IAAI,EAAER;IACrC;IAEA,OAAO;QACL,sCAAsC;QACtCP,IAAII,MAAM,CAACC,SAAS,CAACC,OAAO,GAAGH;IACjC;AACF"}

View File

@ -0,0 +1,7 @@
/**
* A single Addr / Port pair that was accessed during the duration of the trace
*/ /**
* A function that restores the original state of a proxy
*/ export { };
//# sourceMappingURL=types.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["../../../src/build/turborepo-access-trace/types.ts"],"names":[],"mappings":"AAAA;;CAEC,GAwCD;;CAEC,GACD,WAAgD"}