Skip to content

Commit

Permalink
CLI: Adds source-map=directory support.
Browse files Browse the repository at this point in the history
* For multi-file compilation.
* Written test.
* Usage:

  ```javascript
  node-sass --source-map source-map/dir --output css/path style/src/
  ```

Issue URL: sass#903.
PR URL: sass#964.
  • Loading branch information
am11 committed May 18, 2015
1 parent 58a85a0 commit 1c65c53
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 33 deletions.
64 changes: 40 additions & 24 deletions bin/node-sass
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ var cli = meow({
function isDirectory(filePath) {
var isDir = false;
try {
var absolutePath = path.resolve(process.cwd(), filePath);
var absolutePath = path.resolve(filePath);
isDir = fs.lstatSync(absolutePath).isDirectory();
} catch (e) {
isDir = e.code === 'ENOENT';
Expand Down Expand Up @@ -173,20 +173,44 @@ function getOptions(args, options) {
options.src = args[0];

if (args[1]) {
options.dest = path.resolve(process.cwd(), args[1]);
options.dest = path.resolve(args[1]);
} else if (options.output) {
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.
}

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 cssDir = path.resolve(process.cwd(), options.output);
var cssDir = path.resolve(options.output);
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;
}

Expand All @@ -201,7 +225,7 @@ function getOptions(args, options) {
function watch(options, emitter) {
var watch = [];

var graphOptions = {loadPaths: options.includePath};
var graphOptions = { loadPaths: options.includePath };
var graph;
if (options.directory) {
graph = grapher.parseDir(options.directory, graphOptions);
Expand Down Expand Up @@ -253,32 +277,23 @@ function run(options, emitter) {
}
}

if (options.sourceMap) {
if (options.sourceMap === '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.sourceMapOriginal && options.directory && !isDirectory(options.sourceMapOriginal) && options.sourceMapOriginal !== 'true') {
emitter.emit('error', 'Multi-file compilation: requires sourceMap to be a directory or "true".');
}

if (options.importer) {
if ((path.resolve(options.importer) === path.normalize(options.importer).replace(/(.+)([\/|\\])$/, '$1'))) {
options.importer = require(options.importer);
} else {
options.importer = require(path.resolve(process.cwd(), options.importer));
options.importer = require(path.resolve(options.importer));
}
}

if (options.functions) {
if ((path.resolve(options.functions) === path.normalize(options.functions).replace(/(.+)([\/|\\])$/, '$1'))) {
options.functions = require(options.functions);
} else {
options.functions = require(path.resolve(process.cwd(), options.functions));
options.functions = require(path.resolve(options.functions));
}
}

Expand Down Expand Up @@ -315,13 +330,14 @@ function renderFile(file, options, emitter) {
* @api private
*/
function renderDir(options, emitter) {
var globPath = path.resolve(process.cwd(), options.directory, globPattern(options));
glob(globPath, {ignore: '**/_*'}, function(err, files) {
if(err) {
var globPath = path.resolve(options.directory, globPattern(options));
glob(globPath, { ignore: '**/_*' }, function(err, files) {
if (err) {
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.');
}

forEach(files, function(subject) {
emitter.once('done', this.async());
renderFile(subject, options, emitter);
Expand Down Expand Up @@ -359,7 +375,7 @@ if (!options.src && process.stdin.isTTY) {
*/

if (options.src) {
if (isDirectory(options.src)){
if (isDirectory(options.src)) {
options.directory = options.src;
}
run(options, emitter);
Expand Down
17 changes: 11 additions & 6 deletions lib/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,19 @@ module.exports = function(options, emitter) {
if (options.sourceMap) {
todo++;

fs.writeFile(options.sourceMap, result.map, function(err) {
mkdirp(path.dirname(options.sourceMap), function(err) {
if (err) {
return emitter.emit('error', chalk.red('Error' + err));
return emitter.emit('error', chalk.red(err));
}

emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, result.map);
done();
fs.writeFile(options.sourceMap, result.map, function(err) {
if (err) {
return emitter.emit('error', chalk.red('Error' + err));
}

emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
emitter.emit('write-source-map', err, options.sourceMap, result.map);
done();
});
});
}

Expand Down
22 changes: 19 additions & 3 deletions test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ describe('cli', function() {
'--watch', srcDir
]);

setTimeout(function () {
setTimeout(function() {
fs.appendFileSync(srcFile, 'a {color:green;}\n');
setTimeout(function () {
setTimeout(function() {
bin.kill();
var files = fs.readdirSync(destDir);
assert.deepEqual(files, ['index.css']);
Expand Down Expand Up @@ -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 dest = fixture('input-directory/css');
var bin = spawn(cli, [src, '--output', dest]);
Expand All @@ -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) {
var src = fixture('input-directory/sass');
var dest = fixture('input-directory/css');
Expand Down

0 comments on commit 1c65c53

Please sign in to comment.