diff --git a/.github/workflows/ci-go.yml b/.github/workflows/ci-go.yml index 0f5dd4dbf0fc1..b2dd7b3ad8b92 100644 --- a/.github/workflows/ci-go.yml +++ b/.github/workflows/ci-go.yml @@ -2,7 +2,7 @@ name: CI on: push: - branches: ["*"] + branches: ["main"] pull_request: types: [opened, synchronize] diff --git a/create-turbo/__tests__/cli.test.ts b/create-turbo/__tests__/cli.test.ts index 3c95a39f3e665..6819c750b77d1 100644 --- a/create-turbo/__tests__/cli.test.ts +++ b/create-turbo/__tests__/cli.test.ts @@ -24,6 +24,7 @@ const DEFAULT_JEST_TIMEOUT = 5000; describe("create-turbo cli", () => { beforeAll(() => { jest.setTimeout(DEFAULT_JEST_TIMEOUT * 3); + fs.rmdirSync(path.join(__dirname, "../my-turborepo"), { recursive: true }); if (!fs.existsSync(createTurbo)) { // TODO: Consider running the build here instead of throwing throw new Error( @@ -34,18 +35,20 @@ describe("create-turbo cli", () => { afterAll(() => { jest.setTimeout(DEFAULT_JEST_TIMEOUT); + fs.rmdirSync(path.join(__dirname, "../my-turborepo"), { recursive: true }); }); it("guides the user through the process", (done) => { - let cli = spawn("node", [createTurbo], {}); + let cli = spawn("node", [createTurbo, "--no-install"], {}); let promptCount = 0; let previousPrompt: string; - + const messages: string[] = []; cli.stdout.on("data", async (data) => { let prompt = cleanPrompt(data); + if ( !prompt || - prompt === ">>> TURBOREPO" || + prompt.startsWith(">>> TURBOREPO") || isSamePrompt(prompt, previousPrompt) ) { return; @@ -72,16 +75,14 @@ describe("create-turbo cli", () => { expect(getPromptChoices(prompt)).toEqual(["Yarn", "NPM"]); cli.stdin.write(keys.enter); break; - case 4: - expect(prompt).toEqual( - "? Do you want me to run `yarn install`? (Y/n)" - ); - cli.stdin.write("n"); + // Bootstrap info + expect( + prompt.startsWith( + ">>> Bootstrapped a new turborepo with the following:" + ) + ).toBe(true); - // At this point the CLI will create directories and all that fun stuff - // TODO: We should actually test this stuff too, kinda a big deal - cli.kill("SIGINT"); break; } @@ -90,7 +91,6 @@ describe("create-turbo cli", () => { cli.on("exit", () => { try { - expect(promptCount).toEqual(4); done(); } catch (error) { done(error); @@ -126,7 +126,9 @@ describe("create-turbo cli", () => { If is not provided up front you will be prompted for it. - Flags: + Flags: + --use-npm Explicitly tell the CLI to bootstrap the app using npm. + --no-install Explicitly do not run the package mananger's install command --help, -h Show this help message --version, -v Show the version of this script @@ -147,7 +149,9 @@ describe("create-turbo cli", () => { If is not provided up front you will be prompted for it. - Flags: + Flags: + --use-npm Explicitly tell the CLI to bootstrap the app using npm. + --no-install Explicitly do not run the package mananger's install command --help, -h Show this help message --version, -v Show the version of this script @@ -182,7 +186,6 @@ function isSamePrompt( if (previousPrompt === undefined) { return false; } - let promptStart = previousPrompt.split("\n")[0]; promptStart = promptStart.slice(0, promptStart.lastIndexOf("(")); diff --git a/create-turbo/src/index.ts b/create-turbo/src/index.ts index 12e1bf6329d7e..374cdffbdba82 100644 --- a/create-turbo/src/index.ts +++ b/create-turbo/src/index.ts @@ -20,7 +20,9 @@ const help = ` If is not provided up front you will be prompted for it. - Flags: + Flags: + --use-npm Explicitly tell the CLI to bootstrap the app using npm. + --no-install Explicitly do not run the package mananger's install command --help, -h Show this help message --version, -v Show the version of this script `; @@ -45,8 +47,11 @@ run() async function run() { let { input, flags, showHelp, showVersion } = meow(help, { + booleanDefault: undefined, flags: { help: { type: "boolean", default: false, alias: "h" }, + useNpm: { type: "boolean", default: false }, + install: { type: "boolean", default: true }, version: { type: "boolean", default: false, alias: "v" }, }, }); @@ -80,33 +85,28 @@ async function run() { ); const isYarnInstalled = shouldUseYarn(); - let answers = await inquirer.prompt<{ - packageManager: "yarn" | "npm"; - install: boolean; - }>([ - { - name: "packageManager", - type: "list", - message: "Which package manager do you want to use?", - choices: [ - { - name: "Yarn", - value: "yarn", - disabled: !isYarnInstalled && "not installed", - }, - { name: "NPM", value: "npm" }, - // { name: "PNPM", value: "pnpm" }, - ], - }, - { - name: "install", - type: "confirm", - message: function (answers) { - return `Do you want me to run \`${answers.packageManager} install\`?`; + let answers; + if (flags.useNpm) { + answers = { packageManager: "npm" }; + } else { + answers = await inquirer.prompt<{ + packageManager: "yarn" | "npm"; + }>([ + { + name: "packageManager", + type: "list", + message: "Which package manager do you want to use?", + choices: [ + { + name: "Yarn", + value: "yarn", + disabled: !isYarnInstalled && "not installed", + }, + { name: "NPM", value: "npm" }, + ], }, - default: true, - }, - ]); + ]); + } // Create the app directory let relativeProjectDir = path.relative(process.cwd(), projectDir); @@ -169,7 +169,7 @@ async function run() { JSON.stringify(appPkg, null, 2) ); - if (answers.install) { + if (flags.install) { console.log(); console.log(`>>> Bootstrapping a new turborepo with the following:`); console.log(); @@ -199,50 +199,64 @@ async function run() { cwd: projectDir, }); spinner.stop(); + } else { + console.log(); + console.log(`>>> Bootstrapped a new turborepo with the following:`); + console.log(); + console.log(` - ${chalk.bold("apps/web")}: Next.js with TypeScript`); + console.log(` - ${chalk.bold("apps/docs")}: Next.js with TypeScript`); + console.log( + ` - ${chalk.bold("packages/ui")}: Shared React component library` + ); + console.log( + ` - ${chalk.bold("packages/config")}: Shared configuration (ESLint)` + ); + console.log( + ` - ${chalk.bold( + "packages/tsconfig" + )}: Shared TypeScript \`tsconfig.json\`` + ); + console.log(); } process.chdir(projectDir); tryGitInit(relativeProjectDir); - - console.log( - `${chalk.bold(turboGradient(">>> Success!"))} Your new Turborepo is ready. ` - ); - console.log(); - console.log(`To build all apps and packages, run the following:`); - console.log(); - if (!projectDirIsCurrentDir) { - console.log(` cd ${relativeProjectDir}`); + if (projectDirIsCurrentDir) { + console.log( + `${chalk.bold( + turboGradient(">>> Success!") + )} Your new Turborepo is ready. ` + ); + console.log("Inside this directory, you can run several commands:"); + } else { + console.log( + `${chalk.bold( + turboGradient(">>> Success!") + )} Created a new Turborepo at "${relativeProjectDir}". ` + ); + console.log("Inside that directory, you can run several commands:"); } - console.log(` ${answers.packageManager} run build`); + console.log(); - console.log(`To develop all apps and packages, run the following:`); + console.log(chalk.cyan(` ${answers.packageManager} run build`)); + console.log(` Build all apps and packages`); console.log(); - if (!projectDirIsCurrentDir) { - console.log(` cd ${relativeProjectDir}`); - } - console.log(` ${answers.packageManager} run dev`); + console.log(chalk.cyan(` ${answers.packageManager} run dev`)); + console.log(` Develop all apps and packages`); console.log(); console.log(`Turborepo will cache locally by default. For an additional`); console.log(`speed boost, enable Remote Caching (beta) with Vercel by`); - console.log(`entering the following commands:`); + console.log(`entering the following command:`); + console.log(); + console.log(chalk.cyan(` npx turbo login`)); + console.log(); + console.log(`We suggest that you begin by typing:`); console.log(); if (!projectDirIsCurrentDir) { - console.log(` cd ${relativeProjectDir}`); + console.log(` ${chalk.cyan("cd")} ${relativeProjectDir}`); } - console.log(` npx turbo login`); + console.log(chalk.cyan(` npx turbo login`)); console.log(); - if (projectDirIsCurrentDir) { - console.log(`For more info, checkout the README`); - } else { - console.log( - `For more info, checkout the README in ${chalk.bold(relativeProjectDir)}` - ); - } - console.log( - `as well as the official Turborepo docs ${chalk.underline( - "https://turborepo.org/docs" - )}` - ); } const update = checkForUpdate(cliPkgJson).catch(() => null); diff --git a/create-turbo/src/shouldUseYarn.ts b/create-turbo/src/shouldUseYarn.ts index 0153ae01e5548..69ef256ce1f48 100644 --- a/create-turbo/src/shouldUseYarn.ts +++ b/create-turbo/src/shouldUseYarn.ts @@ -3,8 +3,8 @@ import { execSync } from "child_process"; export function shouldUseYarn(): boolean { try { const userAgent = process.env.npm_config_user_agent; - if (userAgent) { - return Boolean(userAgent && userAgent.startsWith("yarn")); + if (userAgent && userAgent.startsWith("yarn")) { + return true; } execSync("yarnpkg --version", { stdio: "ignore" }); return true; diff --git a/package.json b/package.json index 2c048357ebf4d..9950daf2b5514 100644 --- a/package.json +++ b/package.json @@ -35,11 +35,11 @@ "baseBranch": "origin/main", "pipeline": { "test": { - "dependsOn": [ - "build" - ], "outputs": [ "coverage/**/*" + ], + "dependsOn": [ + "^build" ] }, "lint": { @@ -63,6 +63,12 @@ "turbo.exe" ], "dependsOn": [] + }, + "create-turbo#test": { + "dependsOn": [ + "create-turbo#build" + ], + "outputs": [] } } }