UNPKG

charlike

Version:

Small, fast, simple and streaming project scaffolder for myself, but not only. Supports hundreds of template engines through the @JSTransformers API or if you want custom `render` function passed through options

289 lines (241 loc) 8.45 kB
'use strict'; var dateFormat = require('dateformat'); var getPkgRepo = require('get-pkg-repo'); var gitSemverTags = require('git-semver-tags'); var normalizePackageData = require('normalize-package-data'); var Q = require('q'); var gitRemoteOriginUrl; try { gitRemoteOriginUrl = require('git-remote-origin-url'); } catch (err) { gitRemoteOriginUrl = function() { return Q.reject(err); }; } var readPkg = require('read-pkg'); var readPkgUp = require('read-pkg-up'); var url = require('url'); var _ = require('lodash'); var rhosts = /github|bitbucket|gitlab/i; var rtag = /tag:\s*[v=]?(.+?)[,\)]/gi; function mergeConfig(options, context, gitRawCommitsOpts, parserOpts, writerOpts) { var configPromise; var pkgPromise; var semverTagsPromise; var gitRemoteOriginUrlPromise; context = context || {}; gitRawCommitsOpts = gitRawCommitsOpts || {}; options = _.merge({ pkg: { transform: function(pkg) { return pkg; } }, append: false, releaseCount: 1, debug: function() {}, transform: function(commit, cb) { if (_.isString(commit.gitTags)) { var match = rtag.exec(commit.gitTags); rtag.lastIndex = 0; if (match) { commit.version = match[1]; } } if (commit.committerDate) { commit.committerDate = dateFormat(commit.committerDate, 'yyyy-mm-dd', true); } cb(null, commit); } }, options); options.warn = options.warn || options.debug; if (options.config) { if (_.isFunction(options.config)) { configPromise = Q.nfcall(options.config); } else { configPromise = Q(options.config); // jshint ignore:line } } if (options.pkg) { if (options.pkg.path) { pkgPromise = Q(readPkg(options.pkg.path)); // jshint ignore:line } else { pkgPromise = Q(readPkgUp()); // jshint ignore:line } } semverTagsPromise = Q.nfcall(gitSemverTags); gitRemoteOriginUrlPromise = Q(gitRemoteOriginUrl()); // jshint ignore:line return Q.allSettled([configPromise, pkgPromise, semverTagsPromise, gitRemoteOriginUrlPromise]) .spread(function(configObj, pkgObj, tagsObj, gitRemoteOriginUrlObj) { var config; var pkg; var fromTag; var repo; var hostOpts; var gitSemverTags = []; if (configPromise) { if (configObj.state === 'fulfilled') { config = configObj.value; } else { options.warn('Error in config' + configObj.reason.toString()); config = {}; } } else { config = {}; } context = _.assign(context, config.context); if (options.pkg) { if (pkgObj.state === 'fulfilled') { if (options.pkg.path) { pkg = pkgObj.value; } else { pkg = pkgObj.value.pkg || {}; } pkg = options.pkg.transform(pkg); } else if (options.pkg.path) { options.warn(pkgObj.reason.toString()); } } if ((!pkg || !pkg.repository || !pkg.repository.url) && gitRemoteOriginUrlObj.state === 'fulfilled') { pkg = pkg || {}; pkg.repository = pkg.repository || {}; pkg.repository.url = gitRemoteOriginUrlObj.value; normalizePackageData(pkg); } if (pkg) { context.version = context.version || pkg.version; try { repo = getPkgRepo(pkg); } catch (err) { repo = {}; } if (repo.browse) { var browse = repo.browse(); var parsedBrowse = url.parse(browse); context.host = context.host || (repo.domain ? (parsedBrowse.protocol + (parsedBrowse.slashes ? '//' : '') + repo.domain) : null); context.owner = context.owner || repo.user || ''; context.repository = context.repository || repo.project; context.repoUrl = browse; } context.packageData = pkg; } if (tagsObj.state === 'fulfilled') { gitSemverTags = context.gitSemverTags = tagsObj.value; fromTag = gitSemverTags[options.releaseCount - 1]; var lastTag = gitSemverTags[0]; if (lastTag === context.version || lastTag === 'v' + context.version) { if (options.outputUnreleased) { context.version = 'Unreleased'; } else { options.outputUnreleased = false; } } } if (!_.isBoolean(options.outputUnreleased)) { options.outputUnreleased = true; } if (context.host && (!context.issue || !context.commit || !parserOpts || !parserOpts.referenceActions)) { var type; if (context.host) { var match = context.host.match(rhosts); if (match) { type = match[0]; } } else if (repo && repo.type) { type = repo.type; } if (type) { hostOpts = require('../hosts/' + type); context = _.assign({ issue: hostOpts.issue, commit: hostOpts.commit }, context); } else { options.warn('Host: "' + context.host + '" does not exist'); hostOpts = {}; } } else { hostOpts = {}; } gitRawCommitsOpts = _.assign({ format: '%B%n-hash-%n%H%n-gitTags-%n%d%n-committerDate-%n%ci', from: fromTag, merges: false, debug: options.debug }, config.gitRawCommitsOpts, gitRawCommitsOpts ); if (options.append) { gitRawCommitsOpts.reverse = gitRawCommitsOpts.reverse || true; } parserOpts = _.assign( {}, config.parserOpts, { warn: options.warn }, parserOpts); if (hostOpts.referenceActions && parserOpts) { parserOpts.referenceActions = hostOpts.referenceActions; } if (_.isEmpty(parserOpts.issuePrefixes) && hostOpts.issuePrefixes) { parserOpts.issuePrefixes = hostOpts.issuePrefixes; } writerOpts = _.assign({ finalizeContext: function(context, writerOpts, filteredCommits, keyCommit, originalCommits) { var firstCommit = originalCommits[0]; var lastCommit = originalCommits[originalCommits.length - 1]; var firstCommitHash = firstCommit ? firstCommit.hash : null; var lastCommitHash = lastCommit ? lastCommit.hash : null; if ((!context.currentTag || !context.previousTag) && keyCommit) { var match = /tag:\s*(.+?)[,\)]/gi.exec(keyCommit.gitTags); var currentTag = context.currentTag; context.currentTag = currentTag || match ? match[1] : null; var index = gitSemverTags.indexOf(context.currentTag); // if `keyCommit.gitTags` is not a semver if (index === -1) { context.currentTag = currentTag || null; } else { var previousTag = context.previousTag = gitSemverTags[index + 1]; if (!previousTag) { if (options.append) { context.previousTag = context.previousTag || firstCommitHash; } else { context.previousTag = context.previousTag || lastCommitHash; } } } } else { context.previousTag = context.previousTag || gitSemverTags[0]; if (context.version === 'Unreleased') { if (options.append) { context.currentTag = context.currentTag || lastCommitHash; } else { context.currentTag = context.currentTag || firstCommitHash; } } else { context.currentTag = context.currentTag || 'v' + context.version; } } if (!_.isBoolean(context.linkCompare) && context.previousTag && context.currentTag) { context.linkCompare = true; } return context; }, debug: options.debug }, config.writerOpts, { reverse: options.append, doFlush: options.outputUnreleased }, writerOpts ); return { options: options, context: context, gitRawCommitsOpts: gitRawCommitsOpts, parserOpts: parserOpts, writerOpts: writerOpts }; }); } module.exports = mergeConfig;