UNPKG

create-nx-workspace

Version:

Smart Repos · Fast Builds

171 lines (170 loc) • 7.92 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getInterruptedWorkspaceState = getInterruptedWorkspaceState; exports.createWorkspace = createWorkspace; exports.extractConnectUrl = extractConnectUrl; const node_fs_1 = require("node:fs"); const path_1 = require("path"); const create_empty_workspace_1 = require("./create-empty-workspace"); const create_preset_1 = require("./create-preset"); const create_sandbox_1 = require("./create-sandbox"); const setup_ci_1 = require("./utils/ci/setup-ci"); const error_utils_1 = require("./utils/error-utils"); const git_1 = require("./utils/git/git"); const nx_cloud_1 = require("./utils/nx/nx-cloud"); const output_1 = require("./utils/output"); const get_third_party_preset_1 = require("./utils/preset/get-third-party-preset"); const preset_1 = require("./utils/preset/preset"); const clone_template_1 = require("./utils/template/clone-template"); const child_process_utils_1 = require("./utils/child-process-utils"); const package_manager_1 = require("./utils/package-manager"); // State for SIGINT handler - only set after workspace is fully installed let workspaceDirectory; let cloudConnectUrl; function getInterruptedWorkspaceState() { return { directory: workspaceDirectory, connectUrl: cloudConnectUrl }; } async function createWorkspace(preset, options, rawArgs) { const { packageManager, name, nxCloud, skipGit = false, defaultBase = 'main', commit, cliName, useGitHub, skipGitHubPush = false, verbose = false, } = options; if (cliName) { output_1.output.setCliName(cliName ?? 'NX'); } let directory; if (options.template) { if (!options.template.startsWith('nrwl/')) throw new Error(`Invalid template. Only templates from the 'nrwl' GitHub org are supported.`); const templateUrl = `https://github.com/${options.template}`; const workingDir = process.cwd().replace(/\\/g, '/'); directory = (0, path_1.join)(workingDir, name); const ora = require('ora'); const workspaceSetupSpinner = ora(`Creating workspace from template`).start(); try { await (0, clone_template_1.cloneTemplate)(templateUrl, name); // Remove npm lockfile from template since we'll generate the correct one const npmLockPath = (0, path_1.join)(directory, 'package-lock.json'); if ((0, node_fs_1.existsSync)(npmLockPath)) { (0, node_fs_1.unlinkSync)(npmLockPath); } // Generate package manager specific files (e.g., .yarnrc.yml for Yarn Berry) (0, package_manager_1.generatePackageManagerFiles)(directory, packageManager); // Install dependencies with the user's package manager const pmc = (0, package_manager_1.getPackageManagerCommand)(packageManager); if (pmc.preInstall) { await (0, child_process_utils_1.execAndWait)(pmc.preInstall, directory); } await (0, child_process_utils_1.execAndWait)(pmc.install, directory); // Mark workspace as ready for SIGINT handler workspaceDirectory = directory; workspaceSetupSpinner.succeed(`Successfully created the workspace: ${directory}`); } catch (e) { workspaceSetupSpinner.fail(); throw e; } // Connect to Nx Cloud for template flow if (nxCloud !== 'skip') { await (0, nx_cloud_1.connectToNxCloudForTemplate)(directory, 'create-nx-workspace', useGitHub); } } else { // Preset flow - existing behavior const tmpDir = await (0, create_sandbox_1.createSandbox)(packageManager); const workspaceGlobs = getWorkspaceGlobsFromPreset(preset); // nx new requires a preset currently. We should probably make it optional. directory = await (0, create_empty_workspace_1.createEmptyWorkspace)(tmpDir, name, packageManager, { ...options, preset, workspaceGlobs, }); // Mark workspace as ready for SIGINT handler workspaceDirectory = directory; // If the preset is a third-party preset, we need to call createPreset to install it // For first-party presets, it will be created by createEmptyWorkspace instead. // In createEmptyWorkspace, it will call `nx new` -> `@nx/workspace newGenerator` -> `@nx/workspace generatePreset`. const thirdPartyPackageName = (0, get_third_party_preset_1.getPackageNameFromThirdPartyPreset)(preset); if (thirdPartyPackageName) { await (0, create_preset_1.createPreset)(thirdPartyPackageName, options, packageManager, directory); } } const isTemplate = !!options.template; // Generate CI for preset flow (not template) // When nxCloud === 'yes' (from simplified prompt), use GitHub as the CI provider if (nxCloud !== 'skip' && !isTemplate) { const ciProvider = nxCloud === 'yes' ? 'github' : nxCloud; await (0, setup_ci_1.setupCI)(directory, ciProvider, packageManager); } let pushedToVcs = git_1.VcsPushStatus.SkippedGit; if (!skipGit) { try { await (0, git_1.initializeGitRepo)(directory, { defaultBase, commit }); // Push to GitHub if commit was made, GitHub push is not skipped, and: // - CI provider is GitHub (preset flow with CLI arg), OR // - Nx Cloud enabled via simplified prompt (nxCloud === 'yes') if (commit && !skipGitHubPush && (nxCloud === 'github' || nxCloud === 'yes')) { pushedToVcs = await (0, git_1.pushToGitHub)(directory, { skipGitHubPush, name, defaultBase, verbose, }); } } catch (e) { if (e instanceof Error) { output_1.output.error({ title: 'Could not initialize git repository', bodyLines: (0, error_utils_1.mapErrorToBodyLines)(e), }); } else { console.error(e); } } } // Create onboarding URL AFTER git operations so getVcsRemoteInfo() can detect the repo let connectUrl; let nxCloudInfo; if (nxCloud !== 'skip') { const token = (0, nx_cloud_1.readNxCloudToken)(directory); connectUrl = await (0, nx_cloud_1.createNxCloudOnboardingUrl)(nxCloud, token, directory, useGitHub); // Store for SIGINT handler cloudConnectUrl = connectUrl; nxCloudInfo = await (0, nx_cloud_1.getNxCloudInfo)(connectUrl, pushedToVcs, options.completionMessageKey); } else if (isTemplate && nxCloud === 'skip') { // Show nx connect message when user skips cloud in template flow nxCloudInfo = (0, nx_cloud_1.getSkippedNxCloudInfo)(); } return { nxCloudInfo, directory, pushedToVcs, connectUrl, }; } function extractConnectUrl(text) { const urlPattern = /(https:\/\/[^\s]+\/connect\/[^\s]+)/g; const match = text.match(urlPattern); return match ? match[0] : null; } function getWorkspaceGlobsFromPreset(preset) { // Should match how apps are created in `packages/workspace/src/generators/preset/preset.ts`. switch (preset) { case preset_1.Preset.AngularMonorepo: case preset_1.Preset.Expo: case preset_1.Preset.Express: case preset_1.Preset.Nest: case preset_1.Preset.NextJs: case preset_1.Preset.NodeMonorepo: case preset_1.Preset.Nuxt: case preset_1.Preset.ReactNative: case preset_1.Preset.ReactMonorepo: case preset_1.Preset.VueMonorepo: case preset_1.Preset.WebComponents: return ['apps/*']; default: return ['packages/*']; } }