From 2417392d2342864d63e450486d041fcb58f11f1a Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Sat, 21 Dec 2019 13:37:12 -0600 Subject: [PATCH 1/8] bump version. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1f7daf2..235ddee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "labman", - "version": "0.3.0", + "version": "0.4.0", "description": "👨🏼‍🔬 github label manager cli", "keywords": [ "github", From 5bf094c3e62cbb6914ded7d3935232d502d915f8 Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Sun, 22 Dec 2019 21:56:18 -0600 Subject: [PATCH 2/8] add optional labels argument. closes #17. --- src/cli.js | 2 +- src/clone.js | 9 +++++++-- src/handlers.js | 4 ++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/cli.js b/src/cli.js index 299e1cd..dc52c6c 100755 --- a/src/cli.js +++ b/src/cli.js @@ -21,7 +21,7 @@ yargs ) .command("logout", "Remove GitHub credentials.", {}, logoutHandler) .command( - "clone ", + "clone [labels...]", "Clone issue labels from one repo to another.", {}, cloneHandler, diff --git a/src/clone.js b/src/clone.js index b3ca820..b864425 100644 --- a/src/clone.js +++ b/src/clone.js @@ -1,6 +1,6 @@ const {getLabels, deleteLabels, createLabels} = require("./github") -const clone = async (source, destination) => { +const clone = async (source, destination, labels = []) => { const [sourceOwner, sourceRepo] = source.split("/") const [destinationOwner, destinationRepo] = destination.split("/") @@ -9,7 +9,12 @@ const clone = async (source, destination) => { await deleteLabels(oldLabels, destinationOwner, destinationRepo) // create new labels - const newLabels = await getLabels(sourceOwner, sourceRepo) + const sourceLabels = await getLabels(sourceOwner, sourceRepo) + + const newLabels = labels.length + ? sourceLabels.filter(label => labels.includes(label.name)) + : sourceLabels + await createLabels(newLabels, destinationOwner, destinationRepo) } diff --git a/src/handlers.js b/src/handlers.js index 9a0dec0..6ec21a7 100644 --- a/src/handlers.js +++ b/src/handlers.js @@ -33,7 +33,7 @@ const logoutHandler = () => { } const cloneHandler = async argv => { - const {source, destination} = argv + const {source, destination, labels} = argv const token = config.get("token") if (!token) { @@ -50,7 +50,7 @@ const cloneHandler = async argv => { createOctokit(token) try { - await clone(source, destination) + await clone(source, destination, labels) } catch (error) { console.log( `\n${chalk.redBright( From f8fc7420ebb1af65f1db8e24f872f550baf25219 Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Sun, 22 Dec 2019 22:39:51 -0600 Subject: [PATCH 3/8] add purge flag. closes #20. --- src/cli.js | 9 ++++++++- src/clone.js | 8 +++++--- src/handlers.js | 4 ++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/cli.js b/src/cli.js index dc52c6c..35d0fb0 100755 --- a/src/cli.js +++ b/src/cli.js @@ -23,7 +23,14 @@ yargs .command( "clone [labels...]", "Clone issue labels from one repo to another.", - {}, + { + purge: { + alias: "p", + type: "boolean", + default: false, + description: "Purge destination labels", + }, + }, cloneHandler, ) .help() diff --git a/src/clone.js b/src/clone.js index b864425..e7007db 100644 --- a/src/clone.js +++ b/src/clone.js @@ -1,12 +1,14 @@ const {getLabels, deleteLabels, createLabels} = require("./github") -const clone = async (source, destination, labels = []) => { +const clone = async (source, destination, labels = [], purge = false) => { const [sourceOwner, sourceRepo] = source.split("/") const [destinationOwner, destinationRepo] = destination.split("/") // delete existing labels - const oldLabels = await getLabels(destinationOwner, destinationRepo) - await deleteLabels(oldLabels, destinationOwner, destinationRepo) + if (purge) { + const oldLabels = await getLabels(destinationOwner, destinationRepo) + await deleteLabels(oldLabels, destinationOwner, destinationRepo) + } // create new labels const sourceLabels = await getLabels(sourceOwner, sourceRepo) diff --git a/src/handlers.js b/src/handlers.js index 6ec21a7..d81584a 100644 --- a/src/handlers.js +++ b/src/handlers.js @@ -33,7 +33,7 @@ const logoutHandler = () => { } const cloneHandler = async argv => { - const {source, destination, labels} = argv + const {source, destination, labels, purge} = argv const token = config.get("token") if (!token) { @@ -50,7 +50,7 @@ const cloneHandler = async argv => { createOctokit(token) try { - await clone(source, destination, labels) + await clone(source, destination, labels, purge) } catch (error) { console.log( `\n${chalk.redBright( From f6945dfbbbb2af1d3566472e9197270fd26782a1 Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Mon, 23 Dec 2019 20:29:35 -0600 Subject: [PATCH 4/8] rename purge to clobber. --- package-lock.json | 2 +- src/cli.js | 6 +++--- src/clone.js | 4 ++-- src/handlers.js | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 317c348..f8fef66 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "labman", - "version": "0.2.0", + "version": "0.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/cli.js b/src/cli.js index 35d0fb0..5c5d3a9 100755 --- a/src/cli.js +++ b/src/cli.js @@ -24,11 +24,11 @@ yargs "clone [labels...]", "Clone issue labels from one repo to another.", { - purge: { - alias: "p", + clobber: { + alias: "c", type: "boolean", default: false, - description: "Purge destination labels", + description: "Clobber destination labels", }, }, cloneHandler, diff --git a/src/clone.js b/src/clone.js index e7007db..d46e00e 100644 --- a/src/clone.js +++ b/src/clone.js @@ -1,11 +1,11 @@ const {getLabels, deleteLabels, createLabels} = require("./github") -const clone = async (source, destination, labels = [], purge = false) => { +const clone = async (source, destination, labels = [], clobber = false) => { const [sourceOwner, sourceRepo] = source.split("/") const [destinationOwner, destinationRepo] = destination.split("/") // delete existing labels - if (purge) { + if (clobber) { const oldLabels = await getLabels(destinationOwner, destinationRepo) await deleteLabels(oldLabels, destinationOwner, destinationRepo) } diff --git a/src/handlers.js b/src/handlers.js index d81584a..6d0b0c8 100644 --- a/src/handlers.js +++ b/src/handlers.js @@ -33,7 +33,7 @@ const logoutHandler = () => { } const cloneHandler = async argv => { - const {source, destination, labels, purge} = argv + const {source, destination, labels, clobber} = argv const token = config.get("token") if (!token) { @@ -50,7 +50,7 @@ const cloneHandler = async argv => { createOctokit(token) try { - await clone(source, destination, labels, purge) + await clone(source, destination, labels, clobber) } catch (error) { console.log( `\n${chalk.redBright( From 119e5443c5eb41294e25a3133ac8a769ccb699df Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Mon, 23 Dec 2019 20:51:47 -0600 Subject: [PATCH 5/8] make copy command the default. closes #22. --- readme.md | 6 +++--- src/cli.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/readme.md b/readme.md index 313c400..fbb956c 100644 --- a/readme.md +++ b/readme.md @@ -20,7 +20,7 @@ If you have `labman` installed globally you can run it as shown below. ``` labman login -labman clone +labman ``` Where `token` is your GitHub [personal access token][token]. @@ -30,14 +30,14 @@ Here is an example. ``` labman login bradgarropy 1234abcd -labman clone bradgarropy/label-source bradgarropy/label-destination +labman bradgarropy/label-source bradgarropy/label-destination ``` Alternatively, you can run it with [`npx`][npx]. ``` npx labman login -npx labman clone +npx labman ``` ## ❔ Questions diff --git a/src/cli.js b/src/cli.js index 5c5d3a9..e4fdc6e 100755 --- a/src/cli.js +++ b/src/cli.js @@ -21,8 +21,8 @@ yargs ) .command("logout", "Remove GitHub credentials.", {}, logoutHandler) .command( - "clone [labels...]", - "Clone issue labels from one repo to another.", + "* [labels...]", + "Copy issue labels from one repo to another.", { clobber: { alias: "c", From 97cbe4856f4cbb0371c5e390d20530fec9b907c9 Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Mon, 23 Dec 2019 21:13:04 -0600 Subject: [PATCH 6/8] organize cli commands. closes #23. --- package.json | 4 +-- src/cli.js | 38 ----------------------- src/cli/default.js | 54 +++++++++++++++++++++++++++++++++ src/cli/index.js | 13 ++++++++ src/cli/login.js | 46 ++++++++++++++++++++++++++++ src/cli/logout.js | 15 +++++++++ src/{clone.js => copy.js} | 0 src/handlers.js | 64 --------------------------------------- 8 files changed, 130 insertions(+), 104 deletions(-) delete mode 100755 src/cli.js create mode 100644 src/cli/default.js create mode 100644 src/cli/index.js create mode 100644 src/cli/login.js create mode 100644 src/cli/logout.js rename src/{clone.js => copy.js} (100%) delete mode 100644 src/handlers.js diff --git a/package.json b/package.json index 235ddee..5110e30 100644 --- a/package.json +++ b/package.json @@ -22,14 +22,14 @@ "url": "https://bradgarropy.com" }, "bin": { - "labman": "src/cli.js" + "labman": "src/cli/index.js" }, "repository": { "type": "git", "url": "https://github.com/bradgarropy/labman-cli" }, "scripts": { - "start": "node src/cli.js" + "start": "node src/cli/index.js" }, "dependencies": { "@octokit/rest": "^16.35.2", diff --git a/src/cli.js b/src/cli.js deleted file mode 100755 index e4fdc6e..0000000 --- a/src/cli.js +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env node - -const yargs = require("yargs") -const {name} = require("../package.json") -const {loginHandler, logoutHandler, cloneHandler} = require("./handlers") - -yargs - .scriptName(name) - .command( - "login ", - "Persist GitHub credentials.", - { - force: { - alias: "f", - type: "boolean", - default: false, - description: "Force login", - }, - }, - loginHandler, - ) - .command("logout", "Remove GitHub credentials.", {}, logoutHandler) - .command( - "* [labels...]", - "Copy issue labels from one repo to another.", - { - clobber: { - alias: "c", - type: "boolean", - default: false, - description: "Clobber destination labels", - }, - }, - cloneHandler, - ) - .help() - .alias("help", "h") - .alias("version", "v").argv diff --git a/src/cli/default.js b/src/cli/default.js new file mode 100644 index 0000000..0b2781f --- /dev/null +++ b/src/cli/default.js @@ -0,0 +1,54 @@ +const conf = require("conf") +const chalk = require("chalk") +const copy = require("../copy") +const {createOctokit} = require("../octokit") + +const config = new conf() + +const command = "* [labels...]" +const description = "Copy issue labels from one repo to another" + +const builder = { + clobber: { + alias: "c", + type: "boolean", + default: false, + description: "Clobber destination labels", + }, +} + +const handler = async argv => { + const {source, destination, labels, clobber} = argv + const token = config.get("token") + + if (!token) { + console.log( + `\nYou are not logged in, please run the ${chalk.cyanBright( + "login", + )} command.\n`, + ) + + console.log(chalk.cyanBright("labman login \n")) + return + } + + createOctokit(token) + + try { + await copy(source, destination, labels, clobber) + } catch (error) { + console.log( + `\n${chalk.redBright( + "Invalid token!", + )} Please run the ${chalk.cyanBright("login")} command again.\n`, + ) + console.log(chalk.cyanBright("labman login \n")) + } +} + +module.exports = { + command, + description, + builder, + handler, +} diff --git a/src/cli/index.js b/src/cli/index.js new file mode 100644 index 0000000..d16dc66 --- /dev/null +++ b/src/cli/index.js @@ -0,0 +1,13 @@ +#!/usr/bin/env node + +const yargs = require("yargs") +const {name} = require("../../package.json") + +yargs + .scriptName(name) + .command(require("./login")) + .command(require("./logout")) + .command(require("./default")) + .help() + .alias("help", "h") + .alias("version", "v").argv diff --git a/src/cli/login.js b/src/cli/login.js new file mode 100644 index 0000000..14be94b --- /dev/null +++ b/src/cli/login.js @@ -0,0 +1,46 @@ +const conf = require("conf") +const chalk = require("chalk") +const {validToken} = require("../github") + +const config = new conf() + +const command = "login " +const description = "Persist GitHub credentials" + +const builder = { + force: { + alias: "f", + type: "boolean", + default: false, + description: "Force login", + }, +} + +const handler = async argv => { + const {username, token, force} = argv + const storedToken = config.get("token") + + if (!force && storedToken) { + console.log("\nYou are already logged in!\n") + return + } + + const valid = await validToken(token) + + if (!valid) { + console.log(`\n${chalk.redBright("Login failed!")} Please try again.\n`) + return + } + + config.set({username, token}) + console.log(chalk.greenBright("\nLogin successful!\n")) + + return +} + +module.exports = { + command, + description, + builder, + handler, +} diff --git a/src/cli/logout.js b/src/cli/logout.js new file mode 100644 index 0000000..09f0154 --- /dev/null +++ b/src/cli/logout.js @@ -0,0 +1,15 @@ +const conf = require("conf") + +const config = new conf() + +const command = "logout" +const description = "Remove GitHub credentials" +const builder = {} +const handler = () => config.clear() + +module.exports = { + command, + description, + builder, + handler, +} diff --git a/src/clone.js b/src/copy.js similarity index 100% rename from src/clone.js rename to src/copy.js diff --git a/src/handlers.js b/src/handlers.js deleted file mode 100644 index 6d0b0c8..0000000 --- a/src/handlers.js +++ /dev/null @@ -1,64 +0,0 @@ -const conf = require("conf") -const chalk = require("chalk") -const clone = require("./clone") -const {validToken} = require("./github") -const {createOctokit} = require("./octokit") - -const config = new conf() - -const loginHandler = async argv => { - const {username, token, force} = argv - const storedToken = config.get("token") - - if (!force && storedToken) { - console.log("\nYou are already logged in!\n") - return - } - - const valid = await validToken(token) - - if (!valid) { - console.log(`\n${chalk.redBright("Login failed!")} Please try again.\n`) - return - } - - config.set({username, token}) - console.log(chalk.greenBright("\nLogin successful!\n")) - - return -} - -const logoutHandler = () => { - config.clear() -} - -const cloneHandler = async argv => { - const {source, destination, labels, clobber} = argv - const token = config.get("token") - - if (!token) { - console.log( - `\nYou are not logged in, please run the ${chalk.cyanBright( - "login", - )} command.\n`, - ) - - console.log(chalk.cyanBright("labman login \n")) - return - } - - createOctokit(token) - - try { - await clone(source, destination, labels, clobber) - } catch (error) { - console.log( - `\n${chalk.redBright( - "Invalid token!", - )} Please run the ${chalk.cyanBright("login")} command again.\n`, - ) - console.log(chalk.cyanBright("labman login \n")) - } -} - -module.exports = {loginHandler, logoutHandler, cloneHandler} From 2b4677e92941b41505a98721cc3a1e477c51ba12 Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Mon, 23 Dec 2019 21:20:20 -0600 Subject: [PATCH 7/8] rename clone to copy. --- src/copy.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/copy.js b/src/copy.js index d46e00e..4825ee7 100644 --- a/src/copy.js +++ b/src/copy.js @@ -1,6 +1,6 @@ const {getLabels, deleteLabels, createLabels} = require("./github") -const clone = async (source, destination, labels = [], clobber = false) => { +const copy = async (source, destination, labels = [], clobber = false) => { const [sourceOwner, sourceRepo] = source.split("/") const [destinationOwner, destinationRepo] = destination.split("/") @@ -20,4 +20,4 @@ const clone = async (source, destination, labels = [], clobber = false) => { await createLabels(newLabels, destinationOwner, destinationRepo) } -module.exports = clone +module.exports = copy From ae0b131eeed435de4b4fd8a7a12113c99c4e338d Mon Sep 17 00:00:00 2001 From: Brad Garropy Date: Mon, 23 Dec 2019 21:23:15 -0600 Subject: [PATCH 8/8] update readme. --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index fbb956c..db535fa 100644 --- a/readme.md +++ b/readme.md @@ -23,7 +23,7 @@ labman login labman ``` -Where `token` is your GitHub [personal access token][token]. +Where `token` is a GitHub [personal access token][token] with `repo` scope. Where `source` and `destination` are GitHub repositories in the form of `owner/repo`. Here is an example.