Skip to content

Commit 4ae9d39

Browse files
committed
add builtin task to run hardhat scripts
1 parent dc48f55 commit 4ae9d39

File tree

11 files changed

+239
-1
lines changed

11 files changed

+239
-1
lines changed

v-next/hardhat-errors/src/descriptors.ts

+16
Original file line numberDiff line numberDiff line change
@@ -640,6 +640,22 @@ The first supported version is {firstSupportedVersion}`,
640640
Please use a newer, supported version.`,
641641
shouldBeReported: true,
642642
},
643+
RUN_FILE_NOT_FOUND: {
644+
number: 603,
645+
messageTemplate: `Script {script} doesn't exist`,
646+
websiteTitle: "Script doesn't exist",
647+
websiteDescription: `Tried to use \`hardhat run\` to execute a nonexistent script.
648+
649+
Please double check your script's path.`,
650+
},
651+
RUN_SCRIPT_ERROR: {
652+
number: 604,
653+
messageTemplate: `Error running script {script}: {error}`,
654+
websiteTitle: "Error running script",
655+
websiteDescription: `Running a script resulted in an error.
656+
657+
Please check Hardhat's output for more details.`,
658+
},
643659
},
644660
ARTIFACTS: {
645661
NOT_FOUND: {
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import type { HardhatPlugin } from "@nomicfoundation/hardhat-core/types/plugins";
22

33
import hardhatFoo from "./hardhat-foo/index.js";
4+
import run from "./run/index.js";
45

5-
export const builtinPlugins: HardhatPlugin[] = [hardhatFoo];
6+
export const builtinPlugins: HardhatPlugin[] = [hardhatFoo, run];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { HardhatPlugin } from "@nomicfoundation/hardhat-core/types/plugins";
2+
3+
import { ParameterType, task } from "@nomicfoundation/hardhat-core/config";
4+
5+
import { runScriptWithHardhat } from "./runScriptWithHardhat.js";
6+
7+
export default {
8+
id: "run",
9+
tasks: [
10+
task("run", "Runs a user-defined script after compiling the project")
11+
.addPositionalParameter({
12+
name: "script",
13+
description: "A js or ts file to be run within hardhat's environment",
14+
type: ParameterType.STRING,
15+
})
16+
.addFlag({
17+
name: "noCompile",
18+
description: "Don't compile before running this task",
19+
})
20+
.setAction(runScriptWithHardhat)
21+
.build(),
22+
],
23+
} satisfies HardhatPlugin;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import type { NewTaskActionFunction } from "@nomicfoundation/hardhat-core/types/tasks";
2+
3+
import path from "node:path";
4+
5+
import {
6+
HardhatError,
7+
assertHardhatInvariant,
8+
} from "@nomicfoundation/hardhat-errors";
9+
import { exists } from "@nomicfoundation/hardhat-utils/fs";
10+
11+
export const runScriptWithHardhat: NewTaskActionFunction = async (
12+
{ script, noCompile },
13+
_hre,
14+
) => {
15+
assertHardhatInvariant(
16+
typeof script === "string",
17+
"Expected script to be a string",
18+
);
19+
20+
assertHardhatInvariant(
21+
typeof noCompile === "boolean",
22+
"Expected noCompile to be a boolean",
23+
);
24+
25+
const scriptPath = path.resolve(process.cwd(), script);
26+
27+
if (!(await exists(scriptPath))) {
28+
throw new HardhatError(
29+
HardhatError.ERRORS.BUILTIN_TASKS.RUN_FILE_NOT_FOUND,
30+
{ script },
31+
);
32+
}
33+
34+
if (!noCompile) {
35+
// todo: run compile task
36+
}
37+
38+
try {
39+
await import(scriptPath);
40+
} catch (error) {
41+
if (error instanceof Error) {
42+
throw new HardhatError(
43+
HardhatError.ERRORS.BUILTIN_TASKS.RUN_SCRIPT_ERROR,
44+
{
45+
script,
46+
error: error.message,
47+
},
48+
error,
49+
);
50+
}
51+
52+
throw error;
53+
}
54+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { task } from "@nomicfoundation/hardhat/config";
2+
3+
export default {
4+
tasks: [
5+
task("test", "Prints a test")
6+
.setAction(async () => {
7+
console.log("test!");
8+
})
9+
.build(),
10+
],
11+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import hre from "@nomicfoundation/hardhat";
2+
3+
if (!hre.tasks.rootTasks.has("test")) {
4+
throw new Error("test task not found");
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
throw new Error("broken script");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { task } from "@nomicfoundation/hardhat/config";
2+
3+
export default {
4+
tasks: [
5+
task("test", "Prints a test")
6+
.setAction(async () => {
7+
console.log("test!");
8+
})
9+
.build(),
10+
],
11+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import hre from "@nomicfoundation/hardhat";
2+
3+
if (!hre.tasks.rootTasks.has("test")) {
4+
throw new Error("test task not found");
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
throw new Error("broken script");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import type { HardhatRuntimeEnvironment } from "@nomicfoundation/hardhat-core/types/hre";
2+
3+
import assert from "node:assert/strict";
4+
import { before, describe, it } from "node:test";
5+
6+
import { createHardhatRuntimeEnvironment } from "@nomicfoundation/hardhat-core";
7+
import { HardhatError } from "@nomicfoundation/hardhat-errors";
8+
9+
import { runScriptWithHardhat } from "../../../../src/internal/builtin-plugins/run/runScriptWithHardhat.js";
10+
import { useFixtureProject } from "../../../helpers/project.js";
11+
12+
describe("runScriptWithHardhat", function () {
13+
let hre: HardhatRuntimeEnvironment;
14+
15+
before(async function () {
16+
hre = await createHardhatRuntimeEnvironment({});
17+
});
18+
19+
it("should throw if script is not a string", async function () {
20+
await assert.rejects(async () => {
21+
await runScriptWithHardhat({ script: 123, noCompile: false }, hre);
22+
}, /An internal invariant was violated: Expected script to be a string/);
23+
});
24+
25+
it("should throw if noCompile is not a boolean", async function () {
26+
await assert.rejects(async () => {
27+
await runScriptWithHardhat({ script: "script.js", noCompile: 123 }, hre);
28+
}, /An internal invariant was violated: Expected noCompile to be a boolean/);
29+
});
30+
31+
describe("javascript", function () {
32+
useFixtureProject("run-js-script");
33+
34+
it("should throw if script does not exist", async function () {
35+
await assert.rejects(
36+
async () => {
37+
await runScriptWithHardhat(
38+
{ script: "./scripts/non-existent.js", noCompile: false },
39+
hre,
40+
);
41+
},
42+
new HardhatError(HardhatError.ERRORS.BUILTIN_TASKS.RUN_FILE_NOT_FOUND, {
43+
script: "./scripts/non-existent.js",
44+
}),
45+
);
46+
});
47+
48+
it("should run a script successfully", async function () {
49+
await runScriptWithHardhat(
50+
{ script: "./scripts/success.js", noCompile: false },
51+
hre,
52+
);
53+
});
54+
55+
it("should throw if the script throws", async function () {
56+
await assert.rejects(
57+
async () => {
58+
await runScriptWithHardhat(
59+
{ script: "./scripts/throws.js", noCompile: false },
60+
hre,
61+
);
62+
},
63+
new HardhatError(HardhatError.ERRORS.BUILTIN_TASKS.RUN_SCRIPT_ERROR, {
64+
script: "./scripts/throws.js",
65+
error: "broken script",
66+
}),
67+
);
68+
});
69+
});
70+
71+
describe("typescript", function () {
72+
useFixtureProject("run-ts-script");
73+
74+
it("should throw if script does not exist", async function () {
75+
await assert.rejects(
76+
async () => {
77+
await runScriptWithHardhat(
78+
{ script: "./scripts/non-existent.ts", noCompile: false },
79+
hre,
80+
);
81+
},
82+
new HardhatError(HardhatError.ERRORS.BUILTIN_TASKS.RUN_FILE_NOT_FOUND, {
83+
script: "./scripts/non-existent.ts",
84+
}),
85+
);
86+
});
87+
88+
it("should run a script successfully", async function () {
89+
await runScriptWithHardhat(
90+
{ script: "./scripts/success.ts", noCompile: false },
91+
hre,
92+
);
93+
});
94+
95+
it("should throw if the script throws", async function () {
96+
await assert.rejects(
97+
async () => {
98+
await runScriptWithHardhat(
99+
{ script: "./scripts/throws.ts", noCompile: false },
100+
hre,
101+
);
102+
},
103+
new HardhatError(HardhatError.ERRORS.BUILTIN_TASKS.RUN_SCRIPT_ERROR, {
104+
script: "./scripts/throws.ts",
105+
error: "broken script",
106+
}),
107+
);
108+
});
109+
});
110+
});

0 commit comments

Comments
 (0)