Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 23e6282

Browse files
committed
Merge pull request #964 from am11/master
CLI: Adds source-map=directory support
2 parents 58a85a0 + d1eae08 commit 23e6282

File tree

4 files changed

+72
-33
lines changed

4 files changed

+72
-33
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,8 @@ Pass a directory as the input to compile multiple files. For example: `node-sass
484484

485485
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.
486486

487+
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.
488+
487489
## Post-install Build
488490

489491
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.

bin/node-sass

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ var cli = meow({
106106
function isDirectory(filePath) {
107107
var isDir = false;
108108
try {
109-
var absolutePath = path.resolve(process.cwd(), filePath);
109+
var absolutePath = path.resolve(filePath);
110110
isDir = fs.lstatSync(absolutePath).isDirectory();
111111
} catch (e) {
112112
isDir = e.code === 'ENOENT';
@@ -173,20 +173,44 @@ function getOptions(args, options) {
173173
options.src = args[0];
174174

175175
if (args[1]) {
176-
options.dest = path.resolve(process.cwd(), args[1]);
176+
options.dest = path.resolve(args[1]);
177177
} else if (options.output) {
178178
options.dest = path.join(
179-
path.resolve(process.cwd(), options.output),
179+
path.resolve(options.output),
180180
[path.basename(options.src, path.extname(options.src)), '.css'].join('')); // replace ext.
181181
}
182182

183183
if (options.directory) {
184-
var sassDir = path.resolve(process.cwd(), options.directory);
184+
var sassDir = path.resolve(options.directory);
185185
var file = path.relative(sassDir, args[0]);
186-
var cssDir = path.resolve(process.cwd(), options.output);
186+
var cssDir = path.resolve(options.output);
187187
options.dest = path.join(cssDir, file).replace(path.extname(file), '.css');
188188
}
189189

190+
if (options.sourceMap) {
191+
if(!options.sourceMapOriginal) {
192+
options.sourceMapOriginal = options.sourceMap;
193+
}
194+
195+
// check if sourceMap path ends with .map to avoid isDirectory false-positive
196+
var sourceMapIsDirectory = options.sourceMapOriginal.indexOf('.map', options.sourceMapOriginal.length - 4) === -1 && isDirectory(options.sourceMapOriginal);
197+
198+
if (options.sourceMapOriginal === 'true') {
199+
options.sourceMap = options.dest + '.map';
200+
} else if (!sourceMapIsDirectory) {
201+
options.sourceMap = path.resolve(options.sourceMapOriginal);
202+
} else if (sourceMapIsDirectory) {
203+
if (!options.directory) {
204+
options.sourceMap = path.resolve(options.sourceMapOriginal, path.basename(options.dest) + '.map');
205+
} else {
206+
var sassDir = path.resolve(options.directory);
207+
var file = path.relative(sassDir, args[0]);
208+
var mapDir = path.resolve(options.sourceMapOriginal);
209+
options.sourceMap = path.join(mapDir, file).replace(path.extname(file), '.css.map');
210+
}
211+
}
212+
}
213+
190214
return options;
191215
}
192216

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

204-
var graphOptions = {loadPaths: options.includePath};
228+
var graphOptions = { loadPaths: options.includePath };
205229
var graph;
206230
if (options.directory) {
207231
graph = grapher.parseDir(options.directory, graphOptions);
@@ -253,32 +277,23 @@ function run(options, emitter) {
253277
}
254278
}
255279

256-
if (options.sourceMap) {
257-
if (options.sourceMap === 'true') {
258-
if (options.dest) {
259-
options.sourceMap = options.dest + '.map';
260-
} else {
261-
// replace ext.
262-
options.sourceMap = [path.basename(options.src, path.extname(options.src)), '.css.map'].join('');
263-
}
264-
} else {
265-
options.sourceMap = path.resolve(process.cwd(), options.sourceMap);
266-
}
280+
if (options.sourceMapOriginal && options.directory && !isDirectory(options.sourceMapOriginal) && options.sourceMapOriginal !== 'true') {
281+
emitter.emit('error', 'Multi-file compilation: requires sourceMap to be a directory or "true".');
267282
}
268283

269284
if (options.importer) {
270285
if ((path.resolve(options.importer) === path.normalize(options.importer).replace(/(.+)([\/|\\])$/, '$1'))) {
271286
options.importer = require(options.importer);
272287
} else {
273-
options.importer = require(path.resolve(process.cwd(), options.importer));
288+
options.importer = require(path.resolve(options.importer));
274289
}
275290
}
276291

277292
if (options.functions) {
278293
if ((path.resolve(options.functions) === path.normalize(options.functions).replace(/(.+)([\/|\\])$/, '$1'))) {
279294
options.functions = require(options.functions);
280295
} else {
281-
options.functions = require(path.resolve(process.cwd(), options.functions));
296+
options.functions = require(path.resolve(options.functions));
282297
}
283298
}
284299

@@ -315,13 +330,14 @@ function renderFile(file, options, emitter) {
315330
* @api private
316331
*/
317332
function renderDir(options, emitter) {
318-
var globPath = path.resolve(process.cwd(), options.directory, globPattern(options));
319-
glob(globPath, {ignore: '**/_*'}, function(err, files) {
320-
if(err) {
333+
var globPath = path.resolve(options.directory, globPattern(options));
334+
glob(globPath, { ignore: '**/_*' }, function(err, files) {
335+
if (err) {
321336
return emitter.emit('error', util.format('You do not have permission to access this path: %s.', err.path));
322-
} else if(!files.length) {
337+
} else if (!files.length) {
323338
return emitter.emit('error', 'No input file was found.');
324339
}
340+
325341
forEach(files, function(subject) {
326342
emitter.once('done', this.async());
327343
renderFile(subject, options, emitter);
@@ -359,7 +375,7 @@ if (!options.src && process.stdin.isTTY) {
359375
*/
360376

361377
if (options.src) {
362-
if (isDirectory(options.src)){
378+
if (isDirectory(options.src)) {
363379
options.directory = options.src;
364380
}
365381
run(options, emitter);

lib/render.js

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,19 @@ module.exports = function(options, emitter) {
8181
if (options.sourceMap) {
8282
todo++;
8383

84-
fs.writeFile(options.sourceMap, result.map, function(err) {
84+
mkdirp(path.dirname(options.sourceMap), function(err) {
8585
if (err) {
86-
return emitter.emit('error', chalk.red('Error' + err));
86+
return emitter.emit('error', chalk.red(err));
8787
}
88-
89-
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
90-
emitter.emit('write-source-map', err, options.sourceMap, result.map);
91-
done();
88+
fs.writeFile(options.sourceMap, result.map, function(err) {
89+
if (err) {
90+
return emitter.emit('error', chalk.red('Error' + err));
91+
}
92+
93+
emitter.emit('warn', chalk.green('Wrote Source Map to ' + options.sourceMap));
94+
emitter.emit('write-source-map', err, options.sourceMap, result.map);
95+
done();
96+
});
9297
});
9398
}
9499

test/cli.js

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,9 @@ describe('cli', function() {
324324
'--watch', srcDir
325325
]);
326326

327-
setTimeout(function () {
327+
setTimeout(function() {
328328
fs.appendFileSync(srcFile, 'a {color:green;}\n');
329-
setTimeout(function () {
329+
setTimeout(function() {
330330
bin.kill();
331331
var files = fs.readdirSync(destDir);
332332
assert.deepEqual(files, ['index.css']);
@@ -420,7 +420,7 @@ describe('cli', function() {
420420
});
421421
});
422422

423-
it('it should compile all files in the folder', function(done) {
423+
it('should compile all files in the folder', function(done) {
424424
var src = fixture('input-directory/sass');
425425
var dest = fixture('input-directory/css');
426426
var bin = spawn(cli, [src, '--output', dest]);
@@ -435,6 +435,22 @@ describe('cli', function() {
435435
});
436436
});
437437

438+
it('should compile with --source-map set to directory', function(done) {
439+
var src = fixture('input-directory/sass');
440+
var dest = fixture('input-directory/css');
441+
var destMap = fixture('input-directory/map');
442+
var bin = spawn(cli, [src, '--output', dest, '--source-map', destMap]);
443+
444+
bin.once('close', function() {
445+
var map = JSON.parse(read(fixture('input-directory/map/nested/three.css.map'), 'utf8'));
446+
447+
assert.equal(map.file, '../../css/nested/three.css');
448+
rimraf.sync(dest);
449+
rimraf.sync(destMap);
450+
done();
451+
});
452+
});
453+
438454
it('should skip files with an underscore', function(done) {
439455
var src = fixture('input-directory/sass');
440456
var dest = fixture('input-directory/css');

0 commit comments

Comments
 (0)