diff --git a/README.md b/README.md index 4be412298..368c0007d 100644 --- a/README.md +++ b/README.md @@ -17,32 +17,92 @@ The shared styles for TACC WMA Workspace Portals & Websites #### CLI ```bash -Usage: cli [options] +Usage: core-styles [options] [command] Options: - -i, --input-dir parse CSS files from which directory - -o, --output-dir output CSS files to which directory - -e, --file-ext extension of CSS files to parse (default: "css") (default: "css") - -v, --version print the version of this software - --verbose print more information from build log - -c, --custom-config-files overwrite base config with values from YAML files¹² (advanced) - -h, --help display help for command - -Note: - The dir structure within '--input-dir' will be mirrored in '--output-dir'. - -Footnotes: - ¹ The file formats are like '.postcssrc.yml' from https://github.com/postcss/postcss-load-config#postcssrc. - ² The first file is merged on top of the base config. - Each successive file overwrites the file before it. + -V, --version output the version number + -h, --help display help for command + +Commands: + build [options] build stylesheets with TACC standard process: + - "post-css" plugins + - custom input dir + - custom output dir + - custom configs + + version [options] create a stylesheet with preserved comment w/ + - app name + - app version (via "git describe") + - app license + - custom output path + + help [command] display help for command +``` + +##### Build Command + +```bash +Usage: core-styles build [options] + +build stylesheets with TACC standard process: +- "post-css" plugins +- custom input dir +- custom output dir +- custom configs + + +Options: + -i, --input-dir parse source from which directory¹ + -o, --output-dir output CSS files to which directory¹ + -e, --file-ext extensions to parse (default: "css") + -v, --verbose print more info during build process + -c, --custom-configs extend base config with YAML files²³ + -h, --help display help for command + +Notes: + ¹ Folder structure of "--input-dir" mirrored in "--output-dir" e.g. + + given input + - "input_dir/x.css" + - "input_dir/sub_dir_a/y.css" + + expect output + - "output_dir/x.css" + - "output_dir/sub_dir_a/y.css" + + ² The file formats are like ".postcssrc.yml" from + https://github.com/postcss/postcss-load-config#postcssrc + + ³ The first file is merged on top of the base config. + Each successive file overwrites the file before it. +``` + +##### Version Command + +```bash +Usage: core-styles version [options] + +create a stylesheet with preserved comment w/ +- app name +- app version (via "git describe") +- app license +- custom output path + + +Options: + -o, --output-path output version stylesheet at what path + -v, --verbose print more info during file creation + -h, --help display help for command ``` #### Module +##### Build Script + ```js -const coreStyles = require('core-styles'); +const buildStylesheets = require('core-styles'); -coreStyles( +buildStylesheets( // Parse CSS files from which directory (required) `path/to/your/css/src`, // Output CSS files to which directory (required) @@ -51,7 +111,7 @@ coreStyles( // (The first file is merged on top of the base config.) // (Each successive file overwrites the file before it.) // SEE: https://github.com/postcss/postcss-load-config#postcssrc - customConfigFiles: [ + customConfigs: [ // The "base" config is `/.postcssrc.base.yml` `path/to/custom/configthat/extends/base/.postcssrc.yml`, `path/to/custom/config/that/extends/above/.postcssrc.yml` @@ -66,6 +126,19 @@ coreStyles( ); ``` +##### Version Script + +```js +const createVersionStylesheet = require('core-styles'); + +createVersionStylesheet( + // Output version file at which path (required) + `path/to/put/_version.css`, { + // Print more info from build log (optional, default: false) + verbose: true + } +); +``` ## Local Development Setup diff --git a/bin/build.js b/bin/build.js index cdf60dec8..e77078c0d 100644 --- a/bin/build.js +++ b/bin/build.js @@ -7,8 +7,10 @@ const cmd = require('node-cmd'); // SEE: https://stackoverflow.com/a/63530170 process.env.FORCE_COLOR = true + + /** - * Build styles from external CSS + * Build stylesheets from source CSS * @param {string} inputDir - Parse CSS files from which directory * @param {string} outputDir - Output CSS files to which directory * @param {object} [opts={}] - Options @@ -17,14 +19,21 @@ process.env.FORCE_COLOR = true * @param {boolean} [opts.verbose=false] - To print more info from build log */ function build(inputDir, outputDir, opts = {}) { + // Get data const fileExt = opts.fileExt || 'css'; const configDir = opts.configDir || `${__dirname}/../`; const verbose = (opts.verbose === true) ? '--verbose' : ''; + // Build command const command = `postcss "${inputDir}/*.${fileExt}" --dir "${outputDir}" ${verbose} --config "${configDir}"`; + console.log(`Building stylesheets to ${outputDir}`); + + // Run command cmd.runSync(command); - // console.log(command); // only shown if command execution is commented out } + + +// Export module.exports = build; diff --git a/bin/config.js b/bin/config.js index e759e3a5a..13085a416 100755 --- a/bin/config.js +++ b/bin/config.js @@ -9,36 +9,45 @@ const yaml = require('js-yaml'); const baseConfigFile = `${__dirname}/../.postcssrc.base.yml`; const newConfigFile = `${__dirname}/../.postcssrc.yml`; + + /** * Save base config as auto-loaded file (also can overwrite with custom values) - * @param {array.string} [customConfigFiles] - List of YAML config files + * @param {array.string} [customConfigs] - List of YAML config file paths * (The first file is merged on top of the base config.) * (Each successive file overwrites the file before it.) * @see https://github.com/postcss/postcss-load-config#postcssrc */ -function config(customConfigFiles) { +function config(customConfigs) { + // Get data let baseFile = baseConfigFile; let newYaml; - if (customConfigFiles) { - customConfigFiles.forEach(nextFile => { + // Either extend base config with any custom configs + if (customConfigs) { + customConfigs.forEach(nextFile => { if (nextFile && fs.existsSync(nextFile)) { newYaml = getMergedConfig(baseFile, nextFile); baseFile = newConfigFile; } else { - console.info(`Custom config ${nextFile} not found. Skipping`); + console.info(`Skipping custom config ${nextFile} (not found)`); } }); - } else { - console.info('No custom files passed. Using only base config.'); + } + // Or just use the base config + else { + console.info('Using only base config (no custom configs provided)'); const baseConfig = fs.readFileSync(baseConfigFile, 'utf8'); const baseJson = yaml.load(baseConfig); newYaml = yaml.dump(baseJson); } + // Write file fs.writeFileSync(newConfigFile, newYaml, 'utf8'); } + + /** * Get content of merging one config file atop another * @param {array.string} baseFile - YAML config file to be extended @@ -46,12 +55,15 @@ function config(customConfigFiles) { * @return {string} - Merged YAML */ function getMergedConfig(baseFile, customFile) { + // Get data const baseConfig = fs.readFileSync(baseFile, 'utf8'); const baseJson = yaml.load(baseConfig); const baseYaml = yaml.dump(baseJson); + // Default to base config content let newYaml = baseYaml; + // Any custom configs are merged onto the content if (customFile) { const customConfig = fs.readFileSync(customFile, 'utf8'); const customJson = yaml.load(customConfig); @@ -60,7 +72,11 @@ function config(customConfigFiles) { newYaml = yaml.dump(newJson); } + // Return content return newYaml; } + + +// Export module.exports = config; diff --git a/bin/update-version.js b/bin/update-version.js deleted file mode 100755 index c1e0707e0..000000000 --- a/bin/update-version.js +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env node - -/** Create CSS file to import that prints project version */ - -const fs = require('fs'); -const path = require('../package.json'); -const childProcess = require('child_process'); - -// Get data -const appLicense = path.license; -const appGitRef = childProcess.execSync('git describe --always').toString(); -const filePath = __dirname + '/../source/_version.css'; -const fileContent = `/*! @tacc/core-styles ${appGitRef} | ${appLicense} | github.com/TACC/Core-Styles */` + "\n"; - -// Tell user -console.log(`Updating CSS version to ${appGitRef}`); - -// Write version -fs.writeFileSync( filePath, fileContent ); diff --git a/bin/version.js b/bin/version.js new file mode 100755 index 000000000..fd16be609 --- /dev/null +++ b/bin/version.js @@ -0,0 +1,34 @@ +#!/usr/bin/env node + +/** Create CSS file to import that prints project version */ + +const fs = require('fs'); +const path = require('../package.json'); +const childProcess = require('child_process'); + + + +/** + * Create version stylesheet at specificed path + * @param {string} outputPath - Output version file at which path + */ +function create(outputPath) { + // Get data + const appName = process.env.npm_package_name; + const appLicense = path.license; + const appGitRef = childProcess.execSync('git describe --always').toString(); + const fileContent = `/*! ${appName} ${appGitRef.replace("\n", "")} ` + + `| ${appLicense} | github.com/TACC/Core-Styles */` + + "\n"; + + // Tell user + console.log(`Updating CSS version to ${appGitRef}`); + + // Write version + fs.writeFileSync( outputPath, fileContent ); +} + + + +// Export +module.exports = create; diff --git a/cli.js b/cli.js index 379800d6e..0f48cea1a 100755 --- a/cli.js +++ b/cli.js @@ -1,45 +1,96 @@ #!/usr/bin/env node -/** A user-facing CLI to build styles and configure build */ +/** CLI to custom build stylesheets and create a version stylesheet */ const { program } = require('commander'); -const coreStyles = require('./index.js'); +const package = require('./package.json'); +const { + buildStylesheets, + createVersionStylesheet +} = require('./index.js'); + + + +// Setup program .name('core-styles') + .version(package.version) + .showHelpAfterError('(add --help for additional information)'); + + + +// Build Command +program + .command('build') + .description(`build stylesheets with TACC standard process: +- "post-css" plugins +- custom input dir +- custom output dir +- custom configs + `) .requiredOption('-i, --input-dir ', - 'parse CSS files from which directory') + 'parse source from which directory¹') .requiredOption('-o, --output-dir ', - 'output CSS files to which directory') + 'output CSS files to which directory¹') .option('-e, --file-ext ', - 'extension of CSS files to parse (default: "css")', 'css') - .option('-v, --version', - 'print the version of this software') - .option('--verbose', - 'print more information from build log') - .option('-c, --custom-config-files ', - `overwrite base config with values from YAML files¹² (advanced)`); + 'extensions to parse', 'css') + .option('-v, --verbose', + 'print more info during build process') + .option('-c, --custom-configs ', + `extend base config with YAML files²³`) + .addHelpText('after', ` +Notes: + ¹ Folder structure of "--input-dir" mirrored in "--output-dir" e.g. + + given input + - "input_dir/x.css" + - "input_dir/sub_dir_a/y.css" -program.addHelpText('after', ` -Note: - The dir structure within '--input-dir' will be mirrored in '--output-dir'. + expect output + - "output_dir/x.css" + - "output_dir/sub_dir_a/y.css" -Footnotes: - ¹ The file formats are like '.postcssrc.yml' from: - https://github.com/postcss/postcss-load-config#postcssrc + ² The file formats are like ".postcssrc.yml" from + https://github.com/postcss/postcss-load-config#postcssrc - ² The first file is merged on top of the base config. - Each successive file overwrites the file before it. -`); + ³ The first file is merged on top of the base config. + Each successive file overwrites the file before it. + `).action( programOpts => { + const { inputDir, outputDir, ...opts } = programOpts; -program.showHelpAfterError('(add --help for additional information)'); + if (opts.verbose) { + console.log('cli.js > build:', programOpts); + } + buildStylesheets( inputDir, outputDir, opts ); + }); -program.parse(process.argv); -const { inputDir, outputDir, ...buildOpts } = program.opts(); -if (buildOpts.verbose) { - console.log('[cli.js]', { inputDir, outputDir, buildOpts }); -} -coreStyles( inputDir, outputDir, buildOpts ); +// Version Command +program + .command('version') + .description(`create a stylesheet with preserved comment w/ +- app name +- app version (via "git describe") +- app license +- custom output path + `) + .requiredOption('-o, --output-path ', + 'output version stylesheet at what path') + .option('-v, --verbose', + 'print more info during file creation') + .action( programOpts => { + const { outputPath, ...opts } = programOpts; + + if (opts.verbose) { + console.log('cli.js > version:', programOpts); + } + createVersionStylesheet( outputPath, opts ); + }); + + + +// Parse +program.parse(process.argv); diff --git a/index.js b/index.js index 8c4d9ca86..94dd8f355 100755 --- a/index.js +++ b/index.js @@ -1,31 +1,29 @@ #!/usr/bin/env node -/** Export user-facing function to build styles and configure build */ +/** Functions to custom build stylesheets and create a version stylesheet */ const { resolve } = require('path'); const build = require('./bin/build.js'); const config = require('./bin/config.js'); +const version = require('./bin/version.js'); + + /** - * Build styles from external CSS + * Build stylesheets from source CSS * @param {string} inputDir - Parse CSS files from which directory * @param {string} outputDir - Output CSS files to which directory * @param {object} [opts={}] - Options * @param {object} [opts.fileExt='css'] - Extension of CSS files to parse - * @param {array.string} [opts.customConfigFiles] - List of YAML config files + * @param {array.string} [opts.customConfigs] - List of YAML config file paths * (The first file is merged on top of the base config.) * (Each successive file overwrites the file before it.) - * @param {boolean} [opts.version=false] - Print the version of this software - * @param {boolean} [opts.verbose=false] - Print more info from build log + * @param {boolean} [opts.verbose=false] - Print more in log output */ - module.exports = function coreStyles(inputDir, outputDir, opts = {}) { +function buildStylesheets(inputDir, outputDir, opts = {}) { if (opts.verbose) { - console.log('[index.js]', { inputDir, outputDir, opts }); - } - - if (opts.version) { - console.log(process.env.npm_package_version); + console.log('index.js > buildStyles..():', { inputDir, outputDir, opts }); } const buildOpts = { @@ -35,11 +33,34 @@ const config = require('./bin/config.js'); const inputDirResolved = resolve(inputDir); const outputDirResolved = resolve(outputDir); - const customConfigFiles = (opts.customConfigFiles) ? - opts.customConfigFiles.map(file => - (file) ? resolve(file) : null + const customConfigs = (opts.customConfigs) ? + opts.customConfigs.map(filePath => + (filePath) ? resolve(filePath) : null ) : null; - config(customConfigFiles); + config(customConfigs); build(inputDirResolved, outputDirResolved, buildOpts); } + + + +/** + * Create version stylesheet at specificed path + * @param {string} outputPath - Output version file at which path + * @param {object} [opts={}] - Options + * @param {boolean} [opts.verbose=false] - Print more in log output + */ +function createVersionStylesheet(outputPath, opts = {}) { + if (opts.verbose) { + console.log('index.js > createVersion...():', { outputPath, opts }); + } + + const outputPathResolved = resolve(outputPath); + + version(outputPathResolved); +} + + + +// Export +module.exports = { buildStylesheets, createVersionStylesheet }; diff --git a/package.json b/package.json index 1052049c0..faf4ce091 100644 --- a/package.json +++ b/package.json @@ -15,8 +15,10 @@ "main": "index.js", "bin": "cli.js", "scripts": { - "build": "bin/update-version.js && npm run build:via-cli", - "build:via-cli": "node cli.js -i \"./source\" -o \"./dist\"" + "build": "npm run version && npm run build:via-cli", + "build:verbose": "npm run version -- --verbose && npm run build:via-cli -- --verbose", + "build:via-cli": "node cli.js build -i \"./source\" -o \"./dist\"", + "version": "node cli.js version -o \"./source/_version.css\"" }, "engines": { "node": ">=12.x", diff --git a/source/_version.css b/source/_version.css index 1eca01d80..76269f1f3 100644 --- a/source/_version.css +++ b/source/_version.css @@ -1,2 +1 @@ -/*! @tacc/core-styles v0.1.0-6-ge1c85ae - | MIT | github.com/TACC/Core-Styles */ +/*! @tacc/core-styles v0.1.0-9-g7f3eeab | MIT | github.com/TACC/Core-Styles */