Skip to content

Commit ad807ef

Browse files
authored
Merge pull request #35 from pkgjs/octokit
2 parents 4786e99 + b9e63d6 commit ad807ef

File tree

8 files changed

+292
-115
lines changed

8 files changed

+292
-115
lines changed

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ List the Node.js versions supported by the package/repository
44

55
This repository is managed by the [Package Maintenance Working Group](https://github.com/nodejs/package-maintenance), see [Governance](https://github.com/nodejs/package-maintenance/blob/master/Governance.md).
66

7+
## Setup
8+
9+
No setup is required, however if you do not have a `GH_TOKEN` environment limit, you will likely hit a request rate limit on Github API, which may result in very long wait times for retries.
10+
711
## Usage (command line)
812

913
```

lib/loader/octokit-wrapper.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
3+
const { Octokit } = require('@octokit/rest');
4+
const { throttling } = require('@octokit/plugin-throttling');
5+
6+
const Constants = require('../constants');
7+
const Logger = require('../logger');
8+
9+
10+
const internals = {
11+
Octokit: Octokit.plugin(throttling)
12+
};
13+
14+
15+
exports.create = () => {
16+
17+
const octokit = new internals.Octokit({
18+
auth: process.env.GH_TOKEN,
19+
userAgent: Constants.userAgent,
20+
throttle: {
21+
onRateLimit: (retryAfter, options) => {
22+
23+
Logger.warn(['loader'], 'Request quota exceeded for request %s %s. Will retry in %d seconds. Have you set a GH_TOKEN in env?', options.method, options.url, retryAfter);
24+
25+
return true;
26+
},
27+
onAbuseLimit: (retryAfter, options) => {
28+
29+
return false;
30+
}
31+
}
32+
});
33+
34+
return octokit;
35+
};

lib/loader/repository.js

+30-16
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
'use strict';
22

33
const GitUrlParse = require('git-url-parse');
4-
const Wreck = require('@hapi/wreck');
54

65
const Logger = require('../logger');
6+
const OctokitWrapper = require('./octokit-wrapper');
77
const Utils = require('../utils');
88

99

@@ -30,40 +30,54 @@ exports.create = (repository) => {
3030

3131
return head;
3232
},
33-
loadFile: async (filename, options) => {
33+
loadFile: async (filename, options = {}) => {
3434

3535
if (parsedRepository.source !== 'github.com') {
3636
throw new Error('Only github.com paths supported, feel free to PR at https://github.com/pkgjs/detect-node-support');
3737
}
3838

39-
const url = `https://raw.githubusercontent.com/${parsedRepository.full_name}/HEAD/${filename}`;
40-
Logger.log(['loader'], 'Loading: %s', url);
39+
const resource = `${parsedRepository.full_name}:${filename}@HEAD`;
40+
Logger.log(['loader'], 'Loading: %s', resource);
4141

42-
if (options === undefined && internals.cache.has(url)) {
43-
Logger.log(['loader'], 'From cache: %s', url);
44-
return internals.cache.get(url);
45-
}
42+
const octokit = OctokitWrapper.create();
4643

4744
try {
48-
const { payload } = await Wreck.get(url, options);
4945

50-
if (options === undefined) {
51-
internals.cache.set(url, payload);
46+
let result;
47+
if (internals.cache.has(resource)) {
48+
Logger.log(['loader'], 'From cache: %s', resource);
49+
result = internals.cache.get(resource);
50+
}
51+
else {
52+
result = await octokit.repos.getContent({
53+
owner: parsedRepository.owner,
54+
repo: parsedRepository.name,
55+
path: filename
56+
});
57+
}
58+
59+
internals.cache.set(resource, result);
60+
61+
Logger.log(['loader'], 'Loaded: %s', resource);
62+
63+
const content = Buffer.from(result.data.content, 'base64');
64+
65+
if (options.json) {
66+
return JSON.parse(content.toString());
5267
}
5368

54-
Logger.log(['loader'], 'Loaded: %s', url);
55-
return payload;
69+
return content;
5670
}
5771
catch (err) {
5872

59-
if (err.data && err.data.res.statusCode === 404) {
60-
Logger.log(['loader'], 'Not found: %s', url);
73+
if (err.status === 404) {
74+
Logger.log(['loader'], 'Not found: %s', resource);
6175
const error = new Error(`${repository} does not contain a ${filename}`);
6276
error.code = 'ENOENT';
6377
throw error;
6478
}
6579

66-
Logger.error(['loader'], 'Failed to load: %s', url);
80+
Logger.error(['loader'], 'Failed to load: %s', resource);
6781
throw err;
6882
}
6983
}

lib/package.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ exports.detect = async (what) => {
4545

4646
const { loadFile, getCommit } = await Loader.create({ path, repository, packageName });
4747

48-
const packageJson = await loadFile('package.json', { json: 'force' });
48+
const packageJson = await loadFile('package.json', { json: true });
4949

5050
const meta = {
5151
packageJson,

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@
3535
"sinon": "^10.0.0"
3636
},
3737
"dependencies": {
38-
"@hapi/wreck": "^17.0.0",
3938
"@npmcli/arborist": "^2.0.0",
39+
"@octokit/plugin-throttling": "^3.2.2",
40+
"@octokit/rest": "^18.0.0",
4041
"@pkgjs/nv": "0.1.0",
4142
"debug": "^4.1.1",
4243
"git-url-parse": "^11.1.2",

test/fixtures/index.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,12 @@ module.exports = class TestContext {
7070
.get('/dist/index.json')
7171
.reply(200, Fs.readFileSync(Path.join(__dirname, 'node-release-dist.json')));
7272

73-
Nock('https://raw.githubusercontent.com')
73+
Nock('https://api.github.com')
7474
.persist()
75-
.get('/nodejs/ci-config-travis/HEAD/lts/gte-10.yml')
76-
.reply(200, Fs.readFileSync(Path.join(__dirname, 'travis-ymls', 'nodejs-ci-config-travis-gte-10.yml')));
75+
.get('/repos/nodejs/ci-config-travis/contents/lts%2Fgte-10.yml')
76+
.reply(200, {
77+
content: Fs.readFileSync(Path.join(__dirname, 'travis-ymls', 'nodejs-ci-config-travis-gte-10.yml')).toString('base64')
78+
});
7779

7880
this._cleanup.push(() => {
7981

0 commit comments

Comments
 (0)