Skip to content

Commit 1cf29b1

Browse files
authored
v3 (#35)
BREAKING CHANGE: `octoherd` can no longer be run without a command. Use `octoherd run` instead BREAKING CHANGE: the script and repos arguments are now flags. Instead of ``` octoherd --octoherd-token $TOKEN script.js octoherd/octoherd ``` do ``` octoherd run --octoherd-token $TOKEN --octoherd-script script.js --octoherd-repos octoherd/octoherd ``` or use the shortcut aliases ``` octoherd run -T $TOKEN -S script.js -R octoherd/octoherd ```
1 parent 8ceb78e commit 1cf29b1

14 files changed

+4364
-1215
lines changed

.github/update-endpoints.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Update Prettier
2+
on:
3+
repository_dispatch:
4+
types: [octokit/openapi]
5+
workflow_dispatch: {}
6+
jobs:
7+
update_prettier:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v2
11+
- uses: actions/setup-node@v2
12+
with:
13+
version: 12
14+
- uses: actions/cache@v2
15+
with:
16+
path: ~/.npm
17+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
18+
restore-keys: |
19+
${{ runner.os }}-node-
20+
- run: npm ci
21+
- run: npm install @octokit/openapi@latest
22+
- run: node scripts/generate-endpoints.js
23+
- uses: gr2m/create-or-update-pull-request-action@v1.x
24+
env:
25+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
26+
with:
27+
title: "Enpoints updated"
28+
body: "An update to `@octokit/openapi` resulted in an update to `lib/generated/endpoints.js`"
29+
branch: ${{ github.ref }}
30+
commit-message: "build: endpoints updated"

README.md

+25-18
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,33 @@
55
## Usage
66

77
```
8-
$ octoherd.js [script] [repos...]
9-
10-
Positionals:
11-
script Path to *.js script. Must be an ES Module.
12-
repos One or multiple arrays in the form of 'repo-owner/repo-name'.
13-
'repo-owner/*' will find all repositories for one owner. '*' will find
14-
all repositories the user has access to [default: []]
8+
Usage: octoherd run -S path/to/script.js [options]
159
1610
Options:
17-
--help Show help [boolean]
18-
--version Show version number [boolean]
19-
--octoherd-token Requires the "public_repo" scope for public
20-
repositories, "repo" scope for private
21-
repositories. [string] [required]
22-
--octoherd-cache Cache responses for debugging. Creates a ./cache
23-
folder if flag is set. Override by passing custom
24-
path [string]
25-
--octoherd-debug Show debug logs [boolean] [default: false]
26-
--octoherd-bypass-confirms Bypass prompts to confirm mutating requests
27-
[boolean] [default: false]
11+
--help Show help [boolean]
12+
-S, --octoherd-script Path to *.js script. Must be an ES Module. [string] [required]
13+
-T, --octoherd-token Requires the "public_repo" scope for public repositories, "rep
14+
o" scope for private repositories. Creates an OAuth token if n
15+
ot set. [string]
16+
-R, --octoherd-repos One or multiple repositories in the form of 'repo-owner/repo-n
17+
ame'. 'repo-owner/*' will find all repositories for one owner.
18+
'*' will find all repositories the user has access to. Will p
19+
rompt for repositories if not set. [array]
20+
--octoherd-cache Cache responses for debugging. Creates a ./cache folder if fla
21+
g is set. Override by passing custom path [string]
22+
--octoherd-debug Show debug logs [boolean] [default: false]
23+
--octoherd-bypass-confirms Bypass prompts to confirm mutating requests
24+
[boolean] [default: false]
25+
--version Show version number [boolean]
26+
27+
Examples:
28+
octoherd run -S path/to/script.js Minimal usage example
29+
octoherd run -S path/to/script.js -T $TOKEN -R Pass token and repos as CLI flags
30+
octoherd/cli
31+
octoherd run -S path/to/script.js -T $TOKEN -R Avoid prompts for token and repos
32+
octoherd/cli
33+
octoherd run -S path/to/script.js -T $TOKEN -R Avoid any prompts
34+
octoherd/cli --octoherd-bypass-confirms
2835
```
2936

3037
The `script` must export a `script` function which takes three parameters:

bin/cli-options.js

-23
This file was deleted.

bin/commands/run.js

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { resolve } from "path";
2+
3+
import chalk from "chalk";
4+
import { VERSION as OctokitVersion } from "@octoherd/octokit";
5+
6+
import { VERSION } from "../../version.js";
7+
8+
const VERSIONS = `
9+
@octoherd/cli: v${VERSION}
10+
@octoherd/octokit: v${OctokitVersion}
11+
Node.js: ${process.version}, ${process.platform} ${process.arch}`.trim();
12+
13+
/** @type { {[key: string]: import("yargs").Options} } */
14+
const options = {
15+
"octoherd-script": {
16+
description: "Path to *.js script. Must be an ES Module.",
17+
demandOption: true,
18+
type: "string",
19+
alias: "S",
20+
},
21+
"octoherd-token": {
22+
description:
23+
'Requires the "public_repo" scope for public repositories, "repo" scope for private repositories. Creates an OAuth token if not set.',
24+
type: "string",
25+
alias: "T",
26+
},
27+
"octoherd-repos": {
28+
description:
29+
"One or multiple repositories in the form of 'repo-owner/repo-name'. 'repo-owner/*' will find all repositories for one owner. '*' will find all repositories the user has access to. Will prompt for repositories if not set.",
30+
type: "string",
31+
array: true,
32+
alias: "R",
33+
},
34+
"octoherd-cache": {
35+
description:
36+
"Cache responses for debugging. Creates a ./cache folder if flag is set. Override by passing custom path",
37+
type: "string",
38+
},
39+
"octoherd-debug": {
40+
description: "Show debug logs",
41+
type: "boolean",
42+
default: false,
43+
},
44+
"octoherd-bypass-confirms": {
45+
description: "Bypass prompts to confirm mutating requests",
46+
type: "boolean",
47+
default: false,
48+
},
49+
};
50+
51+
/** @type import('yargs').CommandModule */
52+
const runCommand = {
53+
command: "run",
54+
describe: "",
55+
builder: (yargs) =>
56+
yargs
57+
.wrap(96)
58+
.usage("Usage: octoherd run -S path/to/script.js [options]")
59+
.example([
60+
["octoherd run -S path/to/script.js", "Minimal usage example"],
61+
[
62+
"octoherd run -S path/to/script.js -T $TOKEN -R octoherd/cli",
63+
"Pass token and repos as CLI flags",
64+
],
65+
[
66+
"octoherd run -S path/to/script.js -T $TOKEN -R octoherd/cli",
67+
"Avoid prompts for token and repos",
68+
],
69+
[
70+
"octoherd run -S path/to/script.js -T $TOKEN -R octoherd/cli --octoherd-bypass-confirms",
71+
"Avoid any prompts",
72+
],
73+
])
74+
.options(options)
75+
.version(VERSIONS)
76+
.coerce("octoherd-script", async (script) => {
77+
if (!script) return;
78+
79+
if (typeof script === "function") return script;
80+
81+
let scriptModule;
82+
const path = resolve(process.cwd(), script);
83+
84+
try {
85+
scriptModule = await import(path);
86+
} catch (error) {
87+
throw new Error(
88+
`[octoherd] ${path} does not exist or is not an ES Module`
89+
);
90+
}
91+
92+
if (!scriptModule.script) {
93+
throw new Error(`[octoherd] no "script" exported at ${path}`);
94+
}
95+
96+
return scriptModule.script;
97+
}),
98+
handler: () => {
99+
console.log(
100+
`\n${chalk.bold("Running @octoherd/cli v%s")} ${chalk.gray(
101+
"(@octoherd/octokit v%s, Node.js: %s, %s %s)"
102+
)}\n`,
103+
VERSION,
104+
OctokitVersion,
105+
process.version,
106+
process.platform,
107+
process.arch
108+
);
109+
},
110+
};
111+
112+
export default runCommand;

bin/octoherd.js

+14-54
Original file line numberDiff line numberDiff line change
@@ -2,67 +2,27 @@
22

33
import yargs from "yargs";
44
import { hideBin } from "yargs/helpers";
5-
import { resolve } from "path";
6-
import { VERSION as OctokitVersion } from "@octoherd/octokit";
5+
76
import chalk from "chalk";
87

98
import { octoherd } from "../index.js";
109
import { VERSION } from "../version.js";
11-
import { cliOptions } from "./cli-options.js";
12-
13-
const argv = yargs(hideBin(process.argv))
14-
.usage("Usage: $0 [options] [script] [repos...]")
15-
.example(
16-
"$0 --token 0123456789012345678901234567890123456789 octokit/rest.js"
17-
)
18-
.command("$0 [script] [repos...]", "", (yargs) => {
19-
yargs.positional("script", {
20-
demandOption: true,
21-
describe: "Path to *.js script. Must be an ES Module.",
22-
});
23-
yargs.positional("repos", {
24-
demandOption: true,
25-
describe:
26-
"One or multiple arrays in the form of 'repo-owner/repo-name'. 'repo-owner/*' will find all repositories for one owner. '*' will find all repositories the user has access to",
27-
default: [],
28-
});
29-
})
30-
.options(cliOptions)
31-
.version(VERSION)
32-
.epilog(`copyright 2020-${new Date().getFullYear()}`).argv;
33-
34-
const { _, $0, script, repos, ...options } = argv;
35-
36-
console.log(
37-
`\n${chalk.bold("Running @octoherd/cli v%s")} ${chalk.gray(
38-
"(@octoherd/octokit v%s, Node.js: %s, %s %s)"
39-
)}`,
40-
VERSION,
41-
OctokitVersion,
42-
process.version,
43-
process.platform,
44-
process.arch
45-
);
10+
import runCommand from "./commands/run.js";
4611

47-
let octoherdScript;
48-
const path = resolve(process.cwd(), script);
12+
const EPILOG = chalk.gray(`Questions? Ideas? Feedback?
13+
https://github.com/octoherd/octoherd/discussions
14+
15+
Copyright 2020-${new Date().getFullYear()} Octoherd Contributors`);
4916

50-
console.log("Loading script at %s\n", script);
17+
const argv = await yargs(hideBin(process.argv))
18+
.command(runCommand)
19+
.demandCommand()
20+
.version(VERSION)
21+
.epilog(EPILOG).argv;
5122

5223
try {
53-
octoherdScript = (await import(path)).script;
24+
await octoherd(argv);
5425
} catch (error) {
55-
console.error(error.stack);
56-
throw new Error(`[octoherd] ${script} script could not be found`);
57-
}
58-
59-
if (!octoherdScript) {
60-
throw new Error(`[octoherd] no "script" exported at ${path}`);
26+
console.error(error);
27+
process.exit(1);
6128
}
62-
63-
octoherd({ ...options, octoherdScript, octoherdRepos: repos }).catch(
64-
(error) => {
65-
console.error(error);
66-
process.exit(1);
67-
}
68-
);

bin/run.js

+11-41
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import yargs from "yargs";
22
import { hideBin } from "yargs/helpers";
33

4-
import { VERSION as OctokitVersion } from "@octoherd/octokit";
5-
import chalk from "chalk";
6-
74
import { octoherd } from "../index.js";
8-
import { VERSION } from "../version.js";
9-
import { cliOptions } from "./cli-options.js";
5+
import runCommand from "./commands/run.js";
106

117
/**
128
* Function is used by Octoherd Script modules to provide a dedicated CLI binary
@@ -17,41 +13,15 @@ import { cliOptions } from "./cli-options.js";
1713
*
1814
* @param {function} script Octoherd Script function
1915
*/
20-
export function run(script) {
21-
const argv = yargs(hideBin(process.argv))
22-
.usage("Usage: $0 [options] [repos...]")
23-
.example(
24-
"$0 --token 0123456789012345678901234567890123456789 octokit/rest.js"
25-
)
26-
.command("$0 [repos...]", "", (yargs) => {
27-
yargs.positional("repos", {
28-
demandOption: true,
29-
describe:
30-
"One or multiple arrays in the form of 'repo-owner/repo-name'. 'repo-owner/*' will find all repositories for one owner. '*' will find all repositories the user has access to",
31-
default: [],
32-
});
33-
})
34-
.options(cliOptions)
35-
.version(VERSION)
36-
.epilog(`copyright 2020-${new Date().getFullYear()}`).argv;
37-
38-
const { _, $0, repos, ...options } = argv;
39-
40-
console.log(
41-
`\n${chalk.bold("Running @octoherd/cli v%s")} ${chalk.gray(
42-
"(@octoherd/octokit v%s, Node.js: %s, %s %s)"
43-
)}\n`,
44-
VERSION,
45-
OctokitVersion,
46-
process.version,
47-
process.platform,
48-
process.arch
49-
);
16+
export async function run(script) {
17+
const argv = await yargs(["run", ...hideBin(process.argv)])
18+
.command(runCommand)
19+
.default("octoherd-script", () => script).argv;
5020

51-
octoherd({ ...options, octoherdScript: script, octoherdRepos: repos }).catch(
52-
(error) => {
53-
console.error(error);
54-
process.exit(1);
55-
}
56-
);
21+
try {
22+
await octoherd(argv);
23+
} catch (error) {
24+
console.error(error);
25+
process.exit(1);
26+
}
5727
}

0 commit comments

Comments
 (0)