@imqueue/cli
Version:
Command Line Interface for IMQ
205 lines • 6.74 kB
JavaScript
;
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.builder = exports.describe = exports.command = void 0;
const chalk_1 = require("chalk");
const lib_1 = require("../../lib");
const child_process_1 = require("child_process");
const path_1 = require("path");
const fs_1 = require("fs");
const console_1 = require("console");
const BASE_SERVICE_NAME = 'IMQService';
let PROGRAM = '';
let ROOT_DIRECTORY = process.cwd();
/**
* NOTE: Creating new console to avoid output from imported services
*/
const logger = new console_1.Console(process.stdout, process.stderr);
/**
* Checks if directory contains service
* @param {string} servicePath - path to directory, which contains service
* @returns {boolean} -
* returns true if directory contains service, or false instead
*/
function isFolderContainsService(servicePath) {
const originalLogger = console.log;
try {
console.log = () => { };
process.chdir(servicePath);
const service = require(servicePath);
for (const [prop, func] of Object.entries(service)) {
if (!prop.includes('Service')) {
continue;
}
// noinspection TypeScriptUnresolvedVariable
return func.__proto__.name === BASE_SERVICE_NAME;
}
process.chdir(ROOT_DIRECTORY);
}
catch (err) { /* ignore */ }
console.log = originalLogger;
return false;
}
/**
* Walks through array of folders paths and executes git flow
*
* @param {string[]} paths - array of paths to folders with services
* @param {Arguments} args - cli args
* @returns {void}
*/
function walkThroughFolders(paths, args) {
for (const path of paths) {
// noinspection TypeScriptValidateTypes
logger.log(chalk_1.default.blue('\nService:', path));
execGitFlow(path, args);
}
}
/**
* Changes current branch to passed
* @param {string} servicePath - path to directory, which contains service
* @param {string} branch
* @returns {SpawnSyncReturns<Buffer>}
*/
function gitCheckout(servicePath, branch) {
logger.log(`Switching on branch ${branch}...`);
return (0, child_process_1.spawnSync)('git', ['checkout', branch], {
cwd: servicePath,
stdio: 'pipe',
});
}
/**
* Pulls changes from repository
* @param {string} servicePath - path to directory, which contains service
* @returns {SpawnSyncReturns<Buffer>}
*/
function gitPull(servicePath) {
logger.log('Execution git pull...');
return (0, child_process_1.spawnSync)(`git`, ['pull'], {
cwd: servicePath,
stdio: 'pipe',
});
}
/**
* Changes version of package
* @param {string} servicePath - path to directory, which contains service
* @param {string} version - version which should be changed
* @returns {SpawnSyncReturns<Buffer>}
*/
function changeVersion(servicePath, version) {
logger.log(`Execute npm version ${version}`);
return (0, child_process_1.spawnSync)('npm', ['version', version], {
cwd: servicePath,
stdio: 'pipe',
});
}
/**
* Pushes changes to repository
* @param {string} servicePath - path to directory, which contains service
* @returns {SpawnSyncReturns<Buffer>}
*/
function gitPush(servicePath) {
logger.log('Execution git push...');
return (0, child_process_1.spawnSync)('git', ['push', '--follow-tags'], {
cwd: servicePath,
stdio: 'pipe',
});
}
/**
* Handles response from executed command
* @param {SpawnSyncReturns<Buffer>} response -
* response from executing command
* @returns {number | null}
*/
function handleSpawnResponse(response) {
if (response.status !== 0 || response.error && response.stderr) {
// noinspection TypeScriptValidateTypes
logger.log(chalk_1.default.red(response.stderr.toString()));
}
return response.status;
}
/**
* Executes git flow with next sequence
* 1. git checkout <branch>
* 2. git pull
* 3. npm version <version>
* 4. git push --follow-tags
* @param {string} servicePath - path to directory, which contains service
* @param {Arguments} args - cli args
* @returns {void}
*/
function execGitFlow(servicePath, args) {
let response;
response = gitCheckout(servicePath, args.branch);
if (handleSpawnResponse(response)) {
return;
}
response = gitPull(servicePath);
if (handleSpawnResponse(response)) {
return;
}
response = changeVersion(servicePath, args.npmVersion);
if (handleSpawnResponse(response)) {
return;
}
response = gitPush(servicePath);
if (handleSpawnResponse(response)) {
return;
}
// noinspection TypeScriptValidateTypes
logger.log(chalk_1.default.green('Done!'));
}
/**
* Walks through folders and check if each folder contains service
*
* @param {string} path - path to root folder with services
* @returns {string[]} - array of folders with services
*/
function getServicesFolders(path) {
const folders = [];
path = (0, path_1.resolve)(path);
// NOTE: Check if we call update-version from service folder
if (isFolderContainsService(path)) {
folders.push(path);
}
else {
for (const dir of (0, fs_1.readdirSync)(path)) {
const pathToService = (0, path_1.resolve)(path, dir);
const containsService = isFolderContainsService(pathToService);
if (containsService) {
folders.push(pathToService);
}
}
}
return folders;
}
// noinspection JSUnusedGlobalSymbols
_a = {
command: 'update-version <path> [branch] [version]',
describe: 'Updates services under given path with new version tag ' +
'and automatically pushes changes to repository, triggering builds.',
async builder(yargs) {
PROGRAM = (await yargs.argv).$0;
return yargs
.option('b', {
alias: 'branch',
default: 'master',
describe: 'The branch to checkout and use during update.',
})
.option('n', {
alias: 'npm-version',
default: 'prerelease',
describe: 'NPM version to update (major|minor|patch|prerelease).'
})
.describe('path', 'Path to directory containing services.');
},
handler(argv) {
try {
const folders = getServicesFolders(argv.path);
walkThroughFolders(folders, argv);
}
catch (err) {
(0, lib_1.printError)(err);
}
}
}, exports.command = _a.command, exports.describe = _a.describe, exports.builder = _a.builder, exports.handler = _a.handler;
//# sourceMappingURL=update-version.js.map