base cli
This commit is contained in:
parent
c7ca3c9816
commit
0538691173
6
bin/run
Normal file
6
bin/run
Normal file
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
require('../build/src/index')
|
||||
.run()
|
||||
.then(require('@oclif/command/flush'))
|
||||
.catch(require('@oclif/errors/handle'));
|
19
package.json
19
package.json
|
@ -17,6 +17,21 @@
|
|||
"lint:prettier": "yarn prettier --check src",
|
||||
"lint:prettier:fix": "yarn prettier --check --write src"
|
||||
},
|
||||
"bin": {
|
||||
"copycat": "./bin/run"
|
||||
},
|
||||
"files": [
|
||||
"/bin",
|
||||
"/build/src",
|
||||
"/oclif.manifest.json"
|
||||
],
|
||||
"oclif": {
|
||||
"commands": "./src/cli",
|
||||
"bin": "copycat",
|
||||
"plugins": [
|
||||
"@oclif/plugin-help"
|
||||
]
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"pre-commit": "yarn lint:fix"
|
||||
|
@ -24,6 +39,9 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
"@oclif/command": "^1.8.0",
|
||||
"@oclif/config": "^1.17.0",
|
||||
"@oclif/plugin-help": "^3.2.1",
|
||||
"appdata-path": "^1.0.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"got": "^11.5.1",
|
||||
|
@ -35,6 +53,7 @@
|
|||
"@graphql-codegen/introspection": "1.17.6",
|
||||
"@graphql-codegen/typescript": "1.17.6",
|
||||
"@graphql-codegen/typescript-resolvers": "1.17.6",
|
||||
"@oclif/dev-cli": "^1.26.0",
|
||||
"@types/fs-extra": "^9.0.1",
|
||||
"@types/iarna__toml": "^2.0.0",
|
||||
"@types/js-yaml": "^3.12.5",
|
||||
|
|
39
src/cli/replicate.ts
Normal file
39
src/cli/replicate.ts
Normal file
|
@ -0,0 +1,39 @@
|
|||
import { Command, flags } from '@oclif/command';
|
||||
import assert from 'assert';
|
||||
import Copycat from '../copycat';
|
||||
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 }),
|
||||
};
|
||||
|
||||
static args = [];
|
||||
|
||||
async run() {
|
||||
const { flags } = this.parse(Replicate);
|
||||
|
||||
const sourcePath = parsePath(flags.source);
|
||||
const destPath = parsePath(flags.dest);
|
||||
|
||||
assert(sourcePath.entity === ENTITY_TYPE.ISSUE, 'Only issues are supported now');
|
||||
|
||||
const cc = new Copycat();
|
||||
await cc.initialize();
|
||||
const sourceVendor = cc.vendorManagers.find((v) => v.vendor.domain === sourcePath.domain);
|
||||
assert(sourceVendor, 'Source vendor not found in config');
|
||||
const destVendor = cc.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);
|
||||
const sourceEntity = await sourceRepo.getIssue(sourcePath.entityID);
|
||||
const replicatedEntity = await destRepo.replicateIssue(sourceEntity);
|
||||
console.log(replicatedEntity);
|
||||
}
|
||||
}
|
11
src/index.ts
Executable file
11
src/index.ts
Executable file
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env ts-node
|
||||
|
||||
import { run } from '@oclif/command';
|
||||
|
||||
if (process.argv[1] === __filename) {
|
||||
(run() as Promise<any>)
|
||||
.then(require('@oclif/command/flush'))
|
||||
.catch(require('@oclif/errors/handle'));
|
||||
}
|
||||
|
||||
export { run };
|
47
src/utils.ts
47
src/utils.ts
|
@ -9,7 +9,7 @@
|
|||
import { readFileSync, writeFileSync } from 'fs-extra';
|
||||
import toml from '@iarna/toml';
|
||||
import appdataPath from 'appdata-path';
|
||||
import { CopycatConfig, CopycatProfile } from './types';
|
||||
import { CopycatConfig, ENTITY_TYPE } from './types';
|
||||
|
||||
export const DEFAULT_CONFIG: CopycatConfig = {
|
||||
vendorConfigs: [],
|
||||
|
@ -33,3 +33,48 @@ export const setConfig = (config: CopycatConfig) =>
|
|||
writeFileSync(getConfigPath(), toml.stringify({ ...DEFAULT_CONFIG, ...config } as any), {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
||||
export type Path =
|
||||
| {
|
||||
domain: string;
|
||||
path: string;
|
||||
entity: ENTITY_TYPE;
|
||||
entityID: string;
|
||||
}
|
||||
| {
|
||||
domain: string;
|
||||
path: string;
|
||||
entity: null;
|
||||
entityID: null;
|
||||
};
|
||||
|
||||
export const parsePath = (path: string): Path => {
|
||||
let mobj = /^https?:\/\/([^/]+)\/([a-zA-Z\d-]+\/(?:[a-zA-Z\d-]+\/)*?[a-zA-Z\d-]+)(?:\/-)?(?:\/(issues|pulls?|merge_requests)(?:\/(\d+))?\/?)(?:\?[^#]+)?(?:#.+)?$/.exec(
|
||||
path,
|
||||
);
|
||||
if (mobj) {
|
||||
return {
|
||||
domain: mobj[1],
|
||||
path: mobj[2],
|
||||
entity: {
|
||||
issues: ENTITY_TYPE.ISSUE,
|
||||
merge_requests: ENTITY_TYPE.MERGE_REQUEST,
|
||||
pull: ENTITY_TYPE.MERGE_REQUEST,
|
||||
pulls: ENTITY_TYPE.MERGE_REQUEST,
|
||||
}[mobj[3] as 'issues' | 'merge_requests' | 'pull' | 'pulls'],
|
||||
entityID: mobj[4],
|
||||
};
|
||||
}
|
||||
mobj = /^https?:\/\/([^/]+)\/([a-zA-Z\d-]+\/(?:[a-zA-Z\d-]+\/)*?[a-zA-Z\d-]+)(?:\?[^#]+)?(?:#.+)?$/.exec(
|
||||
path,
|
||||
);
|
||||
if (mobj) {
|
||||
return {
|
||||
domain: mobj[1],
|
||||
path: mobj[2],
|
||||
entity: null,
|
||||
entityID: null,
|
||||
};
|
||||
}
|
||||
throw new Error('Path could not be parsed');
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue