UNPKG

@codefresh-io/cf-git-providers

Version:

An NPM module/CLI for interacting with various git providers

148 lines 6.13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.handler = exports.builder = exports.desc = exports.aliases = exports.command = void 0; const p_limit_1 = __importDefault(require("p-limit")); const fs_1 = require("fs"); const readline_1 = require("readline"); const helpers_1 = require("../../../helpers"); // tslint:disable-next-line: no-var-requires const logger = (0, helpers_1.createNewLogger)('codefresh:list:branches'); const MAX_REPOS_FETCHED_CONCURRENTLY = 4; exports.command = 'branches'; exports.aliases = ['br']; exports.desc = 'Get a list of branches from a git repository'; const builder = (yargs) => yargs .usage('Usage: $0 list branches [options]') .option('owner', { alias: 'o', describe: 'The name of the owner of the git repository', type: 'string' }) .option('repo', { alias: 'r', describe: 'The name of the git repository', type: 'string' }) .option('repos', { describe: 'Comma-separated list, or a file with full repository names', type: 'string', conflicts: ['repo', 'owner'] }) .option('full', { describe: 'Return branches in full format (and not just the name)', type: 'boolean', default: false, }) .middleware([async (argv) => { if (typeof argv.repos === 'string') { argv.repos = await _coerceListOfRepos(argv.repos); } }]) .check((argv) => { if (!(argv.owner && argv.repo) && !argv.repos) { (0, helpers_1.exitWithError)(`must provide either "repo" and "owner" options, or "repos" option`); } else if (argv.owner && !argv.repo) { (0, helpers_1.exitWithError)(`must provide "repo" option when using "owner" option`); } else if (!argv.owner && argv.repo) { (0, helpers_1.exitWithError)(`must provide "owner" option when using "repo" option`); } return true; }) .example(`$0 list ${exports.command} -o some-owner -r some-repo`, 'Will list all branches from repo: "some-owner/some-repo"') .example(`$0 list ${exports.command} -o some-owner -r some-repo -l 40`, 'Will list up to 40 branches from repo: "some-owner/some-repo"') .example(`$0 list ${exports.command} --repos owner1/some-repo1,owner2/some-repo2`, 'Will list all the branches of repo owner1/some-repo1 and all the branches of repo owner2/some-repo2') .example(`$0 list ${exports.command} --repos ./repos_file`, 'The file should contain a list or repository names, one repository per line') .example(`$0 list ${exports.command} --repos=-`, 'Will read the list of repos, line by line, from stdin'); exports.builder = builder; const handler = async (argv) => { const owner = argv.owner; const repo = argv.repo; const repos = (argv.repos || []); const provider = argv.provider; const output = argv.output; const full = argv.full; const limit = argv.limit; const page = argv.page; logger.debug(`owner=${owner}`); logger.debug(`repo=${repo}`); logger.debug(`repos=${repos.length} repos`); logger.debug(`output=${output}`); logger.debug(`limit=${limit}`); logger.debug(`page=${page}`); logger.debug(`full=${full}`); let result = ''; if (owner || repo) { const branches = await _getBranchesForRepo(provider, { owner, repo, limit, page }); result = JSON.stringify(full ? branches : branches.map((b) => b.name)); } else { const reposAndBranches = await _getBranchesForMultipleRepos(provider, { repos, limit, page, full }); result = JSON.stringify(reposAndBranches); } if (output) { await (0, helpers_1.writeResultsToFile)(output, result); } else { console.log(result); } }; exports.handler = handler; const _getBranchesForMultipleRepos = async (provider, args) => { const { repos, limit, page, full } = args; const progress = (0, helpers_1.createProgress)('repositories branches', repos.length); // control how many repos we're fetching the branches of concurrently const limiter = (0, p_limit_1.default)(MAX_REPOS_FETCHED_CONCURRENTLY); return repos.reduce(async (acc, curRepo) => { const { owner, repo } = curRepo; const branches = await limiter(async () => _getBranchesForRepo(provider, { limit, page, owner, repo })); logger.info(`${owner}/${repo} -> [${branches.length} branches]`); progress.tick(); const finalResult = await acc; finalResult[`${owner}/${repo}`] = full ? branches : branches.map(b => b.name); return finalResult; }, Promise.resolve({})); }; const _getBranchesForRepo = async (provider, args) => { const { owner, repo, limit, page } = args; const [listBranchesErr, branches] = await (0, helpers_1.to)(provider.listBranches({ owner, repo, limit, page })); if (listBranchesErr) { (0, helpers_1.exitWithError)(`failed to get the list of branches from ${owner}/${repo}, ${listBranchesErr}`); } return branches; }; const _coerceListOfRepos = async (reposArg) => { if (reposArg === '-') { // need to read list from stdin return _getListFromStream(process.stdin); } else if ((0, fs_1.existsSync)(reposArg)) { return _getListFromStream((0, fs_1.createReadStream)(reposArg)); } return _getListFromString(reposArg); }; const _getListFromString = (reposArg) => { const fullRepoNames = reposArg.split(','); return fullRepoNames.map(fullRepoName => { const [owner, repo] = fullRepoName.split('/'); return { owner, repo }; }); }; const _getListFromStream = async (stream) => { const lineReader = (0, readline_1.createInterface)({ input: stream, crlfDelay: Number.POSITIVE_INFINITY, }); const repos = []; for await (const line of lineReader) { repos.push(line); } return repos.map(fullRepoName => { const [owner, repo] = fullRepoName.split('/'); return { owner, repo }; }); }; //# sourceMappingURL=branches.cmd.js.map