UNPKG

runas-plugin-scm-git

Version:

Runas plugin for SCM operations (Git implementation)

279 lines (232 loc) 6.94 kB
'use strict' const fs = require('fs') const path = require('path') const async = require('async') const _ = require('lodash') const gitCmd = 'git' const processDescriptor = (args, options) => { return { cmd: gitCmd, args: args || [], options: options || {} } } const _scmDescriptors = { add: (options) => { return processDescriptor(['add', '--all', options.file ? options.file : '.'], { cwd: options.folder || '.' }) }, clone: (options) => { const args = ['clone', options.repo].concat(options.args || []) return processDescriptor(args, { cwd: options.folder || '.' }) }, commit: (options) => { return processDescriptor(['commit', '-m', options.message || 'Initial commit', options.file ? options.file : '.'], { cwd: options.folder || '.' }) }, pull: (options) => { const args = [ 'pull' ] if (!options.simple) { args.push('--rebase') } return processDescriptor(args, { cwd: options.folder || '.' }) }, fetch: (options) => { return processDescriptor(['fetch', '-p'], { cwd: options.folder || '.' }) }, push: (options) => { return processDescriptor(['push', '-u', 'origin', options.branch || 'master'], { cwd: options.folder || '.' }) }, checkout: (options) => { const match = options.repo.match(/([^/]+)\.git$/) const repoName = match ? match[1] : null const repoFolder = path.join(options.folder, repoName) const exists = fs.existsSync(repoFolder) return exists ? _scmDescriptors.pull({ folder: repoFolder }) : _scmDescriptors.clone(options) }, init: (options) => { return processDescriptor([ 'init' ], { cwd: options.folder || '.' }) }, remoteAddOrigin: (options) => { return processDescriptor(['remote', 'add', 'origin', options.repo], { cwd: options.folder || '.' }) }, config: (options) => { const flags = options.global ? [ '--global' ] : [] const key = [ options.key ] const value = [ options.value ] const args = [ 'config' ].concat(flags).concat(key).concat(value) return processDescriptor(args, { cwd: options.folder || '.' }) } } const _scmDescriptor = (operation) => _scmDescriptors[operation] const _scmOperation = function(operation, options) { const pd = _scmDescriptor(operation)(options) return this.execute(pd.cmd, pd.args, pd.options) } /** * options { * repo: String, * folder: String * } */ const scmClone = function(options) { return this._scmOperation('clone', options) } /** * options { * folder: String * } */ const scmAdd = function(options) { return this._scmOperation('add', options) } /** * options { * message: String, * folder: String * } */ const scmCommit = function(options) { return this._scmOperation('commit', options) } /** * options { * folder: String * } */ const scmPull = function(options) { return this._scmOperation('pull', options) } const scmUpdate = scmPull /** * options { * branch: String, * folder: String * } */ const scmPush = function(options) { return this._scmOperation('push', options) } /** * options { * repo: String, * folder: String * } */ const scmCheckout = function(options) { return this._scmOperation('checkout', options) } /** * options { * folder: String * } */ const scmFetch = function(options) { options = options ? options : {} options.simple = true return this._scmOperation('fetch', options) .then(() => this.scmPull(options)) } const scmGetBranch = function() { if (!this.params.branch) { const res = this.sh(`${gitCmd} branch --all`) const lines = res.stdout.toString().split('\n') let branch = lines.map((line) => line.startsWith('*') ? line : null).filter((e) => e !== null).pop() this.params.branch = branch ? branch.replace('* ', '') : undefined } return this.params.branch } /** * options { * folder: String * } */ const scmInit = function(options) { return this._scmOperation('init', options) } /** * options { * repo: String * folder: String * } */ const scmRemoteAddOrigin = function(options) { return this._scmOperation('remoteAddOrigin', options) } /** * options { * flags: Array<String> * key: String * value: String * } */ const scmConfig = function(options) { return this._scmOperation('config', options) } const scmGetSymbolicFullName = function(branch) { const res = this.sh(`${gitCmd} rev-parse --symbolic-full-name ${branch}`) const _err = res.stderr.toString() return _err ? undefined : res.stdout.toString().trim() } const scmMassiveOperation = function(operation, repos) { const descriptors = repos.map(repo => _scmDescriptor(operation)(repo)) const jobs = _.get(this, 'params.scm.jobs', 10) return this.executeMassive(descriptors, jobs) } const _getError = function(repos, errors) { let fail = '' const process = (error) => { const cmd = error.cmd const args = error.args.join(' ') let options = '' _.keys(error.options).forEach(key => options += `[${key}]:${error.options[key]}`) fail += `${cmd} ${args} ${options}\n` if (error.error) { const lines = error.error.split('\n') lines.forEach(line => fail += (line + '\n')) } } errors.forEach(error => process(error)) const errMsg = `${errors.length} operations failed` this.logger.info('#green', `${repos.length - errors.length} operations OK`) this.logger.info('#red', errMsg) this.logger.info('#red', '\n' + fail) return { error: errMsg, output: fail } } module.exports = { config() { const repos = _.get(this, 'params.scm.repos', false) const operation = _.get(this, 'params.scm.operation', false) const ignoreErrors = _.get(this, 'params.scm.ignoreErrors', false) if (operation) { return repos.length > 1 ? this.scmMassiveOperation(operation, repos) .then(() => this.logger.info('#green', `${repos.length} operations OK`)) .catch(errors => { const _error = this._getError(repos, errors) return ignoreErrors ? Promise.resolve() : Promise.reject(_error) }) : this._scmOperation(operation, repos[0]) .then(() => this.logger.info('#green', 'operation OK')) .catch(error => { const _error = this._getError([ repos[0] ], [ error ]) return ignoreErrors ? Promise.resolve() : Promise.reject(_error) }) } }, addons: { gitCmd: gitCmd, _getError: _getError, _scmOperation: _scmOperation, scmClone: scmClone, scmUpdate: scmUpdate, scmCheckout: scmCheckout, scmPull: scmPull, scmFetch: scmFetch, scmGetBranch: scmGetBranch, scmGetSymbolicFullName: scmGetSymbolicFullName, scmAdd: scmAdd, scmCommit: scmCommit, scmPush: scmPush, scmInit: scmInit, scmConfig: scmConfig, scmRemoteAddOrigin: scmRemoteAddOrigin, scmMassiveOperation: scmMassiveOperation } }