From 72d20b73e403975177c1912b3ceb217ebcf7f322 Mon Sep 17 00:00:00 2001 From: Evan Sangaline Date: Wed, 10 Jul 2024 10:57:32 -0500 Subject: [PATCH] Set default circomspect library paths when versions allow Circomspect added support for a `-L`/`--library` search path flag in analogy to Circom's `-l` argument (as of trailofbits/circomspect#21) that we use on the backend with defaults of the project root and the `node_modules` subdirectory. This PR updates the `sindri lint` command to check whether the current Circomspect version supports the argument, and then to specify the same search paths if the argument is supported. We'll probably end up making the search paths configurable, but this makes the backend consistent with `sindri lint` in the meantime. For testing it manually, you can run ```bash docker compose up -d docker compose exec sindri-js bash ``` on the latest branch, change into a directory with one of our example Circom circuits that has been failing linting, and then run: ```bash sindri lint ``` to make sure that things work as expected. Merges #116 LGTM given by: @KPreisner --- src/cli/lint.ts | 26 +++++++++++++++++++++++++- src/cli/utils.ts | 11 +++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/cli/lint.ts b/src/cli/lint.ts index 739ee29..2907ce5 100644 --- a/src/cli/lint.ts +++ b/src/cli/lint.ts @@ -202,13 +202,37 @@ export const lintCommand = new Command() let sarif: SarifLog | undefined; let ranInDocker: boolean; try { + // Check if circomspect supports the `--library` flag (introduced in v9.0.0). + const { code: libraryPathSupportedTestCode } = await execCommand( + "circomspect", + ["--library", "/test/path/"], + { + tty: false, + }, + ); + const libraryPathSupported: boolean = + libraryPathSupportedTestCode === 0; + // Conditionally include library paths if supported by the Ciromspect version. + // It's important that this path logic is kept in sync with the Sindri backend. + const libraryPathArgs: string[] = libraryPathSupported + ? ["--library", ".", "--library", path.join(".", "node_modules")] + : []; + + // Try to run circomspect. const circuitPath: string = "circuitPath" in sindriJson && sindriJson.circuitPath ? (sindriJson.circuitPath as string) : "circuit.circom"; const { method } = await execCommand( "circomspect", - ["--level", "INFO", "--sarif-file", sarifFile, circuitPath], + [ + ...libraryPathArgs, + "--level", + "INFO", + "--sarif-file", + sarifFile, + circuitPath, + ], { cwd: rootDirectory, logger: sindri.logger, diff --git a/src/cli/utils.ts b/src/cli/utils.ts index 8753a0f..f60fbfc 100644 --- a/src/cli/utils.ts +++ b/src/cli/utils.ts @@ -32,6 +32,7 @@ const currentDirectoryPath = path.dirname(currentFilePath); */ export function checkCommandExists(command: string): Promise { return new Promise((resolve) => { + // TODO: Circomspect doesn't support this argument, so this will always fail for that command. const process = spawn(command, ["--version"]); process.on("error", () => { @@ -130,7 +131,10 @@ export async function execCommand( `"${process.env.SINDRI_FORCE_DOCKER}".`, ); } else if (await checkCommandExists(command)) { - logger?.debug(`Executing the "${command}" command locally.`); + logger?.debug( + { args, command }, + `Executing the "${command}" command locally.`, + ); return { code: await execLocalCommand(command, args, { cwd, logger, tty }), method: "local", @@ -143,7 +147,10 @@ export async function execCommand( // Fall back to using Docker if possible. if (await checkDockerAvailability(logger)) { - logger?.debug(`Executing the "${command}" command in a Docker container.`); + logger?.debug( + { args, command }, + `Executing the "${command}" command in a Docker container.`, + ); return { code: await execDockerCommand(command, args, { cwd,