bin/modernizr
#!/usr/bin/env node
'use strict';
var fs = require('fs');
var _ = require('lodash');
var path = require('path');
var mkdirp = require('mkdirp');
var Modernizr = require(path.resolve(__dirname + '/../lib/cli.js'));
var yargs = require('yargs')
.options('h', {
alias: 'help',
describe: 'Print Help'
})
.options('V', {
alias: ['v', 'version'],
describe: 'Print the version and exit'
})
.options('f', {
alias: 'features',
describe: 'comma separated list of feature detects'
})
.options('o', {
alias: 'options',
describe: 'comma separated list of extensibility options'
})
.options('c', {
alias: 'config',
describe: 'Path to a JSON file containing Modernizr configuration. See lib/config-all.json for an example'
})
.options('d', {
alias: 'dest',
describe: 'Path to write the Modernizr build file to. Defaults to ./modernizr.js'
})
.options('m', {
alias: 'metadata',
describe: 'Path to where the Modernizr feature-detect metadata should be saved. Defaults to ./metadata.json'
})
.options('u', {
alias: 'uglify',
describe: 'uglify/minify the output'
})
.options('s', {
alias: 'scriptGlobalName',
describe: 'Script global variable where Modernizr is attached. Defaults to window'
})
.options('q', {
alias: 'quiet',
describe: 'Silence all output'
});
var argv = yargs.argv;
var cwd = process.cwd();
var dest = cwd + '/modernizr.js';
var configPath;
var config;
function log() {
if (!argv.q) {
console.log.apply(console, arguments);
}
}
function stringify(obj, minified) {
var replacer = function(key, value) {
return value;
};
var args = minified ? [replacer,2] : [];
args.unshift(obj);
return JSON.stringify.apply(JSON, args);
}
if (argv.h) {
yargs.showHelp();
process.exit();
}
if (argv.V) {
var pkg = require('../package.json');
console.log('Modernizr v' + pkg.version);
process.exit();
}
if (argv.d) {
dest = path.normalize(argv.d);
var exists = fs.existsSync(dest);
var isDir = exists && fs.statSync(dest).isDirectory();
var fileRequested = _.endsWith(dest, '.js');
if ((exists && isDir) || (!exists && !fileRequested)) {
dest = path.join(dest, 'modernizr.js');
}
mkdirp.sync(path.dirname(dest));
}
if (argv.m) {
// path.normalize is used instead of normalize in order to support ~
// we get an absolute path on the fallback from cwd, and any user supplied
// argument will be relative to their current directory.
var metaDest = path.normalize(argv.m === true ? cwd + '/metadata.json' : argv.m);
Modernizr.metadata(function(metadata) {
mkdirp.sync(path.dirname(metaDest));
fs.writeFileSync(metaDest, stringify(metadata, !argv.u));
log('metadata saved to ' + metaDest);
});
if (!argv.d) {
// return early unless we explicitly request Modernizr to be built
return;
}
}
if (argv.o || argv.f) {
var metadata = Modernizr.metadata();
var options = Modernizr.options();
var find = function(config, source) {
if (!config) {
return;
}
return config
.replace(/-/g, ',')
.split(',')
.map(function(prop) {
var obj = _.find(source, function(o) {
if (o.property instanceof Array) {
return o.property.includes(prop);
} else {
return o.property === prop;
}
});
// setClasses is technically a flag, not an option. But it is passed
// in as an option. Since it doesn't exist as an option we have to
// special case around it :[
if (prop === 'setClasses') {
return 'setClasses';
} else if (_.isUndefined(obj)) {
throw new Error('invalid key value name - ' + prop);
} else {
return obj.amdPath || obj.property;
}
});
};
config = {
'feature-detects': find(argv.f, metadata),
'options': find(argv.o, options)
};
}
if (argv.c) {
try {
configPath = fs.realpathSync(argv.c);
} catch (e) {
console.error(argv.c + ' does not exist.');
process.exit(1);
}
if (!configPath) {
configPath = path.resolve(__dirname, '../lib/config-all.json');
}
}
try {
if (!config && !configPath) {
console.error('config file, inline features, or options required.');
yargs.showHelp();
process.exit(1);
} else {
config = config || {};
if (configPath) {
config = _.extend(config, require(configPath));
}
if (config && config.dest) {
dest = path.join(cwd, config.dest, 'modernizr.js');
}
}
} catch (e) {
console.error(configPath + ' is not valid JSON.');
console.error(e);
process.exit(1);
}
if (argv.u) {
config.minify = true;
}
if (argv.scriptGlobalName) {
config.scriptGlobalName = argv.scriptGlobalName;
}
Modernizr.build(config, function(output) {
fs.writeFileSync(dest, output);
log('Modernizr build saved to ' + dest);
});