import { Command, flags } from '@oclif/command'; import assert from 'assert'; import Copykitku from '../copykitku'; import { ENTITY_TYPE } from '../types'; import { parsePath } from '../utils'; export default class Replicate extends Command { static description = 'Replicate issues/MRs between repositories'; static flags = { help: flags.help({ char: 'h' }), source: flags.string({ char: 's', required: true }), dest: flags.string({ char: 'd', required: true }), destBranch: flags.string({ description: 'name of the new branch (optional for MRs, required for commits)', }), doNotCommit: flags.boolean({ description: 'do not commit the applied changes (for MRs)', allowNo: false, }), remote: flags.string({ description: 'git remote where the commits are pushed (for MRs)', default: 'origin', }), targetBranch: flags.string({ description: 'branch to which the MR should target', default: 'master', // TODO: check in the repository instead of taking a wild guess }), }; static args = []; async run() { const { flags } = this.parse(Replicate); const { destBranch, doNotCommit, remote, targetBranch } = flags; const sourcePath = parsePath(flags.source); const destPath = parsePath(flags.dest); assert(sourcePath.entityID, 'Source must be a repo element, not a repo itself'); const kitku = new Copykitku(); await kitku.initialize(); const sourceVendor = kitku.vendorManagers.find((v) => v.vendor.domain === sourcePath.domain); assert(sourceVendor, 'Source vendor not found in config'); const destVendor = kitku.vendorManagers.find((v) => v.vendor.domain === destPath.domain); assert(destVendor, 'Destination vendor not found in config'); const sourceRepo = await sourceVendor.getRepo(sourcePath.path); const destRepo = await destVendor.getRepo(destPath.path); switch (sourcePath.entity) { case ENTITY_TYPE.ISSUE: { const sourceIssue = await sourceRepo.getIssue(sourcePath.entityID); const repl = await kitku.replicateIssue(sourceIssue, destRepo); console.log(`Replicated successfully: ${repl.url}`); break; } case ENTITY_TYPE.MERGE_REQUEST: { const sourceMR = await sourceRepo.getMergeRequest(sourcePath.entityID); const repl = await kitku.replicateMergeRequest(sourceMR, destRepo, { destBranch, doNotCommit, remote, targetBranch, }); if (repl === true) { // patches got applied to the branch, without pushing and creating a MR (due to --doNotCommit) console.log('Replicated commits successfully'); } else { // commits got pushed and a MR was created console.log(`Replicated successfully: ${repl.url}`); } break; } case ENTITY_TYPE.COMMIT: { // there's no way to get a single commit from repository yet /* const sourceCommit = await sourceRepo.getCommit(sourcePath.entityID); const repl = await kitku.replicateCommits(sourceCommit, destRepo, { destBranch, doNotCommit, }); */ console.log('No commit replication yet, sorry'); break; } default: { throw new Error('Unknown entity type'); } } } }