Skip to content

Commit

Permalink
wip: implement the simplest version of compilation job cache
Browse files Browse the repository at this point in the history
  • Loading branch information
galargh committed Jan 9, 2025
1 parent d341544 commit 1807993
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
getContractArtifact,
getDuplicatedContractNamesDeclarationFile,
} from "./artifacts.js";
import { Cache } from "./cache.js";
import { CompilationJobImplementation } from "./compilation-job.js";
import { downloadConfiguredCompilers, getCompiler } from "./compiler/index.js";
import { buildDependencyGraph } from "./dependency-graph-building.js";
Expand All @@ -67,11 +68,16 @@ export interface SolidityBuildSystemOptions {

export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
readonly #options: SolidityBuildSystemOptions;
readonly #compilerOutputCache: Cache;
readonly #defaultConcurrenty = Math.max(os.cpus().length - 1, 1);
#downloadedCompilers = false;

constructor(options: SolidityBuildSystemOptions) {
this.#options = options;
this.#compilerOutputCache = new Cache(
options.cachePath,
"hardhat:core:solidity:build-system:compiler-output",
);
}

public async getRootFilePaths(): Promise<string[]> {
Expand Down Expand Up @@ -112,8 +118,6 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {

const compilationJobs = [...new Set(compilationJobsPerFile.values())];

// TODO: Filter the compilation jobs based on the cache

const results: CompilerOutput[] = await pMap(
compilationJobs,
(compilationJob) => this.runCompilationJob(compilationJob),
Expand Down Expand Up @@ -312,6 +316,17 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
compilationJob: CompilationJob,
options?: RunCompilationJobOptions,
): Promise<CompilerOutput> {
if (options?.force !== true) {
const buildId = compilationJob.getBuildId();

const cachedCompilerOutput =
await this.#compilerOutputCache.getJson<CompilerOutput>(buildId);
if (cachedCompilerOutput !== undefined) {
log(`Using cached compiler output for build ${buildId}`);
return cachedCompilerOutput;
}
}

await this.#downloadConfiguredCompilers(options?.quiet);

let numberOfFiles = 0;
Expand All @@ -332,7 +347,19 @@ export class SolidityBuildSystemImplementation implements SolidityBuildSystem {
"The long version of the compiler should match the long version of the compilation job",
);

return compiler.compile(compilationJob.getSolcInput());
const compilerOutput = await compiler.compile(
compilationJob.getSolcInput(),
);

if (options?.force !== true) {
const buildId = compilationJob.getBuildId();

if (!this.#hasCompilationErrors(compilerOutput)) {
await this.#compilerOutputCache.setJson(buildId, compilerOutput);
}
}

return compilerOutput;
}

public async remapCompilerError(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import path from "node:path";

import {
exists,
readJsonFile,
writeJsonFile,
} from "@ignored/hardhat-vnext-utils/fs";

export class Cache {
readonly #basePath: string;
readonly #namespace: string;

constructor(basePath: string, namespace: string) {
this.#basePath = basePath;
this.#namespace = namespace;

console.log(`Using cache at ${this.#basePath}`);
}

public async getJson<T>(key: string): Promise<T | undefined> {
const filePath = path.join(this.#basePath, this.#namespace, key);
if (await exists(filePath)) {
return readJsonFile<T>(filePath);
}
return undefined;
}

public async setJson<T>(key: string, value: T): Promise<void> {
const filePath = path.join(this.#basePath, this.#namespace, key);
await writeJsonFile(filePath, value);
}
}
8 changes: 7 additions & 1 deletion v-next/hardhat/src/types/solidity/build-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ export type GetCompilationJobsOptions = Omit<
* The options of the `runCompilationJob` method.
*/
export interface RunCompilationJobOptions {
/**
* If `true`, this option foces the build system to rerun the compilation job,
* even if its output is cached.
*/
force?: boolean;

/**
* If `true`, the compilation process doesn't print any output.
*/
Expand Down Expand Up @@ -265,7 +271,7 @@ export interface SolidityBuildSystem {
* This method should only be used after a complete build has succeeded, as
* it relies on the build system to have generated all the necessary artifact
* files.
* @param rootFilePaths All the root files of the project.
*/
cleanupArtifacts(rootFilePaths: string[]): Promise<void>;
Expand Down

0 comments on commit 1807993

Please sign in to comment.