UNPKG

grunt-terrific-modules

Version:
652 lines (526 loc) 14.1 kB
/* * grunt-terrific-modules * https://github.com/smollweide/grunt-terrific-modules * * Copyright (c) 2014 Jan Widmer, Simon Mollweide * Licensed under the MIT license. */ /* eslint complexity: 0 */ /** * * generates a Module * * @constructor ModuleGenerator * @author Simon Mollweide * @namespace grunt * @param {Object} options - the class options * @returns {void} */ function ModuleGenerator(options) { this.init(options); } ModuleGenerator.prototype = { constructor: ModuleGenerator, /** * * called by constructor * * @method init * @param {Object} options - the class options * @returns {*} returns context */ init: function (options) { var _this = this; _this.options = options; _this.args = _this.options.args; _this.taskPlaceholder = _this.options.options.placeholder; _this.taskFiles = _this.options.options.files; _this.triggerFile = _this.options.options.triggerFile; _this.complete = _this.options.options.complete; _this._data = {}; return this; }, /** * * @method detectArgs * @returns {*} returns context */ detectArgs: function () { var _this = this, args = _this.args, argLen = args.length, patternTemplate = /^%/, patternAuthor = /^@/, patternType = /^-/, name, item, i = 1; _this._data = {}; if (argLen <= 0) { _this.errorArgs(); return this; } _this._console('log', ''); _this._console('log', ''); _this._console('log', '----- generator-module -----'); _this._console('log', ''); name = args[0]; _this._data.module = { name: name, nameU: _this._toUnderscore(name), nameC: _this._toCamelCase(name) }; _this._data.type = { name: 'atoms', nameU: _this._toUnderscore('atoms'), nameC: _this._toCamelCase('atoms') }; if (argLen <= 1) { return this; } for (i; i < argLen; i += 1) { item = args[i]; if (item.search(patternAuthor) >= 0) { _this._data.author = item.replace(patternAuthor, ''); } else if (item.search(patternTemplate) >= 0) { name = item.replace(patternTemplate, ''); _this._data.template = { name: name, nameU: _this._toUnderscore(name), nameC: _this._toCamelCase(name) }; } else if (item.search(patternType) >= 0) { name = item.replace(patternType, ''); _this._data.type = { name: name, nameU: _this._toUnderscore(name), nameC: _this._toCamelCase(name) }; } else { name = item; _this._data.skin = { name: name, nameU: _this._toUnderscore(name), nameC: _this._toCamelCase(name) }; } } _this._data = _this.attachCustomReplacements(_this._data); return this; }, /** * @method attachCustomReplacements * @param {Object} obj the object where custom attributes should be attached * @returns {Object} the object where custom attributes were attached */ attachCustomReplacements: function (obj) { var _this = this; this._forIn(obj, function (key, value) { var val = value, underscoreCustom, camelCaseCustom; if (!_this.taskPlaceholder[key]) { val.nameUCustom = val.nameU; val.nameCCustom = val.nameC; } if (!_this.taskPlaceholder[key].underscoreCustom) { val.nameUCustom = val.nameU; } else { underscoreCustom = _this.taskPlaceholder[key].underscoreCustom; val.nameUCustom = underscoreCustom[1][val.nameU]; } if (!_this.taskPlaceholder[key].camelCaseCustom) { val.nameCCustom = val.nameC; } else { camelCaseCustom = _this.taskPlaceholder[key].camelCaseCustom; val.nameCCustom = camelCaseCustom[1][val.nameC]; } }); return obj; }, /** * * @method write * @returns {*} returns context */ write: function () { var _this = this; if (typeof(_this._data.module) !== 'object') { return this; } _this.writeModule(_this._data.module, _this._data.author); if (typeof(_this._data.skin) === 'object') { _this.writeSkin(_this._data.module, _this._data.skin, _this._data.author); } if (typeof(_this._data.template) === 'object') { _this.writeTemplate(_this._data.module, _this._data.template, _this._data.author); } if (typeof(_this.triggerFile) === 'string') { _this.options.grunt.file.write(_this.triggerFile, ''); _this._console('log', 'write file: ' + new Date()); } if (typeof(_this.complete) === 'function') { _this.complete.call(_this, _this._data); } return this; }, /** * @method enrichWithReplacement * @param {string} name of the replace part * @param {Array} arr - the array which should be enriched * @returns {void} */ enrichWithReplacement: function (name, arr) { var placeholder = this.taskPlaceholder, obj = this._data[name]; if (!obj || !obj.name || !placeholder[name]) { return; } arr.push({ _that: placeholder[name].underscore, _with: obj.nameU }); arr.push({ _that: placeholder[name].camelCase, _with: obj.nameC }); if (placeholder[name].underscoreCustom) { arr.push({ _that: placeholder[name].underscoreCustom[0], _with: placeholder[name].underscoreCustom[1][obj.nameU] }); } if (placeholder[name].camelCaseCustom) { arr.push({ _that: placeholder[name].camelCaseCustom[0], _with: placeholder[name].camelCaseCustom[1][obj.nameC] }); } }, /** * @method getReplacements * @returns {Array} array filled with the replacement objects */ getReplacements: function () { var out = []; this.enrichWithReplacement('module', out); this.enrichWithReplacement('type', out); this.enrichWithReplacement('skin', out); this.enrichWithReplacement('template', out); return out; }, /** * * @method writeModule * @param {Object} module - the module object * @param {string} author - the given author * @returns {*} returns context */ writeModule: function (module, author) { var _this = this, moduleFiles = _this.taskFiles.module; if (typeof(moduleFiles) !== 'object') { return this; } _this._console('log', 'write module: ' + module.nameU); _this._console('log', '-----------------------------'); _this._for(moduleFiles, function () { _this.writeFile({ src: this.src, dest: this.dest, folder: this.folder, name: module.nameU, template: this.template, enrichWith: this.enrichWith, author: author, replacement: _this.getReplacements() }); }); _this._console('log', '-----------------------------'); _this._console('log', ''); return this; }, /** * * @method writeSkin * * @param {Object} module - the module object * @param {Object} skin - the skin object * @param {string} author - the author name * @returns {*} returns context */ writeSkin: function (module, skin, author) { var _this = this, skinFiles = _this.taskFiles.skin; if (typeof(skinFiles) !== 'object') { return this; } _this._console('log', 'write skin: ' + skin.nameU + ' (' + module.nameU + ')'); _this._console('log', '-----------------------------'); _this._for(skinFiles, function () { _this.writeFile({ src: this.src, dest: this.dest, folder: this.folder, name: module.nameU, template: this.template, enrichWith: this.enrichWith, author: author, replacement: _this.getReplacements() }); }); _this._console('log', '-----------------------------'); _this._console('log', ''); return this; }, /** * * @method writeTemplate * @param {Object} module - the module object * @param {Object} template - the template object * @param {string} author - the author name * @returns {*} returns context */ writeTemplate: function (module, template, author) { var _this = this, filesTemplate = _this.taskFiles.template; _this._console('log', 'writeTemplate'); if (typeof(filesTemplate) !== 'object') { return this; } _this._console('log', 'write template: ' + template.nameU + ' (' + module.nameU + ')'); _this._console('log', '-----------------------------'); _this._for(filesTemplate, function () { _this.writeFile({ src: this.src, dest: this.dest, folder: this.folder, name: module.nameU, template: this.template, author: author, enrichWith: this.enrichWith, replacement: _this.getReplacements() }); }); _this._console('log', '-----------------------------'); _this._console('log', ''); return this; }, /** * * @method writeFile * @param {Object} options - the given options * @returns {*} returns context */ writeFile: function (options) { var _this = this, placeholder = _this.taskPlaceholder, grunt = _this.options.grunt, path = options.dest + '/' + options.template, templatePath = options.src + '/' + options.template, content = '', pattern; // add author if exist if (typeof(options.author) === 'string') { options.replacement.push({ _that: placeholder.author, _with: options.author }); } // replace file path and content content = grunt.file.read(templatePath); _this._for(options.replacement, function () { pattern = new RegExp(this._that, 'g'); path = path.replace(pattern, this._with); content = content.replace(pattern, this._with); }); // check file exist if (grunt.file.exists(path)) { _this._console('log', 'file exist: ' + path); return this; } // write file _this._console('log', 'write file: ' + path); grunt.file.write(path, content); // write enrichWith _this.enrichWith(options); return this; }, /** * * enrich "enrichWith.src" with "enrichWith.template" at position "enrichWith.placeholder" * * @method enrichWith * @param {Object} options - the given options * @returns {*} returns context */ enrichWith: function (options) { var _this = this, grunt = _this.options.grunt, pathSrc, pathTemplate, outlet, content, pattern, pattern2; if (typeof(options.enrichWith) !== 'object') { return this; } pathSrc = options.enrichWith.src; pathTemplate = options.enrichWith.template; outlet = grunt.file.read(pathTemplate); _this._for(options.replacement, function () { pattern = new RegExp(this._that, 'g'); pathSrc = pathSrc.replace(pattern, this._with); outlet = outlet.replace(pattern, this._with); }); pattern2 = new RegExp(options.enrichWith.placeholder.replace(/U\+0025/g, '%'), 'g'); if (!grunt.file.exists(pathSrc)) { return this; } content = grunt.file.read(pathSrc); if (content.search(pattern2) < 0) { _this._console('log', 'placeholder (' + options.enrichWith.placeholder + ') not found in file "' + pathSrc + '"'); return this; } content = content.replace(pattern2, outlet); grunt.file.write(pathSrc, content); _this._console('log', 'change file : ' + pathSrc); return this; }, /** * * @method errorArgs * @returns {*} returns context */ errorArgs: function () { this._console('log', ''); this._console('log', ''); this._console('log', '---------- error ----------'); this._console('log', 'terrific-modules: no arguments'); this._console('log', ''); this._console('log', '---------- help -----------'); this._console('log', 'add module'); this._console('log', 'grunt terrific_modules:moduleName:@authorName'); this._console('log', 'or add skin'); this._console('log', 'grunt terrific_modules:moduleName:@authorName:skinName'); this._console('log', 'or add template'); this._console('log', 'grunt terrific_modules:moduleName:@authorName:%templateName'); this._console('log', 'or add type'); this._console('log', 'grunt terrific_modules:moduleName:-typeName:@authorName'); this._console('log', 'or add all'); this._console('log', 'grunt terrific_modules:moduleName:-typeName:@authorName:skinName:%templateName'); return this; }, /** * * @method _console * * @param {string} type - console type (error|log|success) * @param {*} value - the console value * @returns {*} returns context * @private */ _console: function (type, value) { var _this = this, log = function (val) { _this.options.grunt.log.writeln(val); }; if (type === 'dir') { log(JSON.stringify(value)); return this; } log(value); return this; }, /** * * @method _for * @param {Array} array - the loop array * @param {function} onLoop - loop callback * @returns {void} * @private */ _for: function (array, onLoop) { var i = 0, len = array.length; for (i; i < len; i += 1) { onLoop.call(array[i], i); } }, /** * * @method _forIn * @param {Object} obj - object that should be looped * @param {function} onLoop returns key value pair * @returns {void} * @private */ _forIn: function (obj, onLoop) { /* eslint-disable */ for (var key in obj) { if (obj.hasOwnProperty(key)) { onLoop.call(this, key, obj[key]); } } /* eslint-enable */ }, /** * * @method _toCamelCase * * @param {string} value - the value * @returns {string} camelCase value * @private */ _toCamelCase: function (value) { var val = value; if (typeof(value) !== 'string') { return value; } val = val.replace(/^[a-z]/, function () { return arguments[0].toUpperCase(); }); return val.replace(/-[a-z]/g, function () { return arguments[0].toUpperCase().replace('-', ''); }); }, /** * * @method _toUnderscore * * @param {string} value - the value * @returns {string} Underscore value * @private */ _toUnderscore: function (value) { if (typeof(value) !== 'string') { return value; } return value .replace(/[A-Z]/g, '-$&') .toLowerCase() .replace(/^-/, '') .replace(/--/g, '-'); } }; exports.init = function (grunt) { var exports = {}, moduleGenerator; exports.run = function (options) { moduleGenerator = new ModuleGenerator({ grunt: grunt, args: options.arguments, options: options.options }); moduleGenerator.detectArgs(); moduleGenerator.write(); }; exports.getPrototype = function () { return ModuleGenerator.prototype; }; exports.getClass = function () { return ModuleGenerator; }; return exports; };