@codefresh-io/cf-git-providers
Version:
An NPM module/CLI for interacting with various git providers
148 lines • 6.13 kB
JavaScript
;
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