Skip to content

Commit 8e1552a

Browse files
committed
github pagination
closes #3
1 parent e4f1f8e commit 8e1552a

File tree

2 files changed

+101
-62
lines changed

2 files changed

+101
-62
lines changed

index.js

+94-57
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,116 @@
11
var co = require('co')
2+
var request = require('cogent')
3+
var channel = require('chanel')
24
var cp = require('child_process')
3-
var get = require('get-json-plz')
4-
var archan = require('archan')
5+
var reset = require('yield-ratelimit-reset')
6+
var parseLink = require('parse-link-header')
7+
8+
var GITHUB_USERNAME = process.env.GITHUB_USERNAME
9+
var GITHUB_PASSWORD = process.env.GITHUB_PASSWORD
10+
if (GITHUB_PASSWORD && GITHUB_USERNAME) {
11+
request = request.extend({
12+
auth: GITHUB_USERNAME + ':' + GITHUB_PASSWORD,
13+
})
14+
}
515

616
module.exports = execute
717

818
function* execute(org, user, options) {
19+
var state = {}
20+
process.on('uncaughtException', onError)
921
console.log('organization: ' + org)
1022
console.log('user: ' + user)
1123

1224
var me = yield exec('npm', ['whoami'])
13-
if (!me)
14-
throw new Error('log in to npm, man!')
25+
if (!me) throw new Error('log in to npm, man!')
1526

1627
console.log('me: ' + me)
1728

18-
var repos = yield* getRepos(org)
19-
if (!repos.length)
20-
return console.log('no repos to check')
21-
22-
options = options || {}
23-
options.concurrency = options.concurrency || 1
24-
var ch = archan(options)
25-
26-
for (var i = 0; i < repos.length; i++) {
27-
yield* ch.drain()
28-
co(function* () {
29-
var repo = repos[i]
30-
var name = yield* getPackageName(org, repo.name)
31-
if (name)
32-
yield* addOwner(name, me, user)
33-
})(ch.push())
29+
var page = 1;
30+
var ch = channel({
31+
concurrency: 5,
32+
discard: true,
33+
})
34+
35+
while (true) {
36+
console.log('searching page %s of repositories', page)
37+
var res = yield* request('https://api.github.com/search/repositories?q=fork:true+user:' + org + '&page=' + page, true)
38+
if (res.statusCode !== 200) throw new Error('error searching user\'s repos: ' + JSON.stringify(res.headers))
39+
40+
var items = res.body.items
41+
for (var i = 0; i < items.length; i++) {
42+
ch.push(co(add(items[i])))
43+
}
44+
45+
yield* reset(res.headers)
46+
47+
if (!res.headers.link) break
48+
var links = parseLink(res.headers.link)
49+
if (!links.next) break
50+
51+
page++
3452
}
3553

36-
yield* ch.flush()
37-
console.log('you have successfully shared your developer life blood with another')
38-
}
54+
console.log('done searching for repositories')
3955

40-
function* getRepos(org) {
41-
return yield get('https://api.github.com/orgs/' + org + '/repos')
42-
}
56+
yield ch(true)
4357

44-
function* getPackageName(org, repo) {
45-
var json
46-
try {
47-
json = yield get('https://raw.github.com/' + org + '/' + repo + '/master/package.json')
48-
} catch (err) {}
49-
// no package.json
50-
if (!json)
51-
return console.log('"' + repo + '" has no package.json')
52-
if (json.private)
53-
return console.log('"' + repo + '" is private')
54-
return json.name
55-
}
58+
console.log('you have successfully shared your developer life blood with another')
59+
60+
process.removeListener('uncaughtException', onError)
5661

57-
function* addOwner(name, me, user) {
58-
var owners
59-
try {
60-
owners = yield exec('npm', ['owner', 'ls', name])
61-
} catch (err) {
62-
console.log('repo "' + name + '" isnt published on npm')
63-
return
62+
function onError() {
63+
Object.keys(state).forEach(function (repo) {
64+
state[repo] = Date.now() - state[repo]
65+
})
66+
console.log(JSON.stringify(state, null, 2))
67+
setImmediate(function () {
68+
process.exit()
69+
})
6470
}
65-
// you don't have rights!
66-
if (!~owners.indexOf(me))
67-
return console.log('you dont have publishing rights to "' + name + '"')
68-
// this particular individual already has rights!
69-
if (~owners.indexOf(user))
70-
return console.log(user + ' already has the rights to "' + name + '"')
71-
try {
72-
yield exec('npm', ['owner', 'add', user, name])
73-
console.log(user + ' added as owner to "' + name + '"')
74-
} catch (err) {
75-
console.error(err)
76-
// who knows why this would happen
71+
72+
function* add(data) {
73+
if (!data.size) return
74+
var master = data.default_branch
75+
if (!master) return
76+
var repo = data.name
77+
state[repo] = Date.now()
78+
var res
79+
try {
80+
res = yield* request('https://raw.githubusercontent.com/' + org + '/' + repo + '/' + master + '/package.json', true)
81+
} catch (err) {
82+
return // ignore timeouts and shit
83+
}
84+
delete state[repo]
85+
if (res.statusCode !== 200) {
86+
res.resume()
87+
return
88+
}
89+
var json = res.body
90+
if (json.private) return
91+
var name = json.name
92+
if (!name) return
93+
94+
var owners
95+
try {
96+
owners = yield exec('npm', ['owner', 'ls', name])
97+
} catch (err) {
98+
console.log('repo "' + name + '" isnt published on npm')
99+
return
100+
}
101+
// you don't have rights!
102+
if (!~owners.indexOf(me))
103+
return console.log('you dont have publishing rights to "' + name + '"')
104+
// this particular individual already has rights!
105+
if (~owners.indexOf(user))
106+
return console.log(user + ' already has the rights to "' + name + '"')
107+
try {
108+
yield exec('npm', ['owner', 'add', user, name])
109+
console.log(user + ' added as owner to "' + name + '"')
110+
} catch (err) {
111+
console.error(err)
112+
// who knows why this would happen
113+
}
77114
}
78115
}
79116

package.json

+7-5
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
"url": "https://github.com/jonathanong/npm-org-rights/issues"
1919
},
2020
"dependencies": {
21-
"co": "~2.3.0",
22-
"archan": "~0.4.0",
23-
"commander": "~2.1.0",
24-
"get-json-plz": "~0.0.2"
21+
"co": "^3.0.5",
22+
"chanel": "^2.0.2",
23+
"cogent": "~0.3.14",
24+
"commander": "^2.1.0",
25+
"parse-link-header": "~0.1.0",
26+
"yield-ratelimit-reset": "^1.0.0"
2527
},
2628
"engines": {
27-
"node": ">= 0.11.3"
29+
"node": ">= 0.11.12"
2830
},
2931
"bin": {
3032
"npm-org-rights": "./bin/npm-org-rights"

0 commit comments

Comments
 (0)