|
1 | 1 | import { Command } from "@commander-js/extra-typings";
|
2 | 2 |
|
3 |
| -import { SyncArguments, SyncOptions } from "./types/labels"; |
4 |
| -import { sync } from "./labels"; |
| 3 | +import LabelSync from "./labels"; |
| 4 | +import { Action, type SyncOptions, type Tokens } from "./types"; |
| 5 | +import logger, { setVerbose } from "./log"; |
| 6 | +import { promptMultiple } from "./io"; |
5 | 7 | import { name, description, version } from "../package.json";
|
6 | 8 |
|
7 |
| -new Command<SyncArguments, SyncOptions>() |
| 9 | +const validateTokens = (opts: SyncOptions): Tokens | null => { |
| 10 | + const token = opts.token || process.env.GITHUB_TOKEN; |
| 11 | + if (token) { |
| 12 | + return { destToken: token, originToken: token }; |
| 13 | + } |
| 14 | + |
| 15 | + const originToken = opts.tokenOrigin || process.env.GITHUB_TOKEN_ORIGIN; |
| 16 | + if (!originToken) { |
| 17 | + logger.error("No origin token specified and couldn't find any in environment"); |
| 18 | + return null; |
| 19 | + } |
| 20 | + |
| 21 | + const destToken = opts.tokenDestination || process.env.GITHUB_TOKEN_DESTINATION; |
| 22 | + if (!destToken) { |
| 23 | + logger.error("No destination token specified and couldn't find any in environment"); |
| 24 | + return null; |
| 25 | + } |
| 26 | + |
| 27 | + return { destToken, originToken }; |
| 28 | +}; |
| 29 | + |
| 30 | +new Command() |
8 | 31 | .name(name)
|
9 | 32 | .description(description)
|
10 | 33 | .version(version)
|
11 | 34 | .showHelpAfterError("(add --help for additional information)")
|
12 | 35 |
|
13 |
| - .argument("origin <string>", "Repository where the labels we want to keep are: (`{owner}/{repository}`)") |
14 |
| - .argument("target <string>", "Repository whose labels we're updating (`{owner}/{repository}`)") |
| 36 | + .argument("origin", "Repository that has the configs you want to sync: (`{owner}/{repository}`)") |
| 37 | + .argument("destination", "Repository where you want to update the configs: (`{owner}/{repository}`)") |
| 38 | + |
| 39 | + .option( |
| 40 | + "--token <token>", |
| 41 | + "Auth token to allow gh-sync to do it's thing. Use this if the token is the same for both origin and destination repositories", |
| 42 | + ) |
| 43 | + .option("--token-origin <token>", "Auth token of the origin repository, to allow gh-sync to do it's thing") |
| 44 | + .option( |
| 45 | + "--token-destination <token>", |
| 46 | + "Auth token of the destination repository,to allow gh-sync to do it's thing to allow gh-sync to do it's thing", |
| 47 | + ) |
| 48 | + .option("--verbose", `Runs ${name} in verbose mode`, false) |
| 49 | + |
| 50 | + .action(async function (origin, destination, options: SyncOptions) { |
| 51 | + if (options.verbose) { |
| 52 | + setVerbose(); |
| 53 | + } |
| 54 | + |
| 55 | + if (origin === destination) { |
| 56 | + logger.error("`origin` and `destination` can't be the same"); |
| 57 | + return; |
| 58 | + } |
| 59 | + |
| 60 | + const tokens = validateTokens(options); |
| 61 | + if (!tokens) { |
| 62 | + return; |
| 63 | + } |
| 64 | + |
| 65 | + const actions = await promptMultiple<string[]>("What do you want to sync ? (you can choose multiple)", [ |
| 66 | + // fine grained: |
| 67 | + // issues read / write; (get and add) |
| 68 | + // pull requests read / write; (delete labels) |
| 69 | + // metadata read (mandatory) |
| 70 | + { label: "Labels", value: Action.LABELS, hint: "Check documentation for necessary permissions" }, |
| 71 | + { label: "Workflows", value: Action.WORKFLOWS, hint: "Check documentation for necessary permissions" }, |
| 72 | + { label: "Branch rules", value: Action.BRANCH_RULES, hint: "Check documentation for necessary permissions" }, |
| 73 | + ]); |
| 74 | + |
| 75 | + let labelSync: LabelSync | null = null; |
| 76 | + |
| 77 | + if (actions.includes(Action.LABELS)) { |
| 78 | + labelSync = new LabelSync(origin, destination, tokens); |
| 79 | + labelSync.prepare(); |
| 80 | + } |
| 81 | + |
| 82 | + if (Action.WORKFLOWS in actions) { |
| 83 | + // stuff with workflows |
| 84 | + } |
| 85 | + |
| 86 | + if (Action.BRANCH_RULES in actions) { |
| 87 | + // stuff with branch rules |
| 88 | + } |
| 89 | + |
| 90 | + logger.box("Before we proceed, just double checking all the actions.."); |
| 91 | + |
| 92 | + // confirm things |
| 93 | + if (labelSync) { |
| 94 | + labelSync.confirmChoices(); |
| 95 | + } |
| 96 | + |
| 97 | + logger.info("Starting sync process..."); |
15 | 98 |
|
16 |
| - .option("-t, --token <string>", "GitHub token to be able to do stuff in GutHub") |
17 |
| - .option("--verbose", `Runs ${name} in verbose mode`) |
18 |
| - // .option("--clean", "Will delete any existing in the target repos before synchronizing origin's tags") |
| 99 | + // process things |
| 100 | + if (labelSync) { |
| 101 | + logger.info("Syncing labels..."); |
| 102 | + labelSync.sync(); |
| 103 | + logger.info("Finished syncing labels"); |
| 104 | + } |
19 | 105 |
|
20 |
| - // @ts-expect-error todo: fix typing |
21 |
| - .action(sync) |
| 106 | + logger.success("GitHub configurations sync'd"); |
| 107 | + }) |
22 | 108 |
|
23 | 109 | .parse();
|
0 commit comments