@georgewrmarshall/design-system-metrics 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +2 -1
- package/CHANGELOG.md +46 -0
- package/__tests__/metrics.test.js +22 -7
- package/index.js +149 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,8 +5,54 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.6.0] - 2026-02-23
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Complete MMDS Component List**: MMDS Usage sheet now shows all available MMDS components, including those with 0 instances
|
|
13
|
+
- Previously only showed components that were actively used
|
|
14
|
+
- Now displays the full component list with usage counts, making it easier to identify available but unused components
|
|
15
|
+
- Helps track MMDS component adoption opportunities
|
|
16
|
+
|
|
17
|
+
- **Totals Rows**: All sheets now include totals at the bottom for easy summary analysis
|
|
18
|
+
- Migration Progress: Shows total deprecated instances, total MMDS instances, and overall migration percentage (with accurate deduplication)
|
|
19
|
+
- Intermediate Migrations: Shows total instances awaiting intermediate migration
|
|
20
|
+
- MMDS Usage: Shows total MMDS component instances across all components
|
|
21
|
+
- No Replacement: Shows total instances of components without direct replacements
|
|
22
|
+
- Console output now displays these totals for quick visibility
|
|
23
|
+
|
|
24
|
+
- **Grouped Display with Summary Rows**: Migration Progress sheet now groups deprecated components by their MMDS replacement
|
|
25
|
+
- Components mapping to the same MMDS component are displayed together (e.g., all Icon variants grouped together)
|
|
26
|
+
- Individual rows show deprecated component details with "-" for MMDS instances and percentage to avoid misleading duplicates
|
|
27
|
+
- Summary rows (format: "→ Component Total") show aggregated deprecated count, MMDS instances, and accurate migration percentage for each group
|
|
28
|
+
- Single-mapping components continue to display normally with all columns filled
|
|
29
|
+
- Provides much more accurate and meaningful migration percentages
|
|
30
|
+
|
|
31
|
+
### Fixed
|
|
32
|
+
|
|
33
|
+
- **Migration Progress Totals**: Fixed duplicate counting when multiple deprecated components map to the same MMDS component
|
|
34
|
+
- Each MMDS component is counted only once in the total, providing accurate migration percentage
|
|
35
|
+
- Individual rows still show correct per-component breakdown
|
|
36
|
+
|
|
37
|
+
- **Test Suite**: Updated tests to work with date-stamped output files
|
|
38
|
+
- Added helper function to dynamically find generated XLSX files
|
|
39
|
+
- All 14 tests passing
|
|
40
|
+
|
|
41
|
+
## [2.5.0] - 2026-02-21
|
|
42
|
+
|
|
43
|
+
### Fixed
|
|
44
|
+
|
|
45
|
+
- **Version Number**: Corrected CLI version number in index.js to match package.json version (was incorrectly set to "3.0.0")
|
|
46
|
+
|
|
8
47
|
## [2.4.0] - 2026-02-21
|
|
9
48
|
|
|
49
|
+
### Added
|
|
50
|
+
|
|
51
|
+
- **Output File Date Stamps**: Generated XLSX files now automatically include today's date in the filename
|
|
52
|
+
- Format: `{project}-component-metrics-YYYY-MM-DD.xlsx`
|
|
53
|
+
- Example: `extension-component-metrics-2026-02-21.xlsx`
|
|
54
|
+
- Makes it easier to track metrics over time and compare historical data
|
|
55
|
+
|
|
10
56
|
### Changed
|
|
11
57
|
|
|
12
58
|
- **Extension Component Mappings**: Corrected replacement targets to reflect actual migration state
|
|
@@ -5,7 +5,13 @@ const ExcelJS = require('exceljs');
|
|
|
5
5
|
|
|
6
6
|
const TEST_CONFIG = path.join(__dirname, 'fixtures/test-config.json');
|
|
7
7
|
const OUTPUT_DIR = path.join(__dirname, 'output');
|
|
8
|
-
|
|
8
|
+
// Helper to get the generated XLSX file (with date stamp)
|
|
9
|
+
const getXLSXOutput = async () => {
|
|
10
|
+
const files = await fs.readdir(OUTPUT_DIR);
|
|
11
|
+
const xlsxFile = files.find(f => f.startsWith('test-metrics-') && f.endsWith('.xlsx'));
|
|
12
|
+
return xlsxFile ? path.join(OUTPUT_DIR, xlsxFile) : null;
|
|
13
|
+
};
|
|
14
|
+
const XLSX_OUTPUT_BASE = 'test-metrics';
|
|
9
15
|
|
|
10
16
|
describe('Design System Metrics', () => {
|
|
11
17
|
beforeAll(() => {
|
|
@@ -50,12 +56,8 @@ describe('Design System Metrics', () => {
|
|
|
50
56
|
{ stdio: 'pipe' }
|
|
51
57
|
);
|
|
52
58
|
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
.then(() => true)
|
|
56
|
-
.catch(() => false);
|
|
57
|
-
|
|
58
|
-
expect(exists).toBe(true);
|
|
59
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
60
|
+
expect(XLSX_OUTPUT).not.toBeNull();
|
|
59
61
|
|
|
60
62
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
61
63
|
const sheetNames = workbook.worksheets.map(ws => ws.name);
|
|
@@ -74,6 +76,7 @@ describe('Design System Metrics', () => {
|
|
|
74
76
|
{ stdio: 'pipe' }
|
|
75
77
|
);
|
|
76
78
|
|
|
79
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
77
80
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
78
81
|
const data = getSheetData(workbook, 'Migration Progress');
|
|
79
82
|
const headers = data[0];
|
|
@@ -92,6 +95,7 @@ describe('Design System Metrics', () => {
|
|
|
92
95
|
{ stdio: 'pipe' }
|
|
93
96
|
);
|
|
94
97
|
|
|
98
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
95
99
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
96
100
|
const data = getSheetData(workbook, 'Migration Progress');
|
|
97
101
|
|
|
@@ -111,6 +115,7 @@ describe('Design System Metrics', () => {
|
|
|
111
115
|
{ stdio: 'pipe' }
|
|
112
116
|
);
|
|
113
117
|
|
|
118
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
114
119
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
115
120
|
const data = getSheetData(workbook, 'Migration Progress');
|
|
116
121
|
|
|
@@ -128,6 +133,7 @@ describe('Design System Metrics', () => {
|
|
|
128
133
|
{ stdio: 'pipe' }
|
|
129
134
|
);
|
|
130
135
|
|
|
136
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
131
137
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
132
138
|
const data = getSheetData(workbook, 'Path-Level Detail');
|
|
133
139
|
const headers = data[0];
|
|
@@ -144,6 +150,7 @@ describe('Design System Metrics', () => {
|
|
|
144
150
|
{ stdio: 'pipe' }
|
|
145
151
|
);
|
|
146
152
|
|
|
153
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
147
154
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
148
155
|
const data = getSheetData(workbook, 'Path-Level Detail');
|
|
149
156
|
|
|
@@ -159,6 +166,7 @@ describe('Design System Metrics', () => {
|
|
|
159
166
|
{ stdio: 'pipe' }
|
|
160
167
|
);
|
|
161
168
|
|
|
169
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
162
170
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
163
171
|
const data = getSheetData(workbook, 'Path-Level Detail');
|
|
164
172
|
|
|
@@ -174,6 +182,7 @@ describe('Design System Metrics', () => {
|
|
|
174
182
|
{ stdio: 'pipe' }
|
|
175
183
|
);
|
|
176
184
|
|
|
185
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
177
186
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
178
187
|
const data = getSheetData(workbook, 'Path-Level Detail');
|
|
179
188
|
|
|
@@ -190,6 +199,7 @@ describe('Design System Metrics', () => {
|
|
|
190
199
|
{ stdio: 'pipe' }
|
|
191
200
|
);
|
|
192
201
|
|
|
202
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
193
203
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
194
204
|
const data = getSheetData(workbook, 'MMDS Usage');
|
|
195
205
|
const headers = data[0];
|
|
@@ -205,6 +215,7 @@ describe('Design System Metrics', () => {
|
|
|
205
215
|
{ stdio: 'pipe' }
|
|
206
216
|
);
|
|
207
217
|
|
|
218
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
208
219
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
209
220
|
const data = getSheetData(workbook, 'MMDS Usage');
|
|
210
221
|
|
|
@@ -222,6 +233,7 @@ describe('Design System Metrics', () => {
|
|
|
222
233
|
{ stdio: 'pipe' }
|
|
223
234
|
);
|
|
224
235
|
|
|
236
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
225
237
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
226
238
|
const data = getSheetData(workbook, 'MMDS Usage');
|
|
227
239
|
|
|
@@ -237,6 +249,7 @@ describe('Design System Metrics', () => {
|
|
|
237
249
|
{ stdio: 'pipe' }
|
|
238
250
|
);
|
|
239
251
|
|
|
252
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
240
253
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
241
254
|
const data = getSheetData(workbook, 'MMDS Usage');
|
|
242
255
|
|
|
@@ -253,6 +266,7 @@ describe('Design System Metrics', () => {
|
|
|
253
266
|
{ stdio: 'pipe' }
|
|
254
267
|
);
|
|
255
268
|
|
|
269
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
256
270
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
257
271
|
const data = getSheetData(workbook, 'No Replacement');
|
|
258
272
|
const headers = data[0];
|
|
@@ -269,6 +283,7 @@ describe('Design System Metrics', () => {
|
|
|
269
283
|
{ stdio: 'pipe' }
|
|
270
284
|
);
|
|
271
285
|
|
|
286
|
+
const XLSX_OUTPUT = await getXLSXOutput();
|
|
272
287
|
const workbook = await readXLSX(XLSX_OUTPUT);
|
|
273
288
|
const data = getSheetData(workbook, 'No Replacement');
|
|
274
289
|
|
package/index.js
CHANGED
|
@@ -46,7 +46,7 @@ const validateConfig = (cfg) => {
|
|
|
46
46
|
|
|
47
47
|
// Define CLI options using Commander
|
|
48
48
|
program
|
|
49
|
-
.version("
|
|
49
|
+
.version("2.6.0")
|
|
50
50
|
.description("Design System Metrics CLI Tool - Track component usage and migration progress")
|
|
51
51
|
.requiredOption(
|
|
52
52
|
"-p, --project <name>",
|
|
@@ -259,12 +259,19 @@ const main = async () => {
|
|
|
259
259
|
rootFolder,
|
|
260
260
|
ignoreFolders,
|
|
261
261
|
filePattern,
|
|
262
|
-
outputFile,
|
|
262
|
+
outputFile: baseOutputFile,
|
|
263
263
|
deprecatedComponents = {},
|
|
264
264
|
currentComponents = [],
|
|
265
265
|
currentPackages = [],
|
|
266
266
|
} = projectConfig;
|
|
267
267
|
|
|
268
|
+
// Add today's date to the output filename
|
|
269
|
+
const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD format
|
|
270
|
+
const ext = path.extname(baseOutputFile);
|
|
271
|
+
const basename = path.basename(baseOutputFile, ext);
|
|
272
|
+
const dirname = path.dirname(baseOutputFile);
|
|
273
|
+
const outputFile = path.join(dirname, `${basename}-${today}${ext}`);
|
|
274
|
+
|
|
268
275
|
const currentComponentsSet = new Set(currentComponents);
|
|
269
276
|
|
|
270
277
|
console.log(chalk.blue(`\nStarting audit for project: ${projectName}\n`));
|
|
@@ -362,27 +369,99 @@ const main = async () => {
|
|
|
362
369
|
(metrics.replacement.package.includes("@metamask/design-system"))
|
|
363
370
|
);
|
|
364
371
|
|
|
372
|
+
// Group deprecated components by their MMDS replacement component
|
|
373
|
+
const groupedByMMDS = new Map();
|
|
365
374
|
componentsWithMMDSReplacement.forEach(([componentName, metrics]) => {
|
|
366
375
|
const mmdsComp = metrics.replacement.component;
|
|
367
|
-
|
|
376
|
+
if (!groupedByMMDS.has(mmdsComp)) {
|
|
377
|
+
groupedByMMDS.set(mmdsComp, []);
|
|
378
|
+
}
|
|
379
|
+
groupedByMMDS.get(mmdsComp).push([componentName, metrics]);
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
let totalDeprecated = 0;
|
|
383
|
+
let totalMMDS = 0;
|
|
384
|
+
|
|
385
|
+
// Process each MMDS component group
|
|
386
|
+
for (const [mmdsComp, deprecatedComponents] of groupedByMMDS.entries()) {
|
|
368
387
|
const mmdsCount = currentMetrics.get(mmdsComp)?.count || 0;
|
|
369
|
-
const total = deprecatedCount + mmdsCount;
|
|
370
|
-
const percentage = total > 0 ? (mmdsCount / total) * 100 : 0;
|
|
371
|
-
const sourcePaths = deprecatedComponents[componentName].paths.join(", ");
|
|
372
388
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
deprecatedCount
|
|
378
|
-
mmdsCount
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
389
|
+
if (deprecatedComponents.length === 1) {
|
|
390
|
+
// Single component mapping - show normally
|
|
391
|
+
const [componentName, metrics] = deprecatedComponents[0];
|
|
392
|
+
const deprecatedCount = metrics.totalCount;
|
|
393
|
+
const total = deprecatedCount + mmdsCount;
|
|
394
|
+
const percentage = total > 0 ? (mmdsCount / total) * 100 : 0;
|
|
395
|
+
const sourcePaths = config.projects[projectName].deprecatedComponents[componentName].paths.join(", ");
|
|
396
|
+
|
|
397
|
+
totalDeprecated += deprecatedCount;
|
|
398
|
+
totalMMDS += mmdsCount;
|
|
399
|
+
|
|
400
|
+
migrationSheet.addRow([
|
|
401
|
+
componentName,
|
|
402
|
+
sourcePaths,
|
|
403
|
+
mmdsComp,
|
|
404
|
+
deprecatedCount,
|
|
405
|
+
mmdsCount,
|
|
406
|
+
`${percentage.toFixed(2)}%`,
|
|
407
|
+
]);
|
|
408
|
+
} else {
|
|
409
|
+
// Multiple components mapping to same MMDS component
|
|
410
|
+
let groupDeprecatedTotal = 0;
|
|
411
|
+
|
|
412
|
+
// Add individual rows (without MMDS count and percentage)
|
|
413
|
+
deprecatedComponents.forEach(([componentName, metrics]) => {
|
|
414
|
+
const deprecatedCount = metrics.totalCount;
|
|
415
|
+
const sourcePaths = config.projects[projectName].deprecatedComponents[componentName].paths.join(", ");
|
|
416
|
+
|
|
417
|
+
groupDeprecatedTotal += deprecatedCount;
|
|
418
|
+
|
|
419
|
+
migrationSheet.addRow([
|
|
420
|
+
componentName,
|
|
421
|
+
sourcePaths,
|
|
422
|
+
mmdsComp,
|
|
423
|
+
deprecatedCount,
|
|
424
|
+
"-",
|
|
425
|
+
"-",
|
|
426
|
+
]);
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
// Add summary row for the group
|
|
430
|
+
const total = groupDeprecatedTotal + mmdsCount;
|
|
431
|
+
const percentage = total > 0 ? (mmdsCount / total) * 100 : 0;
|
|
432
|
+
|
|
433
|
+
migrationSheet.addRow([
|
|
434
|
+
`→ ${mmdsComp} Total`,
|
|
435
|
+
"",
|
|
436
|
+
mmdsComp,
|
|
437
|
+
groupDeprecatedTotal,
|
|
438
|
+
mmdsCount,
|
|
439
|
+
`${percentage.toFixed(2)}%`,
|
|
440
|
+
]);
|
|
441
|
+
|
|
442
|
+
totalDeprecated += groupDeprecatedTotal;
|
|
443
|
+
totalMMDS += mmdsCount;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Add totals row
|
|
448
|
+
const totalAll = totalDeprecated + totalMMDS;
|
|
449
|
+
const totalPercentage = totalAll > 0 ? (totalMMDS / totalAll) * 100 : 0;
|
|
450
|
+
migrationSheet.addRow([
|
|
451
|
+
"TOTAL",
|
|
452
|
+
"",
|
|
453
|
+
"",
|
|
454
|
+
totalDeprecated,
|
|
455
|
+
totalMMDS,
|
|
456
|
+
`${totalPercentage.toFixed(2)}%`,
|
|
457
|
+
]);
|
|
382
458
|
|
|
383
459
|
console.log(
|
|
384
460
|
chalk.blue(`Migration Progress: ${componentsWithMMDSReplacement.length} components tracked`)
|
|
385
461
|
);
|
|
462
|
+
console.log(
|
|
463
|
+
chalk.blue(`Total Migration: ${totalMMDS}/${totalAll} (${totalPercentage.toFixed(2)}%)`)
|
|
464
|
+
);
|
|
386
465
|
|
|
387
466
|
// Sheet 2: Intermediate Migrations (components migrating to component-library)
|
|
388
467
|
const intermediateSheet = workbook.addWorksheet("Intermediate Migrations");
|
|
@@ -400,11 +479,15 @@ const main = async () => {
|
|
|
400
479
|
metrics.replacement.package === "component-library"
|
|
401
480
|
);
|
|
402
481
|
|
|
482
|
+
let totalIntermediate = 0;
|
|
483
|
+
|
|
403
484
|
componentsWithIntermediateReplacement.forEach(([componentName, metrics]) => {
|
|
404
485
|
const oldPaths = deprecatedComponents[componentName].paths.join(", ");
|
|
405
486
|
const newComponent = metrics.replacement.component;
|
|
406
487
|
const newPath = metrics.replacement.path || metrics.replacement.package;
|
|
407
488
|
|
|
489
|
+
totalIntermediate += metrics.totalCount;
|
|
490
|
+
|
|
408
491
|
intermediateSheet.addRow([
|
|
409
492
|
componentName,
|
|
410
493
|
oldPaths,
|
|
@@ -414,9 +497,21 @@ const main = async () => {
|
|
|
414
497
|
]);
|
|
415
498
|
});
|
|
416
499
|
|
|
500
|
+
// Add totals row
|
|
501
|
+
intermediateSheet.addRow([
|
|
502
|
+
"TOTAL",
|
|
503
|
+
"",
|
|
504
|
+
"",
|
|
505
|
+
"",
|
|
506
|
+
totalIntermediate,
|
|
507
|
+
]);
|
|
508
|
+
|
|
417
509
|
console.log(
|
|
418
510
|
chalk.blue(`Intermediate Migrations: ${componentsWithIntermediateReplacement.length} components tracked`)
|
|
419
511
|
);
|
|
512
|
+
console.log(
|
|
513
|
+
chalk.blue(`Total Intermediate Instances: ${totalIntermediate}`)
|
|
514
|
+
);
|
|
420
515
|
|
|
421
516
|
// Sheet 3: Path-Level Detail
|
|
422
517
|
const pathDetailSheet = workbook.addWorksheet("Path-Level Detail");
|
|
@@ -446,15 +541,35 @@ const main = async () => {
|
|
|
446
541
|
const mmdsSheet = workbook.addWorksheet("MMDS Usage");
|
|
447
542
|
mmdsSheet.addRow(["Component", "Instances", "File Paths"]);
|
|
448
543
|
|
|
449
|
-
|
|
450
|
-
|
|
544
|
+
// Include all MMDS components, even those with 0 instances
|
|
545
|
+
let totalMMDSUsage = 0;
|
|
546
|
+
|
|
547
|
+
currentComponentsSet.forEach((componentName) => {
|
|
548
|
+
const metrics = currentMetrics.get(componentName);
|
|
549
|
+
const count = metrics ? metrics.count : 0;
|
|
550
|
+
const files = metrics ? metrics.files.join(", ") : "";
|
|
551
|
+
|
|
552
|
+
totalMMDSUsage += count;
|
|
553
|
+
|
|
554
|
+
console.log(`${chalk.cyan(componentName)}: ${count} (MMDS)`);
|
|
451
555
|
mmdsSheet.addRow([
|
|
452
556
|
componentName,
|
|
453
|
-
|
|
454
|
-
|
|
557
|
+
count,
|
|
558
|
+
files,
|
|
455
559
|
]);
|
|
456
560
|
});
|
|
457
561
|
|
|
562
|
+
// Add totals row
|
|
563
|
+
mmdsSheet.addRow([
|
|
564
|
+
"TOTAL",
|
|
565
|
+
totalMMDSUsage,
|
|
566
|
+
"",
|
|
567
|
+
]);
|
|
568
|
+
|
|
569
|
+
console.log(
|
|
570
|
+
chalk.blue(`Total MMDS Usage: ${totalMMDSUsage} instances`)
|
|
571
|
+
);
|
|
572
|
+
|
|
458
573
|
// Sheet 5: No Replacement Components
|
|
459
574
|
const noReplacementSheet = workbook.addWorksheet("No Replacement");
|
|
460
575
|
noReplacementSheet.addRow(["Component", "Path", "Instances", "File Paths"]);
|
|
@@ -462,8 +577,12 @@ const main = async () => {
|
|
|
462
577
|
const componentsWithNoReplacement = Array.from(deprecatedMetrics.entries())
|
|
463
578
|
.filter(([, metrics]) => !metrics.replacement);
|
|
464
579
|
|
|
580
|
+
let totalNoReplacement = 0;
|
|
581
|
+
|
|
465
582
|
componentsWithNoReplacement.forEach(([componentName, metrics]) => {
|
|
466
583
|
const paths = deprecatedComponents[componentName].paths.join(", ");
|
|
584
|
+
totalNoReplacement += metrics.totalCount;
|
|
585
|
+
|
|
467
586
|
noReplacementSheet.addRow([
|
|
468
587
|
componentName,
|
|
469
588
|
paths,
|
|
@@ -472,9 +591,20 @@ const main = async () => {
|
|
|
472
591
|
]);
|
|
473
592
|
});
|
|
474
593
|
|
|
594
|
+
// Add totals row
|
|
595
|
+
noReplacementSheet.addRow([
|
|
596
|
+
"TOTAL",
|
|
597
|
+
"",
|
|
598
|
+
totalNoReplacement,
|
|
599
|
+
"",
|
|
600
|
+
]);
|
|
601
|
+
|
|
475
602
|
console.log(
|
|
476
603
|
chalk.blue(`No Replacement: ${componentsWithNoReplacement.length} components`)
|
|
477
604
|
);
|
|
605
|
+
console.log(
|
|
606
|
+
chalk.blue(`Total No Replacement Instances: ${totalNoReplacement}`)
|
|
607
|
+
);
|
|
478
608
|
|
|
479
609
|
// Create output directory if it doesn't exist
|
|
480
610
|
const outputDir = path.dirname(outputFile);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@georgewrmarshall/design-system-metrics",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "A CLI tool to audit design system component usage from local libraries, NPM packages, and track deprecated components across MetaMask codebases",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"packageManager": "yarn@4.3.1",
|