@diamondslab/diamonds-hardhat-foundry 2.2.2 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,173 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const config_1 = require("hardhat/config");
4
+ const logger_1 = require("../utils/logger");
5
+ /**
6
+ * Task: diamonds-forge:coverage
7
+ *
8
+ * Runs Forge coverage with Diamond deployment.
9
+ * - Ensures Diamond deployment exists
10
+ * - Generates Solidity helpers
11
+ * - Runs forge coverage with specified options
12
+ *
13
+ * Use Hardhat's built-in --network flag to specify the network
14
+ */
15
+ (0, config_1.task)("diamonds-forge:coverage", "Run forge coverage for Diamond contracts")
16
+ .addParam("diamondName", "Name of the Diamond to analyze", undefined, config_1.types.string)
17
+ // Report options
18
+ .addOptionalParam("report", "Report type (summary, lcov, debug, bytecode) - can be used multiple times by passing comma-separated values", undefined, config_1.types.string)
19
+ .addOptionalParam("reportFile", "Output path for report file", undefined, config_1.types.string)
20
+ .addOptionalParam("lcovVersion", "LCOV format version", undefined, config_1.types.string)
21
+ .addFlag("includeLibs", "Include libraries in coverage report")
22
+ .addFlag("excludeTests", "Exclude tests from coverage report")
23
+ .addFlag("irMinimum", "Enable viaIR with minimum optimization")
24
+ // Test filtering
25
+ .addOptionalParam("matchTest", "Run tests matching pattern (--match-test)", undefined, config_1.types.string)
26
+ .addOptionalParam("noMatchTest", "Exclude tests matching pattern (--no-match-test)", undefined, config_1.types.string)
27
+ .addOptionalParam("matchContract", "Run contracts matching pattern (--match-contract)", undefined, config_1.types.string)
28
+ .addOptionalParam("noMatchContract", "Exclude contracts matching pattern (--no-match-contract)", undefined, config_1.types.string)
29
+ .addOptionalParam("matchPath", "Run files matching glob (--match-path)", undefined, config_1.types.string)
30
+ .addOptionalParam("noMatchPath", "Exclude files matching glob (--no-match-path)", undefined, config_1.types.string)
31
+ .addOptionalParam("noMatchCoverage", "Exclude files from coverage report (--no-match-coverage)", undefined, config_1.types.string)
32
+ // Display options
33
+ .addOptionalParam("verbosity", "Verbosity level (1-5, more v's = more verbose)", undefined, config_1.types.int)
34
+ .addFlag("quiet", "Suppress log output")
35
+ .addFlag("json", "Format output as JSON")
36
+ .addFlag("md", "Format output as Markdown")
37
+ .addOptionalParam("color", "Color mode (auto, always, never)", undefined, config_1.types.string)
38
+ // Test execution options
39
+ .addOptionalParam("threads", "Number of threads to use", undefined, config_1.types.int)
40
+ .addOptionalParam("fuzzRuns", "Number of fuzz runs", undefined, config_1.types.int)
41
+ .addOptionalParam("fuzzSeed", "Seed for fuzz randomness", undefined, config_1.types.string)
42
+ .addFlag("failFast", "Stop on first failure")
43
+ .addFlag("allowFailure", "Exit 0 even if tests fail")
44
+ // EVM options
45
+ .addOptionalParam("forkBlockNumber", "Fork from specific block number", undefined, config_1.types.int)
46
+ .addOptionalParam("initialBalance", "Initial balance for test contracts", undefined, config_1.types.string)
47
+ .addOptionalParam("sender", "Test sender address", undefined, config_1.types.string)
48
+ .addFlag("ffi", "Enable FFI cheatcode")
49
+ // Build options
50
+ .addFlag("force", "Force recompile and redeploy")
51
+ .addFlag("noCache", "Disable cache")
52
+ .addFlag("optimize", "Enable Solidity optimizer")
53
+ .addOptionalParam("optimizerRuns", "Optimizer runs", undefined, config_1.types.int)
54
+ .addFlag("viaIr", "Use Yul IR compilation")
55
+ .setAction(async (taskArgs, hre) => {
56
+ logger_1.Logger.section("Running Forge Coverage with Diamond");
57
+ const diamondName = taskArgs.diamondName;
58
+ const networkName = hre.network.name;
59
+ // Validate required parameters
60
+ if (!diamondName) {
61
+ logger_1.Logger.error("--diamond-name is required");
62
+ process.exitCode = 1;
63
+ return;
64
+ }
65
+ logger_1.Logger.info(`Diamond: ${diamondName}`);
66
+ logger_1.Logger.info(`Network: ${networkName}`);
67
+ try {
68
+ // Lazy-load framework classes to avoid circular dependency
69
+ const { DeploymentManager } = await import("../framework/DeploymentManager.js");
70
+ const { HelperGenerator } = await import("../framework/HelperGenerator.js");
71
+ // Step 1: Ensure Diamond deployment
72
+ logger_1.Logger.section("Step 1/3: Ensuring Diamond Deployment");
73
+ const deploymentManager = new DeploymentManager(hre);
74
+ await deploymentManager.ensureDeployment(diamondName, networkName, taskArgs.force || false, false // Don't write deployment data for coverage (ephemeral by default)
75
+ );
76
+ // Step 2: Generate helpers
77
+ logger_1.Logger.section("Step 2/3: Generating Solidity Helpers");
78
+ const deployment = await deploymentManager.getDeployment(diamondName, networkName);
79
+ if (!deployment) {
80
+ logger_1.Logger.error("No deployment found. Cannot generate helpers.");
81
+ process.exitCode = 1;
82
+ return;
83
+ }
84
+ const provider = hre.ethers.provider;
85
+ const network = await provider.getNetwork();
86
+ const chainId = Number(network.chainId);
87
+ const deploymentData = deployment.getDeployedDiamondData();
88
+ const helperGenerator = new HelperGenerator(hre);
89
+ await helperGenerator.generateDeploymentHelpers(diamondName, networkName, chainId, deploymentData, deployment);
90
+ // Step 3: Run coverage
91
+ logger_1.Logger.section("Step 3/3: Running Forge Coverage");
92
+ // Construct fork URL for network
93
+ // Coverage requires forking from a running network to access deployed contracts
94
+ let forkUrl;
95
+ if (networkName !== "hardhat") {
96
+ // Use the configured network's URL
97
+ forkUrl = provider._hardhatProvider?._wrapped?.url || "http://127.0.0.1:8545";
98
+ logger_1.Logger.info(`Forking from ${networkName}: ${forkUrl}`);
99
+ }
100
+ else {
101
+ // Default to localhost for hardhat network
102
+ // This assumes user has `npx hardhat node` running
103
+ forkUrl = "http://127.0.0.1:8545";
104
+ logger_1.Logger.warn(`⚠️ Network is "${networkName}" - defaulting to localhost fork: ${forkUrl}`);
105
+ logger_1.Logger.warn(`💡 Make sure Hardhat node is running: npx hardhat node`);
106
+ logger_1.Logger.warn(`💡 Or specify network explicitly: --network localhost`);
107
+ }
108
+ // Lazy-load framework to avoid circular dependency
109
+ const { ForgeCoverageFramework } = await import("../framework/ForgeCoverageFramework.js");
110
+ // Build coverage options from task args
111
+ const options = {
112
+ // Fork URL
113
+ forkUrl,
114
+ // Report options
115
+ report: taskArgs.report ? taskArgs.report.split(",") : undefined,
116
+ reportFile: taskArgs.reportFile,
117
+ lcovVersion: taskArgs.lcovVersion,
118
+ includeLibs: taskArgs.includeLibs,
119
+ excludeTests: taskArgs.excludeTests,
120
+ irMinimum: taskArgs.irMinimum,
121
+ // Test filtering
122
+ matchTest: taskArgs.matchTest,
123
+ noMatchTest: taskArgs.noMatchTest,
124
+ matchContract: taskArgs.matchContract,
125
+ noMatchContract: taskArgs.noMatchContract,
126
+ matchPath: taskArgs.matchPath,
127
+ noMatchPath: taskArgs.noMatchPath,
128
+ noMatchCoverage: taskArgs.noMatchCoverage,
129
+ // Display options
130
+ verbosity: taskArgs.verbosity,
131
+ quiet: taskArgs.quiet,
132
+ json: taskArgs.json,
133
+ md: taskArgs.md,
134
+ color: taskArgs.color,
135
+ // Test execution options
136
+ threads: taskArgs.threads,
137
+ fuzzRuns: taskArgs.fuzzRuns,
138
+ fuzzSeed: taskArgs.fuzzSeed,
139
+ failFast: taskArgs.failFast,
140
+ allowFailure: taskArgs.allowFailure,
141
+ // EVM options
142
+ forkBlockNumber: taskArgs.forkBlockNumber,
143
+ initialBalance: taskArgs.initialBalance,
144
+ sender: taskArgs.sender,
145
+ ffi: taskArgs.ffi,
146
+ // Build options
147
+ force: taskArgs.force,
148
+ noCache: taskArgs.noCache,
149
+ optimize: taskArgs.optimize,
150
+ optimizerRuns: taskArgs.optimizerRuns,
151
+ viaIr: taskArgs.viaIr,
152
+ };
153
+ // Run coverage
154
+ const framework = new ForgeCoverageFramework(hre);
155
+ const success = await framework.runCoverage(options);
156
+ if (success) {
157
+ logger_1.Logger.section("Coverage Analysis Complete");
158
+ logger_1.Logger.success("Coverage analysis completed successfully!");
159
+ process.exitCode = 0;
160
+ }
161
+ else {
162
+ logger_1.Logger.section("Coverage Analysis Complete");
163
+ logger_1.Logger.error("Coverage analysis failed");
164
+ process.exitCode = 1;
165
+ }
166
+ }
167
+ catch (error) {
168
+ logger_1.Logger.error(`Coverage execution failed: ${error.message}`);
169
+ process.exitCode = 1;
170
+ throw error;
171
+ }
172
+ });
173
+ //# sourceMappingURL=coverage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage.js","sourceRoot":"","sources":["../../src/tasks/coverage.ts"],"names":[],"mappings":"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","sourcesContent":["import { task, types } from \"hardhat/config\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { Logger } from \"../utils/logger\";\n\n/**\n * Task: diamonds-forge:coverage\n *\n * Runs Forge coverage with Diamond deployment.\n * - Ensures Diamond deployment exists\n * - Generates Solidity helpers\n * - Runs forge coverage with specified options\n *\n * Use Hardhat's built-in --network flag to specify the network\n */\ntask(\"diamonds-forge:coverage\", \"Run forge coverage for Diamond contracts\")\n .addParam(\n \"diamondName\",\n \"Name of the Diamond to analyze\",\n undefined,\n types.string\n )\n // Report options\n .addOptionalParam(\n \"report\",\n \"Report type (summary, lcov, debug, bytecode) - can be used multiple times by passing comma-separated values\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"reportFile\",\n \"Output path for report file\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"lcovVersion\",\n \"LCOV format version\",\n undefined,\n types.string\n )\n .addFlag(\"includeLibs\", \"Include libraries in coverage report\")\n .addFlag(\"excludeTests\", \"Exclude tests from coverage report\")\n .addFlag(\"irMinimum\", \"Enable viaIR with minimum optimization\")\n // Test filtering\n .addOptionalParam(\n \"matchTest\",\n \"Run tests matching pattern (--match-test)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"noMatchTest\",\n \"Exclude tests matching pattern (--no-match-test)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"matchContract\",\n \"Run contracts matching pattern (--match-contract)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"noMatchContract\",\n \"Exclude contracts matching pattern (--no-match-contract)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"matchPath\",\n \"Run files matching glob (--match-path)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"noMatchPath\",\n \"Exclude files matching glob (--no-match-path)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"noMatchCoverage\",\n \"Exclude files from coverage report (--no-match-coverage)\",\n undefined,\n types.string\n )\n // Display options\n .addOptionalParam(\n \"verbosity\",\n \"Verbosity level (1-5, more v's = more verbose)\",\n undefined,\n types.int\n )\n .addFlag(\"quiet\", \"Suppress log output\")\n .addFlag(\"json\", \"Format output as JSON\")\n .addFlag(\"md\", \"Format output as Markdown\")\n .addOptionalParam(\n \"color\",\n \"Color mode (auto, always, never)\",\n undefined,\n types.string\n )\n // Test execution options\n .addOptionalParam(\n \"threads\",\n \"Number of threads to use\",\n undefined,\n types.int\n )\n .addOptionalParam(\n \"fuzzRuns\",\n \"Number of fuzz runs\",\n undefined,\n types.int\n )\n .addOptionalParam(\n \"fuzzSeed\",\n \"Seed for fuzz randomness\",\n undefined,\n types.string\n )\n .addFlag(\"failFast\", \"Stop on first failure\")\n .addFlag(\"allowFailure\", \"Exit 0 even if tests fail\")\n // EVM options\n .addOptionalParam(\n \"forkBlockNumber\",\n \"Fork from specific block number\",\n undefined,\n types.int\n )\n .addOptionalParam(\n \"initialBalance\",\n \"Initial balance for test contracts\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"sender\",\n \"Test sender address\",\n undefined,\n types.string\n )\n .addFlag(\"ffi\", \"Enable FFI cheatcode\")\n // Build options\n .addFlag(\"force\", \"Force recompile and redeploy\")\n .addFlag(\"noCache\", \"Disable cache\")\n .addFlag(\"optimize\", \"Enable Solidity optimizer\")\n .addOptionalParam(\n \"optimizerRuns\",\n \"Optimizer runs\",\n undefined,\n types.int\n )\n .addFlag(\"viaIr\", \"Use Yul IR compilation\")\n .setAction(async (taskArgs, hre: HardhatRuntimeEnvironment) => {\n Logger.section(\"Running Forge Coverage with Diamond\");\n\n const diamondName = taskArgs.diamondName;\n const networkName = hre.network.name;\n\n // Validate required parameters\n if (!diamondName) {\n Logger.error(\"--diamond-name is required\");\n process.exitCode = 1;\n return;\n }\n\n Logger.info(`Diamond: ${diamondName}`);\n Logger.info(`Network: ${networkName}`);\n\n try {\n // Lazy-load framework classes to avoid circular dependency\n const { DeploymentManager } = await import(\"../framework/DeploymentManager.js\");\n const { HelperGenerator } = await import(\"../framework/HelperGenerator.js\");\n\n // Step 1: Ensure Diamond deployment\n Logger.section(\"Step 1/3: Ensuring Diamond Deployment\");\n \n const deploymentManager = new DeploymentManager(hre);\n \n await deploymentManager.ensureDeployment(\n diamondName,\n networkName,\n taskArgs.force || false,\n false // Don't write deployment data for coverage (ephemeral by default)\n );\n\n // Step 2: Generate helpers\n Logger.section(\"Step 2/3: Generating Solidity Helpers\");\n \n const deployment = await deploymentManager.getDeployment(\n diamondName,\n networkName\n );\n\n if (!deployment) {\n Logger.error(\"No deployment found. Cannot generate helpers.\");\n process.exitCode = 1;\n return;\n }\n\n const provider = hre.ethers.provider;\n const network = await provider.getNetwork();\n const chainId = Number(network.chainId);\n const deploymentData = deployment.getDeployedDiamondData();\n\n const helperGenerator = new HelperGenerator(hre);\n await helperGenerator.generateDeploymentHelpers(\n diamondName,\n networkName,\n chainId,\n deploymentData,\n deployment\n );\n\n // Step 3: Run coverage\n Logger.section(\"Step 3/3: Running Forge Coverage\");\n\n // Construct fork URL for network\n // Coverage requires forking from a running network to access deployed contracts\n let forkUrl: string;\n if (networkName !== \"hardhat\") {\n // Use the configured network's URL\n forkUrl = (provider as any)._hardhatProvider?._wrapped?.url || \"http://127.0.0.1:8545\";\n Logger.info(`Forking from ${networkName}: ${forkUrl}`);\n } else {\n // Default to localhost for hardhat network\n // This assumes user has `npx hardhat node` running\n forkUrl = \"http://127.0.0.1:8545\";\n Logger.warn(`⚠️ Network is \"${networkName}\" - defaulting to localhost fork: ${forkUrl}`);\n Logger.warn(`💡 Make sure Hardhat node is running: npx hardhat node`);\n Logger.warn(`💡 Or specify network explicitly: --network localhost`);\n }\n\n // Lazy-load framework to avoid circular dependency\n const { ForgeCoverageFramework } = await import(\"../framework/ForgeCoverageFramework.js\");\n type CoverageOptions = Parameters<InstanceType<typeof ForgeCoverageFramework>[\"runCoverage\"]>[0];\n\n // Build coverage options from task args\n const options: CoverageOptions = {\n // Fork URL\n forkUrl,\n\n // Report options\n report: taskArgs.report ? taskArgs.report.split(\",\") : undefined,\n reportFile: taskArgs.reportFile,\n lcovVersion: taskArgs.lcovVersion,\n includeLibs: taskArgs.includeLibs,\n excludeTests: taskArgs.excludeTests,\n irMinimum: taskArgs.irMinimum,\n\n // Test filtering\n matchTest: taskArgs.matchTest,\n noMatchTest: taskArgs.noMatchTest,\n matchContract: taskArgs.matchContract,\n noMatchContract: taskArgs.noMatchContract,\n matchPath: taskArgs.matchPath,\n noMatchPath: taskArgs.noMatchPath,\n noMatchCoverage: taskArgs.noMatchCoverage,\n\n // Display options\n verbosity: taskArgs.verbosity,\n quiet: taskArgs.quiet,\n json: taskArgs.json,\n md: taskArgs.md,\n color: taskArgs.color as \"auto\" | \"always\" | \"never\" | undefined,\n\n // Test execution options\n threads: taskArgs.threads,\n fuzzRuns: taskArgs.fuzzRuns,\n fuzzSeed: taskArgs.fuzzSeed,\n failFast: taskArgs.failFast,\n allowFailure: taskArgs.allowFailure,\n\n // EVM options\n forkBlockNumber: taskArgs.forkBlockNumber,\n initialBalance: taskArgs.initialBalance,\n sender: taskArgs.sender,\n ffi: taskArgs.ffi,\n\n // Build options\n force: taskArgs.force,\n noCache: taskArgs.noCache,\n optimize: taskArgs.optimize,\n optimizerRuns: taskArgs.optimizerRuns,\n viaIr: taskArgs.viaIr,\n };\n\n // Run coverage\n const framework = new ForgeCoverageFramework(hre);\n const success = await framework.runCoverage(options);\n\n if (success) {\n Logger.section(\"Coverage Analysis Complete\");\n Logger.success(\"Coverage analysis completed successfully!\");\n process.exitCode = 0;\n } else {\n Logger.section(\"Coverage Analysis Complete\");\n Logger.error(\"Coverage analysis failed\");\n process.exitCode = 1;\n }\n } catch (error: any) {\n Logger.error(`Coverage execution failed: ${error.message}`);\n process.exitCode = 1;\n throw error;\n }\n });\n"]}
@@ -38,4 +38,84 @@ export interface DiamondsFoundryConfig {
38
38
  * Default configuration values
39
39
  */
40
40
  export declare const DEFAULT_CONFIG: Required<DiamondsFoundryConfig>;
41
+ /**
42
+ * Type for forge coverage report formats
43
+ */
44
+ export type CoverageReportType = "summary" | "lcov" | "debug" | "bytecode";
45
+ /**
46
+ * Type for color output modes
47
+ */
48
+ export type ColorMode = "auto" | "always" | "never";
49
+ /**
50
+ * Coverage options for forge coverage command
51
+ * Maps to all available forge coverage command-line options
52
+ */
53
+ export interface CoverageOptions {
54
+ /** Report type(s) - can specify multiple */
55
+ report?: CoverageReportType[];
56
+ /** Output path for report file */
57
+ reportFile?: string;
58
+ /** LCOV format version (default: 1) */
59
+ lcovVersion?: string;
60
+ /** Include libraries in coverage report */
61
+ includeLibs?: boolean;
62
+ /** Exclude tests from coverage report */
63
+ excludeTests?: boolean;
64
+ /** Enable viaIR with minimum optimization */
65
+ irMinimum?: boolean;
66
+ /** Run tests matching regex pattern */
67
+ matchTest?: string;
68
+ /** Exclude tests matching regex pattern */
69
+ noMatchTest?: string;
70
+ /** Run contracts matching regex pattern */
71
+ matchContract?: string;
72
+ /** Exclude contracts matching regex pattern */
73
+ noMatchContract?: string;
74
+ /** Run files matching glob pattern */
75
+ matchPath?: string;
76
+ /** Exclude files matching glob pattern */
77
+ noMatchPath?: string;
78
+ /** Exclude files from coverage report matching regex */
79
+ noMatchCoverage?: string;
80
+ /** Verbosity level (1-5) - more v's = more verbose */
81
+ verbosity?: number;
82
+ /** Suppress log output */
83
+ quiet?: boolean;
84
+ /** Format output as JSON */
85
+ json?: boolean;
86
+ /** Format output as Markdown */
87
+ md?: boolean;
88
+ /** Color output mode */
89
+ color?: ColorMode;
90
+ /** Number of threads to use for parallel execution */
91
+ threads?: number;
92
+ /** Number of fuzz test runs */
93
+ fuzzRuns?: number;
94
+ /** Seed for fuzz test randomness (for reproducibility) */
95
+ fuzzSeed?: string;
96
+ /** Stop running tests after first failure */
97
+ failFast?: boolean;
98
+ /** Exit with code 0 even if tests fail */
99
+ allowFailure?: boolean;
100
+ /** Fork URL for network state */
101
+ forkUrl?: string;
102
+ /** Fork from specific block number */
103
+ forkBlockNumber?: number;
104
+ /** Initial balance for deployed test contracts */
105
+ initialBalance?: string;
106
+ /** Address to use as test sender */
107
+ sender?: string;
108
+ /** Enable FFI (Foreign Function Interface) cheatcode */
109
+ ffi?: boolean;
110
+ /** Force recompilation and cache clearing */
111
+ force?: boolean;
112
+ /** Disable compiler cache */
113
+ noCache?: boolean;
114
+ /** Enable Solidity optimizer */
115
+ optimize?: boolean;
116
+ /** Number of optimizer runs */
117
+ optimizerRuns?: number;
118
+ /** Use Yul intermediate representation compilation */
119
+ viaIr?: boolean;
120
+ }
41
121
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC;IAEtD;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,qBAAqB,CAO1D,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,aAAa,GAAG,MAAM,CAAC,CAAC;IAEtD;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,qBAAqB,CAO1D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE3E;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEpD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAE9B,4CAA4C;IAC5C,MAAM,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC9B,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yCAAyC;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,OAAO,CAAC;IAGpB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wDAAwD;IACxD,eAAe,CAAC,EAAE,MAAM,CAAC;IAGzB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,wBAAwB;IACxB,KAAK,CAAC,EAAE,SAAS,CAAC;IAGlB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;IAGvB,iCAAiC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,sCAAsC;IACtC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,GAAG,CAAC,EAAE,OAAO,CAAC;IAGd,6CAA6C;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6BAA6B;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+BAA+B;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAwCH;;GAEG;AACU,QAAA,cAAc,GAAoC;IAC7D,UAAU,EAAE,sBAAsB;IAClC,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC;IAC7C,cAAc,EAAE,SAAS;IACzB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,EAAE;CAClB,CAAC","sourcesContent":["/**\n * Configuration types for diamonds-hardhat-foundry plugin\n * Will be fully implemented in Task 2.1\n */\n\nexport interface DiamondsFoundryConfig {\n /**\n * Output directory for generated helpers (relative to project root)\n * @default \"test/foundry/helpers\"\n */\n helpersDir?: string;\n\n /**\n * Whether to generate example tests on init\n * @default true\n */\n generateExamples?: boolean;\n\n /**\n * Example test templates to generate\n * @default [\"unit\", \"integration\", \"fuzz\"]\n */\n exampleTests?: Array<\"unit\" | \"integration\" | \"fuzz\">;\n\n /**\n * Default network for deployments\n * @default \"hardhat\"\n */\n defaultNetwork?: string;\n\n /**\n * Whether to reuse existing deployment or deploy fresh\n * @default true\n */\n reuseDeployment?: boolean;\n\n /**\n * Additional forge test arguments\n * @default []\n */\n forgeTestArgs?: string[];\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<DiamondsFoundryConfig> = {\n helpersDir: \"test/foundry/helpers\",\n generateExamples: true,\n exampleTests: [\"unit\", \"integration\", \"fuzz\"],\n defaultNetwork: \"hardhat\",\n reuseDeployment: true,\n forgeTestArgs: [],\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAwCH;;GAEG;AACU,QAAA,cAAc,GAAoC;IAC7D,UAAU,EAAE,sBAAsB;IAClC,gBAAgB,EAAE,IAAI;IACtB,YAAY,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC;IAC7C,cAAc,EAAE,SAAS;IACzB,eAAe,EAAE,IAAI;IACrB,aAAa,EAAE,EAAE;CAClB,CAAC","sourcesContent":["/**\n * Configuration types for diamonds-hardhat-foundry plugin\n * Will be fully implemented in Task 2.1\n */\n\nexport interface DiamondsFoundryConfig {\n /**\n * Output directory for generated helpers (relative to project root)\n * @default \"test/foundry/helpers\"\n */\n helpersDir?: string;\n\n /**\n * Whether to generate example tests on init\n * @default true\n */\n generateExamples?: boolean;\n\n /**\n * Example test templates to generate\n * @default [\"unit\", \"integration\", \"fuzz\"]\n */\n exampleTests?: Array<\"unit\" | \"integration\" | \"fuzz\">;\n\n /**\n * Default network for deployments\n * @default \"hardhat\"\n */\n defaultNetwork?: string;\n\n /**\n * Whether to reuse existing deployment or deploy fresh\n * @default true\n */\n reuseDeployment?: boolean;\n\n /**\n * Additional forge test arguments\n * @default []\n */\n forgeTestArgs?: string[];\n}\n\n/**\n * Default configuration values\n */\nexport const DEFAULT_CONFIG: Required<DiamondsFoundryConfig> = {\n helpersDir: \"test/foundry/helpers\",\n generateExamples: true,\n exampleTests: [\"unit\", \"integration\", \"fuzz\"],\n defaultNetwork: \"hardhat\",\n reuseDeployment: true,\n forgeTestArgs: [],\n};\n\n/**\n * Type for forge coverage report formats\n */\nexport type CoverageReportType = \"summary\" | \"lcov\" | \"debug\" | \"bytecode\";\n\n/**\n * Type for color output modes\n */\nexport type ColorMode = \"auto\" | \"always\" | \"never\";\n\n/**\n * Coverage options for forge coverage command\n * Maps to all available forge coverage command-line options\n */\nexport interface CoverageOptions {\n // Report options\n /** Report type(s) - can specify multiple */\n report?: CoverageReportType[];\n /** Output path for report file */\n reportFile?: string;\n /** LCOV format version (default: 1) */\n lcovVersion?: string;\n /** Include libraries in coverage report */\n includeLibs?: boolean;\n /** Exclude tests from coverage report */\n excludeTests?: boolean;\n /** Enable viaIR with minimum optimization */\n irMinimum?: boolean;\n\n // Test filtering\n /** Run tests matching regex pattern */\n matchTest?: string;\n /** Exclude tests matching regex pattern */\n noMatchTest?: string;\n /** Run contracts matching regex pattern */\n matchContract?: string;\n /** Exclude contracts matching regex pattern */\n noMatchContract?: string;\n /** Run files matching glob pattern */\n matchPath?: string;\n /** Exclude files matching glob pattern */\n noMatchPath?: string;\n /** Exclude files from coverage report matching regex */\n noMatchCoverage?: string;\n\n // Display options\n /** Verbosity level (1-5) - more v's = more verbose */\n verbosity?: number;\n /** Suppress log output */\n quiet?: boolean;\n /** Format output as JSON */\n json?: boolean;\n /** Format output as Markdown */\n md?: boolean;\n /** Color output mode */\n color?: ColorMode;\n\n // Test execution options\n /** Number of threads to use for parallel execution */\n threads?: number;\n /** Number of fuzz test runs */\n fuzzRuns?: number;\n /** Seed for fuzz test randomness (for reproducibility) */\n fuzzSeed?: string;\n /** Stop running tests after first failure */\n failFast?: boolean;\n /** Exit with code 0 even if tests fail */\n allowFailure?: boolean;\n\n // EVM options\n /** Fork URL for network state */\n forkUrl?: string;\n /** Fork from specific block number */\n forkBlockNumber?: number;\n /** Initial balance for deployed test contracts */\n initialBalance?: string;\n /** Address to use as test sender */\n sender?: string;\n /** Enable FFI (Foreign Function Interface) cheatcode */\n ffi?: boolean;\n\n // Build options\n /** Force recompilation and cache clearing */\n force?: boolean;\n /** Disable compiler cache */\n noCache?: boolean;\n /** Enable Solidity optimizer */\n optimize?: boolean;\n /** Number of optimizer runs */\n optimizerRuns?: number;\n /** Use Yul intermediate representation compilation */\n viaIr?: boolean;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diamondslab/diamonds-hardhat-foundry",
3
- "version": "2.2.2",
3
+ "version": "2.3.0",
4
4
  "description": "Hardhat plugin that integrates Foundry testing with Diamond proxy contracts, providing deployment helpers and fuzzing support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -68,8 +68,8 @@
68
68
  "typescript": "~5.0.0"
69
69
  },
70
70
  "peerDependencies": {
71
- "@diamondslab/diamonds": "^1.3.0",
72
- "@diamondslab/hardhat-diamonds": "^1.1.12",
71
+ "@diamondslab/diamonds": "workspace:^",
72
+ "@diamondslab/hardhat-diamonds": "workspace:^",
73
73
  "@nomicfoundation/hardhat-ethers": "^3.0.8",
74
74
  "ethers": "^6.0.0",
75
75
  "hardhat": "^2.26.0"
@@ -0,0 +1,287 @@
1
+ import { spawn } from "child_process";
2
+ import { HardhatRuntimeEnvironment } from "hardhat/types";
3
+ import { CoverageOptions } from "../types/config";
4
+ import { Logger } from "../utils/logger";
5
+
6
+ /**
7
+ * ForgeCoverageFramework - Orchestrates forge coverage execution for Diamond contracts
8
+ *
9
+ * Responsibilities:
10
+ * 1. Build forge coverage command with all options
11
+ * 2. Execute forge coverage with proper fork URL
12
+ * 3. Stream output to terminal
13
+ * 4. Handle errors appropriately
14
+ */
15
+ export class ForgeCoverageFramework {
16
+ constructor(private hre: HardhatRuntimeEnvironment) {}
17
+
18
+ /**
19
+ * Run forge coverage with provided options
20
+ *
21
+ * @param options - Coverage execution options
22
+ * @returns Promise<boolean> - true if coverage succeeds, false otherwise
23
+ */
24
+ async runCoverage(options: CoverageOptions = {}): Promise<boolean> {
25
+ Logger.section("Forge Coverage - Execution");
26
+
27
+ try {
28
+ // Build command arguments
29
+ const args = this.buildCoverageCommand(options);
30
+
31
+ Logger.info(`Executing: forge coverage ${args.join(" ")}`);
32
+ Logger.info("⏳ Running coverage analysis (this may take a while)...\n");
33
+
34
+ // Execute forge coverage
35
+ const success = await this.executeForge(args);
36
+
37
+ if (success) {
38
+ Logger.success("✅ Coverage analysis completed successfully");
39
+ } else {
40
+ Logger.error("❌ Coverage analysis failed");
41
+ }
42
+
43
+ return success;
44
+ } catch (error: any) {
45
+ Logger.error(`Coverage execution error: ${error.message}`);
46
+ return false;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Build complete forge coverage command arguments
52
+ *
53
+ * @param options - Coverage options
54
+ * @returns Array of command arguments
55
+ */
56
+ private buildCoverageCommand(options: CoverageOptions): string[] {
57
+ const args: string[] = [];
58
+
59
+ // Add fork URL if provided
60
+ if (options.forkUrl) {
61
+ args.push("--fork-url", options.forkUrl);
62
+ }
63
+
64
+ // Add all option groups
65
+ args.push(...this.buildReportOptions(options));
66
+ args.push(...this.buildFilterOptions(options));
67
+ args.push(...this.buildDisplayOptions(options));
68
+ args.push(...this.buildTestOptions(options));
69
+ args.push(...this.buildEvmOptions(options));
70
+ args.push(...this.buildBuildOptions(options));
71
+
72
+ return args.filter((arg) => arg !== "");
73
+ }
74
+
75
+ /**
76
+ * Build report-related options
77
+ */
78
+ private buildReportOptions(options: CoverageOptions): string[] {
79
+ const args: string[] = [];
80
+
81
+ // Multiple --report flags
82
+ if (options.report && options.report.length > 0) {
83
+ options.report.forEach((reportType) => {
84
+ args.push("--report", reportType);
85
+ });
86
+ }
87
+
88
+ if (options.reportFile) {
89
+ args.push("--report-file", options.reportFile);
90
+ }
91
+
92
+ if (options.lcovVersion) {
93
+ args.push("--lcov-version", options.lcovVersion);
94
+ }
95
+
96
+ if (options.includeLibs) {
97
+ args.push("--include-libs");
98
+ }
99
+
100
+ if (options.excludeTests) {
101
+ args.push("--exclude-tests");
102
+ }
103
+
104
+ if (options.irMinimum) {
105
+ args.push("--ir-minimum");
106
+ }
107
+
108
+ return args;
109
+ }
110
+
111
+ /**
112
+ * Build test filtering options
113
+ */
114
+ private buildFilterOptions(options: CoverageOptions): string[] {
115
+ const args: string[] = [];
116
+
117
+ if (options.matchTest) {
118
+ args.push("--match-test", options.matchTest);
119
+ }
120
+
121
+ if (options.noMatchTest) {
122
+ args.push("--no-match-test", options.noMatchTest);
123
+ }
124
+
125
+ if (options.matchContract) {
126
+ args.push("--match-contract", options.matchContract);
127
+ }
128
+
129
+ if (options.noMatchContract) {
130
+ args.push("--no-match-contract", options.noMatchContract);
131
+ }
132
+
133
+ if (options.matchPath) {
134
+ args.push("--match-path", options.matchPath);
135
+ }
136
+
137
+ if (options.noMatchPath) {
138
+ args.push("--no-match-path", options.noMatchPath);
139
+ }
140
+
141
+ if (options.noMatchCoverage) {
142
+ args.push("--no-match-coverage", options.noMatchCoverage);
143
+ }
144
+
145
+ return args;
146
+ }
147
+
148
+ /**
149
+ * Build display options
150
+ */
151
+ private buildDisplayOptions(options: CoverageOptions): string[] {
152
+ const args: string[] = [];
153
+
154
+ // Verbosity (-v, -vv, -vvv, etc.)
155
+ if (options.verbosity && options.verbosity > 0) {
156
+ args.push("-" + "v".repeat(options.verbosity));
157
+ }
158
+
159
+ if (options.quiet) {
160
+ args.push("--quiet");
161
+ }
162
+
163
+ if (options.json) {
164
+ args.push("--json");
165
+ }
166
+
167
+ if (options.md) {
168
+ args.push("--md");
169
+ }
170
+
171
+ if (options.color) {
172
+ args.push("--color", options.color);
173
+ }
174
+
175
+ return args;
176
+ }
177
+
178
+ /**
179
+ * Build test execution options
180
+ */
181
+ private buildTestOptions(options: CoverageOptions): string[] {
182
+ const args: string[] = [];
183
+
184
+ if (options.threads !== undefined) {
185
+ args.push("--threads", options.threads.toString());
186
+ }
187
+
188
+ if (options.fuzzRuns !== undefined) {
189
+ args.push("--fuzz-runs", options.fuzzRuns.toString());
190
+ }
191
+
192
+ if (options.fuzzSeed) {
193
+ args.push("--fuzz-seed", options.fuzzSeed);
194
+ }
195
+
196
+ if (options.failFast) {
197
+ args.push("--fail-fast");
198
+ }
199
+
200
+ if (options.allowFailure) {
201
+ args.push("--allow-failure");
202
+ }
203
+
204
+ return args;
205
+ }
206
+
207
+ /**
208
+ * Build EVM options
209
+ */
210
+ private buildEvmOptions(options: CoverageOptions): string[] {
211
+ const args: string[] = [];
212
+
213
+ if (options.forkBlockNumber !== undefined) {
214
+ args.push("--fork-block-number", options.forkBlockNumber.toString());
215
+ }
216
+
217
+ if (options.initialBalance) {
218
+ args.push("--initial-balance", options.initialBalance);
219
+ }
220
+
221
+ if (options.sender) {
222
+ args.push("--sender", options.sender);
223
+ }
224
+
225
+ if (options.ffi) {
226
+ args.push("--ffi");
227
+ }
228
+
229
+ return args;
230
+ }
231
+
232
+ /**
233
+ * Build build options
234
+ */
235
+ private buildBuildOptions(options: CoverageOptions): string[] {
236
+ const args: string[] = [];
237
+
238
+ if (options.force) {
239
+ args.push("--force");
240
+ }
241
+
242
+ if (options.noCache) {
243
+ args.push("--no-cache");
244
+ }
245
+
246
+ if (options.optimize) {
247
+ args.push("--optimize");
248
+ }
249
+
250
+ if (options.optimizerRuns !== undefined) {
251
+ args.push("--optimizer-runs", options.optimizerRuns.toString());
252
+ }
253
+
254
+ if (options.viaIr) {
255
+ args.push("--via-ir");
256
+ }
257
+
258
+ return args;
259
+ }
260
+
261
+ /**
262
+ * Execute forge coverage command and stream output
263
+ *
264
+ * @param args - Command arguments
265
+ * @returns Promise<boolean> - true if command succeeds
266
+ */
267
+ private executeForge(args: string[]): Promise<boolean> {
268
+ return new Promise((resolve, reject) => {
269
+ const forgeProcess = spawn("forge", ["coverage", ...args], {
270
+ cwd: this.hre.config.paths.root,
271
+ stdio: "inherit", // Stream output directly to terminal
272
+ });
273
+
274
+ forgeProcess.on("close", (code) => {
275
+ if (code === 0) {
276
+ resolve(true);
277
+ } else {
278
+ resolve(false);
279
+ }
280
+ });
281
+
282
+ forgeProcess.on("error", (error) => {
283
+ reject(new Error(`Failed to execute forge coverage: ${error.message}`));
284
+ });
285
+ });
286
+ }
287
+ }
@@ -1,4 +1,4 @@
1
- import { DeployedDiamondData } from "@diamondslab/diamonds";
1
+ import { DeployedDiamondData, Diamond } from "@diamondslab/diamonds";
2
2
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
3
3
  import { HardhatRuntimeEnvironment } from "hardhat/types";
4
4
  import { join } from "path";
@@ -79,12 +79,16 @@ export class HelperGenerator {
79
79
  * @private
80
80
  */
81
81
  private setForgeEnvironmentVariables(
82
- diamond: any,
82
+ diamond: Diamond,
83
83
  deploymentData: DeployedDiamondData
84
84
  ): void {
85
85
  try {
86
- // Get Diamond ABI path
87
- const abiPath = diamond.getDiamondAbiFilePath?.() || `./diamond-abi/${deploymentData.DiamondAddress}.json`;
86
+ // Get Diamond ABI path - remove leading "./" for Foundry compatibility
87
+ let abiPath = diamond.getDiamondAbiFilePath?.() || `diamond-abi/${diamond.getDiamondConfig().diamondName}.json` || `diamond-abi/Diamond.json`;
88
+ // Normalize path - remove leading "./" if present
89
+ if (abiPath.startsWith('./')) {
90
+ abiPath = abiPath.substring(2);
91
+ }
88
92
 
89
93
  // Get Diamond address
90
94
  const diamondAddress = deploymentData.DiamondAddress;
@@ -222,7 +226,7 @@ export class HelperGenerator {
222
226
  // Diamond ABI path
223
227
  source += ` /// @notice Path to the Diamond ABI file\n`;
224
228
  source += ` /// @dev Used by DiamondFuzzBase to load ABI for testing\n`;
225
- source += ` string constant DIAMOND_ABI_PATH = "./diamond-abi/${diamondName}.json";\n\n`;
229
+ source += ` string constant DIAMOND_ABI_PATH = "diamond-abi/${diamondName}.json";\n\n`;
226
230
 
227
231
  // Diamond address
228
232
  source += ` /// @notice Address of the deployed ${diamondName} contract\n`;