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

91.66% Statements 22/24
87.5% Branches 35/40
100% Functions 4/4
90.47% Lines 19/21

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                                              7x 7x   7x 28x     28x     17x     14x 14x 14x 14x       7x                   1x 1x                                             1x     1x   1x 1x       1x   1x                                        
/**
 * 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)
 *   - case: GUS Change Case number
 *   - nexusCreds: Nexus credentials (user:pass)
 *   - pearlOnly: whether to run the pearl-only release mode
 *   - pearlVersion: pearl subtheme version string
 *   - expectedSourceSha: immutable source commit used to generate release artifacts
 */
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'));
 
  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,
 
    pearlOnly: process.argv.includes('--pearl-only') || process.argv.includes('--pearlOnly'),
    pearlVersion: nconf.get('pearlVersion') || releaseConfig.PEARL_VERSION || null,
    expectedSourceSha:
      nconf.get('expectedSourceSha') ||
      process.env.SCS_EXPECTED_SOURCE_SHA ||
      releaseConfig.SCS_EXPECTED_SOURCE_SHA ||
      null,
  };
}