Skip to content

Commit 9e9fada

Browse files
authored
Merge pull request #5540 from NomicFoundation/clean-task
Clean task
2 parents 597e760 + 1af5952 commit 9e9fada

File tree

12 files changed

+221
-5
lines changed

12 files changed

+221
-5
lines changed

v-next/core/src/global-dir.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ensureDir } from "@ignored/hardhat-vnext-utils/fs";
22

33
/**
4-
* Returns the path to the hardhat configuration directory.
4+
* Returns the path to the hardhat configuration directory.
55
*
66
* @returns The path to the hardhat configuration directory.
77
*/
@@ -11,6 +11,17 @@ export async function getConfigDir(): Promise<string> {
1111
return config;
1212
}
1313

14+
/**
15+
* Returns the path to the hardhat cache directory.
16+
*
17+
* @returns The path to the hardhat cache directory.
18+
*/
19+
export async function getCacheDir(): Promise<string> {
20+
const { cache } = await generatePaths();
21+
await ensureDir(cache);
22+
return cache;
23+
}
24+
1425
async function generatePaths(packageName = "hardhat") {
1526
const { default: envPaths } = await import("env-paths");
1627
return envPaths(packageName);

v-next/core/src/internal/hre.ts

+2
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,8 @@ async function resolveUserConfig(
196196
tasks: config.tasks ?? [],
197197
paths: {
198198
root: projectRoot,
199+
cache: config.paths?.cache ?? "", // TODO: resolve cache path
200+
artifacts: config.paths?.artifacts ?? "", // TODO: resolve artifacts path
199201
},
200202
};
201203

v-next/core/src/types/config.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ export interface HardhatUserConfig {
5252
/**
5353
* The different paths that conform a Hardhat project.
5454
*/
55-
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- TODO: add the paths
56-
export interface ProjectPathsUserConfig {}
55+
export interface ProjectPathsUserConfig {
56+
root?: string;
57+
cache?: string;
58+
artifacts?: string;
59+
}
5760

5861
/**
5962
* The resolved Hardhat configuration.
@@ -64,4 +67,6 @@ export interface HardhatConfig {
6467

6568
export interface ProjectPathsConfig {
6669
root: string;
70+
cache: string;
71+
artifacts: string;
6772
}

v-next/core/test/internal/configuration-variables/configuration-variables.ts

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ describe("ResolvedConfigurationVariable", () => {
2626
plugins: [],
2727
paths: {
2828
root: projectRoot,
29+
cache: "",
30+
artifacts: "",
2931
},
3032
},
3133
hooks: hookManager,

v-next/core/test/internal/hook-manager.ts

+28
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ describe("HookManager", () => {
103103
plugins: [],
104104
paths: {
105105
root: projectRoot,
106+
cache: "",
107+
artifacts: "",
106108
},
107109
},
108110
hooks: hookManager,
@@ -171,6 +173,8 @@ describe("HookManager", () => {
171173
tasks: [],
172174
paths: {
173175
root: projectRoot,
176+
cache: "",
177+
artifacts: "",
174178
},
175179
};
176180

@@ -224,6 +228,8 @@ describe("HookManager", () => {
224228
tasks: [],
225229
paths: {
226230
root: projectRoot,
231+
cache: "",
232+
artifacts: "",
227233
},
228234
};
229235

@@ -327,6 +333,8 @@ describe("HookManager", () => {
327333
plugins: [],
328334
paths: {
329335
root: projectRoot,
336+
cache: "",
337+
artifacts: "",
330338
},
331339
},
332340
hooks: hookManager,
@@ -345,6 +353,8 @@ describe("HookManager", () => {
345353
tasks: [],
346354
paths: {
347355
root: projectRoot,
356+
cache: "",
357+
artifacts: "",
348358
},
349359
};
350360

@@ -429,6 +439,8 @@ describe("HookManager", () => {
429439
tasks: [],
430440
paths: {
431441
root: projectRoot,
442+
cache: "",
443+
artifacts: "",
432444
},
433445
};
434446

@@ -550,6 +562,8 @@ describe("HookManager", () => {
550562
plugins: [],
551563
paths: {
552564
root: projectRoot,
565+
cache: "",
566+
artifacts: "",
553567
},
554568
},
555569
hooks: hookManager,
@@ -642,6 +656,8 @@ describe("HookManager", () => {
642656
tasks: [],
643657
paths: {
644658
root: projectRoot,
659+
cache: "",
660+
artifacts: "",
645661
},
646662
};
647663

@@ -684,6 +700,8 @@ describe("HookManager", () => {
684700
plugins: [],
685701
paths: {
686702
root: projectRoot,
703+
cache: "",
704+
artifacts: "",
687705
},
688706
},
689707
hooks: hookManager,
@@ -700,6 +718,8 @@ describe("HookManager", () => {
700718
tasks: [],
701719
paths: {
702720
root: projectRoot,
721+
cache: "",
722+
artifacts: "",
703723
},
704724
};
705725

@@ -718,6 +738,8 @@ describe("HookManager", () => {
718738
tasks: [],
719739
paths: {
720740
root: projectRoot,
741+
cache: "",
742+
artifacts: "",
721743
},
722744
};
723745

@@ -801,6 +823,8 @@ describe("HookManager", () => {
801823
tasks: [],
802824
paths: {
803825
root: projectRoot,
826+
cache: "",
827+
artifacts: "",
804828
},
805829
};
806830

@@ -843,6 +867,8 @@ describe("HookManager", () => {
843867
plugins: [],
844868
paths: {
845869
root: projectRoot,
870+
cache: "",
871+
artifacts: "",
846872
},
847873
},
848874
hooks: hookManager,
@@ -1002,6 +1028,8 @@ function buildMockHardhatRuntimeEnvironment(
10021028
plugins: [],
10031029
paths: {
10041030
root: projectRoot,
1031+
cache: "",
1032+
artifacts: "",
10051033
},
10061034
},
10071035
tasks: mockTaskManager,

v-next/core/test/internal/user-interruptions/user-interruptions-manager.ts

+6
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ describe("UserInterruptionManager", () => {
3030
plugins: [],
3131
paths: {
3232
root: projectRoot,
33+
cache: "",
34+
artifacts: "",
3335
},
3436
},
3537
globalOptions: {},
@@ -74,6 +76,8 @@ describe("UserInterruptionManager", () => {
7476
plugins: [],
7577
paths: {
7678
root: projectRoot,
79+
cache: "",
80+
artifacts: "",
7781
},
7882
},
7983
globalOptions: {},
@@ -120,6 +124,8 @@ describe("UserInterruptionManager", () => {
120124
plugins: [],
121125
paths: {
122126
root: projectRoot,
127+
cache: "",
128+
artifacts: "",
123129
},
124130
},
125131
globalOptions: {},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { HardhatPlugin } from "@ignored/hardhat-vnext-core/types/plugins";
2+
3+
import { task } from "@ignored/hardhat-vnext-core/config";
4+
5+
const hardhatPlugin: HardhatPlugin = {
6+
id: "clean",
7+
tasks: [
8+
task("clean", "Clears the cache and deletes all artifacts")
9+
.addFlag({
10+
name: "global",
11+
description: "Clear the global cache",
12+
})
13+
.setAction(import.meta.resolve("./task-action.js"))
14+
.build(),
15+
],
16+
};
17+
18+
export default hardhatPlugin;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import type { NewTaskActionFunction } from "@ignored/hardhat-vnext-core/types/tasks";
2+
3+
import { getCacheDir } from "@ignored/hardhat-vnext-core/global-dir";
4+
import { emptyDir, remove } from "@ignored/hardhat-vnext-utils/fs";
5+
6+
interface CleanActionArguments {
7+
global: boolean;
8+
}
9+
10+
const cleanAction: NewTaskActionFunction<CleanActionArguments> = async (
11+
{ global },
12+
{ config },
13+
) => {
14+
if (global) {
15+
const globalCacheDir = await getCacheDir();
16+
await emptyDir(globalCacheDir);
17+
}
18+
19+
await emptyDir(config.paths.cache);
20+
await remove(config.paths.artifacts);
21+
};
22+
23+
export default cleanAction;
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import type { HardhatPlugin } from "@ignored/hardhat-vnext-core/types/plugins";
22

3+
import clean from "./clean/index.js";
34
import hardhatFoo from "./hardhat-foo/index.js";
45
import run from "./run/index.js";
56

67
// Note: When importing a plugin, you have to export its types, so that its
78
// type extensions, if any, also get loaded.
9+
export type * from "./clean/index.js";
810
export type * from "./hardhat-foo/index.js";
911
export type * from "./run/index.js";
1012

11-
export const builtinPlugins: HardhatPlugin[] = [hardhatFoo, run];
13+
export const builtinPlugins: HardhatPlugin[] = [clean, hardhatFoo, run];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
import type { HardhatRuntimeEnvironment } from "@ignored/hardhat-vnext-core/types/hre";
2+
3+
import assert from "node:assert/strict";
4+
import path from "node:path";
5+
import { before, beforeEach, describe, it } from "node:test";
6+
7+
import { getCacheDir } from "@ignored/hardhat-vnext-core/global-dir";
8+
import {
9+
exists,
10+
mkdir,
11+
readdir,
12+
remove,
13+
writeUtf8File,
14+
} from "@ignored/hardhat-vnext-utils/fs";
15+
16+
import { createHardhatRuntimeEnvironment } from "../../../../src/hre.js";
17+
import cleanAction from "../../../../src/internal/builtin-plugins/clean/task-action.js";
18+
import { useFixtureProject } from "../../../helpers/project.js";
19+
20+
let hre: HardhatRuntimeEnvironment;
21+
let globalCacheDir: string;
22+
let cacheDir: string;
23+
let artifactsDir: string;
24+
25+
function assertCleanBehavior(global: boolean) {
26+
it("should clean the cache and artifacts directories", async () => {
27+
await cleanAction({ global }, hre);
28+
29+
// If the cache dir exists, it should be empty
30+
if (await exists(cacheDir)) {
31+
const cacheContents = await readdir(cacheDir);
32+
assert.ok(cacheContents.length === 0, "Cache dir is not empty");
33+
}
34+
35+
// The artifacts dir should not exist
36+
assert.ok(!(await exists(artifactsDir)), "Artifacts dir exists");
37+
38+
// If the global cache dir exists, it should be empty if the global flag is
39+
// true, and not empty otherwise
40+
if (await exists(globalCacheDir)) {
41+
const globalCacheContents = await readdir(globalCacheDir);
42+
if (global) {
43+
assert.ok(
44+
globalCacheContents.length === 0,
45+
"Global cache dir is not empty",
46+
);
47+
} else {
48+
assert.ok(
49+
globalCacheContents.length > 0,
50+
"Global cache dir is empty when it shouldn't be",
51+
);
52+
}
53+
}
54+
});
55+
}
56+
57+
describe("clean/task-action", () => {
58+
describe("cleanAction", () => {
59+
useFixtureProject("loaded-config");
60+
61+
before(async function () {
62+
globalCacheDir = await getCacheDir();
63+
cacheDir = path.join(process.cwd(), "cache");
64+
artifactsDir = path.join(process.cwd(), "artifacts");
65+
hre = await createHardhatRuntimeEnvironment({
66+
// TODO remove this once cache and artifacts are resolved in the config
67+
paths: { cache: cacheDir, artifacts: artifactsDir },
68+
});
69+
});
70+
71+
describe("when cache and artifact dirs don't exist", async () => {
72+
beforeEach(async () => {
73+
await remove(globalCacheDir);
74+
await remove(cacheDir);
75+
await remove(artifactsDir);
76+
});
77+
78+
assertCleanBehavior(true);
79+
});
80+
81+
describe("when cache and artifact are empty dirs", async () => {
82+
beforeEach(async () => {
83+
await remove(globalCacheDir);
84+
await remove(cacheDir);
85+
await remove(artifactsDir);
86+
await getCacheDir(); // Calling this recreates the cache dir
87+
await mkdir(cacheDir);
88+
await mkdir(artifactsDir);
89+
});
90+
91+
assertCleanBehavior(true);
92+
});
93+
94+
describe("when cache and artifact dirs aren't empty", async () => {
95+
beforeEach(async () => {
96+
await remove(globalCacheDir);
97+
await remove(cacheDir);
98+
await remove(artifactsDir);
99+
await getCacheDir(); // Calling this recreates the cache dir
100+
await writeUtf8File(path.join(globalCacheDir, "a"), "");
101+
await writeUtf8File(path.join(cacheDir, "a"), "");
102+
await writeUtf8File(path.join(artifactsDir, "a"), "");
103+
});
104+
105+
assertCleanBehavior(true);
106+
});
107+
108+
describe("when global flag is false", async () => {
109+
beforeEach(async () => {
110+
await remove(globalCacheDir);
111+
await getCacheDir(); // Calling this recreates the cache dir
112+
await writeUtf8File(path.join(globalCacheDir, "a"), "");
113+
});
114+
115+
assertCleanBehavior(false);
116+
});
117+
});
118+
});

0 commit comments

Comments
 (0)