Skip to content

Commit

Permalink
Merge pull request #5 from zhangyue1208/master
Browse files Browse the repository at this point in the history
Changed plugin into stream. Now supported gulp.dist.
  • Loading branch information
theJian authored Sep 19, 2016
2 parents a941e48 + ede12e6 commit e9bfd4c
Show file tree
Hide file tree
Showing 31 changed files with 664 additions and 228 deletions.
29 changes: 17 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,27 @@ install via npm:

To import a file called `_name.scss`, there are four ways to do it.

@import 'path-to-file/name';
@import 'path-to-file/_name';
@import 'path-to-file/name.scss';
@import 'path-to-file/_name.scss';
```javascript
@import 'path-to-file/name';
@import 'path-to-file/_name';
@import 'path-to-file/name.scss';
@import 'path-to-file/_name.scss';
```

All of above will have the same result.

```javascript
'use strict';

var gulp = require('gulp');
var gss = require('gulp-shopify-sass');

gulp.task('default', function() {
return gulp.src('./*.scss')
.pipe(gss());
});
var gulp = require('gulp');
var gss = require('gulp-shopify-sass');

gulp.task('default', function() {
return gulp.src('./*.scss')
.pipe(gss())
.pipe(gulp.dest('./path/to/dist'));
});
```

# License
MIT license
MIT license
251 changes: 140 additions & 111 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,130 +1,159 @@
'use strict';

var through = require('through2');
var path = require('path');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;
var vfile = require('vinyl-file');
var vinyl = require('vinyl');
var fs = require('fs');
var path = require('path');
var gutil = require('gulp-util');
var through = require('through2');
var clonedeep = require('lodash.clonedeep');

const PLUGIN_NAME = 'gulp-shopify-sass';

// @param: dir full path and name
// @return: boolean
function checkFileExist (dir) {
try {
fs.accessSync(dir , fs.F_OK);
return true;
} catch (e) {
return false;
}
}

// @param: dir full path and name
// @return: string | boolean
function analyseDir (dir) {
// possible extension array
const dirReg = new RegExp(/(.+\/)(.+)$/, 'g');
const filenameReg = new RegExp(/^(\_)?(?:(.*(?=.scss))(.*)|(.*))$/, 'i');

// split whole path into path the filename
let pathAndName = dirReg.exec(dir);

const filepath = pathAndName[1] || '';
let filename = pathAndName[2] || '';

// [0] original filename
// [1] '_' if exist in the filename, otherwise undefined
// [2] filename if it has extension .scss or .scss.liquid, otherwise undefined
// [3] file extension if filename has extionsion .scss or .scss.liquid, otherwise undefined
// [4] filename if it doesn't have extension, otherwise undefined
let filenameFrags = filenameReg.exec(filename);

// move filename[4] to filename[2] if filename[2] is undefined
filenameFrags[2] = filenameFrags[2] || filenameFrags[4];

// remove original name, all index will reduce 1
filenameFrags.shift();

// remove filename[4] since it's been moved to [2]
filenameFrags.pop()

// [0] was [1], [2] was [3]
let prefix = filenameFrags[0] ? [filenameFrags[0]] : ['', '_'];
let suffix = filenameFrags[2] ? [filenameFrags[2]] : ['.scss', '.scss.liquid'];
let allCombinations = [];

// check all possible combimations
for (let i in prefix) {
for (let j in suffix) {
filenameFrags[0] = prefix[i];
filenameFrags[2] = suffix[j];
filename = filenameFrags.join('');

pathAndName = path.join(filepath, filename);

if (checkFileExist(pathAndName)) {
return pathAndName;
}
}
}

gutil.log('File to import: "' + dir + '" not found.');

return false;
}


