Newer
Older
abysiuscodium / build / check-licenses.js
#!/usr/bin/env node
/**
 * License compliance checker for Abysius Codium build.
 * Scans extension and vscode dependencies for GPL/copyleft licenses.
 * Exit code 0 = clean, 1 = violations found.
 */

const fs = require('fs');
const path = require('path');
const { execSync } = require('child_process');

const BANNED_LICENSES = [
  'GPL-2.0', 'GPL-3.0', 'AGPL-3.0', 'LGPL-2.1', 'LGPL-3.0',
  'GPL', 'AGPL', 'LGPL'
];

const ALLOWED_COPYLEFT_PACKAGES = new Set([
  // Add known-safe exceptions here if needed (e.g., build-only tools)
]);

function scanDir(scanPath) {
  if (!fs.existsSync(path.join(scanPath, 'node_modules'))) {
    console.error(`[LICENSE] No node_modules found in ${scanPath}, skipping...`);
    return [];
  }

  let output;
  try {
    output = execSync('npx license-checker --json --start .', {
      cwd: scanPath,
      encoding: 'utf-8',
      stdio: ['pipe', 'pipe', 'pipe']
    });
  } catch (err) {
    console.warn('[LICENSE] license-checker failed or not installed; install with: npm install -g license-checker');
    return [];
  }

  const packages = JSON.parse(output);
  const violations = [];

  for (const [pkgName, info] of Object.entries(packages)) {
    const licenses = Array.isArray(info.licenses) ? info.licenses : [info.licenses];
    for (const lic of licenses) {
      if (!lic) continue;
      const upper = lic.toUpperCase();
      const isBanned = BANNED_LICENSES.some(b => upper.includes(b));
      if (isBanned && !ALLOWED_COPYLEFT_PACKAGES.has(pkgName)) {
        violations.push({ package: pkgName, license: lic, path: info.path });
      }
    }
  }

  return violations;
}

function main() {
  const root = process.cwd();
  console.log('[LICENSE] Scanning for open-source license compliance...');

  const extDir = path.join(root, 'extensions', 'abysius-ai');
  const vscodeDir = path.join(root, 'work', 'vscode');

  const allViolations = [];

  if (fs.existsSync(extDir)) {
    const extViolations = scanDir(extDir);
    allViolations.push(...extViolations);
  }

  if (fs.existsSync(vscodeDir)) {
    const vscodeViolations = scanDir(vscodeDir);
    allViolations.push(...vscodeViolations);
  }

  if (allViolations.length === 0) {
    console.log('[LICENSE] No copyleft license violations detected.');
    process.exit(0);
  }

  console.error(`[LICENSE] Found ${allViolations.length} potential license violation(s):`);
  for (const v of allViolations) {
    console.error(`  - ${v.package}: ${v.license}`);
  }
  console.error('[LICENSE] Remove or replace these dependencies before distributing binaries.');
  process.exit(1);
}

main();