hardhat 3.1.10 → 3.1.12
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/CHANGELOG.md +26 -0
- package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts +2 -2
- package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/artifacts/artifact-manager.js.map +1 -1
- package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/artifacts/hook-handlers/hre.js.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts +3 -5
- package/dist/src/internal/builtin-plugins/coverage/helpers.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/helpers.js +7 -19
- package/dist/src/internal/builtin-plugins/coverage/helpers.js.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.d.ts +7 -0
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js +42 -0
- package/dist/src/internal/builtin-plugins/coverage/hook-handlers/test.js.map +1 -0
- package/dist/src/internal/builtin-plugins/coverage/index.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/coverage/index.js +1 -0
- package/dist/src/internal/builtin-plugins/coverage/index.js.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.d.ts +53 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js +288 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.js.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.d.ts +0 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.js +2 -14
- package/dist/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.js.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/helpers.d.ts +8 -5
- package/dist/src/internal/builtin-plugins/gas-analytics/helpers.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/helpers.js +20 -18
- package/dist/src/internal/builtin-plugins/gas-analytics/helpers.js.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.d.ts +7 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.js +42 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.js.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/index.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/index.js +36 -2
- package/dist/src/internal/builtin-plugins/gas-analytics/index.js.map +1 -1
- package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts +45 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js +276 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.js.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts +22 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.d.ts.map +1 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js +88 -0
- package/dist/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.js.map +1 -0
- package/dist/src/internal/builtin-plugins/index.js +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js +17 -20
- package/dist/src/internal/builtin-plugins/network-manager/edr/edr-provider.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.d.ts +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.js +2 -2
- package/dist/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.d.ts +0 -2
- package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.js +0 -6
- package/dist/src/internal/builtin-plugins/network-manager/edr/type-validation.js.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts +1 -3
- package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js +0 -49
- package/dist/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts +2 -2
- package/dist/src/internal/builtin-plugins/solidity/build-results.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-results.js +2 -2
- package/dist/src/internal/builtin-plugins/solidity/build-results.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts +1 -0
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js +13 -5
- package/dist/src/internal/builtin-plugins/solidity/build-system/build-system.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.d.ts +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/dependency-graph.js +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts +2 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts +13 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js +30 -5
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts +3 -12
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/types.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/resolver/utils.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.d.ts +8 -6
- package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js +103 -27
- package/dist/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/config.js +2 -2
- package/dist/src/internal/builtin-plugins/solidity/config.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js +5 -0
- package/dist/src/internal/builtin-plugins/solidity/hook-handlers/hre.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.js +1 -1
- package/dist/src/internal/builtin-plugins/solidity/tasks/build.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts +3 -1
- package/dist/src/internal/builtin-plugins/solidity-test/config.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/config.js +9 -0
- package/dist/src/internal/builtin-plugins/solidity-test/config.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/edr-artifacts.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.js +4 -10
- package/dist/src/internal/builtin-plugins/solidity-test/helpers.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/index.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/index.js +0 -1
- package/dist/src/internal/builtin-plugins/solidity-test/index.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/runner.d.ts +2 -2
- package/dist/src/internal/builtin-plugins/solidity-test/runner.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/runner.js +3 -3
- package/dist/src/internal/builtin-plugins/solidity-test/runner.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts +5 -0
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.js +21 -27
- package/dist/src/internal/builtin-plugins/solidity-test/task-action.js.map +1 -1
- package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts +15 -10
- package/dist/src/internal/builtin-plugins/solidity-test/type-extensions.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/telemetry/task-action.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/telemetry/task-action.js +3 -2
- package/dist/src/internal/builtin-plugins/telemetry/task-action.js.map +1 -1
- package/dist/src/internal/builtin-plugins/test/task-action.d.ts.map +1 -1
- package/dist/src/internal/builtin-plugins/test/task-action.js +62 -13
- package/dist/src/internal/builtin-plugins/test/task-action.js.map +1 -1
- package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts +27 -0
- package/dist/src/internal/builtin-plugins/test/type-extensions.d.ts.map +1 -1
- package/dist/src/internal/cli/banner-manager.d.ts +26 -0
- package/dist/src/internal/cli/banner-manager.d.ts.map +1 -0
- package/dist/src/internal/cli/banner-manager.js +146 -0
- package/dist/src/internal/cli/banner-manager.js.map +1 -0
- package/dist/src/internal/cli/init/init.d.ts.map +1 -1
- package/dist/src/internal/cli/init/init.js +8 -0
- package/dist/src/internal/cli/init/init.js.map +1 -1
- package/dist/src/internal/cli/main.d.ts.map +1 -1
- package/dist/src/internal/cli/main.js +18 -1
- package/dist/src/internal/cli/main.js.map +1 -1
- package/dist/src/internal/cli/telemetry/analytics/subprocess.js +2 -0
- package/dist/src/internal/cli/telemetry/analytics/subprocess.js.map +1 -1
- package/dist/src/internal/cli/telemetry/sentry/anonymize-paths.js +1 -1
- package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts +1 -1
- package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.d.ts.map +1 -1
- package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js +47 -38
- package/dist/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.js.map +1 -1
- package/dist/src/internal/core/user-interruptions.js +1 -1
- package/dist/src/types/artifacts.d.ts +32 -3
- package/dist/src/types/artifacts.d.ts.map +1 -1
- package/dist/src/types/network.d.ts +1 -1
- package/dist/src/types/solidity/build-system.d.ts +56 -10
- package/dist/src/types/solidity/build-system.d.ts.map +1 -1
- package/dist/src/types/solidity/build-system.js +26 -2
- package/dist/src/types/solidity/build-system.js.map +1 -1
- package/dist/src/types/solidity/resolved-file.d.ts +2 -2
- package/dist/src/types/tasks.d.ts +8 -0
- package/dist/src/types/tasks.d.ts.map +1 -1
- package/dist/src/types/tasks.js.map +1 -1
- package/dist/src/types/test.d.ts +18 -0
- package/dist/src/types/test.d.ts.map +1 -1
- package/dist/src/types/utils.d.ts +16 -0
- package/dist/src/types/utils.d.ts.map +1 -1
- package/dist/src/utils/result.d.ts +33 -0
- package/dist/src/utils/result.d.ts.map +1 -0
- package/dist/src/utils/result.js +43 -0
- package/dist/src/utils/result.js.map +1 -0
- package/package.json +6 -5
- package/src/internal/builtin-plugins/artifacts/artifact-manager.ts +4 -1
- package/src/internal/builtin-plugins/artifacts/hook-handlers/hre.ts +4 -1
- package/src/internal/builtin-plugins/coverage/helpers.ts +11 -29
- package/src/internal/builtin-plugins/coverage/hook-handlers/test.ts +68 -0
- package/src/internal/builtin-plugins/coverage/index.ts +1 -0
- package/src/internal/builtin-plugins/gas-analytics/function-gas-snapshots.ts +473 -0
- package/src/internal/builtin-plugins/gas-analytics/gas-analytics-manager.ts +3 -17
- package/src/internal/builtin-plugins/gas-analytics/helpers.ts +38 -27
- package/src/internal/builtin-plugins/gas-analytics/hook-handlers/test.ts +68 -0
- package/src/internal/builtin-plugins/gas-analytics/index.ts +37 -2
- package/src/internal/builtin-plugins/gas-analytics/snapshot-cheatcodes.ts +454 -0
- package/src/internal/builtin-plugins/gas-analytics/tasks/solidity-test/task-action.ts +172 -0
- package/src/internal/builtin-plugins/index.ts +1 -1
- package/src/internal/builtin-plugins/network-manager/edr/edr-provider.ts +21 -28
- package/src/internal/builtin-plugins/network-manager/edr/stack-traces/stack-trace-generation-errors.ts +5 -2
- package/src/internal/builtin-plugins/network-manager/edr/type-validation.ts +0 -13
- package/src/internal/builtin-plugins/network-manager/edr/utils/convert-to-edr.ts +0 -64
- package/src/internal/builtin-plugins/solidity/build-results.ts +3 -1
- package/src/internal/builtin-plugins/solidity/build-system/build-system.ts +15 -5
- package/src/internal/builtin-plugins/solidity/build-system/compiler/compiler.ts +1 -1
- package/src/internal/builtin-plugins/solidity/build-system/dependency-graph.ts +1 -1
- package/src/internal/builtin-plugins/solidity/build-system/resolver/dependency-resolver.ts +1 -1
- package/src/internal/builtin-plugins/solidity/build-system/resolver/remapped-npm-packages-graph.ts +36 -6
- package/src/internal/builtin-plugins/solidity/build-system/resolver/types.ts +3 -9
- package/src/internal/builtin-plugins/solidity/build-system/resolver/utils.ts +1 -1
- package/src/internal/builtin-plugins/solidity/build-system/solc-config-selection.ts +125 -28
- package/src/internal/builtin-plugins/solidity/config.ts +2 -2
- package/src/internal/builtin-plugins/solidity/hook-handlers/hre.ts +8 -0
- package/src/internal/builtin-plugins/solidity/tasks/build.ts +1 -1
- package/src/internal/builtin-plugins/solidity-test/config.ts +15 -0
- package/src/internal/builtin-plugins/solidity-test/edr-artifacts.ts +2 -2
- package/src/internal/builtin-plugins/solidity-test/helpers.ts +6 -14
- package/src/internal/builtin-plugins/solidity-test/index.ts +0 -1
- package/src/internal/builtin-plugins/solidity-test/runner.ts +3 -3
- package/src/internal/builtin-plugins/solidity-test/task-action.ts +47 -40
- package/src/internal/builtin-plugins/solidity-test/type-extensions.ts +17 -10
- package/src/internal/builtin-plugins/telemetry/task-action.ts +4 -2
- package/src/internal/builtin-plugins/test/task-action.ts +88 -24
- package/src/internal/builtin-plugins/test/type-extensions.ts +42 -0
- package/src/internal/cli/banner-manager.ts +234 -0
- package/src/internal/cli/init/init.ts +8 -0
- package/src/internal/cli/main.ts +19 -1
- package/src/internal/cli/telemetry/analytics/subprocess.ts +2 -0
- package/src/internal/cli/telemetry/sentry/anonymize-paths.ts +1 -1
- package/src/internal/cli/telemetry/sentry/vendor/integrations/contextlines.ts +98 -50
- package/src/internal/core/user-interruptions.ts +1 -1
- package/src/types/artifacts.ts +40 -3
- package/src/types/hre.ts +1 -1
- package/src/types/network.ts +1 -1
- package/src/types/solidity/build-system.ts +75 -14
- package/src/types/solidity/resolved-file.ts +2 -2
- package/src/types/tasks.ts +10 -0
- package/src/types/test.ts +20 -0
- package/src/types/utils.ts +14 -0
- package/src/utils/result.ts +57 -0
- package/templates/hardhat-3/01-node-test-runner-viem/package.json +9 -9
- package/templates/hardhat-3/02-mocha-ethers/package.json +10 -10
- package/templates/hardhat-3/03-minimal/package.json +1 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.d.ts +0 -19
- package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.d.ts.map +0 -1
- package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.js +0 -2
- package/dist/src/internal/builtin-plugins/network-manager/edr/types/output.js.map +0 -1
- package/src/internal/builtin-plugins/network-manager/edr/types/output.ts +0 -19
|
@@ -4,13 +4,21 @@ import type {
|
|
|
4
4
|
Task,
|
|
5
5
|
TaskArguments,
|
|
6
6
|
} from "../../../types/tasks.js";
|
|
7
|
+
import type { TestSummary } from "../../../types/test.js";
|
|
8
|
+
import type { Result } from "../../../types/utils.js";
|
|
7
9
|
|
|
8
10
|
import {
|
|
9
11
|
assertHardhatInvariant,
|
|
10
12
|
HardhatError,
|
|
11
13
|
} from "@nomicfoundation/hardhat-errors";
|
|
14
|
+
import { isObject } from "@nomicfoundation/hardhat-utils/lang";
|
|
12
15
|
import chalk, { type ChalkInstance } from "chalk";
|
|
13
16
|
|
|
17
|
+
import {
|
|
18
|
+
errorResult,
|
|
19
|
+
isResult,
|
|
20
|
+
successfulResult,
|
|
21
|
+
} from "../../../utils/result.js";
|
|
14
22
|
import { HardhatRuntimeEnvironmentImplementation } from "../../core/hre.js";
|
|
15
23
|
|
|
16
24
|
interface TestActionArguments {
|
|
@@ -21,10 +29,33 @@ interface TestActionArguments {
|
|
|
21
29
|
verbosity: number;
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
// Old plugins may only return { failed, passed } without skipped/todo,
|
|
33
|
+
// so we accept a partial shape and fill defaults in the coordinator.
|
|
34
|
+
interface PartialTestSummary extends Omit<TestSummary, "skipped" | "todo"> {
|
|
35
|
+
skipped?: number;
|
|
36
|
+
todo?: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isTestSummary(value: unknown): value is PartialTestSummary {
|
|
40
|
+
return (
|
|
41
|
+
isObject(value) &&
|
|
42
|
+
typeof value.failed === "number" &&
|
|
43
|
+
typeof value.passed === "number" &&
|
|
44
|
+
(value.skipped === undefined || typeof value.skipped === "number") &&
|
|
45
|
+
(value.todo === undefined || typeof value.todo === "number")
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function isTestRunResult(
|
|
50
|
+
value: unknown,
|
|
51
|
+
): value is { summary: PartialTestSummary } {
|
|
52
|
+
return isObject(value) && "summary" in value && isTestSummary(value.summary);
|
|
53
|
+
}
|
|
54
|
+
|
|
24
55
|
const runAllTests: NewTaskActionFunction<TestActionArguments> = async (
|
|
25
|
-
{ testFiles, chainType, grep, noCompile, verbosity },
|
|
56
|
+
{ testFiles, chainType, grep, noCompile, verbosity, ...otherArgs },
|
|
26
57
|
hre,
|
|
27
|
-
) => {
|
|
58
|
+
): Promise<Result<void, void>> => {
|
|
28
59
|
// If this code is executed, it means the user has not specified a test runner.
|
|
29
60
|
// If file paths are specified, we need to determine which test runner applies to each test file.
|
|
30
61
|
// If no file paths are specified, each test runner will execute all tests located under its configured path in the Hardhat configuration.
|
|
@@ -49,18 +80,10 @@ const runAllTests: NewTaskActionFunction<TestActionArguments> = async (
|
|
|
49
80
|
hre._coverage.disableReport();
|
|
50
81
|
}
|
|
51
82
|
|
|
52
|
-
const testSummaries: Record<
|
|
53
|
-
string,
|
|
54
|
-
{
|
|
55
|
-
failed?: number;
|
|
56
|
-
passed?: number;
|
|
57
|
-
skipped?: number;
|
|
58
|
-
todo?: number;
|
|
59
|
-
failureOutput?: string;
|
|
60
|
-
}
|
|
61
|
-
> = {};
|
|
83
|
+
const testSummaries: Record<string, TestSummary> = {};
|
|
62
84
|
|
|
63
85
|
let failureIndex = 1;
|
|
86
|
+
let hasFailures = false;
|
|
64
87
|
for (const subtask of thisTask.subtasks.values()) {
|
|
65
88
|
const files = getTestFilesForSubtask(subtask, testFiles, subtasksToFiles);
|
|
66
89
|
|
|
@@ -84,18 +107,57 @@ const runAllTests: NewTaskActionFunction<TestActionArguments> = async (
|
|
|
84
107
|
args.verbosity = verbosity;
|
|
85
108
|
}
|
|
86
109
|
|
|
87
|
-
const
|
|
110
|
+
for (const [key, value] of Object.entries(otherArgs)) {
|
|
111
|
+
if (subtask.options.has(key)) {
|
|
112
|
+
args[key] = value;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
88
115
|
|
|
89
116
|
if (subtask.options.has("testSummaryIndex")) {
|
|
90
117
|
args.testSummaryIndex = failureIndex;
|
|
118
|
+
}
|
|
91
119
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
120
|
+
const subtaskResult = await subtask.run(args);
|
|
121
|
+
|
|
122
|
+
let summary: PartialTestSummary | undefined;
|
|
123
|
+
let subtaskFailed = false;
|
|
124
|
+
|
|
125
|
+
if (isResult(subtaskResult, isTestRunResult, isTestRunResult)) {
|
|
126
|
+
const testRunResult = subtaskResult.success
|
|
127
|
+
? subtaskResult.value
|
|
128
|
+
: subtaskResult.error;
|
|
129
|
+
summary = testRunResult.summary;
|
|
130
|
+
subtaskFailed = !subtaskResult.success;
|
|
131
|
+
} else if (isResult(subtaskResult, isTestSummary, isTestSummary)) {
|
|
132
|
+
// Support plugins that return Result<TestSummary, TestSummary>
|
|
133
|
+
summary = subtaskResult.success
|
|
134
|
+
? subtaskResult.value
|
|
135
|
+
: subtaskResult.error;
|
|
136
|
+
subtaskFailed = !subtaskResult.success;
|
|
137
|
+
} else if (isTestSummary(subtaskResult)) {
|
|
138
|
+
// Support plugins that return TestSummary directly
|
|
139
|
+
summary = subtaskResult;
|
|
140
|
+
subtaskFailed = process.exitCode !== undefined && process.exitCode !== 0;
|
|
97
141
|
} else {
|
|
98
|
-
|
|
142
|
+
// Fallback for plugins that don't return a summary at all
|
|
143
|
+
subtaskFailed = process.exitCode !== undefined && process.exitCode !== 0;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
if (summary !== undefined) {
|
|
147
|
+
const summaryId = subtask.id[subtask.id.length - 1];
|
|
148
|
+
testSummaries[summaryId] = {
|
|
149
|
+
skipped: 0,
|
|
150
|
+
todo: 0,
|
|
151
|
+
...summary,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
if (subtask.options.has("testSummaryIndex")) {
|
|
155
|
+
failureIndex += summary.failed;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (subtaskFailed) {
|
|
160
|
+
hasFailures = true;
|
|
99
161
|
}
|
|
100
162
|
}
|
|
101
163
|
|
|
@@ -106,19 +168,19 @@ const runAllTests: NewTaskActionFunction<TestActionArguments> = async (
|
|
|
106
168
|
const outputLines: string[] = [];
|
|
107
169
|
|
|
108
170
|
for (const [subtaskName, results] of Object.entries(testSummaries)) {
|
|
109
|
-
if (results.passed
|
|
171
|
+
if (results.passed > 0) {
|
|
110
172
|
passed.push([subtaskName, results.passed]);
|
|
111
173
|
}
|
|
112
174
|
|
|
113
|
-
if (results.failed
|
|
175
|
+
if (results.failed > 0) {
|
|
114
176
|
failed.push([subtaskName, results.failed]);
|
|
115
177
|
}
|
|
116
178
|
|
|
117
|
-
if (results.skipped
|
|
179
|
+
if (results.skipped > 0) {
|
|
118
180
|
skipped.push([subtaskName, results.skipped]);
|
|
119
181
|
}
|
|
120
182
|
|
|
121
|
-
if (results.todo
|
|
183
|
+
if (results.todo > 0) {
|
|
122
184
|
todo.push([subtaskName, results.todo]);
|
|
123
185
|
}
|
|
124
186
|
|
|
@@ -176,9 +238,11 @@ const runAllTests: NewTaskActionFunction<TestActionArguments> = async (
|
|
|
176
238
|
console.log();
|
|
177
239
|
}
|
|
178
240
|
|
|
179
|
-
if (
|
|
241
|
+
if (hasFailures) {
|
|
180
242
|
console.error("Test run failed");
|
|
181
243
|
}
|
|
244
|
+
|
|
245
|
+
return hasFailures ? errorResult() : successfulResult();
|
|
182
246
|
};
|
|
183
247
|
|
|
184
248
|
function logSummaryLine(
|
|
@@ -39,5 +39,47 @@ declare module "../../../types/hooks.js" {
|
|
|
39
39
|
filePath: string,
|
|
40
40
|
) => Promise<string | undefined>,
|
|
41
41
|
) => Promise<string | undefined>;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* This hook is triggered at the start of a test run, before tests execute.
|
|
45
|
+
*
|
|
46
|
+
* @param context The hook context.
|
|
47
|
+
* @param id A string identifier for the test runner (e.g., "solidity", "nodejs", "mocha").
|
|
48
|
+
* @param next A function to call the next handler for this hook, or the
|
|
49
|
+
* default implementation if no more handlers exist.
|
|
50
|
+
*/
|
|
51
|
+
onTestRunStart: (
|
|
52
|
+
context: HookContext,
|
|
53
|
+
id: string,
|
|
54
|
+
next: (nextContext: HookContext, id: string) => Promise<void>,
|
|
55
|
+
) => Promise<void>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* This hook is triggered when a test worker has finished executing.
|
|
59
|
+
*
|
|
60
|
+
* @param context The hook context.
|
|
61
|
+
* @param id A string identifier for the test runner (e.g., "solidity", "nodejs", "mocha").
|
|
62
|
+
* @param next A function to call the next handler for this hook, or the
|
|
63
|
+
* default implementation if no more handlers exist.
|
|
64
|
+
*/
|
|
65
|
+
onTestWorkerDone: (
|
|
66
|
+
context: HookContext,
|
|
67
|
+
id: string,
|
|
68
|
+
next: (nextContext: HookContext, id: string) => Promise<void>,
|
|
69
|
+
) => Promise<void>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* This hook is triggered at the end of a test run, after all tests have completed.
|
|
73
|
+
*
|
|
74
|
+
* @param context The hook context.
|
|
75
|
+
* @param id A string identifier for the test runner (e.g., "solidity", "nodejs", "mocha").
|
|
76
|
+
* @param next A function to call the next handler for this hook, or the
|
|
77
|
+
* default implementation if no more handlers exist.
|
|
78
|
+
*/
|
|
79
|
+
onTestRunDone: (
|
|
80
|
+
context: HookContext,
|
|
81
|
+
id: string,
|
|
82
|
+
next: (nextContext: HookContext, id: string) => Promise<void>,
|
|
83
|
+
) => Promise<void>;
|
|
42
84
|
}
|
|
43
85
|
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import type { Dispatcher } from "@nomicfoundation/hardhat-utils/request";
|
|
2
|
+
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
readJsonFile,
|
|
7
|
+
writeJsonFile,
|
|
8
|
+
FileNotFoundError,
|
|
9
|
+
} from "@nomicfoundation/hardhat-utils/fs";
|
|
10
|
+
import { getCacheDir } from "@nomicfoundation/hardhat-utils/global-dir";
|
|
11
|
+
import { isObject } from "@nomicfoundation/hardhat-utils/lang";
|
|
12
|
+
import { getRequest } from "@nomicfoundation/hardhat-utils/request";
|
|
13
|
+
import debug from "debug";
|
|
14
|
+
|
|
15
|
+
const log = debug("hardhat:util:banner-manager");
|
|
16
|
+
|
|
17
|
+
interface BannerConfig {
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
formattedMessages: string[];
|
|
20
|
+
minSecondsBetweenDisplays: number;
|
|
21
|
+
minSecondsBetweenRequests: number;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const BANNER_CONFIG_URL =
|
|
25
|
+
"https://raw.githubusercontent.com/NomicFoundation/hardhat/refs/heads/main/banner-config-v3.json";
|
|
26
|
+
|
|
27
|
+
export const BANNER_CACHE_FILE_NAME = "banner-config-v3.json";
|
|
28
|
+
|
|
29
|
+
export class BannerManager {
|
|
30
|
+
static #instance: BannerManager | undefined;
|
|
31
|
+
|
|
32
|
+
#bannerConfig: BannerConfig | undefined;
|
|
33
|
+
#lastDisplayTime: number;
|
|
34
|
+
#lastRequestTime: number;
|
|
35
|
+
readonly #dispatcher: Dispatcher | undefined;
|
|
36
|
+
readonly #print: (message: string) => void;
|
|
37
|
+
|
|
38
|
+
private constructor(
|
|
39
|
+
bannerConfig: BannerConfig | undefined,
|
|
40
|
+
lastDisplayTime: number,
|
|
41
|
+
lastRequestTime: number,
|
|
42
|
+
dispatcher: Dispatcher | undefined,
|
|
43
|
+
print: (message: string) => void,
|
|
44
|
+
) {
|
|
45
|
+
this.#bannerConfig = bannerConfig;
|
|
46
|
+
this.#lastDisplayTime = lastDisplayTime;
|
|
47
|
+
this.#lastRequestTime = lastRequestTime;
|
|
48
|
+
this.#dispatcher = dispatcher;
|
|
49
|
+
this.#print = print;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns a global instance of BannerManager.
|
|
54
|
+
*
|
|
55
|
+
* @param options Options used for testing purposes. Only used in the first
|
|
56
|
+
* invocation of this function, or after calling `resetInstance`.
|
|
57
|
+
* @returns The current global instance of BannerManager.
|
|
58
|
+
*/
|
|
59
|
+
public static async getInstance(options?: {
|
|
60
|
+
testDispatcher?: Dispatcher;
|
|
61
|
+
print?: (message: string) => void;
|
|
62
|
+
}): Promise<BannerManager> {
|
|
63
|
+
if (this.#instance === undefined) {
|
|
64
|
+
log("Initializing BannerManager");
|
|
65
|
+
const { bannerConfig, lastDisplayTime, lastRequestTime } =
|
|
66
|
+
await readCache();
|
|
67
|
+
this.#instance = new BannerManager(
|
|
68
|
+
bannerConfig,
|
|
69
|
+
lastDisplayTime,
|
|
70
|
+
lastRequestTime,
|
|
71
|
+
options?.testDispatcher,
|
|
72
|
+
options?.print ?? console.log,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return this.#instance;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public static resetInstance(): void {
|
|
80
|
+
this.#instance = undefined;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Displays a banner message, if any.
|
|
85
|
+
*
|
|
86
|
+
* @param timeout The timeout in milliseconds to wait for the banner display.
|
|
87
|
+
*/
|
|
88
|
+
public async showBanner(timeout?: number): Promise<void> {
|
|
89
|
+
await this.#requestBannerConfig(timeout);
|
|
90
|
+
|
|
91
|
+
if (
|
|
92
|
+
this.#bannerConfig === undefined ||
|
|
93
|
+
!this.#bannerConfig.enabled ||
|
|
94
|
+
this.#bannerConfig.formattedMessages.length === 0
|
|
95
|
+
) {
|
|
96
|
+
log("Banner is disabled or no messages available.");
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const { formattedMessages, minSecondsBetweenDisplays } = this.#bannerConfig;
|
|
101
|
+
|
|
102
|
+
const timeSinceLastDisplay = Date.now() - this.#lastDisplayTime;
|
|
103
|
+
if (timeSinceLastDisplay < minSecondsBetweenDisplays * 1000) {
|
|
104
|
+
log(
|
|
105
|
+
`Skipping banner display. Time since last display: ${timeSinceLastDisplay}ms`,
|
|
106
|
+
);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// select a random message from the formattedMessages array
|
|
111
|
+
const randomIndex = Math.floor(Math.random() * formattedMessages.length);
|
|
112
|
+
const message = formattedMessages[randomIndex];
|
|
113
|
+
|
|
114
|
+
this.#print(message);
|
|
115
|
+
this.#lastDisplayTime = Date.now();
|
|
116
|
+
await writeCache({
|
|
117
|
+
bannerConfig: this.#bannerConfig,
|
|
118
|
+
lastDisplayTime: this.#lastDisplayTime,
|
|
119
|
+
lastRequestTime: this.#lastRequestTime,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async #requestBannerConfig(timeout?: number): Promise<void> {
|
|
124
|
+
if (this.#bannerConfig !== undefined) {
|
|
125
|
+
const timeSinceLastRequest = Date.now() - this.#lastRequestTime;
|
|
126
|
+
if (
|
|
127
|
+
timeSinceLastRequest <
|
|
128
|
+
this.#bannerConfig.minSecondsBetweenRequests * 1000
|
|
129
|
+
) {
|
|
130
|
+
log(
|
|
131
|
+
`Skipping banner config request. Time since last request: ${timeSinceLastRequest}ms`,
|
|
132
|
+
);
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
const response = await getRequest(
|
|
139
|
+
BANNER_CONFIG_URL,
|
|
140
|
+
undefined,
|
|
141
|
+
this.#dispatcher ?? { timeout },
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
const bannerConfig: unknown = await response.body.json();
|
|
145
|
+
|
|
146
|
+
if (!this.#isBannerConfig(bannerConfig)) {
|
|
147
|
+
log(`Invalid banner config received:`, bannerConfig);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
this.#bannerConfig = bannerConfig;
|
|
152
|
+
this.#lastRequestTime = Date.now();
|
|
153
|
+
|
|
154
|
+
await writeCache({
|
|
155
|
+
bannerConfig: this.#bannerConfig,
|
|
156
|
+
lastDisplayTime: this.#lastDisplayTime,
|
|
157
|
+
lastRequestTime: this.#lastRequestTime,
|
|
158
|
+
});
|
|
159
|
+
} catch (error) {
|
|
160
|
+
log(
|
|
161
|
+
`Error requesting banner config: ${
|
|
162
|
+
error instanceof Error ? error.message : JSON.stringify(error)
|
|
163
|
+
}`,
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
#isBannerConfig(value: unknown): value is BannerConfig {
|
|
169
|
+
if (!isObject(value)) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return (
|
|
174
|
+
Object.getOwnPropertyNames(value).length === 4 &&
|
|
175
|
+
"enabled" in value &&
|
|
176
|
+
typeof value.enabled === "boolean" &&
|
|
177
|
+
"formattedMessages" in value &&
|
|
178
|
+
Array.isArray(value.formattedMessages) &&
|
|
179
|
+
value.formattedMessages.every(
|
|
180
|
+
(message: unknown) => typeof message === "string",
|
|
181
|
+
) &&
|
|
182
|
+
"minSecondsBetweenDisplays" in value &&
|
|
183
|
+
typeof value.minSecondsBetweenDisplays === "number" &&
|
|
184
|
+
"minSecondsBetweenRequests" in value &&
|
|
185
|
+
typeof value.minSecondsBetweenRequests === "number"
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
interface BannerCache {
|
|
191
|
+
bannerConfig: BannerConfig | undefined;
|
|
192
|
+
lastDisplayTime: number;
|
|
193
|
+
lastRequestTime: number;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
async function readCache(): Promise<BannerCache> {
|
|
197
|
+
const cacheDir = await getCacheDir();
|
|
198
|
+
const bannerCacheFilePath = path.join(cacheDir, BANNER_CACHE_FILE_NAME);
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
return await readJsonFile<BannerCache>(bannerCacheFilePath);
|
|
202
|
+
} catch (error) {
|
|
203
|
+
if (error instanceof FileNotFoundError) {
|
|
204
|
+
log("No banner cache file found, using defaults");
|
|
205
|
+
} else {
|
|
206
|
+
log(
|
|
207
|
+
`Error reading cache file: ${
|
|
208
|
+
error instanceof Error ? error.message : JSON.stringify(error)
|
|
209
|
+
}`,
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
bannerConfig: undefined,
|
|
215
|
+
lastDisplayTime: 0,
|
|
216
|
+
lastRequestTime: 0,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
async function writeCache(cache: BannerCache): Promise<void> {
|
|
222
|
+
const cacheDir = await getCacheDir();
|
|
223
|
+
const bannerCacheFilePath = path.join(cacheDir, BANNER_CACHE_FILE_NAME);
|
|
224
|
+
|
|
225
|
+
try {
|
|
226
|
+
await writeJsonFile(bannerCacheFilePath, cache);
|
|
227
|
+
} catch (error) {
|
|
228
|
+
log(
|
|
229
|
+
`Error writing cache file: ${
|
|
230
|
+
error instanceof Error ? error.message : JSON.stringify(error)
|
|
231
|
+
}`,
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -131,6 +131,14 @@ export async function initHardhat(options?: InitHardhatOptions): Promise<void> {
|
|
|
131
131
|
]);
|
|
132
132
|
|
|
133
133
|
showStarOnGitHubMessage();
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const { BannerManager } = await import("../banner-manager.js");
|
|
137
|
+
const bannerManager = await BannerManager.getInstance();
|
|
138
|
+
await bannerManager.showBanner();
|
|
139
|
+
} catch (bannerError) {
|
|
140
|
+
log("Error showing banner", bannerError);
|
|
141
|
+
}
|
|
134
142
|
} catch (e) {
|
|
135
143
|
if (e === "") {
|
|
136
144
|
// If the user cancels any prompt, we quit silently
|
package/src/internal/cli/main.ts
CHANGED
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
type OptionDefinition,
|
|
29
29
|
type PositionalArgumentDefinition,
|
|
30
30
|
} from "../../types/arguments.js";
|
|
31
|
+
import { isResult } from "../../utils/result.js";
|
|
31
32
|
import { BUILTIN_GLOBAL_OPTIONS_DEFINITIONS } from "../builtin-global-options.js";
|
|
32
33
|
import { builtinPlugins } from "../builtin-plugins/index.js";
|
|
33
34
|
import {
|
|
@@ -217,7 +218,24 @@ export async function main(
|
|
|
217
218
|
|
|
218
219
|
log(`Running task "${task.id.join(" ")}"`);
|
|
219
220
|
|
|
220
|
-
await Promise.all([
|
|
221
|
+
const [taskResult] = await Promise.all([
|
|
222
|
+
task.run(taskArguments),
|
|
223
|
+
sendTaskAnalytics(task.id),
|
|
224
|
+
]);
|
|
225
|
+
|
|
226
|
+
if (isResult(taskResult) && !taskResult.success) {
|
|
227
|
+
process.exitCode = 1;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (!isCi() && process.stdout.isTTY === true) {
|
|
231
|
+
try {
|
|
232
|
+
const { BannerManager } = await import("./banner-manager.js");
|
|
233
|
+
const bannerManager = await BannerManager.getInstance();
|
|
234
|
+
await bannerManager.showBanner(200);
|
|
235
|
+
} catch (bannerError) {
|
|
236
|
+
log("Error showing banner", bannerError);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
221
239
|
} catch (error) {
|
|
222
240
|
ensureError(error);
|
|
223
241
|
printErrorMessages(error, builtinGlobalOptions?.showStackTraces);
|
|
@@ -5,7 +5,9 @@ import { postJsonRequest } from "@nomicfoundation/hardhat-utils/request";
|
|
|
5
5
|
|
|
6
6
|
// These keys are expected to be public
|
|
7
7
|
const ANALYTICS_URL = "https://www.google-analytics.com/mp/collect";
|
|
8
|
+
/* cspell:disable-next-line */
|
|
8
9
|
// const API_SECRET = "iXzTRik5RhahYpgiatSv1w"; // DEV
|
|
10
|
+
/* cspell:disable-next-line */
|
|
9
11
|
// const MEASUREMENT_ID = "G-ZFZWHGZ64H"; // DEV
|
|
10
12
|
const API_SECRET = "fQ5joCsDRTOp55wX8a2cVw"; // PROD
|
|
11
13
|
const MEASUREMENT_ID = "G-8LQ007N2QJ"; // PROD
|
|
@@ -107,7 +107,7 @@ function anonymizeSinglePath(path: string): string {
|
|
|
107
107
|
return normalizedPath;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
// We first get the index of the first /node_modules to
|
|
110
|
+
// We first get the index of the first /node_modules to disambiguate some
|
|
111
111
|
// special cases below
|
|
112
112
|
const nodeModulesIndex = normalizedPath.indexOf("/node_modules");
|
|
113
113
|
|