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": "yarn prettier --check src",
|
||||||
"lint:prettier:fix": "yarn prettier --check --write 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": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
"pre-commit": "yarn lint:fix"
|
"pre-commit": "yarn lint:fix"
|
||||||
|
@ -24,6 +39,9 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iarna/toml": "^2.2.5",
|
"@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",
|
"appdata-path": "^1.0.0",
|
||||||
"fs-extra": "^9.0.1",
|
"fs-extra": "^9.0.1",
|
||||||
"got": "^11.5.1",
|
"got": "^11.5.1",
|
||||||
|
@ -35,6 +53,7 @@
|
||||||
"@graphql-codegen/introspection": "1.17.6",
|
"@graphql-codegen/introspection": "1.17.6",
|
||||||
"@graphql-codegen/typescript": "1.17.6",
|
"@graphql-codegen/typescript": "1.17.6",
|
||||||
"@graphql-codegen/typescript-resolvers": "1.17.6",
|
"@graphql-codegen/typescript-resolvers": "1.17.6",
|
||||||
|
"@oclif/dev-cli": "^1.26.0",
|
||||||
"@types/fs-extra": "^9.0.1",
|
"@types/fs-extra": "^9.0.1",
|
||||||
"@types/iarna__toml": "^2.0.0",
|
"@types/iarna__toml": "^2.0.0",
|
||||||
"@types/js-yaml": "^3.12.5",
|
"@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 { readFileSync, writeFileSync } from 'fs-extra';
|
||||||
import toml from '@iarna/toml';
|
import toml from '@iarna/toml';
|
||||||
import appdataPath from 'appdata-path';
|
import appdataPath from 'appdata-path';
|
||||||
import { CopycatConfig, CopycatProfile } from './types';
|
import { CopycatConfig, ENTITY_TYPE } from './types';
|
||||||
|
|
||||||
export const DEFAULT_CONFIG: CopycatConfig = {
|
export const DEFAULT_CONFIG: CopycatConfig = {
|
||||||
vendorConfigs: [],
|
vendorConfigs: [],
|
||||||
|
@ -33,3 +33,48 @@ export const setConfig = (config: CopycatConfig) =>
|
||||||
writeFileSync(getConfigPath(), toml.stringify({ ...DEFAULT_CONFIG, ...config } as any), {
|
writeFileSync(getConfigPath(), toml.stringify({ ...DEFAULT_CONFIG, ...config } as any), {
|
||||||
encoding: 'utf-8',
|
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