All files / packages/design-system/scripts/scs config-loader.js

92.59% Statements 25/27
90.9% Branches 40/44
100% Functions 4/4
91.66% Lines 22/24

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118                                              7x 7x   7x 28x     28x     17x     14x 14x 14x 14x       7x                   1x 1x                                             8x     8x   8x 8x       8x   8x 8x 8x       8x                                            
/**
 * Configuration Loader for SCS Script
 *
 * Loads configuration from multiple sources with the following priority:
 * 1. CLI arguments (--key=value)
 * 2. Environment variables
 * 3. .release-config (shell-style KEY=VALUE file) for versions, WI
 * 4. .distrc.json (nconf JSON file) for nexusCreds, localCorePath
 * 5. Interactive prompts for anything not provided
 */
import fs from 'node:fs';
import path from 'node:path';
import nconf from 'nconf';
 
/**
 * Parse shell-style KEY=VALUE content into a key-value object.
 * Handles lines like: KEY="value" or KEY=value
 * Ignores comments (#), blank lines, and shell directives.
 *
 * @param {string} content - Raw file content
 * @returns {Object} Parsed key-value pairs
 */
export function parseReleaseConfigContent(content) {
  const config = {};
  const lines = content.split('\n');
 
  for (const line of lines) {
    const trimmed = line.trim();
 
    // Skip empty lines and comments
    if (!trimmed || trimmed.startsWith('#')) continue;
 
    // Skip shell directives (export, source, set, etc.)
    if (/^(export|source|set|if|fi|else|elif|return|echo)\b/.test(trimmed)) continue;
 
    // Match KEY=VALUE or KEY="VALUE" patterns
    const match = trimmed.match(/^([A-Z_][A-Z0-9_]*)=["']?(.+?)["']?$/);
    Eif (match) {
      const [, key, value] = match;
      config[key] = value;
    }
  }
 
  return config;
}
 
/**
 * Read and parse a shell-style .release-config file.
 *
 * @param {string} filePath - Path to the .release-config file
 * @returns {Object} Parsed key-value pairs, or {} if file is missing
 */
export function parseReleaseConfig(filePath) {
  Eif (!fs.existsSync(filePath)) {
    return {};
  }
  return parseReleaseConfigContent(fs.readFileSync(filePath, 'utf8'));
}
 
/**
 * Load all configuration sources and return a merged config object.
 *
 * @param {string} packageRoot - Absolute path to packages/design-system
 * @param {Object} [releaseConfigOverride] - Pre-parsed release config object.
 *   When provided, skips reading .release-config from disk.
 * @returns {Object} Merged configuration with the following keys:
 *   - sldsVersion: SLDS1 version string
 *   - slds2Version: SLDS2 version string
 *   - scsVersion: SCS version string
 *   - wi: Work Item ID (SCS_WI)
 *   - nexusCreds: Nexus credentials (user:pass)
 *   - case: GUS Change Case number
 *   - coreBranch: target core-XXX-patch branch on slds-scs
 *   - doPR: whether to create PR
 *   - scsRepoPath: resolved path to the slds-scs repo
 */
export function loadConfig(packageRoot, releaseConfigOverride) {
  const rootPath = (...args) => path.resolve(packageRoot, ...args);
 
  // Load nconf with CLI args, env vars, and .distrc.json
  nconf.argv().env();
 
  const distrcPath = rootPath('.distrc.json');
  Iif (fs.existsSync(distrcPath)) {
    nconf.file({ file: distrcPath });
  }
 
  const releaseConfig = releaseConfigOverride || parseReleaseConfig(rootPath('.release-config'));
 
  const codeDir = releaseConfig.CODE_DIR || null;
  const monorepoRoot = path.resolve(packageRoot, '../..');
  const scsRepoPath = codeDir
    ? path.resolve(codeDir, 'slds-scs')
    : path.resolve(monorepoRoot, '../slds-scs');
 
  return {
    sldsVersion: nconf.get('sldsVersion') || releaseConfig.SLDS1_VERSION || null,
    slds2Version: nconf.get('slds2Version') || releaseConfig.SLDS2_VERSION || null,
    scsVersion: nconf.get('scsVersion') || releaseConfig.SCS_VERSION || null,
 
    wi: nconf.get('wi') || process.env.SCS_WI || releaseConfig.SCS_WI || null,
 
    case: nconf.get('case') || null,
 
    nexusCreds: nconf.get('nexusCreds') || null,
 
    doPR: nconf.get('doPR') || null,
 
    forcePush: nconf.get('forcePush') ?? null,
 
    coreBranch: nconf.get('coreBranch') || releaseConfig.CORE_BRANCH || null,
 
    skipSeed: process.argv.includes('--skip-seed') || process.argv.includes('--skipSeed'),
 
    scsRepoPath,
  };
}