@diamondslab/diamonds-hardhat-foundry 1.0.0 → 1.0.2
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.
- package/dist/foundry.d.ts +11 -0
- package/dist/foundry.d.ts.map +1 -0
- package/dist/foundry.js +104 -0
- package/dist/foundry.js.map +1 -0
- package/dist/framework/DeploymentManager.d.ts +48 -0
- package/dist/framework/DeploymentManager.d.ts.map +1 -0
- package/dist/framework/DeploymentManager.js +145 -0
- package/dist/framework/DeploymentManager.js.map +1 -0
- package/dist/framework/ForgeFuzzingFramework.d.ts +57 -0
- package/dist/framework/ForgeFuzzingFramework.d.ts.map +1 -0
- package/dist/framework/ForgeFuzzingFramework.js +119 -0
- package/dist/framework/ForgeFuzzingFramework.js.map +1 -0
- package/dist/framework/HelperGenerator.d.ts +27 -0
- package/dist/framework/HelperGenerator.d.ts.map +1 -0
- package/dist/framework/HelperGenerator.js +195 -0
- package/dist/framework/HelperGenerator.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +113 -0
- package/dist/index.js.map +1 -0
- package/dist/tasks/deploy.d.ts +2 -0
- package/dist/tasks/deploy.d.ts.map +1 -0
- package/dist/tasks/deploy.js +82 -0
- package/dist/tasks/deploy.js.map +1 -0
- package/dist/tasks/generate-helpers.d.ts +2 -0
- package/dist/tasks/generate-helpers.d.ts.map +1 -0
- package/dist/tasks/generate-helpers.js +66 -0
- package/dist/tasks/generate-helpers.js.map +1 -0
- package/dist/tasks/init.d.ts +2 -0
- package/dist/tasks/init.d.ts.map +1 -0
- package/dist/tasks/init.js +78 -0
- package/dist/tasks/init.js.map +1 -0
- package/dist/tasks/test.d.ts +2 -0
- package/dist/tasks/test.d.ts.map +1 -0
- package/dist/tasks/test.js +83 -0
- package/dist/tasks/test.js.map +1 -0
- package/dist/types/config.d.ts +41 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +19 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/hardhat.d.ts +21 -0
- package/dist/types/hardhat.d.ts.map +1 -0
- package/dist/types/hardhat.js +8 -0
- package/dist/types/hardhat.js.map +1 -0
- package/dist/utils/foundry.d.ts +59 -0
- package/dist/utils/foundry.d.ts.map +1 -0
- package/dist/utils/foundry.js +164 -0
- package/dist/utils/foundry.js.map +1 -0
- package/dist/utils/logger.d.ts +38 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +66 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +33 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +131 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +4 -4
- package/src/tasks/deploy.ts +4 -7
- package/src/tasks/generate-helpers.ts +4 -7
- package/src/tasks/test.ts +4 -7
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_1 = require("hardhat/config");
|
|
4
|
+
const HelperGenerator_1 = require("../framework/HelperGenerator");
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
const validation_1 = require("../utils/validation");
|
|
7
|
+
/**
|
|
8
|
+
* Task: diamonds-forge:init
|
|
9
|
+
*
|
|
10
|
+
* Initializes the project for Forge testing with Diamond contracts.
|
|
11
|
+
* - Validates configuration
|
|
12
|
+
* - Checks Foundry installation
|
|
13
|
+
* - Scaffolds test directory structure
|
|
14
|
+
* - Optionally generates example tests
|
|
15
|
+
*/
|
|
16
|
+
(0, config_1.task)("diamonds-forge:init", "Initialize Forge testing structure for Diamond contracts")
|
|
17
|
+
.addOptionalParam("helpersDir", "Directory for generated helper files", undefined, config_1.types.string)
|
|
18
|
+
.addFlag("examples", "Generate example test files")
|
|
19
|
+
.addFlag("force", "Overwrite existing files")
|
|
20
|
+
.setAction(async (taskArgs, hre) => {
|
|
21
|
+
logger_1.Logger.section("Initializing Diamonds-Forge Testing");
|
|
22
|
+
// Step 1: Validate configuration
|
|
23
|
+
logger_1.Logger.step("Validating configuration...");
|
|
24
|
+
const config = (0, validation_1.validateConfig)(hre.diamondsFoundry);
|
|
25
|
+
// Override with task args if provided
|
|
26
|
+
const helpersDir = taskArgs.helpersDir || config.helpersDir;
|
|
27
|
+
const generateExamples = taskArgs.examples || config.generateExamples;
|
|
28
|
+
logger_1.Logger.info(`Helpers directory: ${helpersDir}`);
|
|
29
|
+
logger_1.Logger.info(`Generate examples: ${generateExamples}`);
|
|
30
|
+
// Step 2: Check Foundry installation
|
|
31
|
+
logger_1.Logger.step("Checking Foundry installation...");
|
|
32
|
+
const foundryInstalled = (0, validation_1.validateFoundryInstallation)();
|
|
33
|
+
if (!foundryInstalled) {
|
|
34
|
+
logger_1.Logger.warn("Foundry is not installed or not in PATH");
|
|
35
|
+
logger_1.Logger.warn("Install from: https://book.getfoundry.sh/getting-started/installation");
|
|
36
|
+
logger_1.Logger.warn("Continuing anyway...");
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
logger_1.Logger.success("Foundry is installed");
|
|
40
|
+
}
|
|
41
|
+
// Step 3: Scaffold project structure
|
|
42
|
+
logger_1.Logger.step("Creating test directory structure...");
|
|
43
|
+
const generator = new HelperGenerator_1.HelperGenerator(hre);
|
|
44
|
+
try {
|
|
45
|
+
await generator.scaffoldProject(helpersDir);
|
|
46
|
+
logger_1.Logger.success("Directory structure created");
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
logger_1.Logger.error(`Failed to scaffold project: ${error.message}`);
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
// Step 4: Generate example tests if requested
|
|
53
|
+
if (generateExamples) {
|
|
54
|
+
logger_1.Logger.step("Generating example test files...");
|
|
55
|
+
try {
|
|
56
|
+
const examplePaths = await generator.generateExampleTests();
|
|
57
|
+
if (examplePaths.length > 0) {
|
|
58
|
+
logger_1.Logger.success(`Generated ${examplePaths.length} example test(s)`);
|
|
59
|
+
examplePaths.forEach((path) => logger_1.Logger.info(` - ${path}`));
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
logger_1.Logger.info("No example tests generated (implementation pending)");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger_1.Logger.error(`Failed to generate examples: ${error.message}`);
|
|
67
|
+
throw error;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// Step 5: Summary
|
|
71
|
+
logger_1.Logger.section("Initialization Complete");
|
|
72
|
+
logger_1.Logger.success("Your project is ready for Forge testing!");
|
|
73
|
+
logger_1.Logger.info("\nNext steps:");
|
|
74
|
+
logger_1.Logger.info(" 1. Deploy your Diamond: npx hardhat diamonds-forge:deploy");
|
|
75
|
+
logger_1.Logger.info(" 2. Generate helpers: npx hardhat diamonds-forge:generate-helpers");
|
|
76
|
+
logger_1.Logger.info(" 3. Run tests: npx hardhat diamonds-forge:test");
|
|
77
|
+
});
|
|
78
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/tasks/init.ts"],"names":[],"mappings":"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","sourcesContent":["import { task, types } from \"hardhat/config\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { HelperGenerator } from \"../framework/HelperGenerator\";\nimport { Logger } from \"../utils/logger\";\nimport { validateConfig, validateFoundryInstallation } from \"../utils/validation\";\n\n/**\n * Task: diamonds-forge:init\n * \n * Initializes the project for Forge testing with Diamond contracts.\n * - Validates configuration\n * - Checks Foundry installation\n * - Scaffolds test directory structure\n * - Optionally generates example tests\n */\ntask(\"diamonds-forge:init\", \"Initialize Forge testing structure for Diamond contracts\")\n .addOptionalParam(\n \"helpersDir\",\n \"Directory for generated helper files\",\n undefined,\n types.string\n )\n .addFlag(\"examples\", \"Generate example test files\")\n .addFlag(\"force\", \"Overwrite existing files\")\n .setAction(async (taskArgs, hre: HardhatRuntimeEnvironment) => {\n Logger.section(\"Initializing Diamonds-Forge Testing\");\n\n // Step 1: Validate configuration\n Logger.step(\"Validating configuration...\");\n const config = validateConfig(hre.diamondsFoundry);\n \n // Override with task args if provided\n const helpersDir = taskArgs.helpersDir || config.helpersDir;\n const generateExamples = taskArgs.examples || config.generateExamples;\n\n Logger.info(`Helpers directory: ${helpersDir}`);\n Logger.info(`Generate examples: ${generateExamples}`);\n\n // Step 2: Check Foundry installation\n Logger.step(\"Checking Foundry installation...\");\n const foundryInstalled = validateFoundryInstallation();\n \n if (!foundryInstalled) {\n Logger.warn(\"Foundry is not installed or not in PATH\");\n Logger.warn(\"Install from: https://book.getfoundry.sh/getting-started/installation\");\n Logger.warn(\"Continuing anyway...\");\n } else {\n Logger.success(\"Foundry is installed\");\n }\n\n // Step 3: Scaffold project structure\n Logger.step(\"Creating test directory structure...\");\n const generator = new HelperGenerator(hre);\n \n try {\n await generator.scaffoldProject(helpersDir);\n Logger.success(\"Directory structure created\");\n } catch (error: any) {\n Logger.error(`Failed to scaffold project: ${error.message}`);\n throw error;\n }\n\n // Step 4: Generate example tests if requested\n if (generateExamples) {\n Logger.step(\"Generating example test files...\");\n try {\n const examplePaths = await generator.generateExampleTests();\n \n if (examplePaths.length > 0) {\n Logger.success(`Generated ${examplePaths.length} example test(s)`);\n examplePaths.forEach((path) => Logger.info(` - ${path}`));\n } else {\n Logger.info(\"No example tests generated (implementation pending)\");\n }\n } catch (error: any) {\n Logger.error(`Failed to generate examples: ${error.message}`);\n throw error;\n }\n }\n\n // Step 5: Summary\n Logger.section(\"Initialization Complete\");\n Logger.success(\"Your project is ready for Forge testing!\");\n Logger.info(\"\\nNext steps:\");\n Logger.info(\" 1. Deploy your Diamond: npx hardhat diamonds-forge:deploy\");\n Logger.info(\" 2. Generate helpers: npx hardhat diamonds-forge:generate-helpers\");\n Logger.info(\" 3. Run tests: npx hardhat diamonds-forge:test\");\n });\n\n\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/tasks/test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config_1 = require("hardhat/config");
|
|
4
|
+
const ForgeFuzzingFramework_1 = require("../framework/ForgeFuzzingFramework");
|
|
5
|
+
const logger_1 = require("../utils/logger");
|
|
6
|
+
/**
|
|
7
|
+
* Task: diamonds-forge:test
|
|
8
|
+
*
|
|
9
|
+
* Runs Forge tests with Diamond deployment.
|
|
10
|
+
* - Ensures Diamond deployment exists
|
|
11
|
+
* - Generates Solidity helpers
|
|
12
|
+
* - Compiles Forge contracts
|
|
13
|
+
* - Runs forge test with specified options
|
|
14
|
+
*
|
|
15
|
+
* Use Hardhat's built-in --network flag to specify the network
|
|
16
|
+
*/
|
|
17
|
+
(0, config_1.task)("diamonds-forge:test", "Run Forge tests with Diamond deployment")
|
|
18
|
+
.addOptionalParam("diamondName", "Name of the Diamond to test", "ExampleDiamond", config_1.types.string)
|
|
19
|
+
.addOptionalParam("matchTest", "Run tests matching pattern (--match-test)", undefined, config_1.types.string)
|
|
20
|
+
.addOptionalParam("matchContract", "Run tests in contracts matching pattern (--match-contract)", undefined, config_1.types.string)
|
|
21
|
+
.addOptionalParam("verbosity", "Verbosity level (1-5, more v's = more verbose)", 2, config_1.types.int)
|
|
22
|
+
.addFlag("gasReport", "Show gas report")
|
|
23
|
+
.addFlag("skipDeployment", "Skip Diamond deployment step")
|
|
24
|
+
.addFlag("skipHelpers", "Skip helper generation step")
|
|
25
|
+
.addFlag("force", "Force redeployment of Diamond")
|
|
26
|
+
.setAction(async (taskArgs, hre) => {
|
|
27
|
+
logger_1.Logger.section("Running Forge Tests with Diamond");
|
|
28
|
+
const diamondName = taskArgs.diamondName;
|
|
29
|
+
// Use Hardhat's built-in network name from HRE
|
|
30
|
+
const networkName = hre.network.name;
|
|
31
|
+
const matchTest = taskArgs.matchTest;
|
|
32
|
+
const matchContract = taskArgs.matchContract;
|
|
33
|
+
const verbosity = taskArgs.verbosity;
|
|
34
|
+
const gasReport = taskArgs.gasReport;
|
|
35
|
+
const skipDeployment = taskArgs.skipDeployment;
|
|
36
|
+
const skipHelpers = taskArgs.skipHelpers;
|
|
37
|
+
const force = taskArgs.force;
|
|
38
|
+
logger_1.Logger.info(`Diamond: ${diamondName}`);
|
|
39
|
+
logger_1.Logger.info(`Network: ${networkName}`);
|
|
40
|
+
if (matchTest)
|
|
41
|
+
logger_1.Logger.info(`Match Test: ${matchTest}`);
|
|
42
|
+
if (matchContract)
|
|
43
|
+
logger_1.Logger.info(`Match Contract: ${matchContract}`);
|
|
44
|
+
if (gasReport)
|
|
45
|
+
logger_1.Logger.info("Gas Report: enabled");
|
|
46
|
+
if (skipDeployment)
|
|
47
|
+
logger_1.Logger.info("Skip Deployment: true");
|
|
48
|
+
if (skipHelpers)
|
|
49
|
+
logger_1.Logger.info("Skip Helpers: true");
|
|
50
|
+
// Create test options
|
|
51
|
+
const options = {
|
|
52
|
+
diamondName,
|
|
53
|
+
networkName,
|
|
54
|
+
force,
|
|
55
|
+
matchTest,
|
|
56
|
+
matchContract,
|
|
57
|
+
verbosity,
|
|
58
|
+
gasReport,
|
|
59
|
+
skipHelpers,
|
|
60
|
+
skipDeployment,
|
|
61
|
+
};
|
|
62
|
+
// Run tests using the framework
|
|
63
|
+
const framework = new ForgeFuzzingFramework_1.ForgeFuzzingFramework(hre);
|
|
64
|
+
try {
|
|
65
|
+
const success = await framework.runTests(options);
|
|
66
|
+
if (success) {
|
|
67
|
+
logger_1.Logger.section("Test Execution Complete");
|
|
68
|
+
logger_1.Logger.success("All tests passed!");
|
|
69
|
+
process.exitCode = 0;
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
logger_1.Logger.section("Test Execution Complete");
|
|
73
|
+
logger_1.Logger.error("Some tests failed");
|
|
74
|
+
process.exitCode = 1;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logger_1.Logger.error(`Test execution failed: ${error.message}`);
|
|
79
|
+
process.exitCode = 1;
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/tasks/test.ts"],"names":[],"mappings":"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","sourcesContent":["import { task, types } from \"hardhat/config\";\nimport { HardhatRuntimeEnvironment } from \"hardhat/types\";\nimport { ForgeFuzzingFramework, ForgeTestOptions } from \"../framework/ForgeFuzzingFramework\";\nimport { Logger } from \"../utils/logger\";\n\n/**\n * Task: diamonds-forge:test\n * \n * Runs Forge tests with Diamond deployment.\n * - Ensures Diamond deployment exists\n * - Generates Solidity helpers\n * - Compiles Forge contracts\n * - Runs forge test with specified options\n * \n * Use Hardhat's built-in --network flag to specify the network\n */\ntask(\"diamonds-forge:test\", \"Run Forge tests with Diamond deployment\")\n .addOptionalParam(\n \"diamondName\",\n \"Name of the Diamond to test\",\n \"ExampleDiamond\",\n types.string\n )\n .addOptionalParam(\n \"matchTest\",\n \"Run tests matching pattern (--match-test)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"matchContract\",\n \"Run tests in contracts matching pattern (--match-contract)\",\n undefined,\n types.string\n )\n .addOptionalParam(\n \"verbosity\",\n \"Verbosity level (1-5, more v's = more verbose)\",\n 2,\n types.int\n )\n .addFlag(\"gasReport\", \"Show gas report\")\n .addFlag(\"skipDeployment\", \"Skip Diamond deployment step\")\n .addFlag(\"skipHelpers\", \"Skip helper generation step\")\n .addFlag(\"force\", \"Force redeployment of Diamond\")\n .setAction(async (taskArgs, hre: HardhatRuntimeEnvironment) => {\n Logger.section(\"Running Forge Tests with Diamond\");\n\n const diamondName = taskArgs.diamondName;\n // Use Hardhat's built-in network name from HRE\n const networkName = hre.network.name;\n const matchTest = taskArgs.matchTest;\n const matchContract = taskArgs.matchContract;\n const verbosity = taskArgs.verbosity;\n const gasReport = taskArgs.gasReport;\n const skipDeployment = taskArgs.skipDeployment;\n const skipHelpers = taskArgs.skipHelpers;\n const force = taskArgs.force;\n\n Logger.info(`Diamond: ${diamondName}`);\n Logger.info(`Network: ${networkName}`);\n \n if (matchTest) Logger.info(`Match Test: ${matchTest}`);\n if (matchContract) Logger.info(`Match Contract: ${matchContract}`);\n if (gasReport) Logger.info(\"Gas Report: enabled\");\n if (skipDeployment) Logger.info(\"Skip Deployment: true\");\n if (skipHelpers) Logger.info(\"Skip Helpers: true\");\n\n // Create test options\n const options: ForgeTestOptions = {\n diamondName,\n networkName,\n force,\n matchTest,\n matchContract,\n verbosity,\n gasReport,\n skipHelpers,\n skipDeployment,\n };\n\n // Run tests using the framework\n const framework = new ForgeFuzzingFramework(hre);\n \n try {\n const success = await framework.runTests(options);\n\n if (success) {\n Logger.section(\"Test Execution Complete\");\n Logger.success(\"All tests passed!\");\n process.exitCode = 0;\n } else {\n Logger.section(\"Test Execution Complete\");\n Logger.error(\"Some tests failed\");\n process.exitCode = 1;\n }\n\n } catch (error: any) {\n Logger.error(`Test execution failed: ${error.message}`);\n process.exitCode = 1;\n throw error;\n }\n });\n\n\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration types for diamonds-hardhat-foundry plugin
|
|
3
|
+
* Will be fully implemented in Task 2.1
|
|
4
|
+
*/
|
|
5
|
+
export interface DiamondsFoundryConfig {
|
|
6
|
+
/**
|
|
7
|
+
* Output directory for generated helpers (relative to project root)
|
|
8
|
+
* @default "test/foundry/helpers"
|
|
9
|
+
*/
|
|
10
|
+
helpersDir?: string;
|
|
11
|
+
/**
|
|
12
|
+
* Whether to generate example tests on init
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
generateExamples?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Example test templates to generate
|
|
18
|
+
* @default ["unit", "integration", "fuzz"]
|
|
19
|
+
*/
|
|
20
|
+
exampleTests?: Array<"unit" | "integration" | "fuzz">;
|
|
21
|
+
/**
|
|
22
|
+
* Default network for deployments
|
|
23
|
+
* @default "hardhat"
|
|
24
|
+
*/
|
|
25
|
+
defaultNetwork?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether to reuse existing deployment or deploy fresh
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
reuseDeployment?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Additional forge test arguments
|
|
33
|
+
* @default []
|
|
34
|
+
*/
|
|
35
|
+
forgeTestArgs?: string[];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Default configuration values
|
|
39
|
+
*/
|
|
40
|
+
export declare const DEFAULT_CONFIG: Required<DiamondsFoundryConfig>;
|
|
41
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration types for diamonds-hardhat-foundry plugin
|
|
4
|
+
* Will be fully implemented in Task 2.1
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DEFAULT_CONFIG = void 0;
|
|
8
|
+
/**
|
|
9
|
+
* Default configuration values
|
|
10
|
+
*/
|
|
11
|
+
exports.DEFAULT_CONFIG = {
|
|
12
|
+
helpersDir: "test/foundry/helpers",
|
|
13
|
+
generateExamples: true,
|
|
14
|
+
exampleTests: ["unit", "integration", "fuzz"],
|
|
15
|
+
defaultNetwork: "hardhat",
|
|
16
|
+
reuseDeployment: true,
|
|
17
|
+
forgeTestArgs: [],
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type extensions for Hardhat Runtime Environment
|
|
3
|
+
*/
|
|
4
|
+
import "hardhat/types/config";
|
|
5
|
+
import "hardhat/types/runtime";
|
|
6
|
+
import { DiamondsFoundryConfig } from "../types/config";
|
|
7
|
+
declare module "hardhat/types/config" {
|
|
8
|
+
interface HardhatUserConfig {
|
|
9
|
+
diamondsFoundry?: Partial<DiamondsFoundryConfig>;
|
|
10
|
+
}
|
|
11
|
+
interface HardhatConfig {
|
|
12
|
+
diamondsFoundry: Required<DiamondsFoundryConfig>;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
declare module "hardhat/types/runtime" {
|
|
16
|
+
interface HardhatRuntimeEnvironment {
|
|
17
|
+
diamondsFoundry: Required<DiamondsFoundryConfig>;
|
|
18
|
+
ethers: any;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=hardhat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardhat.d.ts","sourceRoot":"","sources":["../../src/types/hardhat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,sBAAsB,CAAC;AAC9B,OAAO,uBAAuB,CAAC;AAC/B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAiB,iBAAiB;QAChC,eAAe,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;KAClD;IAED,UAAiB,aAAa;QAC5B,eAAe,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;KAClD;CACF;AAED,OAAO,QAAQ,uBAAuB,CAAC;IACrC,UAAiB,yBAAyB;QACxC,eAAe,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAC;QACjD,MAAM,EAAE,GAAG,CAAC;KACb;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hardhat.js","sourceRoot":"","sources":["../../src/types/hardhat.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAEH,gCAA8B;AAC9B,iCAA+B","sourcesContent":["/**\n * Type extensions for Hardhat Runtime Environment\n */\n\nimport \"hardhat/types/config\";\nimport \"hardhat/types/runtime\";\nimport { DiamondsFoundryConfig } from \"../types/config\";\n\ndeclare module \"hardhat/types/config\" {\n export interface HardhatUserConfig {\n diamondsFoundry?: Partial<DiamondsFoundryConfig>;\n }\n\n export interface HardhatConfig {\n diamondsFoundry: Required<DiamondsFoundryConfig>;\n }\n}\n\ndeclare module \"hardhat/types/runtime\" {\n export interface HardhatRuntimeEnvironment {\n diamondsFoundry: Required<DiamondsFoundryConfig>;\n ethers: any; // Will be provided by @nomicfoundation/hardhat-ethers\n }\n}\n"]}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Execute a Foundry command synchronously
|
|
3
|
+
* @param command - The foundry command (e.g., "forge test")
|
|
4
|
+
* @param args - Command arguments
|
|
5
|
+
* @param options - Execution options
|
|
6
|
+
*/
|
|
7
|
+
export declare function execForgeSync(command: string, args?: string[], options?: {
|
|
8
|
+
cwd?: string;
|
|
9
|
+
stdio?: "inherit" | "pipe";
|
|
10
|
+
}): string;
|
|
11
|
+
/**
|
|
12
|
+
* Execute a Foundry command asynchronously
|
|
13
|
+
* @param command - The foundry command (e.g., "forge")
|
|
14
|
+
* @param args - Command arguments
|
|
15
|
+
* @param options - Execution options
|
|
16
|
+
*/
|
|
17
|
+
export declare function execForgeAsync(command: string, args?: string[], options?: {
|
|
18
|
+
cwd?: string;
|
|
19
|
+
verbose?: boolean;
|
|
20
|
+
}): Promise<{
|
|
21
|
+
stdout: string;
|
|
22
|
+
stderr: string;
|
|
23
|
+
exitCode: number;
|
|
24
|
+
}>;
|
|
25
|
+
/**
|
|
26
|
+
* Run forge test with specified options
|
|
27
|
+
* @param options - Test execution options
|
|
28
|
+
*/
|
|
29
|
+
export declare function runForgeTest(options: {
|
|
30
|
+
matchTest?: string;
|
|
31
|
+
matchContract?: string;
|
|
32
|
+
verbosity?: number;
|
|
33
|
+
gasReport?: boolean;
|
|
34
|
+
cwd?: string;
|
|
35
|
+
env?: Record<string, string>;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
success: boolean;
|
|
38
|
+
output: string;
|
|
39
|
+
}>;
|
|
40
|
+
/**
|
|
41
|
+
* Compile Forge contracts
|
|
42
|
+
* @param options - Compilation options
|
|
43
|
+
*/
|
|
44
|
+
export declare function compileForge(options: {
|
|
45
|
+
cwd?: string;
|
|
46
|
+
verbose?: boolean;
|
|
47
|
+
}): Promise<{
|
|
48
|
+
success: boolean;
|
|
49
|
+
output: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Check if Foundry is installed
|
|
53
|
+
*/
|
|
54
|
+
export declare function isFoundryInstalled(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get Foundry version
|
|
57
|
+
*/
|
|
58
|
+
export declare function getFoundryVersion(): string | null;
|
|
59
|
+
//# sourceMappingURL=foundry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry.d.ts","sourceRoot":"","sources":["../../src/utils/foundry.ts"],"names":[],"mappings":"AAGA;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,GAAG,MAAM,CAAA;CAAO,GACzD,MAAM,CAkBR;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,MAAM,EAAO,EACnB,OAAO,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAqC/D;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsChD;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,GAAG,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsBhD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAO5C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CASjD"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFoundryVersion = exports.isFoundryInstalled = exports.compileForge = exports.runForgeTest = exports.execForgeAsync = exports.execForgeSync = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
/**
|
|
7
|
+
* Execute a Foundry command synchronously
|
|
8
|
+
* @param command - The foundry command (e.g., "forge test")
|
|
9
|
+
* @param args - Command arguments
|
|
10
|
+
* @param options - Execution options
|
|
11
|
+
*/
|
|
12
|
+
function execForgeSync(command, args = [], options = {}) {
|
|
13
|
+
const fullCommand = `${command} ${args.join(" ")}`;
|
|
14
|
+
logger_1.Logger.step(`Running: ${fullCommand}`);
|
|
15
|
+
try {
|
|
16
|
+
const output = (0, child_process_1.execSync)(fullCommand, {
|
|
17
|
+
cwd: options.cwd || process.cwd(),
|
|
18
|
+
stdio: options.stdio || "pipe",
|
|
19
|
+
encoding: "utf-8",
|
|
20
|
+
});
|
|
21
|
+
return output;
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
logger_1.Logger.error(`Forge command failed: ${error.message}`);
|
|
25
|
+
if (error.stdout)
|
|
26
|
+
logger_1.Logger.info(error.stdout);
|
|
27
|
+
if (error.stderr)
|
|
28
|
+
logger_1.Logger.error(error.stderr);
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.execForgeSync = execForgeSync;
|
|
33
|
+
/**
|
|
34
|
+
* Execute a Foundry command asynchronously
|
|
35
|
+
* @param command - The foundry command (e.g., "forge")
|
|
36
|
+
* @param args - Command arguments
|
|
37
|
+
* @param options - Execution options
|
|
38
|
+
*/
|
|
39
|
+
async function execForgeAsync(command, args = [], options = {}) {
|
|
40
|
+
logger_1.Logger.step(`Running: ${command} ${args.join(" ")}`);
|
|
41
|
+
return new Promise((resolve, reject) => {
|
|
42
|
+
const child = (0, child_process_1.spawn)(command, args, {
|
|
43
|
+
cwd: options.cwd || process.cwd(),
|
|
44
|
+
shell: true,
|
|
45
|
+
});
|
|
46
|
+
let stdout = "";
|
|
47
|
+
let stderr = "";
|
|
48
|
+
child.stdout?.on("data", (data) => {
|
|
49
|
+
const text = data.toString();
|
|
50
|
+
stdout += text;
|
|
51
|
+
if (options.verbose) {
|
|
52
|
+
process.stdout.write(text);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
child.stderr?.on("data", (data) => {
|
|
56
|
+
const text = data.toString();
|
|
57
|
+
stderr += text;
|
|
58
|
+
if (options.verbose) {
|
|
59
|
+
process.stderr.write(text);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
child.on("close", (code) => {
|
|
63
|
+
resolve({ stdout, stderr, exitCode: code || 0 });
|
|
64
|
+
});
|
|
65
|
+
child.on("error", (error) => {
|
|
66
|
+
logger_1.Logger.error(`Failed to spawn ${command}: ${error.message}`);
|
|
67
|
+
reject(error);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
exports.execForgeAsync = execForgeAsync;
|
|
72
|
+
/**
|
|
73
|
+
* Run forge test with specified options
|
|
74
|
+
* @param options - Test execution options
|
|
75
|
+
*/
|
|
76
|
+
async function runForgeTest(options) {
|
|
77
|
+
const args = ["test"];
|
|
78
|
+
if (options.matchTest) {
|
|
79
|
+
args.push("--match-test", options.matchTest);
|
|
80
|
+
}
|
|
81
|
+
if (options.matchContract) {
|
|
82
|
+
args.push("--match-contract", options.matchContract);
|
|
83
|
+
}
|
|
84
|
+
if (options.verbosity) {
|
|
85
|
+
args.push("-" + "v".repeat(options.verbosity));
|
|
86
|
+
}
|
|
87
|
+
if (options.gasReport) {
|
|
88
|
+
args.push("--gas-report");
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const result = await execForgeAsync("forge", args, {
|
|
92
|
+
cwd: options.cwd,
|
|
93
|
+
verbose: true,
|
|
94
|
+
});
|
|
95
|
+
const success = result.exitCode === 0;
|
|
96
|
+
if (success) {
|
|
97
|
+
logger_1.Logger.success("Forge tests passed!");
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
logger_1.Logger.error("Forge tests failed");
|
|
101
|
+
}
|
|
102
|
+
return { success, output: result.stdout + result.stderr };
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
logger_1.Logger.error(`Test execution failed: ${error.message}`);
|
|
106
|
+
return { success: false, output: error.message };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
exports.runForgeTest = runForgeTest;
|
|
110
|
+
/**
|
|
111
|
+
* Compile Forge contracts
|
|
112
|
+
* @param options - Compilation options
|
|
113
|
+
*/
|
|
114
|
+
async function compileForge(options) {
|
|
115
|
+
logger_1.Logger.step("Compiling Forge contracts...");
|
|
116
|
+
try {
|
|
117
|
+
const result = await execForgeAsync("forge", ["build"], {
|
|
118
|
+
cwd: options.cwd,
|
|
119
|
+
verbose: options.verbose,
|
|
120
|
+
});
|
|
121
|
+
const success = result.exitCode === 0;
|
|
122
|
+
if (success) {
|
|
123
|
+
logger_1.Logger.success("Forge compilation successful!");
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
logger_1.Logger.error("Forge compilation failed");
|
|
127
|
+
}
|
|
128
|
+
return { success, output: result.stdout + result.stderr };
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
logger_1.Logger.error(`Compilation failed: ${error.message}`);
|
|
132
|
+
return { success: false, output: error.message };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.compileForge = compileForge;
|
|
136
|
+
/**
|
|
137
|
+
* Check if Foundry is installed
|
|
138
|
+
*/
|
|
139
|
+
function isFoundryInstalled() {
|
|
140
|
+
try {
|
|
141
|
+
(0, child_process_1.execSync)("forge --version", { stdio: "pipe" });
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exports.isFoundryInstalled = isFoundryInstalled;
|
|
149
|
+
/**
|
|
150
|
+
* Get Foundry version
|
|
151
|
+
*/
|
|
152
|
+
function getFoundryVersion() {
|
|
153
|
+
try {
|
|
154
|
+
const output = (0, child_process_1.execSync)("forge --version", { encoding: "utf-8", stdio: "pipe" });
|
|
155
|
+
// Extract version from output like "forge 0.2.0 (abc123 2024-01-01T00:00:00.000000000Z)"
|
|
156
|
+
const match = output.match(/forge\s+([\d.]+)/);
|
|
157
|
+
return match ? match[1] : null;
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
exports.getFoundryVersion = getFoundryVersion;
|
|
164
|
+
//# sourceMappingURL=foundry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry.js","sourceRoot":"","sources":["../../src/utils/foundry.ts"],"names":[],"mappings":"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","sourcesContent":["import { execSync, spawn } from \"child_process\";\nimport { Logger } from \"./logger\";\n\n/**\n * Execute a Foundry command synchronously\n * @param command - The foundry command (e.g., \"forge test\")\n * @param args - Command arguments\n * @param options - Execution options\n */\nexport function execForgeSync(\n command: string,\n args: string[] = [],\n options: { cwd?: string; stdio?: \"inherit\" | \"pipe\" } = {}\n): string {\n const fullCommand = `${command} ${args.join(\" \")}`;\n Logger.step(`Running: ${fullCommand}`);\n\n try {\n const output = execSync(fullCommand, {\n cwd: options.cwd || process.cwd(),\n stdio: options.stdio || \"pipe\",\n encoding: \"utf-8\",\n });\n\n return output;\n } catch (error: any) {\n Logger.error(`Forge command failed: ${error.message}`);\n if (error.stdout) Logger.info(error.stdout);\n if (error.stderr) Logger.error(error.stderr);\n throw error;\n }\n}\n\n/**\n * Execute a Foundry command asynchronously\n * @param command - The foundry command (e.g., \"forge\")\n * @param args - Command arguments\n * @param options - Execution options\n */\nexport async function execForgeAsync(\n command: string,\n args: string[] = [],\n options: { cwd?: string; verbose?: boolean } = {}\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n Logger.step(`Running: ${command} ${args.join(\" \")}`);\n\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, {\n cwd: options.cwd || process.cwd(),\n shell: true,\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n child.stdout?.on(\"data\", (data) => {\n const text = data.toString();\n stdout += text;\n if (options.verbose) {\n process.stdout.write(text);\n }\n });\n\n child.stderr?.on(\"data\", (data) => {\n const text = data.toString();\n stderr += text;\n if (options.verbose) {\n process.stderr.write(text);\n }\n });\n\n child.on(\"close\", (code) => {\n resolve({ stdout, stderr, exitCode: code || 0 });\n });\n\n child.on(\"error\", (error) => {\n Logger.error(`Failed to spawn ${command}: ${error.message}`);\n reject(error);\n });\n });\n}\n\n/**\n * Run forge test with specified options\n * @param options - Test execution options\n */\nexport async function runForgeTest(options: {\n matchTest?: string;\n matchContract?: string;\n verbosity?: number;\n gasReport?: boolean;\n cwd?: string;\n env?: Record<string, string>;\n}): Promise<{ success: boolean; output: string }> {\n const args: string[] = [\"test\"];\n\n if (options.matchTest) {\n args.push(\"--match-test\", options.matchTest);\n }\n\n if (options.matchContract) {\n args.push(\"--match-contract\", options.matchContract);\n }\n\n if (options.verbosity) {\n args.push(\"-\" + \"v\".repeat(options.verbosity));\n }\n\n if (options.gasReport) {\n args.push(\"--gas-report\");\n }\n\n try {\n const result = await execForgeAsync(\"forge\", args, {\n cwd: options.cwd,\n verbose: true,\n });\n\n const success = result.exitCode === 0;\n \n if (success) {\n Logger.success(\"Forge tests passed!\");\n } else {\n Logger.error(\"Forge tests failed\");\n }\n\n return { success, output: result.stdout + result.stderr };\n } catch (error: any) {\n Logger.error(`Test execution failed: ${error.message}`);\n return { success: false, output: error.message };\n }\n}\n\n/**\n * Compile Forge contracts\n * @param options - Compilation options\n */\nexport async function compileForge(options: {\n cwd?: string;\n verbose?: boolean;\n}): Promise<{ success: boolean; output: string }> {\n Logger.step(\"Compiling Forge contracts...\");\n\n try {\n const result = await execForgeAsync(\"forge\", [\"build\"], {\n cwd: options.cwd,\n verbose: options.verbose,\n });\n\n const success = result.exitCode === 0;\n \n if (success) {\n Logger.success(\"Forge compilation successful!\");\n } else {\n Logger.error(\"Forge compilation failed\");\n }\n\n return { success, output: result.stdout + result.stderr };\n } catch (error: any) {\n Logger.error(`Compilation failed: ${error.message}`);\n return { success: false, output: error.message };\n }\n}\n\n/**\n * Check if Foundry is installed\n */\nexport function isFoundryInstalled(): boolean {\n try {\n execSync(\"forge --version\", { stdio: \"pipe\" });\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get Foundry version\n */\nexport function getFoundryVersion(): string | null {\n try {\n const output = execSync(\"forge --version\", { encoding: \"utf-8\", stdio: \"pipe\" });\n // Extract version from output like \"forge 0.2.0 (abc123 2024-01-01T00:00:00.000000000Z)\"\n const match = output.match(/forge\\s+([\\d.]+)/);\n return match ? match[1] : null;\n } catch {\n return null;\n }\n}\n"]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logger utility for colored console output
|
|
3
|
+
*/
|
|
4
|
+
export declare class Logger {
|
|
5
|
+
/**
|
|
6
|
+
* Log an info message in cyan
|
|
7
|
+
*/
|
|
8
|
+
static info(message: string): void;
|
|
9
|
+
/**
|
|
10
|
+
* Log a success message in green
|
|
11
|
+
*/
|
|
12
|
+
static success(message: string): void;
|
|
13
|
+
/**
|
|
14
|
+
* Log a warning message in yellow
|
|
15
|
+
*/
|
|
16
|
+
static warn(message: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* Log an error message in red
|
|
19
|
+
*/
|
|
20
|
+
static error(message: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Log a step message in blue
|
|
23
|
+
*/
|
|
24
|
+
static step(message: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Log a verbose/debug message in gray
|
|
27
|
+
*/
|
|
28
|
+
static debug(message: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Log a highlighted message in magenta
|
|
31
|
+
*/
|
|
32
|
+
static highlight(message: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* Create a formatted section header
|
|
35
|
+
*/
|
|
36
|
+
static section(title: string): void;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,qBAAa,MAAM;IACjB;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIlC;;OAEG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAInC;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIvC;;OAEG;IACH,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAOpC"}
|