Skip to content

Commit 260cbc6

Browse files
committed
Merge branch 'v-next' into test_hangs_on_fork_mode
2 parents f843ac0 + 8035b5e commit 260cbc6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+1354
-76
lines changed

.changeset/purple-pans-happen.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"hardhat": patch
3+
---
4+
5+
Added Hardhat v2 template support to `hardhat --init` ([#7035](https://github.com/NomicFoundation/hardhat/issues/7035))

pnpm-lock.yaml

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
packages:
22
- "v-next/*"
3-
- "v-next/hardhat/templates/*"
3+
- "v-next/hardhat/templates/hardhat-3/*"

v-next/hardhat/.prettierignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
/dist
33
/CHANGELOG.md
44
/src/internal/cli/telemetry/sentry/vendor
5-
/templates/*/artifacts
6-
/templates/*/cache
5+
/templates/*/*/artifacts
6+
/templates/*/*/cache
77
/test/fixture-projects/**/artifacts
88
/test/fixture-projects/**/cache

v-next/hardhat/src/internal/cli/init/init.ts

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ import {
3737
promptForTemplate,
3838
promptForUpdate,
3939
promptForWorkspace,
40+
promptForHardhatVersion,
4041
} from "./prompt.js";
4142
import { spawn } from "./subprocess.js";
4243
import { getTemplates } from "./template.js";
4344

4445
export interface InitHardhatOptions {
46+
hardhatVersion?: "hardhat-2" | "hardhat-3";
4547
workspace?: string;
4648
migrateToEsm?: boolean;
4749
template?: string;
@@ -85,17 +87,24 @@ export async function initHardhat(options?: InitHardhatOptions): Promise<void> {
8587

8688
await printWelcomeMessage();
8789

90+
const hardhatVersion =
91+
options?.hardhatVersion ?? (await promptForHardhatVersion());
92+
8893
// Ask the user for the workspace to initialize the project in
8994
// if it was not provided, and validate that it is not already initialized
9095
const workspace = await getWorkspace(options?.workspace);
9196

92-
// Create the package.json file if it does not exist
93-
// and validate that it is an esm package
94-
await validatePackageJson(workspace, options?.migrateToEsm);
95-
9697
// Ask the user for the template to use for the project initialization
9798
// if it was not provided, and validate that it exists
98-
const template = await getTemplate(options?.template);
99+
const template = await getTemplate(hardhatVersion, options?.template);
100+
101+
// Create the package.json file if it does not exist
102+
// and validate that it is an esm package
103+
await validatePackageJson(
104+
workspace,
105+
template.packageJson,
106+
options?.migrateToEsm,
107+
);
99108

100109
// Copy the template files to the workspace
101110
// Overwrite existing files only if the user opts-in to it
@@ -234,8 +243,11 @@ export async function getWorkspace(workspace?: string): Promise<string> {
234243
* @param template The name of the template to use for the project initialization.
235244
* @returns
236245
*/
237-
export async function getTemplate(template?: string): Promise<Template> {
238-
const templates = await getTemplates();
246+
export async function getTemplate(
247+
hardhatVersion: "hardhat-2" | "hardhat-3",
248+
template?: string,
249+
): Promise<Template> {
250+
const templates = await getTemplates(hardhatVersion);
239251

240252
// Ask the user for the template to use for the project initialization if it was not provided
241253
if (template === undefined) {
@@ -266,21 +278,57 @@ export async function getTemplate(template?: string): Promise<Template> {
266278
*/
267279
export async function validatePackageJson(
268280
workspace: string,
281+
templatePkg: PackageJson,
269282
migrateToEsm?: boolean,
270283
): Promise<void> {
271284
const absolutePathToPackageJson = path.join(workspace, "package.json");
285+
const shouldUseEsm = templatePkg.type === "module";
272286

273287
// Create the package.json file if it does not exist
274288
if (!(await exists(absolutePathToPackageJson))) {
275289
const packageJson: PackageJson = {
276290
name: path.basename(workspace),
277-
type: "module",
278291
version: "1.0.0",
279292
};
280293

294+
if (shouldUseEsm) {
295+
packageJson.type = "module";
296+
}
297+
281298
await writeJsonFile(absolutePathToPackageJson, packageJson);
282299
}
283300

301+
const packageManager = await getPackageManager(workspace);
302+
303+
// We know this works with npm, pnpm, but not with yarn. If, so we use
304+
// pnpm or npm exclusively.
305+
// If you read this comment and wonder if this is outdated, you can
306+
// answer it by checking if the most popular versions of yarn and other
307+
// package managers support `<package manager> pkg set type=module`.
308+
const packageManagerToUse = packageManager === "pnpm" ? "pnpm" : "npm";
309+
310+
// We need to set the hardhat version in the package.json file
311+
// to ensure that the template is compatible with the current Hardhat version.
312+
// This is needed because we have hardhat-2 and hardhat-3 templates,
313+
// and the user may install hardhat 3 first and then initialize a project
314+
// with a hardhat-2 template.
315+
const templateHardhatVersion = templatePkg.devDependencies?.hardhat ?? "";
316+
if (templateHardhatVersion.startsWith("^2")) {
317+
await spawn(
318+
[packageManagerToUse, "pkg", "delete", "dependencies.hardhat"].join(" "),
319+
[],
320+
{
321+
cwd: workspace,
322+
shell: true,
323+
stdio: "inherit",
324+
},
325+
);
326+
}
327+
328+
if (!shouldUseEsm) {
329+
return;
330+
}
331+
284332
const pkg: PackageJson = await readJsonFile(absolutePathToPackageJson);
285333

286334
// Validate that the package.json file is an esm package
@@ -296,15 +344,6 @@ export async function validatePackageJson(
296344
throw new HardhatError(HardhatError.ERRORS.CORE.GENERAL.ONLY_ESM_SUPPORTED);
297345
}
298346

299-
const packageManager = await getPackageManager(workspace);
300-
301-
// We know this works with npm, pnpm, but not with yarn. If, so we use
302-
// pnpm or npm exclusively.
303-
// If you read this comment and wonder if this is outdated, you can
304-
// answer it by checking if the most popular versions of yarn and other
305-
// package managers support `<package manager> pkg set type=module`.
306-
const packageManagerToUse = packageManager === "pnpm" ? "pnpm" : "npm";
307-
308347
await spawn(
309348
[packageManagerToUse, "pkg", "set", "type=module"].join(" "),
310349
[],

v-next/hardhat/src/internal/cli/init/prompt.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,39 @@ import { HardhatError } from "@nomicfoundation/hardhat-errors";
44
import { shortenPath } from "@nomicfoundation/hardhat-utils/path";
55
import chalk from "chalk";
66

7+
export async function promptForHardhatVersion(): Promise<
8+
"hardhat-2" | "hardhat-3"
9+
> {
10+
ensureTTY();
11+
12+
const { default: enquirer } = await import("enquirer");
13+
14+
const hardhatVersionResponse = await enquirer.prompt<{
15+
hardhatVersion: "hardhat-2" | "hardhat-3";
16+
}>([
17+
{
18+
name: "hardhatVersion",
19+
type: "select",
20+
message: "Which version of Hardhat would you like to use?",
21+
initial: 0,
22+
choices: [
23+
{
24+
name: "hardhat-3",
25+
message: "Hardhat 3 (recommended for new projects)",
26+
value: "hardhat-3",
27+
},
28+
{
29+
name: "hardhat-2",
30+
message: "Hardhat 2 (older version)",
31+
value: "hardhat-2",
32+
},
33+
],
34+
},
35+
]);
36+
37+
return hardhatVersionResponse.hardhatVersion;
38+
}
39+
740
export async function promptForWorkspace(): Promise<string> {
841
ensureTTY();
942

v-next/hardhat/src/internal/cli/init/template.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ export interface Template {
3434
*
3535
* @returns The list of available templates.
3636
*/
37-
export async function getTemplates(): Promise<Template[]> {
37+
export async function getTemplates(
38+
templatesDir: "hardhat-2" | "hardhat-3",
39+
): Promise<Template[]> {
3840
const packageRoot = await findClosestPackageRoot(import.meta.url);
39-
const pathToTemplates = path.join(packageRoot, "templates");
41+
const pathToTemplates = path.join(packageRoot, "templates", templatesDir);
4042

4143
if (!(await exists(pathToTemplates))) {
4244
return [];

v-next/hardhat/src/internal/cli/telemetry/sentry/anonymizer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export class Anonymizer {
5555
const result: Event = {
5656
event_id: event.event_id,
5757
platform: event.platform,
58+
release: event.release,
5859
timestamp: event.timestamp,
5960
extra: event.extra,
6061
};

v-next/hardhat/src/internal/cli/telemetry/sentry/init.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { createGetModuleFromFilename } from "./vendor/utils/module.js";
3030
interface InitOptions {
3131
dsn: string;
3232
transport: (transportOptions: BaseTransportOptions) => Transport;
33+
release?: string;
3334
serverName?: string;
3435
integrations?: (integrations: Integration[]) => Integration[];
3536
}

v-next/hardhat/src/internal/cli/telemetry/sentry/reporter.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class Reporter {
6868
"./vendor/integrations/contextlines.js"
6969
);
7070

71+
const hardhatVersion = await getHardhatVersion();
7172
const { init } = await import("./init.js");
7273

7374
const linkedErrorsIntegrationInstance = linkedErrorsIntegration({
@@ -79,14 +80,15 @@ class Reporter {
7980
await init({
8081
dsn: SENTRY_DSN,
8182
transport: makeSubprocessTransport,
83+
release: `hardhat@${hardhatVersion}`,
8284
integrations: () => [
8385
linkedErrorsIntegrationInstance,
8486
contextLinesIntegrationInstance,
8587
],
8688
});
8789

8890
setExtra("nodeVersion", process.version);
89-
setExtra("hardhatVersion", await getHardhatVersion());
91+
setExtra("hardhatVersion", hardhatVersion);
9092

9193
return this.#instance;
9294
}

0 commit comments

Comments
 (0)