diff --git a/bin/paragon-scripts.js b/bin/paragon-scripts.js index 8410f3cc5b..455fe33d11 100755 --- a/bin/paragon-scripts.js +++ b/bin/paragon-scripts.js @@ -1,33 +1,99 @@ #!/usr/bin/env node const chalk = require('chalk'); +const { program, Option } = require('commander'); const themeCommand = require('../lib/install-theme'); const buildTokensCommand = require('../lib/build-tokens'); const replaceVariablesCommand = require('../lib/replace-variables'); const buildScssCommand = require('../lib/build-scss'); -// command: executor function -const COMMANDS = { - 'install-theme': themeCommand, - 'build-tokens': buildTokensCommand, - 'replace-variables': replaceVariablesCommand, - 'build-scss': buildScssCommand, -}; - -(async () => { - const [command, ...commandArgs] = process.argv.slice(2); - const executor = COMMANDS[command]; - - if (!executor) { - // eslint-disable-next-line no-console - console.log(chalk.red.bold('Unknown command. Usage: paragon ')); - return; - } - +const executor = async (func) => { + const params = process.argv.slice(3); try { - await executor(commandArgs); + await func(params); } catch (error) { // eslint-disable-next-line no-console console.error(chalk.red.bold('An error occurred:', error.message)); process.exit(1); } -})(); +}; + +program + .version('0.0.1') + .command('build-tokens') + .description('Build design tokens for your project') + .option('-s, --source ', 'Specify the source directory for design tokens') + .option('-b, --build-dir ', 'Specify the build directory for the generated tokens') + .option('--source-tokens-only', 'Include only source design tokens in the build') + .option('-t, --themes ', 'Specify themes to include in the token build', val => val.split(',')) + .action(() => executor(buildTokensCommand)); + +program + .version('0.0.1') + .command('replace-variables') + .description('CLI to replace SCSS variables usages or definitions to CSS variables and vice versa in .scss files.') + .requiredOption('-p, --filePath ', 'Path to the file or directory where to replace variables.') + .addOption(new Option('-s, --source ', 'Type of replacement: usage or definition. If set to "definition" the command will only update SCSS variables definitions with CSS variables, if set to "usage" - all occurrences of SCSS variables will we replaced')) + .addOption(new Option('-t, --replacementType ', 'Type of replacement: usage or definition. If set to "definition" the command will only update SCSS variables definitions with CSS variables, if set to "usage" - all occurrences of SCSS variables will we replaced') + .choices(['usage', 'definition']) + .default('definition')) + .addOption(new Option('-d, --direction ', 'Map direction: css-to-scss or scss-to-css, if replacement type parameter is set to "definition" this has no effect.') + .choices(['scss-to-css', 'css-to-scss']) + .default('scss-to-css')) + .action(() => executor(replaceVariablesCommand)); + +program + .version('0.0.1') + .command('install-theme') + .description('Install an @edx/brand theme') + .action(() => executor(themeCommand)); + +program + .version('0.0.1') + .command('build-scss') + .description('CLI to compile Paragon\'s core and themes\' SCSS into CSS.') + .addOption( + new Option( + '--corePath ', + 'Path to the theme\'s core SCSS file, defaults to Paragon\'s core.scss.', + ), + ) + .addOption( + new Option( + '--themesPath ', + `Path to the directory that contains themes' files. Expects directory to have following structure: + themes/ + light/ + │ ├─ index.css + │ ├─ other_css_files + dark/ + │ ├─ index.css + │ ├─ other_css_files + some_other_custom_theme/ + │ ├─ index.css + │ ├─ other_css_files + ... + + where index.css has imported all other CSS files in the theme's subdirectory. The script will output + light.css, dark.css and some_other_custom_theme.css files (together with maps and minified versions). + You can provide any amount of themes. Default to paragon's themes. + `, + ), + ) + .addOption( + new Option( + '--outDir ', + 'Specifies directory where to out resulting CSS files.', + ), + ) + .addOption( + new Option( + '--defaultThemeVariants ', + `Specifies default theme variants. Defaults to a single 'light' theme variant. + You can provide multiple default theme variants by passing multiple values, for + example: \`--defaultThemeVariants light dark\` + `, + ), + ) + .action(() => executor(buildScssCommand)); + +program.parse(process.argv); diff --git a/lib/build-tokens.js b/lib/build-tokens.js index f64bf533a2..200b014699 100755 --- a/lib/build-tokens.js +++ b/lib/build-tokens.js @@ -4,11 +4,17 @@ const { StyleDictionary, colorTransform, createCustomCSSVariables } = require('. const { createIndexCssFile } = require('../tokens/utils'); async function buildTokensCommand(commandArgs) { - const args = minimist(commandArgs); - const buildDir = args['build-dir'] || './build/'; - const tokensSource = args.source; + const args = minimist(commandArgs, { + alias: { + s: 'source', + b: 'build', + t: 'themes', + }, + }); + const buildDir = args['build-dir'] || args.b || './build/'; + const tokensSource = args.source || args.s; const hasSourceTokensOnly = Boolean(args['source-tokens-only']); - const themes = args.themes || ['light']; + const themes = args.themes || args.t || ['light']; const coreConfig = { include: [path.resolve(__dirname, '../tokens/src/core/**/*.json')],