Skip to content

Commit

Permalink
Fix subfont --help
Browse files Browse the repository at this point in the history
Tidy up command line parsing
Add basic tests for cli.js
  • Loading branch information
papandreou committed Oct 22, 2019
1 parent 751c87d commit d5a1e12
Show file tree
Hide file tree
Showing 5 changed files with 150 additions and 42 deletions.
16 changes: 12 additions & 4 deletions lib/cli.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
#!/usr/bin/env node

require('@gustavnikolaj/async-main-wrap')(require('./subfont'))(
require('./parseCommandLineOptions')(),
console
);
const { yargs, help, ...options } = require('./parseCommandLineOptions')();

require('@gustavnikolaj/async-main-wrap')(require('./subfont'), {
processError(err) {
yargs.showHelp();
if (err.constructor === SyntaxError) {
// Avoid rendering a stack trace for the wrong usage errors
err.customOutput = err.message;
}
return err;
}
})(options, console);
42 changes: 10 additions & 32 deletions lib/parseCommandLineOptions.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
const yargs = require('yargs');

module.exports = function parseCommandLineOptions(argv) {
const {
root,
canonicalRoot,
output,
debug,
dryRun,
silent,
inlineFonts,
inlineCss,
fontDisplay,
inPlace,
recursive,
fallbacks,
dynamic,
_: inputFiles
} = yargs(argv)
let yargs = require('yargs');
if (argv) {
yargs = yargs(argv);
}
yargs
.usage(
'Create optimal font subsets from your actual font usage.\n$0 [options] <htmlFile(s) | url(s)>'
)
Expand Down Expand Up @@ -104,22 +91,13 @@ module.exports = function parseCommandLineOptions(argv) {
type: 'boolean',
default: false
})
.wrap(72).argv;
.wrap(require('yargs').terminalWidth());

const { _: inputFiles, ...rest } = yargs.argv;

return {
root,
canonicalRoot,
output,
debug,
dryRun,
silent,
inlineFonts,
inlineCss,
fontDisplay,
inPlace,
yargs,
inputFiles,
recursive,
fallbacks,
dynamic
...rest
};
};
10 changes: 5 additions & 5 deletions lib/subfont.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ module.exports = async function subfont(

if (rootUrl) {
if (rootUrl.startsWith('file:')) {
console.error(`Guessing --root from input files: ${rootUrl}`);
console.warn(`Guessing --root from input files: ${rootUrl}`);
} else {
rootUrl = urlTools.ensureTrailingSlash(rootUrl);
}
Expand All @@ -46,20 +46,20 @@ module.exports = async function subfont(
inputUrls = [`${rootUrl}**/*.html`];
console.warn(`No input files specified, defaulting to ${inputUrls[0]}`);
} else {
throw new Error(
throw new SyntaxError(
"No input files and no --root specified (or it isn't file:), cannot proceed.\n"
);
}

if (!inputUrls[0].startsWith('file:') && !outRoot && !dryRun) {
throw new Error(
throw new SyntaxError(
'--output has to be specified when using non-file input urls'
);
}

if (!inPlace && !outRoot && !dryRun) {
throw new Error(
'Either --output, --in-place, or --dryrun has to be specified'
throw new SyntaxError(
'Either --output, --in-place, or --dry-run has to be specified'
);
}

Expand Down
122 changes: 122 additions & 0 deletions test/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
const pathModule = require('path');
const expect = require('unexpected').clone();

const childProcess = require('child_process');

function consumeStream(stream) {
return new Promise((resolve, reject) => {
const buffers = [];
stream
.on('data', buffer => buffers.push(buffer))
.on('end', () => resolve(Buffer.concat(buffers)))
.on('error', reject);
});
}

async function run(commandAndArgs, stdin) {
if (typeof commandAndArgs !== 'undefined' && !Array.isArray(commandAndArgs)) {
commandAndArgs = [commandAndArgs];
}

const proc = childProcess.spawn(commandAndArgs[0], commandAndArgs.slice(1));

const promises = {
exit: new Promise((resolve, reject) => {
proc.on('error', reject).on('exit', exitCode => {
if (exitCode === 0) {
resolve();
} else {
const err = new Error(`Child process exited with ${exitCode}`);
err.exitCode = exitCode;
reject(err);
}
});
}),
stdin: new Promise((resolve, reject) => {
proc.stdin.on('error', reject).on('close', resolve);
}),
stdout: consumeStream(proc.stdout),
stderr: consumeStream(proc.stderr)
};

if (typeof stdin === 'undefined') {
proc.stdin.end();
} else {
proc.stdin.end(stdin);
}

try {
await Promise.all(Object.values(promises));
return [await promises.stdout, await promises.stderr];
} catch (err) {
err.stdout = await promises.stdout;
err.stderr = await promises.stderr;
throw err;
}
}

async function runSubfont(...args) {
const proc = childProcess.spawn(
pathModule.resolve(__dirname, '..', 'lib', 'cli.js'),
args
);

const promises = {
exit: new Promise((resolve, reject) => {
proc.on('error', reject).on('exit', exitCode => {
if (exitCode === 0) {
resolve();
} else {
const err = new Error(`Child process exited with ${exitCode}`);
err.exitCode = exitCode;
reject(err);
}
});
}),
stdin: new Promise((resolve, reject) => {
proc.stdin.on('error', reject).on('close', resolve);
}),
stdout: consumeStream(proc.stdout),
stderr: consumeStream(proc.stderr)
};

proc.stdin.end();

let err;
try {
await Promise.all(Object.values(promises));
} catch (_err) {
err = _err;
}
return {
err,
stdout: (await promises.stdout).toString('utf-8'),
stderr: (await promises.stderr).toString('utf-8')
};
}

describe('cli', function() {
it('should display usage info if --help is passed', async function() {
const { err, stdout } = await runSubfont('--help');
expect(err, 'to be falsy');
expect(stdout, 'to contain', 'Options:');
expect(stdout, 'not to contain', 'No input files');
});

it('should display usage info if an error is encountered', async function() {
const { err, stderr } = await runSubfont('i-do-not-exist.html');
expect(err, 'to have property', 'exitCode', 1);
expect(stderr, 'to contain', 'Options:');
});

it('should a wrong usage error without a stack trace', async function() {
const { err, stderr } = await runSubfont('https://example.com');
expect(err, 'to have property', 'exitCode', 1);
expect(
stderr,
'to contain',
'--output has to be specified when using non-file input urls'
);
expect(stderr, 'not to match', /^\s+at/m);
});
});
2 changes: 1 addition & 1 deletion test/parseCommandLineOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ describe('parseCommandLineOptions', function() {
'--no-fallbacks',
'--recursive'
]),
'to equal',
'to satisfy',
{
root: undefined,
canonicalRoot: undefined,
Expand Down

0 comments on commit d5a1e12

Please sign in to comment.