Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@
"replace-in-vscode": "cp -R ./dist/codicon.ttf ../vscode/src/vs/base/browser/ui/codicons/codicon/codicon.ttf && cp ./dist/codiconsLibrary.ts ../vscode/src/vs/base/common/codiconsLibrary.ts",
"export-to-ts": "node ./scripts/export-to-ts.js -f ./src/template/mapping.json > ./dist/codiconsLibrary.ts",
"export-to-csv": "node ./scripts/export-to-csv.js -f ./dist/codicon.ttf > ./dist/codicon.csv",
"copy-metadata": "cp ./src/template/metadata.json ./dist/metadata.json",
"embed-metadata": "node ./scripts/embed-metadata.js",
"check-metadata": "node ./scripts/check-metadata.js",
"fonts": "fantasticon",
"dev": "npm run build && npm run replace-in-vscode",
"build": "npm run clean && npm run svgo && npm run fonts && npm run export-to-ts && npm run export-to-csv && npm run sprite",
"build": "npm run clean && npm run svgo && npm run fonts && npm run export-to-ts && npm run export-to-csv && npm run copy-metadata && npm run embed-metadata && npm run sprite",
"version:bump": "node ./scripts/version-bump.js",
"version:patch": "node ./scripts/version-bump.js patch minor",
"version:minor": "node ./scripts/version-bump.js minor minor",
Expand Down
126 changes: 126 additions & 0 deletions scripts/check-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env node

/**
* This script checks which icons are missing metadata and reports them.
* It helps maintain the metadata.json file by identifying gaps.
*/

const fs = require('fs');
const path = require('path');

// Load the mapping file to get all icon names
const mappingPath = path.join(__dirname, '..', 'src', 'template', 'mapping.json');
const metadataPath = path.join(__dirname, '..', 'src', 'template', 'metadata.json');

if (!fs.existsSync(mappingPath)) {
console.error('Error: mapping.json not found at', mappingPath);
process.exit(1);
}

if (!fs.existsSync(metadataPath)) {
console.error('Error: metadata.json not found at', metadataPath);
process.exit(1);
}

const mapping = JSON.parse(fs.readFileSync(mappingPath, 'utf8'));
const metadata = JSON.parse(fs.readFileSync(metadataPath, 'utf8'));

// Collect all unique icon names from mapping
const allIconNames = new Set();
Object.values(mapping).forEach(aliases => {
// For each code point, add the first alias (primary name)
if (aliases && aliases.length > 0) {
allIconNames.add(aliases[0]);
}
});

// Find icons without metadata
const missingMetadata = [];
allIconNames.forEach(iconName => {
if (!metadata[iconName]) {
missingMetadata.push(iconName);
}
});

// Find metadata for icons that don't exist
const orphanedMetadata = [];
Object.keys(metadata).forEach(iconName => {
if (!allIconNames.has(iconName)) {
orphanedMetadata.push(iconName);
}
});

// Report results
console.log('='.repeat(60));
console.log('Icon Metadata Coverage Report');
console.log('='.repeat(60));
console.log();

console.log(`Total icons: ${allIconNames.size}`);
console.log(`Icons with metadata: ${allIconNames.size - missingMetadata.length}`);
console.log(`Coverage: ${Math.round(((allIconNames.size - missingMetadata.length) / allIconNames.size) * 100)}%`);
console.log();

if (missingMetadata.length > 0) {
console.log(`Icons missing metadata (${missingMetadata.length}):`);
console.log('-'.repeat(60));
missingMetadata.sort().forEach(name => {
console.log(` - ${name}`);
});
console.log();
}

if (orphanedMetadata.length > 0) {
console.log(`Metadata entries for non-existent icons (${orphanedMetadata.length}):`);
console.log('-'.repeat(60));
orphanedMetadata.sort().forEach(name => {
console.log(` - ${name}`);
});
console.log();
}

if (missingMetadata.length === 0 && orphanedMetadata.length === 0) {
console.log('✓ All icons have metadata and no orphaned entries found!');
console.log();
}

// Validate existing metadata structure
const invalidEntries = [];
Object.entries(metadata).forEach(([name, meta]) => {
const issues = [];

if (!meta.tags || !Array.isArray(meta.tags)) {
issues.push('missing or invalid tags array');
} else if (meta.tags.length === 0) {
issues.push('empty tags array');
}

if (!meta.category || typeof meta.category !== 'string') {
issues.push('missing or invalid category');
}

if (!meta.description || typeof meta.description !== 'string') {
issues.push('missing or invalid description');
}

if (issues.length > 0) {
invalidEntries.push({ name, issues });
}
});

if (invalidEntries.length > 0) {
console.log(`Metadata entries with validation issues (${invalidEntries.length}):`);
console.log('-'.repeat(60));
invalidEntries.forEach(({ name, issues }) => {
console.log(` - ${name}:`);
issues.forEach(issue => {
console.log(` * ${issue}`);
});
});
console.log();
}

// Exit with error if there are missing entries
if (missingMetadata.length > 0 || orphanedMetadata.length > 0 || invalidEntries.length > 0) {
process.exit(1);
}
25 changes: 25 additions & 0 deletions scripts/embed-metadata.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const fs = require('fs');
const path = require('path');

const metadataPath = path.join(__dirname, '../src/template/metadata.json');
const htmlPath = path.join(__dirname, '../dist/codicon.html');

if (!fs.existsSync(htmlPath)) {
console.error('HTML file not found:', htmlPath);
process.exit(1);
}

const metadata = fs.readFileSync(metadataPath, 'utf8');
let html = fs.readFileSync(htmlPath, 'utf8');

const placeholder = '{} // METADATA_PLACEHOLDER';
const replacement = `${metadata} // METADATA_PLACEHOLDER`;

if (html.includes('// METADATA_PLACEHOLDER')) {
// Use regex to replace the initialization
html = html.replace(/let metadata = .* \/\/ METADATA_PLACEHOLDER/, `let metadata = ${metadata}; // METADATA_PLACEHOLDER`);
fs.writeFileSync(htmlPath, html);
console.log('Metadata embedded into HTML.');
} else {
console.warn('Metadata placeholder not found in HTML.');
}
Loading
Loading