@cjbarth/github-release-notes
Version:
Create a release from a tag and uses issues or commits to creating the release notes. It also can generate a CHANGELOG.md file based on the release notes (or generate a brand new).
428 lines (407 loc) • 10.8 kB
JavaScript
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
var chalk = require("chalk");
var fs = require("fs");
var path = require("path");
var yoctoSpinner = require("@socketregistry/yocto-spinner");
var Path = require("path");
var requireFromUrl = require("require-from-url/sync");
var YAML = require("yaml");
var prettier = require("prettier");
/**
* Sort an object by its keys
*
* @since 0.8.0
* @public
*
* @param {Object} object
* @return {Object}
*/
function sortObject(object) {
return Object.keys(object).sort().reduce(function (result, key) {
result[key] = object[key];
return result;
}, {});
}
/**
* Print a task name in a custom format
*
* @since 0.5.0
* @public
*
* @param {string} name The name of the task
*/ // istanbul ignore next
function printTask(isQuiet, name) {
if (isQuiet) {
return;
}
process.stdout.write(chalk.blue("\n\uD83E\uDD16 - ".concat(name, ":\n===================================\n")));
}
/**
* Outputs the task status
*
* @since 0.5.0
* @public
*
* @param {string} taskName The task name
*
* @return {Function} The function to be fired when is loaded
*/ // istanbul ignore next
function task(gren, taskName) {
if (gren.options.quiet) {
gren.tasks[taskName] = {};
return noop;
}
var spinner = yoctoSpinner({
text: taskName
});
gren.tasks[taskName] = spinner;
spinner.start();
return function (message) {
spinner.success(message);
};
}
/**
* Clears all the tasks that are still running
*
* @since 0.6.0
* @public
*
* @param {GithubReleaseNotes} gren
*/ // istanbul ignore next
function clearTasks(gren) {
if (!Object.keys(gren.tasks.length)) {
return;
}
Object.keys(gren.tasks).forEach(function (taskName) {
gren.tasks[taskName].stop();
});
process.stdout.write(chalk.red("\nTask(s) stopped because of the following error:\n"));
gren.tasks = [];
}
/**
* Check if e value is between a min and a max
*
* @since 0.5.0
* @public
*
* @param {number} value
* @param {number} min
* @param {number} max
*
* @return {Boolean}
*/
function isInRange(value, min, max) {
return !Math.floor((value - min) / (max - min));
}
/**
* Transforms a dasherize string into a camel case one.
*
* @since 0.3.2
* @public
*
* @param {string} value The dasherize string
*
* @return {string} The camel case string
*/
function dashToCamelCase(value) {
return value.toLowerCase().replace(/-([a-z])/g, function (match) {
return match[1].toUpperCase();
});
}
/**
* Converts an array like string to an actual Array,
* converting also underscores to spaces
*
* @since 0.6.0
* @public
*
* @param {string} arrayLike The string of items
* e.g.
* "wont_fix, duplicate, bug"
*
* @return {Array} The items with spaces instead of underscores.
*/
function convertStringToArray(arrayLike) {
if (!arrayLike) {
return [];
}
if (_typeof(arrayLike) === "object") {
return Object.keys(arrayLike).map(function (itemKey) {
return arrayLike[itemKey];
});
}
return arrayLike.replace(/\s/g, "").split(",").map(function (itemName) {
return itemName.replace(/_/g, " ", itemName);
});
}
/**
* Format a date into a string
*
* @since 0.5.0
* @public
*
* @param {Date} date
* @return {string}
*/
function formatDate(date) {
return date.toISOString().split("T")[0];
}
/**
* Gets the content from a filepath a returns an object
*
* @since 0.6.0
* @public
*
* @param {string} filepath
* @return {Object|boolean}
*/
function requireConfig(filepath) {
if (!fs.existsSync(filepath)) {
return false;
}
process.stdout.write(chalk.cyan("Getting gren config from local file ".concat(filepath, "\n")));
var extension = getFileExtension(getFileNameFromPath(filepath));
var fileContent = fs.readFileSync(filepath, "utf8");
if (extension === "yml" || extension === "yaml") {
return YAML.parse(fileContent);
} else if (extension === "js" || extension === "cjs") {
return require(filepath);
}
try {
return JSON.parse(fileContent);
} catch (error) {
throw new Error("Unsupported or invalid format for file: ".concat(filepath));
}
}
/**
* Get configuration from the one of the config files
*
* @since 0.6.0
* @private
*
* @param {string} path Path where to look for config files
* @return {Object} The configuration from the first found file or empty object
*/
function getConfigFromFile(path) {
var customFilename = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
if (customFilename) {
var config = requireConfig(Path.join(path, customFilename));
if (!config) {
throw chalk.red("Could not find custom config file: ".concat(customFilename));
}
return config;
}
return getFileTypes().reduce(function (carry, filename) {
return carry || requireConfig(Path.join(path, filename));
}, false) || {};
}
/**
* Return the extension of a filename
*
* @param {string} filename
*
* @return {string}
*/
function getFileExtension(filename) {
return filename.slice((Math.max(0, filename.lastIndexOf(".")) || Infinity) + 1);
}
/**
* Create the content for a configuration file, based on extension and data
*
* @param {string} path
* @param {Object} data
*
* @return {string} File content
*/
function writeConfigToFile(path, data) {
var extension = getFileExtension(getFileNameFromPath(path));
var formatMap = {
yml: function yml(content) {
return YAML.stringify(content);
},
yaml: function yaml(content) {
return YAML.stringify(content);
},
json: function json(content) {
return prettier.format(JSON.stringify(content), {
parser: "json"
});
},
js: function js(content) {
return prettier.format("module.exports = ".concat(JSON.stringify(content)), {
parser: "babel"
});
},
none: function none(content) {
return prettier.format(JSON.stringify(content), {
parser: "json"
});
}
};
return formatMap[extension || "none"](data);
}
/**
* Get the filename from a path
*
* @since 0.10.0
* @private
*
* @param {string} path
*
* @return {string}
*/
function getFileNameFromPath() {
var path = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "";
return path.replace(/^.*[\\/]/, "");
}
/**
* Get the file types for the configuration
*
* @since 0.13.0
*
* @return {Array}
*/
function getFileTypes() {
return [".grenrc.yml", ".grenrc.json", ".grenrc.yaml", ".grenrc.js", ".grenrc"];
}
/**
* Remove all the configuration files
*
* @since 0.13.0
*
* @param {Boolean} confirm Necessary to force the function.
*/
function cleanConfig(confirm) {
var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : process.cwd();
if (confirm !== true) {
return;
}
getFileTypes().forEach(function (fileName) {
var file = "".concat(path, "/").concat(fileName);
if (!fs.existsSync(file)) {
return false;
}
fs.unlinkSync(file);
return file;
});
}
/**
* judge whether to get config from remote uri
* @since 0.18.0
* @private
*
* @param {string} path
*
* @returns {string}
*/
function getRemoteUrl(path) {
var pkgPath = Path.join(path, "package.json");
var pkgExist = fs.existsSync(pkgPath);
var _ref = pkgExist ? require(pkgPath) : {},
_ref$gren = _ref.gren,
gren = _ref$gren === void 0 ? "" : _ref$gren;
return gren;
}
/**
* get config from remote
* @since 0.18.0
* @private
*
* @param {string} path Path where to look for config files
* @return {Object} The configuration from the first found file or empty object
*/
function getConfigFromRemote(url) {
if (!url) return null;
process.stdout.write(chalk.cyan("Fetching gren config from remote: ".concat(url, "\n")));
var config = null;
try {
config = requireFromUrl(url);
} catch (error) {
// console.error(error);
process.stdout.write(chalk.cyan("Fetched remote config fail: ".concat(url, "\n")));
throw new Error(error);
}
process.stdout.write(chalk.cyan("Fetched remote config succeed"));
return config;
}
/**
* combine getConfigFromRemote & getGrenConfig
* @since 0.18.0
* @public
*
* @param {string} path Path where to look for config files
* @return {Object} The configuration from the first found file or empty object
*/
function getGrenConfig(path) {
var remoteUrl = getRemoteUrl(path);
var config;
if (remoteUrl) {
config = getConfigFromRemote(remoteUrl);
}
if (!config) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
config = getConfigFromFile.apply(void 0, [path].concat(args));
}
return config;
}
/**
* Look at the `package.json` and try to get the version of the current program
* If that fails, return the version of this package
*
* @returns {string} The version of the current package
*/
function findRelevantVersion() {
var startPath = __dirname;
var currentPath = startPath;
var lastVersion = null;
var passedNodeModules = false;
while (true) {
var dirName = path.basename(currentPath);
if (dirName === "node_modules") {
passedNodeModules = true;
} else {
var packageJsonPath = path.join(currentPath, "package.json");
if (fs.existsSync(packageJsonPath)) {
lastVersion = require(packageJsonPath).version;
if (passedNodeModules) {
break;
}
}
}
var newPath = path.resolve(currentPath, "..");
if (newPath === currentPath) {
break; // We're at the root and can't go any higher
}
currentPath = newPath;
}
return lastVersion;
}
/**
* Just a noop function
*/
function noop() {}
// Allow nodeunit to work. Has to be fixed.
module.exports = {
cleanConfig: cleanConfig,
clearTasks: clearTasks,
convertStringToArray: convertStringToArray,
dashToCamelCase: dashToCamelCase,
formatDate: formatDate,
getConfigFromFile: getConfigFromFile,
getRemoteUrl: getRemoteUrl,
getConfigFromRemote: getConfigFromRemote,
getGrenConfig: getGrenConfig,
getFileExtension: getFileExtension,
getFileNameFromPath: getFileNameFromPath,
getFileTypes: getFileTypes,
isInRange: isInRange,
noop: noop,
printTask: printTask,
requireConfig: requireConfig,
sortObject: sortObject,
task: task,
writeConfigToFile: writeConfigToFile,
findRelevantVersion: findRelevantVersion
};