function gulpRubySass(sources, options) { var stream = new Readable({objectMode: true}); // redundant but necessary stream._read = function () {}; options = assign({}, defaults, options); // alert user that `container` is deprecated if (options.container) { gutil.log(gutil.colors.yellow('The container option has been deprecated. Simultaneous tasks work automatically now!')); } // error if user tries to watch their files with the Sass gem if (options.watch || options.poll) { emitErr(stream, '`watch` and `poll` are not valid options for gulp-ruby-sass. Use `gulp.watch` to rebuild your files on change .'); } // error if user tries to pass a Sass option to sourcemap if (typeof options.sourcemap !== 'boolean') { emitErr(stream, 'The sourcemap option must be true or false. See the readme for instructions on using Sass sourcemaps with gulp .'); } options.sourcemap = options.sourcemap === true ? 'file' : 'none'; options.update = true; // simplified handling of array sources, like gulp.src if (!Array.isArray(sources)) { sources = [sources]; } var matches = []; var bases = []; sources.forEach(function (source) { matches.push(glob.sync(source)); bases.push(options.base || utils.calculateBase(source)); }); // log and return stream if there are no file matches if (matches[0].length < 1) { gutil.log('No files matched your Sass source.'); stream.push(null); return stream; } var intermediateDir = createIntermediatePath(sources, matches, options); var compileMappings = []; var baseMappings = {}; matches.forEach(function (matchArray, i) { var base = bases[i]; matchArray.filter(function (match) { // remove _partials return path.basename(match).indexOf('_') !== 0; }) .forEach(function (match) { var dest = gutil.replaceExtension( replaceLocation(match, base, intermediateDir), '.css' ); var relative = path.relative(intermediateDir, dest); // source:dest mappings for the Sass CLI compileMappings.push(match + ':' + dest); // store base values by relative file path baseMappings[relative] = base; }); }); var args = dargs(options, [ 'bundleExec', 'watch', 'poll', 'tempDir', 'verbose', 'emitCompileError', 'base', 'container' ]).concat(compileMappings); var command; if (options.bundleExec) { command = 'bundle'; args.unshift('exec', 'sass'); } else { command = 'sass'; } // plugin logging if (options.verbose) { logger.verbose(command, args); } var sass = spawn(command, args); sass.stdout.setEncoding('utf8'); sass.stderr.setEncoding('utf8'); sass.stdout.on('data', function (data) { logger.stdout(stream, intermediateDir, data); }); sass.stderr.on('data', function (data) { logger.stderr(stream, intermediateDir, data); }); sass.on('error', function (err) { logger.error(stream, err); }); sass.on('close', function (code) { if (options.emitCompileError && code !== 0) { emitErr(stream, 'Sass compilation failed. See console output for more information.'); } glob(path.join(intermediateDir, '**', '*'), function (err, files) { if (err) { emitErr(stream, err); } eachAsync(files, function (file, i, next) { if (fs.statSync(file).isDirectory() || path.extname(file) === '.map') { next(); return; } var relative = path.relative(intermediateDir, file); var base = baseMappings[relative]; fs.readFile(file, function (err, data) { if (err) { emitErr(stream, err); next(); return; } // rewrite file paths so gulp thinks the file came from cwd, not the // intermediate directory var vinylFile = new gutil.File({ cwd: process.cwd(), base: base, path: replaceLocation(file, intermediateDir, base) }); // sourcemap integration if (options.sourcemap === 'file' && pathExists.sync(file + '.map')) { // remove sourcemap comment; gulp-sourcemaps will add it back in data = new Buffer(convert.removeMapFileComments(data.toString())); var sourceMapObject = JSON.parse(fs.readFileSyn ...
n/a
clearCache = function (tempDir) { tempDir = tempDir || defaults.tempDir; rimraf.sync(tempDir); }
...
);
```
### sass.logError(err)
Convenience function for pretty error logging.
### sass.clearCache([tempDir])
In rare cases you may need to clear gulp-ruby-sass's cache. This sync function deletes all files used for Sass caching. If
you've set a custom temporary directory in your task you must pass it to `clearCache`.
## Issues
This plugin wraps the Sass gem for the gulp build system. It does not alter Sass's output in any way. Any issues with Sass
output should be reported to the [Sass issue tracker](https://github.com/sass/sass/issues).
...
logError = function (err) { var message = new gutil.PluginError('gulp-ruby-sass', err); process.stderr.write(message + '\n'); this.emit('end'); }
...
loadPath: [ 'library', '../../shared-components' ]
})
.on('error', sass.logError)
.pipe(gulp.dest('result'))
);
```
### sass.logError(err)
Convenience function for pretty error logging.
### sass.clearCache([tempDir])
In rare cases you may need to clear gulp-ruby-sass's cache. This sync function deletes all files used for Sass caching. If
you've set a custom temporary directory in your task you must pass it to `clearCache`.
...
error = function (stream, err) { if (err.code === 'ENOENT') { // Spawn error: gems not installed emitErr(stream, 'Gem ' + err.path + ' is not installed.'); } else { // Other errors emitErr(stream, err); } }
...
});
sass.stderr.on('data', function (data) {
logger.stderr(stream, intermediateDir, data);
});
sass.on('error', function (err) {
logger.error(stream, err);
});
sass.on('close', function (code) {
if (options.emitCompileError && code !== 0) {
emitErr(stream, 'Sass compilation failed. See console output for more information.');
}
...
prettifyDirectoryLogging = function (msg, intermediateDir) { var escapedDir = escapeStringRegexp(intermediateDir); return msg.replace(new RegExp(escapedDir + '/?', 'g'), './'); }
...
}
// Sass error: directory missing
else if (/No such file or directory @ rb_sysopen/.test(data)) {
emitErr(stream, data.trim());
}
// Not an error: Sass logging
else {
data = logger.prettifyDirectoryLogging(data, intermediateDir);
data = data.trim();
gutil.log(data);
}
};
logger.stderr = function (stream, intermediateDir, data) {
var bundlerMissing = /Could not find 'bundler' \((.*?)\)/.exec(data);
...
stderr = function (stream, intermediateDir, data) { var bundlerMissing = /Could not find 'bundler' \((.*?)\)/.exec(data); var sassVersionMissing = /Could not find gem 'sass \((.*?)\) ruby'/.exec(data); // Ruby error: Bundler gem not installed if (bundlerMissing) { emitErr(stream, 'ruby: Could not find \'bundler\' (' + bundlerMissing[1] + ').'); } // Bundler error: no matching Sass version else if (sassVersionMissing) { emitErr(stream, 'bundler: Could not find gem \'sass (' + sassVersionMissing[1] + ')\'.'); } // Sass error: file missing else if (/No such file or directory @ rb_sysopen/.test(data)) { emitErr(stream, data.trim()); } // Not an error: Sass warnings, debug statements else { data = logger.prettifyDirectoryLogging(data, intermediateDir); data = data.trim(); gutil.log(data); } }
...
sass.stderr.setEncoding('utf8');
sass.stdout.on('data', function (data) {
logger.stdout(stream, intermediateDir, data);
});
sass.stderr.on('data', function (data) {
logger.stderr(stream, intermediateDir, data);
});
sass.on('error', function (err) {
logger.error(stream, err);
});
sass.on('close', function (code) {
...
stdout = function (stream, intermediateDir, data) { // Bundler error: no Sass version found if (/bundler: command not found: sass/.test(data)) { emitErr(stream, 'bundler: command not found: sass'); } // Bundler error: Gemfile not found else if (/Could not locate Gemfile or .bundle\/ directory/.test(data)) { emitErr(stream, 'bundler: could not locate Gemfile or .bundle directory'); } // Sass error: directory missing else if (/No such file or directory @ rb_sysopen/.test(data)) { emitErr(stream, data.trim()); } // Not an error: Sass logging else { data = logger.prettifyDirectoryLogging(data, intermediateDir); data = data.trim(); gutil.log(data); } }
...
var sass = spawn(command, args);
sass.stdout.setEncoding('utf8');
sass.stderr.setEncoding('utf8');
sass.stdout.on('data', function (data) {
logger.stdout(stream, intermediateDir, data);
});
sass.stderr.on('data', function (data) {
logger.stderr(stream, intermediateDir, data);
});
sass.on('error', function (err) {
...
verbose = function (command, args) { gutil.log('Running command ' + command + ' ' + args.join(' ')); }
...
}
else {
command = 'sass';
}
// plugin logging
if (options.verbose) {
logger.verbose(command, args);
}
var sass = spawn(command, args);
sass.stdout.setEncoding('utf8');
sass.stderr.setEncoding('utf8');
...
calculateBase = function (source) { return glob2base(new glob.Glob(source)); }
...
}
var matches = [];
var bases = [];
sources.forEach(function (source) {
matches.push(glob.sync(source));
bases.push(options.base || utils.calculateBase(source));
});
// log and return stream if there are no file matches
if (matches[0].length < 1) {
gutil.log('No files matched your Sass source.');
stream.push(null);
return stream;
...
createIntermediatePath = function (sources, matches, options) { return path.join( options.tempDir, md5Hex( process.cwd() + JSON.stringify(sources) + JSON.stringify(matches) + JSON.stringify(options) ) ); }
n/a
emitErr = function (stream, err) { stream.emit('error', new gutil.PluginError('gulp-ruby-sass', err)); }
n/a
replaceLocation = function (origPath, currentLoc, newLoc) { return path.join( newLoc, path.relative(currentLoc, origPath) ); }
n/a