UNPKG

cli-stash

Version:

CLI application to manage and work with Atlassian Stash. Work with your Stash project and repositories from Command lines.

373 lines (372 loc) 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BaseCommand = exports.BuildFlags = void 0; const core_1 = require("@oclif/core"); const fileSystem_1 = require("../fileSystem"); const config_1 = require("./config"); const ux_1 = require("./ux"); class BuildFlags { static async parseArray(str) { if (!str || str.length === 0) { return []; } const regex = new RegExp(`"(.*?)"|\'(.*?)\'|,`); return str.split(regex).filter((i) => !!i).map((i) => i.trim()); } static async parseKeyValue(str) { const obj = {}; const keyValueRegexp = new RegExp(`"(.*?)"|\'(.*?)\'|=`); const arrayValues = await BuildFlags.parseArray(str); for (const value of arrayValues) { const keyValuePair = value.split(keyValueRegexp).filter((i) => !!i).map((i) => i.trim()); obj[keyValuePair[0]] = keyValuePair[1]; } return obj; } } exports.BuildFlags = BuildFlags; BuildFlags.alias = core_1.Flags.string({ description: 'The Stash instance alias to identify user and instance to connect with', required: true, char: 'a', name: 'Alias' }); BuildFlags.csv = core_1.Flags.boolean({ description: 'Format output as CSV format', required: false, name: 'CSV', exclusive: ['json'] }); BuildFlags.extended = core_1.Flags.boolean({ char: 'x', description: 'Show extra columns when format output as table. (Format by default)', name: 'Extended' }); BuildFlags.filter = (description) => { return core_1.Flags.string({ description: description, required: false, name: 'Filter' }); }; BuildFlags.context = (description) => { return core_1.Flags.string({ description: description, required: false, name: 'Context' }); }; BuildFlags.input = { keyvalue: (doc, required, exclusive) => { const exclusives = ['file', 'data']; if (exclusive && exclusive.length) { exclusives.push(...exclusive); } return core_1.Flags.string({ description: 'Key-Value pair data. (key1=value1,key2=value2...). ' + (exclusives && exclusives.length ? ux_1.UX.cannotUseWith(exclusives) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, name: 'Keyvalue', char: 'k', exclusive: exclusives, parse: (input, context) => { return BuildFlags.parseKeyValue(input); } }); }, jsonData: (doc, required, exclusive) => { const exclusives = ['file', 'keyvalue']; if (exclusive && exclusive.length) { exclusives.push(...exclusive); } return core_1.Flags.string({ description: 'JSON Input data. ' + (exclusives && exclusives.length ? ux_1.UX.cannotUseWith(exclusives) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, name: 'Data', char: 'd', exclusive: exclusives, parse: (input, context) => { return eval('(' + input + ')'); } }); }, data: (doc, required, exclusive) => { const exclusives = ['file', 'keyvalue']; if (exclusive && exclusive.length) { exclusives.push(...exclusive); } return core_1.Flags.string({ description: 'Input data. ' + (exclusives && exclusives.length ? ux_1.UX.cannotUseWith(exclusives) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, name: 'Data', char: 'd', exclusive: exclusives, }); }, jsonFile: (doc, required, exclusive) => { const exclusives = ['data', 'keyvalue']; if (exclusive && exclusive.length) { exclusives.push(...exclusive); } return core_1.Flags.file({ description: 'JSON Input data file path. ' + (exclusives && exclusives.length ? ux_1.UX.cannotUseWith(exclusives) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, exclusive: exclusives, name: 'File', char: 'f' }); }, file: (doc, required, exclusive) => { const exclusives = ['data', 'keyvalue']; if (exclusive && exclusive.length) { exclusives.push(...exclusive); } return core_1.Flags.file({ description: 'Input data file path. ' + (exclusives && exclusives.length ? ux_1.UX.cannotUseWith(exclusives) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, exclusive: exclusives, name: 'File', char: 'f' }); }, }; BuildFlags.output = { file: (doc, required, exclusive) => { return core_1.Flags.file({ description: 'Output file path. ' + (exclusive && exclusive.length ? ux_1.UX.cannotUseWith(exclusive) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, exclusive: exclusive, name: 'Output File', }); }, folder: (doc, required, exclusive) => { return core_1.Flags.directory({ description: 'Output folder path. ' + (exclusive && exclusive.length ? ux_1.UX.cannotUseWith(exclusive) + '. ' : '') + ux_1.UX.processDocumentation(doc), required: required, exclusive: exclusive, name: 'Output Folder', }); }, }; BuildFlags.pagination = { all: core_1.Flags.boolean({ description: 'Return all records on the same page (instead paginate results)', required: false, name: 'All', exclusive: ['limit'], default: false, }), limit: core_1.Flags.integer({ description: 'Indicates how many results to return per page', required: false, name: 'Limit', char: 'l', exclusive: [], default: 25, }), start: core_1.Flags.integer({ description: 'Indicates which item should be used as the first item in the page of results', required: false, name: 'Start', char: 's', exclusive: [], default: 0, }), }; class BaseCommand extends core_1.Command { constructor() { super(...arguments); this.localConfig = new config_1.Config(this.config.dataDir); this.ux = new ux_1.UX(); } get statics() { return this.constructor; } get pageOptions() { if (!this.flags.all) { return { limit: this.flags.limit, start: this.flags.start }; } return undefined; } get allPageOptions() { if (this.flags.all) { return { limit: 100, start: this.flags.start }; } return undefined; } validateRequiredAndExclusives(flagsConfig) { for (const flagName of Object.keys(flagsConfig)) { if (flagName === 'csv' || flagName === 'json') continue; const flagConfig = flagsConfig[flagName]; if (!this.flags[flagName] && flagConfig.exclusive && flagConfig.exclusive.length) { let nExclusives = 0; let flags = ['--' + flagName]; for (const exclusive of flagConfig.exclusive) { if (this.flags[exclusive]) { nExclusives++; } else { flags.push('--' + exclusive); } } if (nExclusives === 0) { throw new Error('Missing Required flags. Must indicate at least one of the following: ' + flags.join(', ')); } } } } hasInputData() { return this.flags.data || this.flags.file || this.flags.keyvalue; } getJSONInputData() { return this.flags.data || (this.flags.file ? JSON.parse(fileSystem_1.FileReader.readFileSync(this.flags.file)) : undefined) || this.flags.keyvalue; } getInputData() { return this.flags.data || (this.flags.file ? fileSystem_1.FileReader.readFileSync(this.flags.file) : undefined); } parseArray(str) { const regex = new RegExp(`"(.*?)"|\'(.*?)\'|,`); return str .split(regex) .filter((i) => !!i) .map((i) => i.trim()); } getRecordsFoundText(recordSize, recordName) { if (recordSize > 0) { return recordSize + ' ' + recordName + ' records found'; } else { return 'Not ' + recordName + ' records found'; } } getRecordRetrievedText(recordName) { return recordName + ' retrieved successfully'; } getRecordCreatedText(recordName) { return recordName + ' created successfully'; } getRecordDeletedText(recordName) { return recordName + ' deleted successfully'; } getRecordUpdatedText(recordName) { return recordName + ' updated successfully'; } checkLogin() { if (this.flags.alias && this.localConfig.instances) { if (!this.localConfig.instances[this.flags.alias]) { throw new Error('Not found instance with alias ' + this.flags.alias + '. Check spelling name or login as new instance'); } } } log(message, level) { switch (this.flags.loglevel) { case 'error': if (level === 'error') { this.error(message); } break; case 'debug': if (level === 'debug') { this.ux.log(message); } break; case 'warn': if (level === 'warn') { this.warn(message); } break; case 'info': if (level === 'info') { this.warn(message); } break; } } /*public async _run<T>(): Promise<any> { // If a result is defined for the command, use that. Otherwise check for a // tableColumnData definition directly on the command. let err: any; try { await this.init(); return await this.run(); } catch (e) { err = e as Error; await this.catch(e); } finally { await this.finally(err); } }*/ async init() { // do some initialization this.localConfig.load(); super.init(); const { args, flags } = await this.parse(this.statics); this.flags = flags; this.args = args; this.ux = new ux_1.UX(this.flags); if (this.statics.loginRequired) { this.checkLogin(); } this.validateRequiredAndExclusives(this.statics.flags); } processError(response, error) { const err = error; if (err.name === 'StashError') { const stashError = error; response.status = -1; response.message = stashError.message || stashError.statusText; response.error = stashError; console.error(response.message); if (stashError.errors) { this.ux.table(stashError.errors, { id: { header: 'ID', }, name: { header: 'Name', }, address: { header: 'Address', get: (row) => { row.hostName + ':' + row.port; } }, local: { header: 'Local', }, }, { csv: this.flags.csv }); } } else { throw err; } } async catch(err) { if (err.code === 'EEXIT') { throw err; } if (err instanceof Error) { err.name = err.name === 'StashError' ? 'StashError' : err.name.replace(/Error$/, ''); } process.exitCode = process.exitCode || err.exitCode || 1; console.error('ERROR: ' + err.message); } async finally(err) { // called after run and catch regardless of whether or not the command errored return super.finally(err); } async run() { } } exports.BaseCommand = BaseCommand; BaseCommand.flags = { loglevel: core_1.Flags.string({ description: 'The logging level for this command execution', type: "option", options: ['error', 'warn', 'info', 'debug'], }), }; BaseCommand.loginRequired = true; BaseCommand.enableJsonFlag = true;