UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

101 lines (89 loc) 3.21 kB
import path from "node:path"; import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors"; import { exists, getAllFilesMatching, isDirectory, readdir, readJsonFile, } from "@nomicfoundation/hardhat-utils/fs"; import { findClosestPackageRoot, type PackageJson, } from "@nomicfoundation/hardhat-utils/package"; /** * This type describes a hardhat project template. It consists of: * - name: The name of the template; * - packageJson: The parsed package.json file of the template; * - path: The absolute path to the template directory; * - files: The relative paths to template files within the template directory, * excluding the package.json file. */ export interface Template { name: string; packageJson: PackageJson; path: string; files: string[]; } /** * getTemplates returns the list of available templates. It retrieves them from * the "templates" folder in the package root. * * @returns The list of available templates. */ export async function getTemplates( templatesDir: "hardhat-2" | "hardhat-3", ): Promise<Template[]> { const packageRoot = await findClosestPackageRoot(import.meta.url); const pathToTemplates = path.join(packageRoot, "templates", templatesDir); if (!(await exists(pathToTemplates))) { return []; } const pathsToTemplates = await readdir(pathToTemplates); pathsToTemplates.sort(); const templates = await Promise.all( pathsToTemplates.map(async (dirName) => { const name = dirName.replace(/^\d+-/, ""); const pathToTemplate = path.join(pathToTemplates, dirName); const pathToPackageJson = path.join(pathToTemplate, "package.json"); if (!(await isDirectory(pathToTemplate))) { return; } // Validate that the the template has a package.json file assertHardhatInvariant( await exists(pathToPackageJson), `package.json for template ${name} is missing`, ); const packageJson: PackageJson = await readJsonFile<PackageJson>(pathToPackageJson); const files = await getAllFilesMatching(pathToTemplate, (f) => { // Ignore the package.json file because it is handled separately if (f === pathToPackageJson) { return false; } // .gitignore files are expected to be called gitignore in the templates // because npm ignores .gitignore files during npm pack (see https://github.com/npm/npm/issues/3763) if (path.basename(f) === ".gitignore") { return false; } // We should ignore all the files according to the .gitignore rules // However, for simplicity, we just ignore the node_modules folder // If we needed to implement a more complex ignore logic, we could // use recently introduced glob from node:fs/promises if ( path.relative(pathToTemplate, f).split(path.sep)[0] === "node_modules" ) { return false; } return true; }).then((fs) => fs.map((f) => path.relative(pathToTemplate, f))); return { name, packageJson, path: pathToTemplate, files, }; }), ); return templates.filter((t) => t !== undefined); }