All files / packages/design-system/scripts/scs rehearse.js

53.06% Statements 26/49
55.26% Branches 21/38
66.66% Functions 6/9
51.16% Lines 22/43

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                                                  1x 1x 1x 1x                           18x       10x 7x     10x   16x 15x 15x     10x 6x 6x 6x       5x 5x 5x 5x 2x   5x                 1x                                                        
#!/usr/bin/env node
/**
 * release:scs:rehearse orchestrator
 *
 * End-to-end dry-run: runs `release:scs`, then the appropriate compare report:
 *   - patch-pairs (newest-vs-previous within slds/) when a patch context is detected
 *   - baseline-vs-source (default) otherwise
 *
 * Patch context = either:
 *   - The current monorepo git branch ends in "-patch" (e.g. main-patch, develop-262-patch), OR
 *   - The supplied --coreBranch ends in "-patch" (e.g. core-262-patch), OR
 *   - The SLDS1 version is a patch increment of the highest-existing version in
 *     packages/slds-scs/slds/ for the slds.css family (same major.minor, higher patch).
 *
 * Both reports are run — they're cheap and complementary. Patch-pairs is run
 * first (more useful for patch reviewers); baseline-vs-source runs second.
 */
import { execSync, spawnSync } from 'node:child_process';
import { fileURLToPath } from 'node:url';
import path from 'node:path';
import fs from 'node:fs';
 
import { loadConfig } from './config-loader.js';
import { parseVersionedFile, compareSemver } from '../validation/compare-output-patch-pairs.js';
 
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const packageRoot = path.resolve(__dirname, '../..');
const monorepoRoot = path.resolve(packageRoot, '../..');
 
function getCurrentBranch() {
  try {
    return execSync('git rev-parse --abbrev-ref HEAD', {
      cwd: monorepoRoot,
      encoding: 'utf8',
    }).trim();
  } catch {
    return null;
  }
}
 
export function isPatchBranch(name) {
  return typeof name === 'string' && /-patch$/.test(name);
}
 
export function isPatchVersionBump(sldsVersion, slds1FilenamesOrDir) {
  if (!sldsVersion) return false;
  const filenames = Array.isArray(slds1FilenamesOrDir)
    ? slds1FilenamesOrDir
    : (fs.existsSync(slds1FilenamesOrDir) ? fs.readdirSync(slds1FilenamesOrDir) : []);
  const newest = filenames
    .map(parseVersionedFile)
    .filter((entry) => entry && entry.family === 'slds' && entry.ext === 'css')
    .map((entry) => entry.version)
    .filter((v) => v !== sldsVersion)
    .sort(compareSemver)
    .pop();
  if (!newest) return false;
  const [newMajor, newMinor] = sldsVersion.split('.').map(Number);
  const [oldMajor, oldMinor] = newest.split('.').map(Number);
  return newMajor === oldMajor && newMinor === oldMinor;
}
 
export function detectPatchContext({ branch, config, slds1Filenames } = {}) {
  const reasons = [];
  if (isPatchBranch(branch)) reasons.push(`monorepo branch ${branch} matches *-patch`);
  if (isPatchBranch(config?.coreBranch)) reasons.push(`coreBranch ${config.coreBranch} matches *-patch`);
  if (isPatchVersionBump(config?.sldsVersion, slds1Filenames || [])) {
    reasons.push(`sldsVersion ${config.sldsVersion} is a patch bump`);
  }
  return { isPatch: reasons.length > 0, reasons };
}
 
function run(cmd, args) {
  const result = spawnSync(cmd, args, { stdio: 'inherit', cwd: packageRoot });
  return result.status === 0;
}
 
// Skip the orchestration when imported by tests
Iif (import.meta.url === `file://${process.argv[1]}`) {
  const config = loadConfig(packageRoot);
  const slds1Dir = path.join(monorepoRoot, 'packages/slds-scs/slds');
  const slds1Filenames = fs.existsSync(slds1Dir) ? fs.readdirSync(slds1Dir) : [];
  const ctx = detectPatchContext({
    branch: getCurrentBranch(),
    config,
    slds1Filenames,
  });
 
  console.log(ctx.isPatch ? '\nšŸ“¦ Patch context detected:' : '\nšŸ“¦ Standard release context');
  ctx.reasons.forEach((r) => console.log(`  • ${r}`));
 
  const releaseOk = run('yarn', ['release:scs', ...process.argv.slice(2)]);
  if (!releaseOk) process.exit(1);
 
  if (ctx.isPatch) {
    console.log('\n→ Running patch-pairs comparison');
    const patchOk = run('yarn', ['release:scs:compare:patch-pairs']);
    if (!patchOk) {
      console.warn('āš ļø  patch-pairs compare exited non-zero — continuing to baseline-vs-source');
    }
  }
 
  console.log('\n→ Running baseline-vs-source comparison');
  const compareOk = run('yarn', ['release:scs:compare']);
  process.exit(compareOk ? 0 : 1);
}