Commit c7539f19 by Kevin Martensson

Cleanup CLI

parent 0e2e5653
#!/usr/bin/env node #!/usr/bin/env node
var Emitter = require('events').EventEmitter,
path = require('path'),
meow = require('meow'),
stdin = require('get-stdin'),
watch = require('node-watch'),
render = require('../lib/render');
var cli = require('../lib/cli')(process.argv.slice(2)); /**
* Initialize CLI
*/
cli.on('log', function(msg){ var cli = meow({
console.log(msg); pkg: '../package.json',
help: [
'Usage',
' node-sass [options] <input.scss> [output.css]',
' cat <input.scss> | node-sass > output.css',
'',
'Example',
' node-sass --output-style compressed foobar.scss foobar.css',
' cat foobar.scss | node-sass --output-style compressed > foobar.css',
'',
'Options',
' -w, --watch Watch a directory or file',
' -o, --output Output CSS file',
' -x, --omit-source-map-url Omit source map URL comment from output',
' -i, --indented-syntax Treat data from stdin as sass code (versus scss)',
' --output-style CSS output style (nested|expanded|compact|compressed)',
' --source-comments Include debug info in output',
' --source-map Emit source map',
' --include-path Path to look for imported files',
' --image-path Path to prepend when using the `image-url()` helper',
' --precision The amount of precision allowed in decimal numbers',
' --stdout Print the resulting CSS to stdout',
' --help Print usage info'
].join('\n')
}, {
boolean: [
'indented-syntax',
'omit-source-map-url',
'stdout',
'watch',
'source-comments'
],
string: [
'image-path',
'include-path',
'output',
'output-style',
'precision'
],
alias: {
i: 'indented-syntax',
o: 'output',
w: 'watch',
x: 'omit-source-map-url',
c: 'source-comments'
},
default: {
'image-path': '',
'include-path': process.cwd(),
'output-style': 'nested',
precision: 5
}
}); });
cli.on('error', function(msg){ /**
console.error(msg); * Throttle
process.exit(1); *
}); * @param {Function} fn
* @api private
*/
cli.on('warn', function(msg){ function throttle(fn) {
console.warn(msg); var timer;
}); var args = [].slice.call(arguments, 1);
return function() {
var self = this;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(self, args);
}, 20);
};
}
/**
* Check if file is a Sass file
*
* @param {String} file
* @api private
*/
function isSassFile(file) {
return file.match(/\.(sass|scss)/);
}
/**
* Create emitter
*
* @api private
*/
function getEmitter() {
var emitter = new Emitter();
emitter.on('error', function(err) {
console.error(err);
process.exit(1);
});
emitter.on('warn', function(data){
console.warn(data);
});
emitter.on('log', function(data){
console.log(data);
});
return emitter;
}
/**
* Construct options
*
* @param {Array} arguments
* @param {Object} options
* @api private
*/
function getOptions(args, options) {
options.src = args[0];
options.dest = options.output || args[1];
if (!options.dest && !options.stdout) {
var suffix = '.css';
if (/\.css$/.test(options.src)) {
suffix = '';
}
options.dest = path.join(process.cwd(), path.basename(options.src, '.scss') + suffix);
}
return options;
}
/**
* Run
*
* @param {Object} options
* @param {Object} emitter
* @api private
*/
function run(options, emitter) {
if (!Array.isArray(options.includePath)) {
options.includePath = [options.includePath];
}
if (options.sourceMap) {
if (options.sourceMap === true) {
options.sourceMap = options.dest + '.map';
} else {
options.sourceMap = path.resolve(process.cwd(), options.sourceMap);
}
}
if (options.watch) {
var throttledRender = throttle(render, options, emitter);
var watchDir = options.watch;
if (watchDir === true) {
watchDir = [];
} else if (!Array.isArray(watchDir)) {
watchDir = [watchDir];
}
watchDir.push(options.src);
watch(watchDir, function(file) {
emitter.emit('warn', '=> changed: '.grey + file.blue);
if (isSassFile(file)) {
throttledRender();
}
});
throttledRender();
} else {
render(options, emitter);
}
}
/**
* Arguments and options
*/
var input = cli.input;
var options = getOptions(input, cli.flags);
var emitter = getEmitter();
/**
* Show usage if no arguments are supplied
*/
if (!input.length && process.stdin.isTTY) {
emitter.emit('error', [
'Provide a Sass file to render',
'',
' Example',
' node-sass --output-style compressed foobar.scss foobar.css',
' cat foobar.scss | node-sass --output-style compressed > foobar.css'
].join('\n'));
}
/**
* Apply arguments
*/
if (options.src) {
run(options, emitter);
} else if (!process.stdin.isTTY) {
stdin(function(data) {
options.data = data;
run(options, emitter);
});
}
return emitter;
var watch = require('node-watch'),
render = require('./render'),
path = require('path'),
Emitter = require('events').EventEmitter,
stdin = require('get-stdin'),
meow = require('meow'),
cwd = process.cwd();
function init(args) {
return meow({
argv: args,
pkg: '../package.json',
help: [
'Usage',
' node-sass [options] <input.scss> [output.css]',
' cat <input.scss> | node-sass > output.css',
'',
'Example',
' node-sass --output-style compressed foobar.scss foobar.css',
' cat foobar.scss | node-sass --output-style compressed > foobar.css',
'',
'Options',
' -w, --watch Watch a directory or file',
' -o, --output Output CSS file',
' -x, --omit-source-map-url Omit source map URL comment from output',
' -i, --indented-syntax Treat data from stdin as sass code (versus scss)',
' --output-style CSS output style (nested|expanded|compact|compressed)',
' --source-comments Include debug info in output',
' --source-map Emit source map',
' --include-path Path to look for imported files',
' --image-path Path to prepend when using the `image-url()` helper',
' --precision The amount of precision allowed in decimal numbers',
' --stdout Print the resulting CSS to stdout',
' --help Print usage info'
].join('\n')
}, {
boolean: [
'indented-syntax',
'omit-source-map-url',
'stdout',
'watch',
'source-comments'
],
string: [
'image-path',
'include-path',
'output',
'output-style',
'precision'
],
alias: {
i: 'indented-syntax',
o: 'output',
w: 'watch',
x: 'omit-source-map-url',
c: 'source-comments'
},
default: {
'image-path': '',
'include-path': cwd,
'output-style': 'nested',
precision: 5
}
});
}
function throttle(fn) {
var timer;
var args = [].slice.call(arguments, 1);
return function() {
var self = this;
clearTimeout(timer);
timer = setTimeout(function() {
fn.apply(self, args);
}, 20);
};
}
function isSassFile(file) {
return file.match(/\.(sass|scss)/);
}
function run(options, emitter) {
if (!Array.isArray(options.includePath)) {
options.includePath = [options.includePath];
}
if (options.sourceMap) {
if (options.sourceMap === true) {
options.sourceMap = options.dest + '.map';
} else {
options.sourceMap = path.resolve(cwd, options.sourceMap);
}
}
if (options.watch) {
var throttledRender = throttle(render, options, emitter);
var watchDir = options.watch;
if (watchDir === true) {
watchDir = [];
} else if (!Array.isArray(watchDir)) {
watchDir = [watchDir];
}
watchDir.push(options.src);
watch(watchDir, function(file) {
emitter.emit('warn', '=> changed: '.grey + file.blue);
if (isSassFile(file)) {
throttledRender();
}
});
throttledRender();
} else {
render(options, emitter);
}
}
module.exports = function(args) {
var cli = init(args);
var emitter = new Emitter();
var input = cli.input;
var options = cli.flags;
emitter.on('error', function(err) {
console.error(err);
process.exit(1);
});
options.src = input[0] || null;
options.dest = options.output || input[1] || null;
if (!options.dest && !options.stdout) {
var suffix = '.css';
if (/\.css$/.test(options.src)) {
suffix = '';
}
options.dest = path.join(cwd, path.basename(options.src, '.scss') + suffix);
}
if (options.src) {
run(options, emitter);
} else if (!input.length && (process.stdin.isTTY || process.env.isTTY)) {
console.error([
'Provide a sass file to render',
'',
' Example',
' node-sass --output-style compressed foobar.scss foobar.css',
' cat foobar.scss | node-sass --output-style compressed > foobar.css'
].join('\n'));
process.exit(1);
} else {
stdin(function(data) {
options.data = data;
run(options, emitter);
});
}
return emitter;
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment