UNPKG

blah

Version:

A command line tool to optimize the repetitive actions.

446 lines (389 loc) 14.8 kB
"use strict"; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var writeFile = require("write-file-trim"), path = require("path"), markdox = require("markdox"), isThere = require("is-there"), rJson = require("r-json"), wJson = require("w-json"), parentSearch = require("parent-search"), findFileInDirs = require("find-file-in-dirs"), ul = require("ul"), sameTime = require("same-time"), oneByOne = require("one-by-one"), deffy = require("deffy"), ejs = require("ejs"), ncp = require("ncp"), semver = require("semver"), abs = require("abs"), yearRange = require("year-range"), initialCommitDate = require("initial-commit-date"), currentYear = require("current-year"); // Constants var BLAH_DIR = ".blah", BLAH_TEMPLATES = ".blah-templates", TEMPLATES = "templates", PACKAGE_JSON = "package.json", DOCUMENTATION_NAME = "DOCUMENTATION.md", DOCUMENTATION_TMPL = "docs.ejs", CONTRIBUTING_TMPL = "CONTRIBUTING.ejs", CONTRIBUTING_NAME = "CONTRIBUTING.md", README_TMPL = "README.ejs", README_NAME = "README.md", LICENSE_NAME = "LICENSE", GITIGNORE_TMPL = "gitignore", GITIGNORE = ".gitignore", DATA_JS = "data.js"; var Blah = function () { /** * Blah * Creates a new `Blah` instance. * * @name Blah * @function * @param {String} cwd The Blah working directory (default: `process.cwd()`). */ function Blah(cwd) { _classCallCheck(this, Blah); // Blah working directory this.path = deffy(cwd, process.cwd()); // .blah/ this.blah_dir = path.join(this.path, BLAH_DIR); // ~/.blah-templates this.usr_templates = abs("~/" + BLAH_TEMPLATES); // templates/ this.lib_templates = path.join(__dirname, TEMPLATES); this.templates = {}; this.pack = {}; this.paths = {}; } /** * search * Searches a file in the blah directories. * * @name search * @function * @param {String} file The relative path to a file to search in the templates * directories (in the following order: local `.blah` directory, * `~/.blah-templates`, library templates). * @param {Function} callback The callback function. */ _createClass(Blah, [{ key: "search", value: function search(file, callback) { findFileInDirs([ // Local .blah/file this.blah_dir // Templates: ~/.blah-templates/file , this.usr_templates // Library templates: templates/file , this.lib_templates], file, function (err, file) { if (err) { return callback(err); } console.log("Using " + file + " as source."); callback(null, file); }); } /** * prepare * Prepares the Blah data. * * @name prepare * @function * @param {Function} callback The callback function. */ }, { key: "prepare", value: function prepare(callback) { var _this = this; if (this.initialized) { return callback(); } oneByOne([function (next) { return sameTime([function (cb) { return _this.search(DOCUMENTATION_TMPL, cb); }, function (cb) { return _this.search(README_TMPL, cb); }, function (cb) { return _this.search(GITIGNORE_TMPL, cb); }, function (cb) { return _this.search(CONTRIBUTING_TMPL, cb); }, function (cb) { parentSearch(_this.path, PACKAGE_JSON, cb); }], next); }, function (next, data) { _this.paths.markdox = data[0]; _this.paths.readme = data[1]; _this.paths.gitignore = data[2]; _this.paths.contributing = data[3]; _this.paths.pack = data[4]; next(); }, function (next) { if (!_this.paths.pack) { return next(null, {}); } rJson(_this.paths.pack, function (err, pack) { pack = deffy(pack, {}); next(null, pack); }); }, function (next, pack) { _this.pack = pack; _this.pack.blah = deffy(_this.pack.blah, {}); _this.copyright = { fullname: _this.pack.author, year: new Date().getFullYear(), project: _this.pack.name, description: _this.pack.description }; next(); }, function (next) { initialCommitDate(function (err, d) { _this.current_year = currentYear(); _this.first_commit_year = err ? _this.current_year : d.getFullYear(); _this.license_year = yearRange(_this.first_commit_year, _this.current_year); next(); }); }], function (err, data) { _this.initialized = true; callback(err, data); }); } /** * init * Inits the `.blah` directory in the current project. * * @name init * @function * @param {Function} callback The callback function. */ }, { key: "init", value: function init(callback) { var _this2 = this; oneByOne([function (next) { return _this2.prepare(next); }, function (next) { return _this2.search(next); }, function (next, path_templates) { if (path_templates === _this2.blah_dir) { return next(new Error("Refusing to override existing templates.")); } ncp(path_templates, _this2.blah_dir, next); }], callback); } /** * docs * Generates the DOCUMENTATION.md file, parsing the input files. * * @name docs * @function * @param {String} input Input file name (default: main file from package.json) * @param {String} output Output file name (default: `DOCUMENTATION.md`) * @param {Boolean} writeToFile If `false`, the docs will be returned via the * callback function, without writing the output file. * @param {Function} callback The callback function. */ }, { key: "docs", value: function docs(input, output, writeToFile, callback) { var _this3 = this; input = deffy(input, ""); if (typeof writeToFile === "function") { callback = writeToFile; writeToFile = true; } if (typeof output === "function") { callback = output; output = path.join(this.path, DOCUMENTATION_NAME); } else if (typeof output === "boolean") { writeToFile = output; output = null; } writeToFile = deffy(writeToFile, true); oneByOne([function (next) { return _this3.prepare(next); }, function (next) { isThere(input, next.bind(_this3, null)); }, function (next, exists) { if (!exists) { if (writeToFile) { return next(new Error("The input file does not exist.")); } return next(null, ""); } markdox.process(input, { template: _this3.paths.markdox }, next); }, function (next, content) { content = content.split("\n").map(function (c) { return c.trimRight(); }).join("\n"); if (writeToFile) { writeFile(output, content, next); } else { next(null, content); } }], function (err, result) { if (err) { return callback(err); } callback(null, result.slice(-1)[0]); }); } /** * readme * Creates the `README.md` file. * * @name readme * @function * @param {Function} callback The callback function */ }, { key: "readme", value: function readme(callback) { var _this4 = this; oneByOne([function (next) { return _this4.prepare(next); }, function (next) { _this4.docs(_this4.pack.blah.main || _this4.pack.main, false, next); }, function (next, docs) { _this4.render(_this4.paths.readme, { docs: docs }, next); }, function (err, content) { writeFile(path.join(_this4.path, README_NAME), content, callback); }], callback); } /** * gitignore * Creates the `.gitignore` file. * * @name gitignore * @function * @param {Function} callback The callback function. */ }, { key: "gitignore", value: function gitignore(callback) { var _this5 = this; oneByOne([function (next) { return _this5.prepare(next); }, function (next) { ncp(_this5.paths.gitignore, path.join(_this5.path, GITIGNORE), next); }], callback); } /** * license * Creates the `LICENSE` file. * * @name license * @function * @param {String} license The license name. * @param {Function} callback The callback function. */ }, { key: "license", value: function license(_license, callback) { var _this6 = this; _license = _license.toLowerCase(); oneByOne([function (next) { return _this6.prepare(next); }, function (next) { _this6.search("licenses/" + _license + ".ejs", next); }, function (next, licensepath) { if (!_this6.copyright.fullname) { return next(new Error("Cannot find the author name. Is the package.json file missing?")); } _this6.render(licensepath, next); }, function (next, content) { writeFile(path.join(_this6.path, LICENSE_NAME), content, next); }], callback); } /** * render * Renders a template from file. * * @name render * @function * @param {String} path The template path. * @param {Object} data Additional data to merge into the template data. * @param {Function} callback The callback function. */ }, { key: "render", value: function render(path, data, callback) { var _this7 = this; if (typeof data === "function") { callback = data; data = {}; } this.search(DATA_JS, async function (err, dataJsPath) { var collectTemplateDataFn = async function collectTemplateDataFn() {}; if (dataJsPath) { collectTemplateDataFn = require(dataJsPath); } var templateData = await collectTemplateDataFn(path, data, _this7); var renderData = ul.merge({ _: _this7, require: require }, ul.merge(templateData, data)); ejs.renderFile(path, renderData, callback); }); } /** * contributing * Generates the `CONTRIBUTING.md` file. * * @name contributing * @function * @param {Function} callback The callback function. */ }, { key: "contributing", value: function contributing(callback) { var _this8 = this; oneByOne([function (next) { return _this8.prepare(next); }, function (next) { _this8.render(_this8.paths.contributing, next); }, function (next, content) { writeFile(path.join(_this8.path, CONTRIBUTING_NAME), content, next); }], callback); } /** * version * Bumps the provided version. * * @name version * @function * @param {String} what The version which should be bumped. It takes one of the following values: `"major"`, `"minor"`, `"patch"`. The default is `"patch"`. * @param {Function} callback The callback function. */ }, { key: "version", value: function version(what, callback) { var _this9 = this; if (typeof what === "function") { callback = what; what = "patch"; } oneByOne([function (next) { return _this9.prepare(next); }, function (next) { var version = _this9.pack.version; if (!version) { return callback(new Error("Cannot find the version in the package.json file.")); } _this9.pack.version = semver.inc(version, what); if (!_this9.pack.version) { return next(new Error("Invalid version.")); } wJson(_this9.paths.pack, _this9.pack, next); }], callback); } }]); return Blah; }(); module.exports = Blah;