Skip to content

Commit 64b8a3a

Browse files
committed
feat: initial version
1 parent 9a87086 commit 64b8a3a

File tree

2 files changed

+68
-7
lines changed

2 files changed

+68
-7
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ Pass all options as CLI flags to avoid user prompts
2121
npx octoherd-script-download-files \
2222
-T ghp_0123456789abcdefghjklmnopqrstuvwxyzA \
2323
-R "stefanbuck/*" \
24-
--ignoreArchived undefined \
2524
--source README.md \
2625
--target ./out
2726
```
@@ -30,9 +29,9 @@ npx octoherd-script-download-files \
3029

3130
| option | type | description |
3231
| --------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
33-
| `--ignore-archived` or `--no-ignore-archived` | boolean | Ignores archive repositories |
3432
| `--source` | string | **Required.** Path to the destination directory |
3533
| `--target` | string | **Required.** File path to download. Note: Directories are not supported yet |
34+
| `--ignore-archived` or `--no-ignore-archived` | boolean | Default `true`. Ignores archive repositories |
3635
| `--octoherd-token`, `-T` | string | A personal access token ([create](https://github.com/settings/tokens/new?scopes=repo)). Script will create one if option is not set |
3736
| `--octoherd-repos`, `-R` | array of strings | One or multiple space-separated 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 |
3837
| `--octoherd-bypass-confirms` | boolean | Bypass prompts to confirm mutating requests |

script.js

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
// @ts-check
22

3+
import os from 'os'
4+
import fs from 'fs'
5+
import path from 'path'
6+
7+
/** @type boolean */
8+
let hasRepoScope;
9+
310
/**
411
* An Octoherd script to download files from repositories
512
*
@@ -10,8 +17,63 @@
1017
* @param {string} options.source Path to the destination directory
1118
* @param {string} options.target File path to download. Note: Directories are not supported yet
1219
*/
13-
export async function script(
14-
octokit,
15-
repository,
16-
{ ignoreArchived, source, target }
17-
) {}
20+
export async function script(octokit, repository, { source, target = process.cwd(), ignoreArchived = true }) {
21+
if (!hasRepoScope) {
22+
const { headers } = await octokit.request("HEAD /");
23+
const scopes = new Set(headers["x-oauth-scopes"].split(", "));
24+
25+
if (!scopes.has("repo")) {
26+
throw new Error(
27+
`The "repo" scope is required for this script. Create a token at https://github.com/settings/tokens/new?scopes=repo then run the script with "-T <paste token here>"`
28+
);
29+
}
30+
hasRepoScope = true;
31+
}
32+
33+
if (ignoreArchived && repository.archived) {
34+
octokit.log.warn(`IGNORE repository is archived`);
35+
return;
36+
}
37+
38+
if (!source) {
39+
octokit.log.error('Please specify a source file to download with --source=README.md')
40+
process.exit(1);
41+
}
42+
43+
if (!target) {
44+
octokit.log.error('Please specify a source file to download with --source=README.md --target=./out')
45+
process.exit(1);
46+
}
47+
48+
await octokit.request(
49+
`GET /repos/{owner}/{repo}/contents/${source}`,
50+
{
51+
owner: repository.owner.login,
52+
repo: repository.name,
53+
headers: {
54+
Accept: "application/vnd.github.v3.raw"
55+
}
56+
}
57+
).then((res) => {
58+
octokit.log.info(`Download ${source}`);
59+
60+
// Expand the ~ character to a users home directory
61+
const newTarget = target.replace("~", os.homedir)
62+
63+
const targetFile = path.join(newTarget, repository.owner.login, repository.name, source);
64+
const targetPath = path.join(newTarget, repository.owner.login, repository.name, path.dirname(source));
65+
66+
if (!fs.existsSync(targetPath)) {
67+
fs.mkdirSync(targetPath, { recursive: true });
68+
}
69+
70+
fs.writeFileSync(targetFile, res.data)
71+
}).catch(error => {
72+
if (error.status === 404) {
73+
octokit.log.warn(`File ${source} not found`);
74+
return false;
75+
}
76+
77+
throw error;
78+
})
79+
}

0 commit comments

Comments
 (0)