128 lines
4.2 KiB
TypeScript
128 lines
4.2 KiB
TypeScript
import { Command, flags } from '@oclif/command';
|
|
import assert from 'assert';
|
|
import Copykitku from '../copykitku';
|
|
import { ENTITY_TYPE } from '../types';
|
|
import { getProjectConfig, parsePath } from '../utils';
|
|
|
|
export default class Replicate extends Command {
|
|
static description = 'Replicate issues/MRs between repositories';
|
|
|
|
static flags = {
|
|
help: flags.help({ char: 'h' }),
|
|
|
|
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
|
|
}),
|
|
patchHook: flags.string({
|
|
description: 'node.js file to patch the patches',
|
|
}),
|
|
};
|
|
|
|
static args = [
|
|
{
|
|
name: 'source',
|
|
required: true,
|
|
description: 'the thing you want to replicate',
|
|
},
|
|
{
|
|
name: 'dest',
|
|
required: false,
|
|
description:
|
|
'where you want the thing to be replicated [required in either cli arg or .copykitkurc.toml file]',
|
|
},
|
|
];
|
|
|
|
async run() {
|
|
const { flags, args } = this.parse(Replicate);
|
|
|
|
const proj = getProjectConfig();
|
|
|
|
const { destBranch, doNotCommit, remote, targetBranch, patchHook } = { ...proj, ...flags };
|
|
|
|
const { source, dest } = {
|
|
...proj,
|
|
|
|
// oclif does set undefined values for non-existant args
|
|
// so we have to filter out these values, or they will replace project config values
|
|
...(Object.keys(args)
|
|
.filter((ak) => args[ak])
|
|
.reduce((acc, curk) => {
|
|
acc[curk] = args[curk];
|
|
return acc;
|
|
}, {} as { [k: string]: string }) as {
|
|
source: string;
|
|
dest?: string;
|
|
}),
|
|
};
|
|
|
|
assert(typeof dest === 'string', 'Destination repository must be defined');
|
|
|
|
const sourcePath = parsePath(source);
|
|
const destPath = parsePath(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,
|
|
patchHook,
|
|
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');
|
|
}
|
|
}
|
|
}
|
|
}
|