All files / src cli.js

100% Statements 45/45
93.1% Branches 27/29
100% Functions 2/2
100% Lines 45/45

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157                          1x 1x   1x   1x 1x   1x                         1x                                                 1x                                   6x 2x 4x 2x   2x                     10x 2x 2x   1x 1x       1x 1x 1x   1x           1x     8x 3x   3x 3x   1x 1x     2x   2x 2x   1x     1x     5x 1x 1x   1x     4x 3x   3x     1x 1x   1x     1x  
'use strict';
/**
 * The command-line interface for Fresnel.
 *
 * This module is invoked by `bin/fresnel` and is in charge of reading user
 * input such as CLI parameters, environment variables, and the `.fresnel.yml`
 * config file.
 *
 * Interacts with: {@link module:conductor conductor}.
 *
 * @module cli
 */
 
const fs = require( 'fs' );
const path = require( 'path' );
 
const yaml = require( 'js-yaml' );
 
const conductor = require( './conductor' );
const printer = require( './printer' );
 
const helpGeneral = `
    Usage: fresnel <command> [options..]
 
COMMANDS
 
fresnel record           Run scenarios and generate a performance report.
 
fresnel compare          Document me.
 
fresnel help <command>   Display options and quick help for a given command.
 
fresnel version          The version of Fresnel is installed.
`;
const helpRecord = `
DESCRIPTION
 
    Run scenarios and generate a performance report.
 
    Configuration for scenarios is read from a .fresnel.yml
    file in the current working directory.
 
OPTIONS
 
    fresnel record [label]
 
    label      The label given to this Fresnel recording.
               Must be valid for use as a directory name.
               Default: "default"
 
ENVIRONMENT
 
    FRESNEL_DIR      Recordings will be saved to this directory.
                     Default: ".fresnel_records"
 
    CHROMIUM_FLAGS   Extra CLI options for the Chromium binary.
                     In Docker containers, Chromium typically
                     needs --no-sandbox.
`;
const helpCompare = `
DESCRIPTION
 
    (Document me.)
 
OPTIONS
 
    fresnel compare <label> <label>
 
    label      The label of a past Fresnel recording.
 
ENVIRONMENT
 
    FRESNEL_DIR      Recordings will be read from this directory.
                     Default: ".fresnel_records"
`;
 
function help( command ) {
	if ( command === 'record' ) {
		console.log( helpRecord );
	} else if ( command === 'compare' ) {
		console.log( helpCompare );
	} else {
		console.log( helpGeneral );
	}
}
 
/**
 * @private
 * @param {string} command
 * @param {...string} params
 * @throws {number} Process exit code
 */
async function cli( command, ...params ) {
	if ( command === 'record' ) {
		const label = params[ 0 ] || 'default';
		if ( params[ 1 ] ) {
			// unknown parameter
			help( 'record' );
			throw 1;
		}
 
		// Read config file from current working directory
		const file = path.join( process.cwd(), '.fresnel.yml' );
		const config = yaml.load( fs.readFileSync( file, 'utf8' ) );
		const outputDir = process.env.FRESNEL_DIR || '.fresnel_records';
 
		await conductor.record(
			config,
			outputDir,
			label,
			printer.progress.bind( null, console.log )
		);
		return;
	}
 
	if ( command === 'compare' ) {
		const outputDir = process.env.FRESNEL_DIR || '.fresnel_records';
 
		const [ before, after ] = params;
		if ( !before || !after || params[ 2 ] ) {
			// missing or unknown parameters
			help( 'compare' );
			throw 1;
		}
 
		const compared = await conductor.compare( outputDir, before, after );
 
		printer.comparison( console.log, compared.result );
		if ( compared.warnings.length ) {
			// TODO: Print warnings
			throw 1;
		}
 
		return;
	}
 
	if ( command === 'version' ) {
		const version = require( '../package.json' ).version;
		console.log( `Fresnel ${version}` );
 
		return;
	}
 
	if ( command === 'help' || !command ) {
		help( params[ 0 ] );
 
		return;
	}
 
	console.error( `fresnel: Unknown command - ${command}` );
	help();
 
	throw 1;
}
 
module.exports = cli;