Skip to content

Commit

Permalink
Update import-icons script.
Browse files Browse the repository at this point in the history
  • Loading branch information
mkrause committed Dec 8, 2024
1 parent c1da9a6 commit 716187b
Showing 1 changed file with 59 additions and 26 deletions.
85 changes: 59 additions & 26 deletions scripts/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import * as fs from 'node:fs/promises';
import { AsyncLocalStorage } from 'node:async_hooks';


//
// Setup
//

type Logger = Pick<Console, 'info' | 'error' | 'log'>;
type Services = { logger: Logger };
const servicesStorage = new AsyncLocalStorage<Services>();
Expand All @@ -26,13 +30,28 @@ const getServices = () => {

type ScriptArgs = {
values: {
help?: undefined | boolean,
silent?: undefined | boolean,
'help'?: undefined | boolean,
'silent'?: undefined | boolean,
'dry-run'?: undefined | boolean,
},
positionals: Array<string>,
};


//
// Common
//

// Return a relative path to the given absolute path, relative to the current CWD
const rel = (absolutePath: string): string => {
return path.relative(process.cwd(), absolutePath);
};


//
// Commands
//

/*
Takes CSS variables of the form `--<var-name>: <expr>;` (as exported from Figma) and converts it to Sass variables. We
expect the same variable to be in the input exactly twice, the first is assumed to be the light mode variant, the
Expand Down Expand Up @@ -101,9 +120,9 @@ const runParseTokens = async (args: ScriptArgs) => {
const runCreateIconsManifest = async (args: ScriptArgs) => {
const { logger } = getServices();

const pathIcons = path.join(process.cwd(), './src/assets/icons');
const pathIconsSource = path.join(process.cwd(), './src/assets/icons');

const files = await fs.readdir(pathIcons);
const files = await fs.readdir(pathIconsSource);
const icons = [];
for (const fileName of files) {
const iconName = fileName.replace(/\.svg$/, '');
Expand All @@ -117,67 +136,80 @@ const runCreateIconsManifest = async (args: ScriptArgs) => {
} as const satisfies Record<string, IconDef>;
`;

const manifestPath = path.join(pathIcons, '_icons.ts');
logger.info(`Writing file: ${manifestPath}`)
const manifestPath = path.join(pathIconsSource, '_icons.ts');
logger.info(`Writing file: ${manifestPath}`);
await fs.writeFile(manifestPath, manifest, { encoding: 'utf-8' });
};

const runImportIcons = async (args: ScriptArgs) => {
const { logger } = getServices();

const isDryRun = args.values['dry-run'] ?? false;

const kebabCase = (string: string) => string
.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/[\s_]+/g, '-')
.toLowerCase();

const remove: Array<string> = [
// Remove other company/project icons
const skippedIcons: Array<string> = [
// Skip other company/project icons
'apache',
];
const rename: Record<string, string> = {
const renamedIcons: Record<string, string> = {
'ki': 'fortanix-ki',
'security-objects': 'security-object',
'carrot-down': 'caret-down', // Typo
'page-fwd': 'page-forward',
'user-account': 'user-profile', // "User account" is a misleading term considering our information architecture
'users': 'user',
// NOTE: missing `account` icon
};

const pathIcons = path.join(process.cwd(), './src/assets/icons_new');
const pathIconsOut = path.join(process.cwd(), './src/assets/icons');
const pathIconsSource = path.join(process.cwd(), './src/assets/icons_source');
const pathIconsTarget = path.join(process.cwd(), './src/assets/icons');

// Delete existing icons
for (const file of await fs.readdir(pathIconsOut)) {
await fs.unlink(path.join(pathIconsOut, file));
logger.log(`Deleting existing icons in ${rel(pathIconsTarget)}`);
if (!isDryRun) {
for (const file of await fs.readdir(pathIconsTarget)) {
await fs.unlink(path.join(pathIconsTarget, file));
}
}

const files = await fs.readdir(pathIcons);
const files = await fs.readdir(pathIconsSource);
for (const fileName of files) {
const fileNameKebab = kebabCase(fileName.replace(/\.svg$/, ''));
const iconName = ((): string => {
if (Object.hasOwn(rename, fileNameKebab) && rename[fileNameKebab]) {
return rename[fileNameKebab];
if (Object.hasOwn(renamedIcons, fileNameKebab) && renamedIcons[fileNameKebab]) {
return renamedIcons[fileNameKebab];
} else {
return fileNameKebab;
}
})();

if (iconName in remove) {
if (skippedIcons.includes(iconName)) {
logger.log(`Skipping icon: ${iconName}`);
continue;
}

const pathSource = path.join(pathIcons, fileName);
const pathTarget = path.join(pathIconsOut, `${iconName}.svg`)
logger.log(`Copying '${pathSource}' to '${pathTarget}'`);
await fs.copyFile(pathSource, pathTarget);
const pathSource = path.join(pathIconsSource, fileName);
const pathTarget = path.join(pathIconsTarget, `${iconName}.svg`)
logger.log(`Copying '${rel(pathSource)}' to '${rel(pathTarget)}'`);
if (!isDryRun) {
await fs.copyFile(pathSource, pathTarget);
}
}

// Create `_icons.ts` manifest file
await runCreateIconsManifest(args);
logger.log(`Creating '_icons.ts' manifest file.`);
if (!isDryRun) {
await runCreateIconsManifest(args);
}
};


//
// Run
//

const printUsage = () => {
const { logger } = getServices();

Expand All @@ -197,8 +229,9 @@ export const run = async (argsRaw: Array<string>): Promise<void> => {
args: argsRaw,
allowPositionals: true,
options: {
help: { type: 'boolean', short: 'h' },
silent: { type: 'boolean' },
'help': { type: 'boolean', short: 'h' },
'silent': { type: 'boolean' },
'dry-run': { type: 'boolean' },
},
});

Expand Down

0 comments on commit 716187b

Please sign in to comment.