UNPKG

create-nx-workspace

Version:

Smart Repos · Fast Builds

257 lines (256 loc) • 8.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.messages = exports.PromptMessages = exports.NxCloudChoices = void 0; exports.getFlowVariant = getFlowVariant; exports.recordStat = recordStat; const node_child_process_1 = require("node:child_process"); const node_fs_1 = require("node:fs"); const node_path_1 = require("node:path"); const node_os_1 = require("node:os"); const is_ci_1 = require("../ci/is-ci"); // TODO(jack): Remove flow variant logic after A/B testing is complete const FLOW_VARIANT_CACHE_FILE = (0, node_path_1.join)((0, node_os_1.tmpdir)(), 'nx-cnw-flow-variant'); const FLOW_VARIANT_EXPIRY_MS = 7 * 24 * 60 * 60 * 1000; // 1 week // In-memory cache to ensure consistency within a single run let flowVariantCache = null; function readCachedFlowVariant() { try { if (!(0, node_fs_1.existsSync)(FLOW_VARIANT_CACHE_FILE)) return null; const stats = (0, node_fs_1.statSync)(FLOW_VARIANT_CACHE_FILE); if (Date.now() - stats.mtimeMs > FLOW_VARIANT_EXPIRY_MS) return null; const value = (0, node_fs_1.readFileSync)(FLOW_VARIANT_CACHE_FILE, 'utf-8').trim(); return value === '0' || value === '1' ? value : null; } catch { return null; } } function writeCachedFlowVariant(variant) { try { (0, node_fs_1.writeFileSync)(FLOW_VARIANT_CACHE_FILE, variant, 'utf-8'); } catch { // Ignore write errors } } /** * Internal function to determine and cache the flow variant. */ function getFlowVariantInternal() { if (flowVariantCache) return flowVariantCache; const variant = process.env.NX_CNW_FLOW_VARIANT ?? readCachedFlowVariant() ?? (Math.random() < 0.5 ? '0' : '1'); flowVariantCache = variant; // Only write to cache if we randomly assigned a variant and no cache exists yet // This ensures the cache expiry is based on original creation time, not last access if (!process.env.NX_CNW_FLOW_VARIANT && !(0, node_fs_1.existsSync)(FLOW_VARIANT_CACHE_FILE)) { writeCachedFlowVariant(variant); } return variant; } /** * Returns the flow variant for tracking (0 = preset, 1 = template). */ function getFlowVariant() { if (process.env.NX_GENERATE_DOCS_PROCESS === 'true') { return '0'; } return flowVariantCache ?? getFlowVariantInternal(); } exports.NxCloudChoices = [ 'github', 'gitlab', 'azure', 'bitbucket-pipelines', 'circleci', 'skip', 'yes', // Deprecated but still handled ]; const messageOptions = { /** * These messages are for setting up CI as part of create-nx-workspace and nx init */ setupCI: [ { code: 'which-ci-provider', message: `Which CI provider would you like to use?`, initial: 0, choices: [ { value: 'github', name: 'GitHub Actions' }, { value: 'gitlab', name: 'Gitlab' }, { value: 'azure', name: 'Azure DevOps' }, { value: 'bitbucket-pipelines', name: 'BitBucket Pipelines' }, { value: 'circleci', name: 'Circle CI' }, { value: 'skip', name: '\nDo it later' }, ], footer: '\nSelf-healing CI, remote caching, and task distribution are provided by Nx Cloud: https://nx.dev/nx-cloud', fallback: { value: 'skip', key: 'setupNxCloud' }, completionMessage: 'ci-setup', }, ], /** * These messages are a fallback for setting up CI as well as when migrating major versions */ setupNxCloud: [ { code: 'enable-caching2', message: `Would you like remote caching to make your build faster?`, initial: 0, choices: [ { value: 'yes', name: 'Yes' }, { value: 'skip', name: 'No - I would not like remote caching', }, ], footer: '\nRead more about remote caching at https://nx.dev/ci/features/remote-cache', hint: `\n(can be disabled any time).`, fallback: undefined, completionMessage: 'cache-setup', }, ], /** * Simplified Cloud prompt for template flow */ setupNxCloudV2: [ //{ // code: 'cloud-v2-remote-cache-visit', // message: 'Enable remote caching with Nx Cloud?', // initial: 0, // choices: [ // { value: 'yes', name: 'Yes' }, // { value: 'skip', name: 'Skip' }, // ], // footer: // '\nRemote caching makes your builds faster for development and in CI: https://nx.dev/ci/features/remote-cache', // fallback: undefined, // completionMessage: 'cache-setup', //}, //{ // code: 'cloud-v2-fast-ci-visit', // message: 'Speed up CI and reduce compute costs with Nx Cloud?', // initial: 0, // choices: [ // { value: 'yes', name: 'Yes' }, // { value: 'skip', name: 'Skip' }, // ], // footer: // '\n70% faster CI, 60% less compute, Automatically fix broken PRs: https://nx.dev/nx-cloud', // fallback: undefined, // completionMessage: 'ci-setup', //}, //{ // code: 'cloud-v2-green-prs-visit', // message: 'Get to green PRs faster with Nx Cloud?', // initial: 0, // choices: [ // { value: 'yes', name: 'Yes' }, // { value: 'skip', name: 'Skip' }, // ], // footer: // '\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud', // fallback: undefined, // completionMessage: 'ci-setup', //}, { code: 'cloud-v2-full-platform-visit', message: 'Try the full Nx platform?', initial: 0, choices: [ { value: 'yes', name: 'Yes' }, { value: 'skip', name: 'Skip' }, ], footer: '\nAutomatically fix broken PRs, 70% faster CI: https://nx.dev/nx-cloud', fallback: undefined, completionMessage: 'platform-setup', }, ], }; class PromptMessages { constructor() { this.selectedMessages = {}; } getPrompt(key) { if (this.selectedMessages[key] === undefined) { if (process.env.NX_GENERATE_DOCS_PROCESS === 'true') { this.selectedMessages[key] = 0; } else { this.selectedMessages[key] = Math.floor(Math.random() * messageOptions[key].length); } } return messageOptions[key][this.selectedMessages[key]]; } codeOfSelectedPromptMessage(key) { const selected = this.selectedMessages[key]; if (selected === undefined) { return ''; } return messageOptions[key][selected].code; } completionMessageOfSelectedPrompt(key) { const selected = this.selectedMessages[key]; if (selected === undefined) { return 'ci-setup'; } else { return messageOptions[key][selected].completionMessage; } } } exports.PromptMessages = PromptMessages; exports.messages = new PromptMessages(); function getCloudUrl() { const url = process.env.NX_CLOUD_API || process.env.NRWL_API || 'https://cloud.nx.app'; // Remove trailing slash if present return url[url.length - 1] === '/' ? url.slice(0, -1) : url; } /** * We are incrementing a counter to track how often create-nx-workspace is used in CI * vs dev environments. No personal information is collected. */ async function recordStat(opts) { try { if (!shouldRecordStats()) { return; } const axios = require('axios'); await (axios['default'] ?? axios) .create({ baseURL: getCloudUrl(), timeout: 400, }) .post('/nx-cloud/stats', { command: opts.command, isCI: (0, is_ci_1.isCI)(), useCloud: opts.useCloud, meta: JSON.stringify({ nxVersion: opts.nxVersion, ...opts.meta }), }); } catch (e) { if (process.env.NX_VERBOSE_LOGGING === 'true') { console.error(e); } } } function shouldRecordStats() { try { // Use npm to check registry - this works regardless of which package manager invoked us const stdout = (0, node_child_process_1.execSync)('npm config get registry', { encoding: 'utf-8', windowsHide: false, }); const url = new URL(stdout.trim()); // don't record stats when testing locally return url.hostname !== 'localhost'; } catch { // fallback to true if we can't detect the registry return true; } }