function importReplacer (file) {

var rex = /@import\s*(?:(?:'([^']+)')|(?:"([^"]+)"))\s*;/gi;
var fileContents = file.contents.toString();
var fileDirname = path.dirname(file.path);
var imports = {};
var match;
/*
* Most of the code in index.js are copied from gulp-sass
*/

while(match = rex.exec(fileContents)) {

// [1] single quotes
// [2] double quotes
var importFile = path.join(fileDirname, (match[1] || match[2]));
//////////////////////////////
// Main Gulp Shopify Sass function
//////////////////////////////
var gulpShopifySass = function gulpShopifySass (options, sync) {
return through.obj(function (file, enc, cb) {

const fileExistCheck = analyseDir(importFile);
var opts, contents;

// if file exists, replace it
if(fileExistCheck) {
imports[match[0]] = fileExistCheck;
if (file.isNull()) {
return cb(null, file);
}

}

for(let imp in imports) {
// replace @import with import file contents
fileContents = fileContents.replace(new RegExp(imp, 'g'), importReplacer(vfile.readSync(imports[imp])).contents.toString());
}

file.contents = new Buffer(fileContents);

return file;
}

module.exports = function () {
return through.obj(function (file, enc, cb) {

// do not support stream
if(file.isStream()) {
this.emit('error', new PluginError(PLUGIN_NAME, 'Streams are not supported!'));
return cb();
return cb(new gutil.PluginError(PLUGIN_NAME, 'Streaming not supported!'));
}

//////////////////////////////
// Handles returning the file to the stream
//////////////////////////////
var filePush = function filePush(contents) {
// console.log(file);
// console.log(file.contents);
// console.log(contents);
// file = new gutil.File({
// 'cwd': __dirname,
// 'base': file.base,
// 'path': gutil.replaceExtension(file.path, '.cat.scss.liquid'),
// 'contents': contents
// });

file.contents = new Buffer(contents);
file.path = gutil.replaceExtension(file.path, '.cat.scss.liquid');

cb(null, file);
};

//////////////////////////////
// Handles error message
//////////////////////////////
var errorM = function errorM(error) {
var relativePath = '',
filePath = error.file === 'stdin' ? file.path : error.file,
message = '';

filePath = filePath ? filePath : file.path;
relativePath = path.relative(process.cwd(), filePath);

message += gutil.colors.underline(relativePath) + '\n';
message += error.formatted;

error.messageFormatted = message;
error.messageOriginal = error.message;
// error.message = gutil.colors.stripColor(message);

error.relativePath = relativePath;

return cb(new gutil.PluginError(
PLUGIN_NAME, error
));
};

// processing buffer
if(file.isBuffer()) {
importReplacer(file);
//////////////////////////////
// gulpShopifySass main process BEGIN
//////////////////////////////

opts = clonedeep(options || {});
opts.data = file.contents.toString();

// we set the file path here so that libsass can correctly resolve import paths
opts.file = file.path;

// TODO: add includePaths feature in options and relavent processer

// Ensure file's parent directory in the include path
// if (opts.includePaths) {
// if (typeof opts.includePaths === 'string') {
// opts.includePaths = [opts.includePaths];
// }
// } else {
// opts.includePaths = [];
// }

// opts.includePaths.unshift(path.dirname(file.path));

// TDDO: enable sync option once async render is done. Only support renderSync for now
// if (sync === true) {
//////////////////////////////
// Sync Sass render
//////////////////////////////

try {
contents = gulpShopifySass.compiler.renderSync(opts);

filePush(contents);
} catch (error) {
return errorM(error);
}

// } else {
// //////////////////////////////
// // Async Sass render
// //////////////////////////////
// var callback = function(error, catFile) {
// if (error) {
// return errorM(error);
// }
// filePush(catFile);
// };

// gulpShopifySass.compiler.render(opts, callback);
// }
//////////////////////////////
// gulpShopifySass main process END
//////////////////////////////
}

this.push(file);

cb();
});
}

//////////////////////////////
// Sync Shopify Sass render
//////////////////////////////

// TDDO: enable sync option once async render is done. Only support renderSync for now

// gulpShopifySass.sync = function sync(options) {
// return gulpShopifySass(options, true);
// };

//////////////////////////////
// Log errors nicely
//////////////////////////////
gulpShopifySass.logError = function logError(error) {
var message = new gutil.PluginError('sass', error.messageFormatted).toString();
process.stderr.write(message + '\n');
this.emit('end');
};

//////////////////////////////
// Store compiler in a prop
//////////////////////////////
gulpShopifySass.compiler = require('./lib/compiler');

module.exports = gulpShopifySass;
Loading

0 comments on commit e9bfd4c

Please sign in to comment.