-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from zhangyue1208/master
Changed plugin into stream. Now supported gulp.dist.
- Loading branch information
Showing
31 changed files
with
664 additions
and
228 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
Oops, something went wrong.