Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added, 'repo' rights, added rate-limiter. works now #34

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 3 additions & 56 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,5 @@
# org-labels
## org-labels-private

[![NPM Version](https://img.shields.io/npm/v/org-labels.svg?style=flat)](https://www.npmjs.org/package/org-labels)
[![NPM Downloads](https://img.shields.io/npm/dm/org-labels.svg?style=flat)](https://www.npmjs.org/package/org-labels)
[![Node.js Version](https://img.shields.io/badge/io.js-≥_1.1.0-orange.svg?style=flat)](http://nodejs.org/download/)
forked from [repo-utils/org-labels](https://github.com/repo-utils/org-labels)

A tool to help manage organization-wide GitHub issue labels.

### Installation

```bash
$ npm install -g org-labels
```

## Usage

```bash
$ org-labels <command>
```

Requires [io.js](https://iojs.org/en/index.html) 1.1.0+ — you can use a node version manager [such as __nvm__](https://github.com/creationix/nvm) to switch node versions easily.

#### GitHub Security

org-labels uses [`ghauth`](https://github.com/rvagg/ghauth) for GitHub authentication.
The version is fixed, and I have done a rough review of its code.

### Commands

- `add` `<org> <label> <color>` - adds a label to all repos.
- `remove` `<org> <label>` - removes a label from all repos.
- `update` `<org> <label> <color>` - updates an existing label for all repos.
- `rename` `<org> <label> <new>` - renames an existing label for all repos.
- `standardize` `<org> <repo>` - reads a `config/github_labels.json` file from a repo and adds / updates labels on all repos.

__color__ must be a hexadecimal color code without the preceding `#`.

Both `<org>` and `<repo>` may optionally be formatted as `<org/repo>`.

#### Options

- `-d` `--destructive` - When enabled, allows `standardize` to remove labels not found in the config file.

## Examples

The following would add a `docs` issue label with the color `d4c5f9` to every repo in `repo-utils`.

```bash
$ org-labels add repo-utils docs d4c5f9
```

The following would standardize labels in all `repo-utils` repos using the [jshttp labels config](https://github.com/jshttp/style-guide/tree/master/config).

```bash
$ org-labels standardize repo-utils jshttp/style-guide
```

## [MIT Licensed](LICENSE)
Works with private organizations and repos
2 changes: 1 addition & 1 deletion bin/org-labels
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function* _org_labels(fn, args) {
configName: 'org-labels'
, userAgent : 'org-labels'
, note : 'org-labels CLI tool'
, scopes : []
, scopes : ['repo']
})

yield check_github_ratelimit(auth)
Expand Down
49 changes: 30 additions & 19 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var request = require('request-promise')
var RateLimiter = require('request-rate-limiter');

/*
* checks that a string is a valid hex color code without the preceding `#`
Expand Down Expand Up @@ -51,6 +52,9 @@ proto.get_repos = get_repos
proto.handle_label = handle_label
proto.send_label = send_label

var limiter = new RateLimiter(40);



/*
* Adds a label with the specified name and color to all repos in an org.
Expand Down Expand Up @@ -119,7 +123,8 @@ function* standardize(args) {
config_repo = org + '/' + config_repo
}

var res = yield request({
console.log('https://api.github.com/repos/' + config_repo + '/contents/config/github_labels.json')
var res = yield limiter.request({
uri : 'https://api.github.com/repos/' + config_repo + '/contents/config/github_labels.json'
, headers: header
, auth : this.auth
Expand All @@ -130,6 +135,7 @@ function* standardize(args) {
if (!res) process.exit()

// github sends the body (json file) as base64
console.log(res.body)
var config = JSON.parse(new Buffer(res.body.content, 'base64').toString('utf8'))
if (!Array.isArray(config))
throw new Error('error: github_labels.json must be a json array')
Expand All @@ -150,13 +156,13 @@ function* standardize(args) {
var i = repos.length
var reqs = []
while (i--) {
console.log(repos[i])
reqs.push(this.handle_repo_labels(org, repos[i], config, this.opts.destructive))
}
var results = yield reqs

var info = log_results(results)
console.log(results)

console.log('%d label updates across %d repos', info.updates, info.repos)
console.log('done standardizing labels')
}

Expand All @@ -168,7 +174,7 @@ function* standardize(args) {
function* handle_repo_labels(org, repo, config, destructive) {

var uri = 'https://api.github.com/repos/' + org + '/' + repo + '/labels'
var res = yield request({
var res = yield limiter.request({
uri : uri
, headers: header
, method : 'GET'
Expand All @@ -183,20 +189,25 @@ function* handle_repo_labels(org, repo, config, destructive) {
var results = []

var i = list.length
console.log(`list length: ${i}`)
while (i--) {
item = list[i]

results.push(request({
console.log(i)
console.log(item)
console.log(uri + (item.method === 'POST' ? '' : '/' + item.name))
var res = yield limiter.request({
uri : uri + (item.method === 'POST' ? '' : '/' + item.name)
, headers: header
, method : item.method
, json : item
, auth : this.auth
, resolveWithFullResponse: true
}))
})
console.log(JSON.stringify(res.body))
results.push(JSON.stringify(res.body))
}

return yield results
return results
}

/*
Expand All @@ -208,7 +219,8 @@ function compare_labels(config, _existing, destructive) {
var out = []
var i = config.length
// don't splice the actual array
var existing = _existing.slice(0)
var existing = _existing.body
console.log(existing)

while (i--) {
var wanted = config[i]
Expand Down Expand Up @@ -260,22 +272,20 @@ function* get_repos(org) {

// handle github pagination for orgs with many repos
while (++page) {
var res = yield request({
uri : 'https://api.github.com/users/' + org + '/repos?page=' + page
var res = yield limiter.request({
uri : 'https://api.github.com/orgs/' + org + '/repos?page=' + page
, headers: header
, auth : this.auth
, json : true
}).catch(log_request_err('error retrieving org\'s repos:'))

if (!res) continue

var i = res.length
var i = res.body.length
while (i--) {
repos.push(res[i].name)
repos.push(res.body[i].name)
}

// if this page has less repos than the last, then it is the last page.
if (res.length < last_length) break
if (res.body.length === 0) break

last_length = res.length
}
Expand Down Expand Up @@ -322,14 +332,14 @@ function* send_label(org, repos, opts, method) {
var uri = 'https://api.github.com/repos/' + org + '/'

while (i--) {
arr.push(request({
arr.push(limiter.request({
uri : uri + repos[i] + '/labels' + (opts.ext ? '/' + opts.ext : '')
, headers: header
, method : method || opts.method
, json : opts
, auth : this.auth
, resolveWithFullResponse: true
}))
}).catch(console.log(`error sending labels from a repo: ${repos[i]}`)))
}

return yield arr
Expand Down Expand Up @@ -402,7 +412,8 @@ function log_result(result, label) {
*/
function log_request_err(msg) {
return function (err) {
if (err.response.headers['x-ratelimit-remaining']>>0 === 0) {
console.log(err)
if (err.response && err.response.headers['x-ratelimit-remaining']>>0 === 0) {
console.log('Exceded GitHub rate-limit. Bailing.')
return process.exit()
}
Expand Down
Loading