Commit 7a2d373f by Andrew Nesbitt

Merge pull request #412 from kevva/stdout

Fix stdin
parents 0b1df747 51435f44
......@@ -53,9 +53,11 @@ var yargs = require('yargs')
type: 'string',
alias: 'help'
})
.check(function(argv){
if (!argv.stdout && argv.o === undefined && argv._.length === 0) { return false; }
.check(function(argv) {
if (argv.help) { return true; }
if (!argv._.length && (process.stdin.isTTY || process.env.isTTY)) {
return false;
}
});
// throttle function, used so when multiple files change at the same time
......@@ -63,6 +65,7 @@ var yargs = require('yargs')
function throttle(fn) {
var timer;
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var self = this;
clearTimeout(timer);
......@@ -76,110 +79,106 @@ function isSassFile(file) {
return file.match(/\.(sass|scss)/);
}
exports = module.exports = function(args) {
var argv = yargs.parse(args);
if (argv.help) {
yargs.showHelp();
process.exit(0);
return;
}
var emitter = new Emitter();
emitter.on('error', function(err){
console.error(err);
process.exit(1);
});
var options = {
stdout: argv.stdout,
omitSourceMapUrl: argv['omit-source-map-url']
};
var inFile = options.inFile = argv._[0];
var outFile = options.outFile = argv.o || argv._[1];
if (!outFile) {
var suffix = '.css';
if (/\.css$/.test(inFile)) {
suffix = '';
}
outFile = options.outFile = path.join(cwd, path.basename(inFile, '.scss') + suffix);
}
// make sure it's an array.
options.includePaths = argv['include-path'];
function run(options, emitter) {
if (!Array.isArray(options.includePaths)) {
options.includePaths = [options.includePaths];
}
// include the image path.
options.imagePath = argv['image-path'];
// if it's an array, make it a string
options.outputStyle = argv['output-style'];
if (Array.isArray(options.outputStyle)) {
options.outputStyle = options.outputStyle[0];
}
// if it's an array, make it a string
options.sourceComments = argv['source-comments'];
if (Array.isArray(options.sourceComments)) {
options.sourceComments = options.sourceComments[0];
}
// Set the sourceMap path if the sourceComment was 'map', but set source-map was missing
if (options.sourceComments === 'map' && !argv['source-map']) {
argv['source-map'] = true;
if (options.sourceComments === 'map' && !options.sourceMap) {
options.sourceMap = true;
}
// set source map file and set sourceComments to 'map'
if (argv['source-map']) {
if (options.sourceMap) {
options.sourceComments = 'map';
if (argv['source-map'] === true) {
options.sourceMap = outFile + '.map';
if (options.sourceMap === true) {
options.sourceMap = options.dest + '.map';
} else {
options.sourceMap = path.resolve(cwd, argv['source-map']);
options.sourceMap = path.resolve(cwd, options.sourceMap);
}
}
options.precision = argv.precision;
if (argv.w) {
var watchDir = argv.w;
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(inFile);
var throttledRender = throttle(render, options, emitter);
watchDir.push(options.src);
watch(watchDir, function(file){
watch(watchDir, function(file) {
emitter.emit('warn', '=> changed: '.grey + file.blue);
if (isSassFile(file)) {
throttledRender();
}
});
throttledRender();
} else {
if (inFile === undefined && args.length > 0) {
stdin(function(data){
options.data = data.toString().trim();
render(options, emitter);
}
}
module.exports = function(args) {
var argv = yargs.parse(args);
var emitter = new Emitter();
var options = {
imagePath: argv['image-path'],
includePaths: argv['include-path'],
omitSourceMapUrl: argv['omit-source-map-url'],
outputStyle: argv['output-style'],
precision: argv.precision,
sourceComments: argv['source-comments'],
sourceMap: argv['source-map'],
stdout: argv.stdout,
watch: argv.w
};
if (argv.help) {
yargs.showHelp();
process.exit();
return;
}
emitter.on('error', function(err) {
console.error(err);
process.exit(1);
});
} else {
render(options, emitter);
options.src = argv._[0];
options.dest = argv.o || argv._[1];
if (!options.dest) {
var suffix = '.css';
if (/\.css$/.test(options.src)) {
suffix = '';
}
options.dest = path.join(cwd, path.basename(options.src, '.scss') + suffix);
}
if (process.stdin.isTTY || process.env.isTTY) {
run(options, emitter);
} else {
stdin(function(data) {
options.data = data;
run(options, emitter);
});
}
return emitter;
};
exports.yargs = yargs;
module.exports.yargs = yargs;
......@@ -3,20 +3,24 @@ var sass = require('../sass'),
fs = require('fs');
function render(options, emitter) {
sass.render({
file: options.inFile,
data: options.data,
includePaths: options.includePaths,
var renderOptions = {
imagePath: options.imagePath,
includePaths: options.includePaths,
omitSourceMapUrl: options.omitSourceMapUrl,
outFile: options.outFile,
outputStyle: options.outputStyle,
sourceComments: options.sourceComments,
sourceMap: options.sourceMap,
precision: options.precision,
outFile: options.outFile,
omitSourceMapUrl: options.omitSourceMapUrl,
success: function(css, sourceMap) {
sourceComments: options.sourceComments,
sourceMap: options.sourceMap
};
if (options.src) {
renderOptions.file = options.src;
} else if (options.data) {
renderOptions.data = options.data;
}
renderOptions.success = function(css, sourceMap) {
var todo = 1;
var done = function() {
if (--todo <= 0) {
......@@ -24,19 +28,17 @@ function render(options, emitter) {
}
};
// Write to stdout
if (options.stdout) {
if (options.stdout || (!process.stdout.isTTY && !process.env.isTTY)) {
emitter.emit('log', css);
return done();
}
// Write to disk
emitter.emit('warn', chalk.green('Rendering Complete, saving .css file...'));
fs.writeFile(options.outFile, css, function(err) {
fs.writeFile(options.dest, css, function(err) {
if (err) { return emitter.emit('error', chalk.red('Error: ' + err)); }
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.outFile));
emitter.emit('write', err, options.outFile, css);
emitter.emit('warn', chalk.green('Wrote CSS to ' + options.dest));
emitter.emit('write', err, options.dest, css);
done();
});
......@@ -51,11 +53,13 @@ function render(options, emitter) {
}
emitter.emit('render', css);
},
error: function(error) {
};
renderOptions.error = function(error) {
emitter.emit('error', chalk.red(error));
}
});
};
sass.render(renderOptions);
}
module.exports = render;
......@@ -54,6 +54,7 @@
"coveralls": "^2.11.1",
"jscoverage": "^0.5.6",
"jshint": "^2.5.5",
"mocha-lcov-reporter": "^0.0.1"
"mocha-lcov-reporter": "^0.0.1",
"object-assign": "^0.3.1"
}
}
......@@ -2,8 +2,8 @@ var path = require('path'),
assert = require('assert'),
fs = require('fs'),
exec = require('child_process').exec,
assign = require('object-assign'),
cli = process.env.NODESASS_COVERAGE ? require('../lib-coverage/cli') : require('../lib/cli'),
cliPath = path.resolve(__dirname, '../bin/node-sass'),
sampleFilename = path.resolve(__dirname, 'sample.scss');
......@@ -33,16 +33,21 @@ var sampleCssMapOutputPath = path.join(__dirname, '../sample.css.map');
describe('cli', function() {
it('should print help when run with no arguments', function(done) {
exec('node ' + cliPath, function(err, stdout, stderr) {
var env = assign(process.env, { isTTY: true });
exec('node ' + cliPath, {
env: env
}, function(err, stdout, stderr) {
done(assert(stderr.trim().indexOf('Compile .scss files with node-sass') === 0));
});
});
it('should compile sample.scss as sample.css', function(done) {
var env = assign(process.env, { isTTY: true });
var resultPath = path.join(__dirname, 'sample.css');
exec('node ' + cliPath + ' ' + sampleFilename, {
cwd: __dirname
cwd: __dirname,
env: env
}, function(err) {
assert.equal(err, null);
......@@ -54,10 +59,12 @@ describe('cli', function() {
});
it('should compile sample.scss to ../out.css', function(done) {
var env = assign(process.env, { isTTY: true });
var resultPath = path.resolve(__dirname, '../out.css');
exec('node ' + cliPath + ' ' + sampleFilename + ' ../out.css', {
cwd: __dirname
cwd: __dirname,
env: env
}, function(err) {
assert.equal(err, null);
......@@ -68,51 +75,51 @@ describe('cli', function() {
});
});
it('should compile with --include-path option', function(done){
it('should compile with --include-path option', function(done) {
var emitter = cli([
'--include-path', path.join(__dirname, 'lib'),
'--include-path', path.join(__dirname, 'functions'),
path.join(__dirname, 'include_path.scss')
]);
emitter.on('error', done);
emitter.on('write', function(err, file, css){
emitter.on('write', function(err, file, css) {
assert.equal(css.trim(), 'body {\n background: red;\n color: #0000fe; }');
fs.unlink(file, done);
});
});
it('should compile with the --output-style', function(done){
it('should compile with the --output-style', function(done) {
var emitter = cli(['--output-style', 'compressed', sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function(err, file, css){
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleCompressed);
fs.unlink(file, done);
});
});
it('should compile with the --source-comments option', function(done){
it('should compile with the --source-comments option', function(done) {
var emitter = cli(['--source-comments', 'none', sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function(err, file, css){
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleNoComments);
fs.unlink(file, done);
});
});
it('should compile with the --image-path option', function(done){
it('should compile with the --image-path option', function(done) {
var emitter = cli(['--image-path', '/path/to/images', path.join(__dirname, 'image_path.scss')]);
emitter.on('error', done);
emitter.on('write', function(err, file, css){
emitter.on('write', function(err, file, css) {
assert.equal(css, expectedSampleCustomImagePath);
fs.unlink(file, done);
});
});
it('should write the output to the file specified with the --output option', function(done){
it('should write the output to the file specified with the --output option', function(done) {
var resultPath = path.join(__dirname, '../output.css');
var emitter = cli(['--output', resultPath, sampleScssPath]);
emitter.on('error', done);
emitter.on('write', function(){
emitter.on('write', function() {
fs.exists(resultPath, function(exists) {
assert(exists);
fs.unlink(resultPath, done);
......@@ -120,19 +127,19 @@ describe('cli', function() {
});
});
it('should write to stdout with the --stdout option', function(done){
it('should write to stdout with the --stdout option', function(done) {
var emitter = cli(['--stdout', sampleScssPath]);
emitter.on('error', done);
emitter.on('log', function(css){
emitter.on('log', function(css) {
assert.equal(css, expectedSampleNoComments);
done();
});
});
it('should not write to disk with the --stdout option', function(done){
it('should not write to disk with the --stdout option', function(done) {
var emitter = cli(['--stdout', sampleScssPath]);
emitter.on('error', done);
emitter.on('done', function(){
emitter.on('done', function() {
fs.exists(sampleCssOutputPath, function(exists) {
assert(!exists);
if (exists) {fs.unlinkSync(sampleCssOutputPath);}
......@@ -141,9 +148,12 @@ describe('cli', function() {
});
});
it('should not exit with the --watch option', function(done){
it('should not exit with the --watch option', function(done) {
var command = cliPath + ' --watch ' + sampleScssPath;
var child = exec('node ' + command);
var env = assign(process.env, { isTTY: true });
var child = exec('node ' + command, {
env: env
});
var exited = false;
child.on('exit', function() {
......@@ -160,7 +170,7 @@ describe('cli', function() {
}, 100);
});
it('should compile with the --source-map option', function(done){
it('should compile with the --source-map option', function(done) {
var emitter = cli([sampleScssPath, '--source-map']);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
......@@ -197,7 +207,7 @@ describe('cli', function() {
});
});
it('should compile a sourceMap if --source-comments="map", but the --source-map option is excluded', function(done){
it('should compile a sourceMap if --source-comments="map", but the --source-map option is excluded', function(done) {
var emitter = cli([sampleScssPath, '--source-comments', 'map']);
emitter.on('error', done);
emitter.on('write-source-map', function(err, file) {
......@@ -214,15 +224,4 @@ describe('cli', function() {
});
});
});
it('should compile with input from stdin', function(done){
var emitter = cli(['--stdout']);
emitter.on('error', done);
emitter.on('log', function(css){
done(assert.equal(css, '#navbar ul {\n list-style-type: none; }\n'));
});
process.stdin.emit('data', '#navbar ul{list-style-type:none;}');
process.stdin.emit('end');
});
});
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