Skip to content

Commit 4ca1ad8

Browse files
committed
Improve shadow mode logging with clear section headers
Each step of the NOTICE generation now logs what it's doing and why: - Step 1: Parse CG Output (what CG found via ClearlyDefined) - Step 2: Remove Dev Dependency Leaks (why mocha/mocha-junit-reporter are filtered) - Step 3: Apply License Overrides (ClearlyDefined mis-classifications) - Step 4: Dynamic Gap Filling (LICENSE from node_modules, extensions, cgmanifest) - Step 5: Static Entries (undiscoverable packages) - Summary with counts and actionable next steps - Action sections: file CD curations, clean up stale entries, fix missing licenses
1 parent d8a06b0 commit 4ca1ad8

1 file changed

Lines changed: 59 additions & 13 deletions

File tree

build/azure-pipelines/oss/generate-notices.ts

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,10 @@ function main(): void {
452452

453453
// -- Step 2: Parse CG output ------------------------------------------
454454

455-
console.log('Parsing CG output...');
455+
console.log('');
456+
console.log('=== Step 1: Parse CG Output ===');
457+
console.log('Reading the NOTICE file generated by Component Governance (notice@0 task).');
458+
console.log(`Source: ${cgPath} (${cgSizeMB.toFixed(2)} MB)`);
456459
const cgEntries = parseNoticeFile(cgContent);
457460
console.log(` Parsed ${cgEntries.length} entries from CG output`);
458461

@@ -472,19 +475,27 @@ function main(): void {
472475

473476
// -- Step 3: Filter dev dependency leaks ------------------------------
474477

478+
console.log('');
479+
console.log('=== Step 2: Remove Dev Dependency Leaks ===');
480+
console.log('CG includes everything in node_modules/ including test frameworks.');
481+
console.log('These packages are used for development/testing only and do not ship with VS Code.');
482+
console.log(`Filtering: ${staticData.devDepFilter.join(', ')}`);
475483
const filteredDevDeps: string[] = [];
476484
for (const devDep of staticData.devDepFilter) {
477485
const key = devDep.toLowerCase();
478486
if (mergedMap.has(key)) {
479487
const entry = mergedMap.get(key)!;
480-
console.log(` FILTERED dev dep: ${entry.name} ${entry.version}`);
488+
console.log(` Removed: ${entry.name} ${entry.version}`);
481489
mergedMap.delete(key);
482490
filteredDevDeps.push(devDep);
483491
}
484492
}
485493

486494
// -- Step 4: Apply overrides ------------------------------------------
487495

496+
console.log('');
497+
console.log('=== Step 3: Apply License Overrides ===');
498+
console.log('Correcting known ClearlyDefined mis-classifications.');
488499
const overridesApplied: string[] = [];
489500
for (const [pkgName, override] of Object.entries(staticData.overrides)) {
490501
const key = pkgName.toLowerCase();
@@ -500,7 +511,11 @@ function main(): void {
500511

501512
// -- Step 5: Dynamic gap filling --------------------------------------
502513

503-
console.log('Finding gaps — packages that need coverage but CG missed...');
514+
console.log('');
515+
console.log('=== Step 4: Dynamic Gap Filling ===');
516+
console.log('For packages CG missed, read LICENSE files directly from node_modules/,');
517+
console.log('extension dependencies, and cgmanifest.json licenseDetail fields.');
518+
console.log('No network calls — all license data is local.');
504519
const dynamicCoverageList: string[] = [];
505520
const missingLicense: string[] = [];
506521

@@ -561,6 +576,11 @@ function main(): void {
561576
}
562577

563578
// 5b: Check extension dependencies (packages bundled into extensions)
579+
console.log('');
580+
console.log(' --- Extension-bundled dependencies ---');
581+
console.log(' Checking packages declared in extension package.json files.');
582+
console.log(' These get webpack-bundled into extension JS but their LICENSE files');
583+
console.log(' are available in node_modules/ at build time.');
564584
const extensionsDir = path.join(repoRoot, 'extensions');
565585
if (fs.existsSync(extensionsDir)) {
566586
for (const ext of fs.readdirSync(extensionsDir)) {
@@ -627,7 +647,10 @@ function main(): void {
627647
}
628648

629649
// 5c: Check cgmanifest.json entries
630-
console.log('Scanning cgmanifest.json entries...');
650+
console.log('');
651+
console.log(' --- Vendored code (cgmanifest.json) ---');
652+
console.log(' Language grammars, themes, and vendored libraries declared in cgmanifest.json.');
653+
console.log(' Uses inline licenseDetail field when available.');
631654
const cgManifestEntries = parseCgManifests(repoRoot);
632655
for (const entry of cgManifestEntries) {
633656
const key = entry.name.toLowerCase();
@@ -649,6 +672,10 @@ function main(): void {
649672

650673
// -- Step 6: Add static entries ---------------------------------------
651674

675+
console.log('');
676+
console.log('=== Step 5: Static Entries ===');
677+
console.log('Packages where LICENSE cannot be discovered automatically (compiled into');
678+
console.log('binaries, native C libraries, etc). These are maintained in static-notices.json.');
652679
let staticEntriesAdded = 0;
653680
const staleStaticEntries: string[] = [];
654681

@@ -732,28 +759,47 @@ function main(): void {
732759
// -- Summary ----------------------------------------------------------
733760

734761
console.log('');
735-
console.log(`Merged NOTICE: ${cgEntryCount} CG + ${dynamicCoverageList.length} dynamic + ${staticEntriesAdded} static - ${filteredDevDeps.length} filtered = ${sorted.length} total`);
736-
console.log(`Output: ${outputPath} (${(output.length / 1024 / 1024).toFixed(2)} MB)`);
737-
console.log(`Report: ${reportPath}`);
762+
console.log('=== Summary ===');
763+
console.log(` CG (ClearlyDefined): ${cgEntryCount} packages`);
764+
console.log(` Dynamic (LICENSE files): ${dynamicCoverageList.length} packages`);
765+
console.log(` Static (manual entries): ${staticEntriesAdded} packages`);
766+
console.log(` Dev deps removed: ${filteredDevDeps.length} (${filteredDevDeps.join(', ') || 'none'})`);
767+
console.log(` --------------------------------`);
768+
console.log(` Total in NOTICE file: ${sorted.length} packages`);
769+
console.log(` Output: ${outputPath} (${(output.length / 1024 / 1024).toFixed(2)} MB)`);
770+
console.log(` Report: ${reportPath}`);
738771

739772
if (dynamicCoverageList.length > 0) {
740-
console.log(`\n${dynamicCoverageList.length} packages covered dynamically — consider filing ClearlyDefined curations:`);
773+
console.log('');
774+
console.log(`=== Action: File ClearlyDefined Curations ===`);
775+
console.log(`${dynamicCoverageList.length} packages were covered by reading LICENSE files locally.`);
776+
console.log('Filing ClearlyDefined curations for these will let CG handle them natively,');
777+
console.log('reducing the dynamic coverage list over time.');
741778
for (const item of dynamicCoverageList) {
742-
console.log(` ${item}`);
779+
console.log(` - ${item}`);
743780
}
744781
}
745782

746783
if (staleStaticEntries.length > 0) {
747-
console.log(`\n${staleStaticEntries.length} static-notices.json entries are now redundant (CG/dynamic covers them):`);
784+
console.log('');
785+
console.log(`=== Action: Clean Up static-notices.json ===`);
786+
console.log(`${staleStaticEntries.length} entries in static-notices.json are now redundant.`);
787+
console.log('CG or dynamic coverage already handles these. Remove them from the file.');
748788
for (const name of staleStaticEntries) {
749-
console.log(` ${name}`);
789+
console.log(` - ${name}`);
750790
}
751791
}
752792

753793
if (missingLicense.length > 0) {
754-
console.warn(`\nWARNING: ${missingLicense.length} packages have no discoverable license:`);
794+
console.log('');
795+
console.log(`=== WARNING: ${missingLicense.length} Packages With No Discoverable License ===`);
796+
console.log('These packages are not covered by CG, have no LICENSE file in node_modules/,');
797+
console.log('no same-repo sibling with a LICENSE, and no licenseDetail in cgmanifest.json.');
798+
console.log('Each needs either:');
799+
console.log(' 1. licenseDetail added to its cgmanifest.json entry, OR');
800+
console.log(' 2. An entry in static-notices.json with full license text');
755801
for (const name of missingLicense) {
756-
console.warn(` x ${name}`);
802+
console.log(` x ${name}`);
757803
}
758804
}
759805
}

0 commit comments

Comments
 (0)