Commit 23e62828 by Adeel Mujahid

Merge pull request #964 from am11/master

CLI: Adds source-map=directory support
parents 58a85a02 d1eae080
...@@ -484,6 +484,8 @@ Pass a directory as the input to compile multiple files. For example: `node-sass ...@@ -484,6 +484,8 @@ Pass a directory as the input to compile multiple files. For example: `node-sass
Also, note `--importer` takes the (absolute or relative to pwd) path to a js file, which needs to have a default `module.exports` set to the importer function. See our test [fixtures](https://github.com/sass/node-sass/tree/974f93e76ddd08ea850e3e663cfe64bb6a059dd3/test/fixtures/extras) for example. Also, note `--importer` takes the (absolute or relative to pwd) path to a js file, which needs to have a default `module.exports` set to the importer function. See our test [fixtures](https://github.com/sass/node-sass/tree/974f93e76ddd08ea850e3e663cfe64bb6a059dd3/test/fixtures/extras) for example.
The source-map option accepts `true` as value, in which case it replaces destination extension with `.css.map`. It also accepts path to `.map` file and even path to the desired directory. In case of multi-file compilation path to `.map` yields error.
## Post-install Build ## Post-install Build
Install runs only two Mocha tests to see if your machine can use the pre-built [libsass] which will save some time during install. If any tests fail it will build from source. Install runs only two Mocha tests to see if your machine can use the pre-built [libsass] which will save some time during install. If any tests fail it will build from source.
......
...@@ -106,7 +106,7 @@ var cli = meow({ ...@@ -106,7 +106,7 @@ var cli = meow({
function isDirectory(filePath) { function isDirectory(filePath) {
var isDir = false; var isDir = false;
try { try {
var absolutePath = path.resolve(process.cwd(), filePath); var absolutePath = path.resolve(filePath);
isDir = fs.lstatSync(absolutePath).isDirectory(); isDir = fs.lstatSync(absolutePath).isDirectory();
} catch (e) { } catch (e) {
isDir = e.code === 'ENOENT'; isDir = e.code === 'ENOENT';
...@@ -173,20 +173,44 @@ function getOptions(args, options) { ...@@ -173,20 +173,44 @@ function getOptions(args, options) {
options.src = args[0]; options.src = args[0];
if (args[1]) { if (args[1]) {
options.dest = path.resolve(process.cwd(), args[1]); options.dest = path.resolve(args[1]);
} else if (options.output) { } else if (options.output) {
options.dest = path.join( options.dest = path.join(
path.resolve(process.cwd(), options.output), path.resolve(options.output),
[path.basename(options.src, path.extname(options.src)), '.css'].join('')); // replace ext. [path.basename(options.src, path.extname(options.src)), '.css'].join('')); // replace ext.
} }
if (options.directory) { if (options.directory) {
var sassDir = path.resolve(process.cwd(), options.directory); var sassDir = path.resolve(options.directory);
var file = path.relative(sassDir, args[0]); var file = path.relative(sassDir, args[0]);
var cssDir = path.resolve(process.cwd(), options.output); var cssDir = path.resolve(options.output);
options.dest = path.join(cssDir, file).replace(path.extname(file), '.css'); options.dest = path.join(cssDir, file).replace(path.extname(file), '.css');
} }
if (options.sourceMap) {
if(!options.sourceMapOriginal) {
options.sourceMapOriginal = options.sourceMap;
}
// check if sourceMap path ends with .map to avoid isDirectory false-positive
var sourceMapIsDirectory = options.sourceMapOriginal.indexOf('.map', options.sourceMapOriginal.length - 4) === -1 && isDirectory(options.sourceMapOriginal);
if (options.sourceMapOriginal === 'true') {
options.sourceMap = options.dest + '.map';
} else if (!sourceMapIsDirectory) {
options.sourceMap = path.resolve(options.sourceMapOriginal);
} else if (sourceMapIsDirectory) {
if (!options.directory) {
options.sourceMap = path.resolve(options.sourceMapOriginal, path.basename(options.dest) + '.map');
} else {
var sassDir = path.resolve(options.directory);
var file = path.relative(sassDir, args[0]);
var mapDir = path.resolve(options.sourceMapOriginal);
options.sourceMap = path.join(mapDir, file).replace(path.extname(file), '.css.map');
}
}
}
return options; return options;
} }
...@@ -201,7 +225,7 @@ function getOptions(args, options) { ...@@ -201,7 +225,7 @@ function getOptions(args, options) {
function watch(options, emitter) { function watch(options, emitter) {
var watch = []; var watch = [];
var graphOptions = {loadPaths: options.includePath}; var graphOptions = { loadPaths: options.includePath };
var graph; var graph;
if (options.directory) { if (options.directory) {
graph = grapher.parseDir(options.directory, graphOptions); graph = grapher.parseDir(options.directory, graphOptions);
...@@ -253,24 +277,15 @@ function run(options, emitter) { ...@@ -253,24 +277,15 @@ function run(options, emitter) {
} }
} }
if (options.sourceMap) { if (options.sourceMapOriginal && options.directory && !isDirectory(options.sourceMapOriginal) && options.sourceMapOriginal !== 'true') {
if (options.sourceMap === 'true') { emitter.emit('error', 'Multi-file compilation: requires sourceMap to be a directory or "true".');
if (options.dest) {
options.sourceMap = options.dest + '.map';
} else {
// replace ext.
options.sourceMap = [path.basename(options.src, path.extname(options.src)), '.css.map'].join('');
}
} else {
options.sourceMap = path.resolve(process.cwd(), options.sourceMap);
}
} }
if (options.importer) { if (options.importer) {
if ((path.resolve(options.importer) === path.normalize(options.importer).replace(/(.+)([\/|\\])$/, '$1'))) { if ((path.resolve(options.importer) === path.normalize(options.importer).replace(/(.+)([\/|\\])$/, '$1'))) {
options.importer = require(options.importer); options.importer = require(options.importer);
} else { } else {
options.importer = require(path.resolve(process.cwd(), options.importer)); options.importer = require(path.resolve(options.importer));
} }
} }
...@@ -278,7 +293,7 @@ function run(options, emitter) { ...@@ -278,7 +293,7 @@ function run(options, emitter) {
if ((path.resolve(options.functions) === path.normalize(options.functions).replace(/(.+)([\/|\\])$/, '$1'))) { if ((path.resolve(options.functions) === path.normalize(options.functions).replace(/(.+)([\/|\\])$/, '$1'))) {
options.functions = require(options.functions); options.functions = require(options.functions);
} else { } else {
options.functions = require(path.resolve(process.cwd(), options.functions)); options.functions = require(path.resolve(options.functions));
} }
} }
...@@ -315,13 +330,14 @@ function renderFile(file, options, emitter) { ...@@ -315,13 +330,14 @@ function renderFile(file, options, emitter) {
* @api private * @api private
*/ */
function renderDir(options, emitter) { function renderDir(options, emitter) {
var globPath = path.resolve(process.cwd(), options.directory, globPattern(options)); var globPath = path.resolve(options.directory, globPattern(options));
glob(globPath, {ignore: '**/_*'}, function(err, files) { glob(globPath, { ignore: '**/_*' }, function(err, files) {
if(err) { if (err) {
return emitter.emit('error', util.format('You do not have permission to access this path: %s.', err.path)); return emitter.emit('error', util.format('You do not have permission to access this path: %s.', err.path));
} else if(!files.length) { } else if (!files.length) {
return emitter.emit('error', 'No input file was found.'); return emitter.emit('error', 'No input file was found.');
} }
forEach(files, function(subject) { forEach(files, function(subject) {
emitter.once('done', this.async()); emitter.once('done', this.async());
renderFile(subject, options, emitter); renderFile(subject, options, emitter);
...@@ -359,7 +375,7 @@ if (!options.src && process.stdin.isTTY) { ...@@ -359,7 +375,7 @@ if (!options.src && process.stdin.isTTY) {
*/ */
if (options.src) { if (options.src) {
if (isDirectory(options.src)){ if (isDirectory(options.src)) {
options.directory = options.src; options.directory = options.src;
} }
run(options, emitter); run(options, emitter);
......
...@@ -81,14 +81,19 @@ module.exports = function(options, emitter) { ...@@ -81,14 +81,19 @@ module.exports = function(options, emitter) {
if (options.sourceMap) { if (options.sourceMap) {
todo++; todo++;
fs.writeFile(options.sourceMap, result.map, function(err) { mkdirp(path.dirname(options.sourceMap), function(err) {
if (err) { if (err) {
return emitter.emit('error', chalk.red('Error' + err)); return emitter.emit('error', chalk.red(err));
} }
fs.writeFile(options.sourceMap, result.map, function(err) {
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap)); if (err) {
emitter.emit('write-source-map', err, options.sourceMap, result.map); return emitter.emit('error', chalk.red('Error' + err));
done(); }
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, result.map);
done();
});
}); });
} }
......
...@@ -324,9 +324,9 @@ describe('cli', function() { ...@@ -324,9 +324,9 @@ describe('cli', function() {
'--watch', srcDir '--watch', srcDir
]); ]);
setTimeout(function () { setTimeout(function() {
fs.appendFileSync(srcFile, 'a {color:green;}\n'); fs.appendFileSync(srcFile, 'a {color:green;}\n');
setTimeout(function () { setTimeout(function() {
bin.kill(); bin.kill();
var files = fs.readdirSync(destDir); var files = fs.readdirSync(destDir);
assert.deepEqual(files, ['index.css']); assert.deepEqual(files, ['index.css']);
...@@ -420,7 +420,7 @@ describe('cli', function() { ...@@ -420,7 +420,7 @@ describe('cli', function() {
}); });
}); });
it('it should compile all files in the folder', function(done) { it('should compile all files in the folder', function(done) {
var src = fixture('input-directory/sass'); var src = fixture('input-directory/sass');
var dest = fixture('input-directory/css'); var dest = fixture('input-directory/css');
var bin = spawn(cli, [src, '--output', dest]); var bin = spawn(cli, [src, '--output', dest]);
...@@ -435,6 +435,22 @@ describe('cli', function() { ...@@ -435,6 +435,22 @@ describe('cli', function() {
}); });
}); });
it('should compile with --source-map set to directory', function(done) {
var src = fixture('input-directory/sass');
var dest = fixture('input-directory/css');
var destMap = fixture('input-directory/map');
var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]);
bin.once('close', function() {
var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8'));
assert.equal(map.file, '../../css/nested/three.css');
rimraf.sync(dest);
rimraf.sync(destMap);
done();
});
});
it('should skip files with an underscore', function(done) { it('should skip files with an underscore', function(done) {
var src = fixture('input-directory/sass'); var src = fixture('input-directory/sass');
var dest = fixture('input-directory/css'); var dest = fixture('input-directory/css');
......
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