diff --git a/.changeset/small-lobsters-arrive.md b/.changeset/small-lobsters-arrive.md new file mode 100644 index 00000000000..c95bd3c555d --- /dev/null +++ b/.changeset/small-lobsters-arrive.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +thirdweb deploy redirects to contract deploy page if no contracts detected diff --git a/packages/cli/src/common/feature-detector.ts b/packages/cli/src/common/feature-detector.ts index 8ddc1496c90..ebe27132552 100644 --- a/packages/cli/src/common/feature-detector.ts +++ b/packages/cli/src/common/feature-detector.ts @@ -117,10 +117,12 @@ export async function detectExtensions(options: any) { }); let deployCmd = `npx thirdweb@latest deploy`; - if (existsSync("package.json")) { + if (existsSync(projectPath + "/package.json")) { const packageManager = getPkgManager(); const useYarn = packageManager === "yarn"; - const pkgJson = JSON.parse(readFileSync("package.json", "utf-8")); + const pkgJson = JSON.parse( + readFileSync(projectPath + "/package.json", "utf-8"), + ); if (pkgJson?.scripts?.deploy === deployCmd) { deployCmd = `${packageManager}${useYarn ? "" : " run"} deploy`; } diff --git a/packages/cli/src/common/processor.ts b/packages/cli/src/common/processor.ts index 776b82233f6..de34e38f0bc 100644 --- a/packages/cli/src/common/processor.ts +++ b/packages/cli/src/common/processor.ts @@ -8,6 +8,7 @@ import { ContractPayload } from "../core/interfaces/ContractPayload"; import { ThirdwebStorage } from "@thirdweb-dev/storage"; import chalk from "chalk"; import { readFileSync } from "fs"; +import ora from "ora"; import path from "path"; export async function processProject( @@ -35,6 +36,27 @@ export async function processProject( const projectType = await detect(projectPath, options); + if (projectType === "none") { + if (command === "deploy") { + info( + "No contracts detected in this directory. Redirecting to the thirdweb contract deployment page.", + ); + return "https://thirdweb.com/contracts"; + } + + error("No detected contracts in this directory."); + logger.info(``); + ora( + `Detected contract files must end with the '.sol' extension and exist in this directory or the '/contracts' subdirectory`, + ).info(); + logger.info(``); + ora("To create a new contracts project, run the following command:").info(); + logger.info(``); + logger.info(` ${chalk.cyan(`npx thirdweb@latest create --contract`)}`); + logger.info(``); + process.exit(1); + } + if (options.ci) { logger.info("Installing dependencies..."); try { diff --git a/packages/cli/src/core/detection/detect.ts b/packages/cli/src/core/detection/detect.ts index 290a8dbe7de..d7901c41aaf 100644 --- a/packages/cli/src/core/detection/detect.ts +++ b/packages/cli/src/core/detection/detect.ts @@ -5,7 +5,9 @@ import { Detector } from "./detector"; import FoundryDetector from "./foundry"; import HardhatDetector from "./hardhat"; import TruffleDetector from "./truffle"; +import fs, { exists, existsSync } from "fs"; import inquirer from "inquirer"; +import { parse } from "path"; const { Confirm } = require("enquirer"); @@ -26,18 +28,24 @@ export default async function detect( //if there is no project returned at all then just return unknown} if (!possibleProjectTypes.length) { - warn(`${ERROR_MESSAGES.noConfiguration} ${path}`); - const prompt = new Confirm({ - name: "continue", - message: - "Do you want to continue and compile this project with solc instead?", - }); - const shouldCompile = await prompt.run(); - if (!shouldCompile) { - logger.warn("Aborted contract compilation"); - process.exit(1); + const canCompile = hasContracts(path); + + if (canCompile) { + warn(`${ERROR_MESSAGES.noConfiguration} ${path}`); + const prompt = new Confirm({ + name: "continue", + message: + "Do you want to continue and compile this project with solc instead?", + }); + const shouldCompile = await prompt.run(); + if (!shouldCompile) { + logger.warn("Aborted contract compilation"); + process.exit(1); + } + return "solc"; + } else { + return "none"; } - return "unknown"; } //if there is only one possible option just return it if (possibleProjectTypes.length === 1) { @@ -64,3 +72,24 @@ export default async function detect( return answer[question]; } } + +// Check if a directory has any .sol files or a /contracts folder with .sol files +function hasContracts(path: any) { + return ( + ["", "/contracts"].filter((p) => { + const dirPath = path + p; + + if (!existsSync(dirPath)) { + return false; + } + + const files = fs.readdirSync(dirPath); + const contracts = files.filter((filePath) => { + const { ext } = parse(filePath); + return ext === ".sol"; + }); + + return contracts.length > 0; + }).length > 0 + ); +} diff --git a/packages/cli/src/core/types/ProjectType.ts b/packages/cli/src/core/types/ProjectType.ts index e06a85f9c42..d187ea9aeac 100644 --- a/packages/cli/src/core/types/ProjectType.ts +++ b/packages/cli/src/core/types/ProjectType.ts @@ -3,4 +3,5 @@ export type ProjectType = | "foundry" | "hardhat" | "truffle" - | "unknown"; + | "solc" + | "none";