UNPKG

techy

Version:

Flat CMS based on Gulp and AbsurdJS

310 lines (292 loc) 8.82 kB
#!/usr/bin/env node var fs = require('fs'); var path = require('path'); var colors = require('colors'); var gulp = require('gulp'); var absurd = require('gulp-absurd'); var concat = require('gulp-concat'); var jshint = require('gulp-jshint'); var uglify = require('gulp-uglify'); var argv = require('minimist')(process.argv.slice(2)); var ncp = require('ncp').ncp; var through2 = require('through2'); var GulpEnd = require('./GulpEnd'); var queue = require('./helpers/queue'); var extend = require('./helpers/extend'); ncp.limit = 16; var Techy = function(r, callback, config) { var root = path.normalize(r || process.cwd()); var defaultDestinationDir = '_dist'; var rootTechy = __dirname; config = config || {}; config.noLogging = config.noLogging || false, config.actAsGulpPlugin = config.actAsGulpPlugin || false; config.techyFile = config.techyFile || (argv.config ? root + '/' + argv.config : null); config.src = config.src || root; config.dest = config.dest || path.normalize(argv.dest ? root + '/' + argv.dest : root + '/' + defaultDestinationDir); config.theme = config.theme || argv.theme || false; config.overwrite = argv.forceUpdate; var CSSDirToWatch = ''; var api = { config: config, root: root, rootTechy: rootTechy, pages: [], copyingDefaultFiles: function(cb) { if(api.config.theme) { var themeDir = ''; if(fs.existsSync(api.rootTechy + '/themes/' + api.config.theme)) { themeDir = path.normalize(api.rootTechy + '/themes/' + api.config.theme); } else { throw new Error('Techy: there is no theme with name \'' + api.config.theme + '\'!'); return; } var resourcesToCopy = fs.readdirSync(themeDir); (function copying() { if(resourcesToCopy.length == 0) { cb(); } else { var item = resourcesToCopy.shift(); api.copyFolder( path.normalize(themeDir + '/' + item), path.normalize(config.src + '/' + item), copying ); } })(); } else { cb(); } }, setMasterConfig: function(cb) { if(fs.existsSync(root + '/Techy.js')) { api.config = extend(api.config, api.processTechyFile(root + '/Techy.js')); } if(fs.existsSync(api.themeDir + '/TechyFile.js')) { api.config = extend(api.config, api.processTechyFile(api.themeDir + '/TechyFile.js')); } else if(fs.existsSync(root + '/TechyFile.js')) { api.config = extend(api.config, api.processTechyFile(root + '/TechyFile.js')); } else if(config && config.techyFile && fs.existsSync(config.techyFile)) { api.config = extend(api.config, api.processTechyFile(config.techyFile)); } cb(); }, processTechyFile: function(techyFilePath) { var data = require(techyFilePath)(); if(data.src) { data.src = path.normalize(root + '/' + data.src); } if(data.dest) { data.dest = path.normalize(root + '/' + data.dest); } return data; }, creatingDestFolder: function(cb) { if(!fs.existsSync(api.config.dest)) { fs.mkdirSync(api.config.dest); } cb(); }, copyingNonSystemFiles: function(cb) { var resourcesToCopy = fs.readdirSync(config.src); var distDirectory = path.normalize(config.dest).split(/\/|\\/g).pop(); (function copying() { if(resourcesToCopy.length == 0) { cb(); } else { var item = resourcesToCopy.shift(); if( item !== distDirectory && item.indexOf('_') !== 0 && item.indexOf('.') !== 0 && item !== 'node_modules' ) { var stat = fs.statSync(path.normalize(config.src + '/' + item)); if(stat.isDirectory()) { api.copyFolder( path.normalize(root + '/' + item), path.normalize(api.config.dest + '/' + item), copying, true, function(file) { var normilized = path.normalize(file); var basenameFile = path.basename(normilized); var result = true; if(basenameFile.indexOf('_') === 0) { var stat = fs.statSync(normilized); if(stat.isDirectory(normilized)) { result = false; } else { return file.split('.').pop().toLowerCase() !== 'md'; } } else { return file.split('.').pop().toLowerCase() !== 'md'; } } ); } else { copying(); } } else { copying(); } } })(); }, copyFolder: function(source, destination, cb, forceOverwrite, filter) { if(fs.existsSync(destination) && !api.config.overwrite && !forceOverwrite) { cb(); return; } var self = this; ncp(source, destination, { filter: filter }, function (err) { if(err === null) { cb.apply(self); } else { throw new Error('Techy: I can\'t copy ' + source + ' folder!'); } }); }, compilePages: function(cb) { if(!this.pagesPattern) { this.pagesPattern = [ api.config.src + '/**/*.md', '!' + api.config.src + '/node_modules/**', '!' + api.config.dest + '/**/*.md' ]; if(api.config.process) { for(var p in api.config.process) { api.config.process[p] = root + '/' + api.config.process[p]; } this.pagesPattern = this.pagesPattern.concat(api.config.process) } } gulp.src(this.pagesPattern) .pipe(Factory.gulp()) .pipe(gulp.dest(api.config.dest)) .pipe(GulpEnd(function() { !api.config.noLogging ? console.log('+ ' + 'Pages'.green + ' compiled') : null; cb ? cb() : null; })); return this; }, compileCSS: function(cb) { if(api.config.css) { var preprocessor = 'css', index = api.root + '/_css/**/*.css' out = path.normalize(api.root + '/_dist/css'); if(api.config.css) { preprocessor = api.config.css.preprocessor || preprocessor; index = api.config.css.index ? api.root + '/' + api.config.css.index : index; out = api.config.css.out ? api.root + '/' + api.config.css.out : out; } CSSDirToWatch = api.root + '/' + api.config.css.watch || index; switch(preprocessor) { case 'less': var less = require('gulp-less'); gulp.src(index) .pipe(less({ paths: [ path.join(__dirname, 'less', 'includes') ] })) .pipe(gulp.dest(out)) .pipe(GulpEnd(cb)); break; case 'sass': var sass = require('gulp-sass'); gulp.src(index) .pipe(sass()) .pipe(gulp.dest(out)) .pipe(GulpEnd(cb)); break; case 'absurd': gulp.src(index) .pipe(absurd({ minify: true, combineSelectors: false })) .pipe(gulp.dest(out)) .pipe(GulpEnd(cb)); break; default: gulp.src(index) .pipe(concat('styles.css')) .pipe(gulp.dest(out)) .pipe(GulpEnd(cb)); break; } !api.config.noLogging ? console.log('+ ' + 'CSS'.green + ' compiled') : null; } else { cb(); } return this; }, compileJS: function(cb) { if(api.config.js) { var pSrc = path.normalize(api.root + '/' + api.config.js.src); var pDest = path.normalize(api.root + '/' + api.config.js.dest); gulp.src(pSrc) // .pipe(uglify()) .pipe(concat(path.basename(pDest))) // .pipe(jshint()) // .pipe(jshint.reporter('default')) .pipe(gulp.dest(path.dirname(pDest))) .pipe(GulpEnd(cb)); !api.config.noLogging ? console.log('+ ' + 'JavaScript'.green + ' compiled') : null; } else { cb(); } return this; }, watchFiles: function() { gulp.watch(this.pagesPattern, function(event) { this.compilePages(); }.bind(this)); if(CSSDirToWatch) { gulp.watch([CSSDirToWatch], function(event) { this.compileCSS(); }.bind(this)); } if(api.config.js) { gulp.watch([path.normalize(api.root + '/' + api.config.js.src)], function(event) { this.compileJS(); }.bind(this)); } !api.config.noLogging ? console.log('Techy is listening for changes!'.green) : null; return this; } } var Factory = api.factory = require('./Factory')(api); queue([ api.setMasterConfig, api.copyingDefaultFiles, !api.config.actAsGulpPlugin ? api.creatingDestFolder : function(cb) { cb(); }, api.compileCSS, api.compileJS, !api.config.actAsGulpPlugin ? api.compilePages : function(cb) { cb(); }, api.copyingNonSystemFiles, callback || function() {} ], api); return api; } module.exports = Techy; module.exports.gulp = function(settings) { settings = settings || {}; var noop = function() {}; var T = Techy( settings.root || process.cwd(), function() {}, extend({ noLogging: true, actAsGulpPlugin: true }, settings) ); return function() { return T.compileCSS(noop).compileJS(noop).factory.gulp(); } } if(!module.parent) { Techy(false, function() { this.watchFiles(); }); }