Add downloadCompilers parallel hook for extensible compiler downloads#8009
Add downloadCompilers parallel hook for extensible compiler downloads#8009
Conversation
🦋 Changeset detectedLatest commit: 0d075d2 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
1cd6812 to
0f7deb7
Compare
fd0f189 to
9deb0c9
Compare
There was a problem hiding this comment.
Pull request overview
This PR introduces a new downloadCompilers parallel hook in the Hardhat build system to enable extensible compiler downloads. This is part 2 in a series of changes to add multi-compiler support, specifically preparing for solx support in Hardhat 3.
Changes:
- Added a new
downloadCompilersparallel hook that receives all compiler configs from all build profiles - Created a built-in hook handler that filters for solc compilers and downloads them in parallel
- Refactored the build system to use the new hook instead of directly calling
downloadSolcCompilers
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| v-next/hardhat/src/internal/builtin-plugins/solidity/type-extensions.ts | Adds the downloadCompilers hook definition to the SolidityHooks interface with comprehensive documentation |
| v-next/hardhat/src/internal/builtin-plugins/solidity/hook-handlers/solidity.ts | Implements the built-in handler that filters for solc configs and downloads them |
| v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/build-system.ts | Refactors download logic to use the new hook and returns full compiler configs instead of just versions |
| v-next/hardhat/src/internal/builtin-plugins/solidity/index.ts | Registers the new solidity hook handler |
| v-next/hardhat/test/internal/builtin-plugins/solidity/hooks.ts | Adds comprehensive test coverage for the new hook |
| v-next/hardhat/test/internal/builtin-plugins/solidity/build-system/build-system.ts | Updates tests to register the built-in hook handlers |
| .changeset/good-eels-buy.md | Documents the change for the changelog |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
d004fe7 to
7cade07
Compare
0fe2822 to
1b72adc
Compare
e265b1b to
5a48ee9
Compare
1b72adc to
7b0ac41
Compare
5a48ee9 to
2fe6cb9
Compare
7b0ac41 to
daa40ad
Compare
2fe6cb9 to
5b313d0
Compare
070b562 to
85e74f6
Compare
5b313d0 to
a7a1164
Compare
85e74f6 to
c64fb8d
Compare
a7a1164 to
29875a4
Compare
c64fb8d to
5a80f5b
Compare
v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/compilation-job.ts
Outdated
Show resolved
Hide resolved
|
|
||
| // We download the compiler for the build info as it may not be configured | ||
| // in the HH config, hence not downloaded with the other compilers | ||
| // Build info recompilation is always solc-only: build info files are |
There was a problem hiding this comment.
I would say that this is an outdated assumption. BuildInfos should include the compiler type, so we should run the same download logic here.
See this change where I added compilerType to SolidityBuildInfo: 6ed3056
There was a problem hiding this comment.
We could create a partial SolidityCompilerConfig like this:
import type { SolidityBuildInfo } from "hardhat/types/solidity";
import type { SolidityCompilerConfig } from "hardhat/types/config";
function getPartialSolidityCompilerConfigFromBuildInfo(
buildInfo: SolidityBuildInfo,
): SolidityCompilerConfig {
return {
// This cast may result in a "type" that no plugin can handle. So we should
// probably have a way to know if a handler downlaoded a certain compiler,
// and throw otherwise. This can't be done with parallel one, but can be
// done with chained ones.
type: buildInfo.compilerType as SolidityCompilerConfig["type"],
version: buildInfo.solcVersion,
settings: buildInfo.input.settings,
};
}There was a problem hiding this comment.
There's no way to know if the buildinfo was built with wasm solc, but that's ok. We were already doing preferWasm: false below
| } from "@nomicfoundation/hardhat-utils/fs"; | ||
|
|
||
| import { SolidityBuildSystemImplementation } from "../../../../../src/internal/builtin-plugins/solidity/build-system/build-system.js"; | ||
| import createSolidityHookHandlers from "../../../../../src/internal/builtin-plugins/solidity/hook-handlers/solidity.js"; |
There was a problem hiding this comment.
Small tip: Moving the implementation of the handler into a separate file makes the test nicer.
The way we tend to think about it is this:
- If the handler requires the context, we may keep the implementation there, and use more integration-like tests.
- If the handler is more pure, we separate it and unit test it.
There was a problem hiding this comment.
For example, this test file has hooks.setContext({} as HookContext); which I don't really like. It assumes that the HookContext is not used b any of the tests. I'd rather unit-test the handler.
| hookHandlers: { | ||
| config: () => import("./hook-handlers/config.js"), | ||
| hre: () => import("./hook-handlers/hre.js"), | ||
| solidity: () => import("./hook-handlers/solidity.js"), |
There was a problem hiding this comment.
This is a surprisingly nice pattern
| } | ||
|
|
||
| for (const job of runnableCompilationJobs) { | ||
| const compilerType = job.solcConfig.type ?? "solc"; |
There was a problem hiding this comment.
I guess the changes in this file from here on in fact belong to #8008, but it's not important. Just mentioning it for my future reference and clarity.
There was a problem hiding this comment.
Reviewed these changes. LGTM
| let jobsPerVersion = jobsPerVersionAndEvmVersion.get(solcVersion); | ||
| // Group by compiler type + Solidity version to produce separate log | ||
| // lines for e.g. "solc 0.8.33" vs "solx 0.1.3 (Solidity 0.8.33)". | ||
| const groupKey = `${compilerType}#${solcVersion}`; |
There was a problem hiding this comment.
I'm more of a fan of multi-level maps than this combined keys, as the type system enforces that you give them some thought. I'm not agains this either.
| [runnableCompilationJob.solcConfig], | ||
| async (_context, cfg) => | ||
| getCompiler(cfg.version, { | ||
| preferWasm: resolvePreferWasm(cfg, buildProfile.preferWasm), |
There was a problem hiding this comment.
I like this. The buildProfile.preferWasm shouldn't affect any other compiler type. I actually forbid using it for build profiles with non-solc compilers in 558ec52
| resolveConfigurationVariable, | ||
| ); | ||
| // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- test registers unregistered types | ||
| resolved.solidity.registeredCompilerTypes.push(...(types as any[])); |
There was a problem hiding this comment.
Just for future reference: in actual plugins we return new resolved config objects rather than modifying it. Otherwise understanding what's going on in the presence of multiple plugins gets really tricky.
5544e68 to
5d68d88
Compare
ef42da0 to
2198ddc
Compare
5d68d88 to
1163e75
Compare
c9abdd0 to
f820760
Compare
f820760 to
0d075d2
Compare
alcuadrado
left a comment
There was a problem hiding this comment.
LGTM. I created an issue for the only open comment, which can be addressed in the future, if needed: #8081
Summary
Create and export two new hooks in the build system,
downloadCompilersandgetCompiler, which can later be used for the solx plugin.This is part 2 in the chain of PRs to introduce solx support in Hardhat 3.
The
downloadCompilershook is a parallel hook that allows each compiler plugin to handle the downloads for their owncompiler.type, and we need thegetCompilerchained hook to be able to correctly set the path to the new downloaded binaries prior to compilation invocation.The previous Part 1 PR is here: #8008
Details
Depends on: #8008 (multi-compiler abstraction)