mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 18:55:26 +00:00
feature(github) add from bower
This commit is contained in:
parent
1bcd27db77
commit
9902e13c11
12 changed files with 1089 additions and 1787 deletions
35
modules/github/.bower.json
Normal file
35
modules/github/.bower.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "github-api",
|
||||
"main": "github.js",
|
||||
"version": "0.10.6",
|
||||
"homepage": "https://github.com/michael/github",
|
||||
"authors": [
|
||||
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)"
|
||||
],
|
||||
"description": "Github.js provides a minimal higher-level wrapper around git's plumbing commands, exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of Prose, a content editor for GitHub.",
|
||||
"moduleType": [
|
||||
"globals"
|
||||
],
|
||||
"keywords": [
|
||||
"github",
|
||||
"oauth"
|
||||
],
|
||||
"license": "BSD",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"_release": "0.10.6",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v0.10.6",
|
||||
"commit": "c2696ec3971c6a3cc2ec9194f84d870818aea305"
|
||||
},
|
||||
"_source": "git://github.com/michael/github.git",
|
||||
"_target": "~0.10.6",
|
||||
"_originalSource": "github",
|
||||
"_direct": true
|
||||
}
|
||||
25
modules/github/LICENSE
Normal file
25
modules/github/LICENSE
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
Copyright (c) 2012 Michael Aufreiter, Development Seed
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright notice, this
|
||||
list of conditions and the following disclaimer in the documentation and/or
|
||||
other materials provided with the distribution.
|
||||
- Neither the name "Development Seed" nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
367
modules/github/README.md
Normal file
367
modules/github/README.md
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
# Github.js
|
||||
|
||||
[](https://waffle.io/michael/github)[](https://travis-ci.org/darvin/github)[](https://coveralls.io/r/michael/github)
|
||||
|
||||
Github.js provides a minimal higher-level wrapper around git's [plumbing commands](http://git-scm.com/book/en/Git-Internals-Plumbing-and-Porcelain), exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of [Prose](http://prose.io), a content editor for GitHub.
|
||||
|
||||
This repo is now officially maintained by [DevelopmentSeed](https://github.com/developmentseed), the people behind [Prose.io](http://prose.io).
|
||||
|
||||
## Installation
|
||||
|
||||
Either grab `github.js` from this repo or install via NPM:
|
||||
|
||||
```
|
||||
npm install github-api
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create a Github instance.
|
||||
|
||||
```js
|
||||
var github = new Github({
|
||||
username: "YOU_USER",
|
||||
password: "YOUR_PASSWORD",
|
||||
auth: "basic"
|
||||
});
|
||||
```
|
||||
|
||||
Or if you prefer OAuth, it looks like this:
|
||||
|
||||
```js
|
||||
var github = new Github({
|
||||
token: "OAUTH_TOKEN",
|
||||
auth: "oauth"
|
||||
});
|
||||
```
|
||||
|
||||
You can use either:
|
||||
* Authorised App Tokens (via client/secret pairs), used for bigger applications, created in web-flows/on the fly
|
||||
* Personal Access Tokens (simpler to set up), used on command lines, scripts etc, created in GitHub web UI
|
||||
|
||||
See these pages for more info:
|
||||
|
||||
[Creating an access token for command-line use](https://help.github.com/articles/creating-an-access-token-for-command-line-use)
|
||||
|
||||
[Github API OAuth Overview] (http://developer.github.com/v3/oauth)
|
||||
|
||||
Enterprise Github instances may be specified using the `apiUrl` option:
|
||||
|
||||
```js
|
||||
var github = new Github({
|
||||
apiUrl: "https://serverName/api/v3",
|
||||
...
|
||||
});
|
||||
```
|
||||
|
||||
## Repository API
|
||||
|
||||
|
||||
```js
|
||||
var repo = github.getRepo(username, reponame);
|
||||
```
|
||||
|
||||
Show repository information
|
||||
|
||||
```js
|
||||
repo.show(function(err, repo) {});
|
||||
```
|
||||
|
||||
Delete a repository
|
||||
|
||||
```js
|
||||
repo.deleteRepo(function(err, res) {});
|
||||
```
|
||||
|
||||
Get contents at a particular path in a particular branch.
|
||||
|
||||
```js
|
||||
repo.contents(branch, "path/to/dir", function(err, contents) {});
|
||||
```
|
||||
|
||||
Fork repository. This operation runs asynchronously. You may want to poll for `repo.contents` until the forked repo is ready.
|
||||
|
||||
```js
|
||||
repo.fork(function(err) {});
|
||||
```
|
||||
|
||||
Create new branch for repo. You can omit oldBranchName to default to "master".
|
||||
|
||||
```js
|
||||
repo.branch(oldBranchName, newBranchName, function(err) {});
|
||||
```
|
||||
|
||||
Create Pull Request.
|
||||
|
||||
```js
|
||||
var pull = {
|
||||
title: message,
|
||||
body: "This pull request has been automatically generated by Prose.io.",
|
||||
base: "gh-pages",
|
||||
head: "michael" + ":" + "prose-patch"
|
||||
};
|
||||
repo.createPullRequest(pull, function(err, pullRequest) {});
|
||||
```
|
||||
|
||||
|
||||
Retrieve all available branches (aka heads) of a repository.
|
||||
|
||||
```js
|
||||
repo.listBranches(function(err, branches) {});
|
||||
```
|
||||
|
||||
Store contents at a certain path, where files that don't yet exist are created on the fly.
|
||||
|
||||
```js
|
||||
repo.write('master', 'path/to/file', 'YOUR_NEW_CONTENTS', 'YOUR_COMMIT_MESSAGE', function(err) {});
|
||||
```
|
||||
|
||||
Not only can you can write files, you can of course read them.
|
||||
|
||||
```js
|
||||
repo.read('master', 'path/to/file', function(err, data) {});
|
||||
```
|
||||
|
||||
Move a file from A to B.
|
||||
|
||||
```js
|
||||
repo.move('master', 'path/to/file', 'path/to/new_file', function(err) {});
|
||||
```
|
||||
|
||||
Remove a file.
|
||||
|
||||
```js
|
||||
repo.remove('master', 'path/to/file', function(err) {});
|
||||
```
|
||||
|
||||
Exploring files of a repository is easy too by accessing the top level tree object.
|
||||
|
||||
```js
|
||||
repo.getCommit('master', sha, function(err, commit) {});
|
||||
```
|
||||
|
||||
Get information about a particular commit.
|
||||
|
||||
```js
|
||||
repo.getTree('master', function(err, tree) {});
|
||||
```
|
||||
|
||||
If you want to access all blobs and trees recursively, you can add `?recursive=true`.
|
||||
|
||||
```js
|
||||
repo.getTree('master?recursive=true', function(err, tree) {});
|
||||
```
|
||||
|
||||
Given a filepath, retrieve the reference blob or tree sha.
|
||||
|
||||
```js
|
||||
repo.getSha('master', '/path/to/file', function(err, sha) {});
|
||||
```
|
||||
|
||||
For a given reference, get the corresponding commit sha.
|
||||
|
||||
```js
|
||||
repo.getRef('heads/master', function(err, sha) {});
|
||||
```
|
||||
|
||||
Create a new reference.
|
||||
|
||||
```js
|
||||
var refSpec = {
|
||||
"ref": "refs/heads/my-new-branch-name",
|
||||
"sha": "827efc6d56897b048c772eb4087f854f46256132"
|
||||
};
|
||||
repo.createRef(refSpec, function(err) {});
|
||||
```
|
||||
|
||||
Delete a reference.
|
||||
|
||||
```js
|
||||
repo.deleteRef('heads/gh-pages', function(err) {});
|
||||
```
|
||||
|
||||
Get contributors list with additions, deletions, and commit counts.
|
||||
|
||||
```js
|
||||
repo.contributors(function(err, data) {});
|
||||
```
|
||||
|
||||
## User API
|
||||
|
||||
|
||||
```js
|
||||
var user = github.getUser();
|
||||
```
|
||||
|
||||
List all repositories of the authenticated user, including private repositories and repositories in which the user is a collaborator and not an owner.
|
||||
|
||||
```js
|
||||
user.repos(function(err, repos) {});
|
||||
```
|
||||
|
||||
List organizations the autenticated user belongs to.
|
||||
|
||||
```js
|
||||
user.orgs(function(err, orgs) {});
|
||||
```
|
||||
|
||||
List authenticated user's gists.
|
||||
|
||||
```js
|
||||
user.gists(function(err, gists) {});
|
||||
```
|
||||
|
||||
List unread notifications for the authenticated user.
|
||||
|
||||
```js
|
||||
user.notifications(function(err, notifications) {});
|
||||
```
|
||||
|
||||
Show user information for a particular username. Also works for organizations.
|
||||
|
||||
```js
|
||||
user.show(username, function(err, user) {});
|
||||
```
|
||||
|
||||
List public repositories for a particular user.
|
||||
|
||||
```js
|
||||
user.userRepos(username, function(err, repos) {});
|
||||
```
|
||||
|
||||
Create a new repo for the authenticated user
|
||||
|
||||
```js
|
||||
user.createRepo({"name": "test"}, function(err, res) {});
|
||||
```
|
||||
Repo description, homepage, private/public can also be set.
|
||||
For a full list of options see the docs [here](https://developer.github.com/v3/repos/#create)
|
||||
|
||||
|
||||
List repositories for a particular organization. Includes private repositories if you are authorized.
|
||||
|
||||
```js
|
||||
user.orgRepos(orgname, function(err, repos) {});
|
||||
```
|
||||
|
||||
List all gists of a particular user. If username is ommitted gists of the current authenticated user are returned.
|
||||
|
||||
```js
|
||||
user.userGists(username, function(err, gists) {});
|
||||
```
|
||||
|
||||
## Gist API
|
||||
|
||||
```js
|
||||
var gist = github.getGist(3165654);
|
||||
```
|
||||
|
||||
Read the contents of a Gist.
|
||||
|
||||
```js
|
||||
gist.read(function(err, gist) {
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
Updating the contents of a Gist. Please consult the documentation on [GitHub](http://developer.github.com/v3/gists/).
|
||||
|
||||
```js
|
||||
var delta = {
|
||||
"description": "the description for this gist",
|
||||
"files": {
|
||||
"file1.txt": {
|
||||
"content": "updated file contents"
|
||||
},
|
||||
"old_name.txt": {
|
||||
"filename": "new_name.txt",
|
||||
"content": "modified contents"
|
||||
},
|
||||
"new_file.txt": {
|
||||
"content": "a new file"
|
||||
},
|
||||
"delete_this_file.txt": null
|
||||
}
|
||||
};
|
||||
|
||||
gist.update(delta, function(err, gist) {
|
||||
|
||||
});
|
||||
```
|
||||
## Issues API
|
||||
|
||||
```js
|
||||
var issues = github.getIssues(username, reponame);
|
||||
```
|
||||
|
||||
To read all the issues of a given repository
|
||||
|
||||
```js
|
||||
issues.list(options, function(err, issues) {});
|
||||
```
|
||||
|
||||
##Setup
|
||||
|
||||
Github.js has the following dependencies:
|
||||
|
||||
- Underscore
|
||||
- btoa (included in modern browsers, an npm module is included in package.json for node)
|
||||
|
||||
Include these before github.js :
|
||||
|
||||
```
|
||||
<script src="lib/underscore-min.js">
|
||||
<script src="github.js">
|
||||
```
|
||||
|
||||
## Compatibility
|
||||
|
||||
[](https://ci.testling.com/darvin/github)
|
||||
|
||||
## Change Log
|
||||
|
||||
### 0.10.X
|
||||
|
||||
Create and delete repositories
|
||||
Repos - getCommit
|
||||
|
||||
### 0.9.X
|
||||
|
||||
Paging (introduced at tail end of 0.8.X, note: different callbacks for success & errors now)
|
||||
|
||||
### 0.8.X
|
||||
|
||||
Fixes and tweaks, simpler auth, CI tests, node.js support, Raw+JSON, UTF8, plus:
|
||||
Users - follow, unfollow, get info, notifications
|
||||
Gists - create
|
||||
Issues - get
|
||||
Repos - createRepo, deleteRepo, createBranch, star, unstar, isStarred, getCommits, listTags, listPulls, getPull, compare
|
||||
Hooks - listHooks, getHook, createHook, editHook, deleteHook
|
||||
|
||||
### 0.7.X
|
||||
|
||||
Switched to a native `request` implementation (thanks @mattpass). Adds support for GitHub gists, forks and pull requests.
|
||||
|
||||
### 0.6.X
|
||||
|
||||
Adds support for organizations and fixes an encoding issue.
|
||||
|
||||
### 0.5.X
|
||||
|
||||
Smart caching of latest commit sha.
|
||||
|
||||
### 0.4.X
|
||||
|
||||
Added support for [OAuth](http://developer.github.com/v3/oauth/).
|
||||
|
||||
### 0.3.X
|
||||
|
||||
Support for Moving and removing files.
|
||||
|
||||
### 0.2.X
|
||||
|
||||
Consider commit messages.
|
||||
|
||||
### 0.1.X
|
||||
|
||||
Initial version.
|
||||
25
modules/github/bower.json
Normal file
25
modules/github/bower.json
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "github-api",
|
||||
"main": "github.js",
|
||||
"version": "0.10.6",
|
||||
"homepage": "https://github.com/michael/github",
|
||||
"authors": [
|
||||
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)"
|
||||
],
|
||||
"description": "Github.js provides a minimal higher-level wrapper around git's plumbing commands, exposing an API for manipulating GitHub repositories on the file level. It is being developed in the context of Prose, a content editor for GitHub.",
|
||||
"moduleType": [
|
||||
"globals"
|
||||
],
|
||||
"keywords": [
|
||||
"github",
|
||||
"oauth"
|
||||
],
|
||||
"license": "BSD",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
851
modules/github/github.js
Normal file
851
modules/github/github.js
Normal file
|
|
@ -0,0 +1,851 @@
|
|||
/*!
|
||||
* @overview Github.js
|
||||
*
|
||||
* @copyright (c) 2013 Michael Aufreiter, Development Seed
|
||||
* Github.js is freely distributable.
|
||||
*
|
||||
* @license Licensed under MIT license
|
||||
*
|
||||
* For all details and documentation:
|
||||
* http://substance.io/michael/github
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
// Initial Setup
|
||||
// -------------
|
||||
|
||||
var XMLHttpRequest, _;
|
||||
/* istanbul ignore else */
|
||||
if (typeof exports !== 'undefined') {
|
||||
XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest;
|
||||
_ = require('underscore');
|
||||
if (typeof btoa === 'undefined') {
|
||||
var btoa = require('btoa'); //jshint ignore:line
|
||||
}
|
||||
|
||||
} else {
|
||||
_ = window._;
|
||||
}
|
||||
|
||||
//prefer native XMLHttpRequest always
|
||||
/* istanbul ignore if */
|
||||
if (typeof window !== 'undefined' && typeof window.XMLHttpRequest !== 'undefined'){
|
||||
XMLHttpRequest = window.XMLHttpRequest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var Github = function(options) {
|
||||
var API_URL = options.apiUrl || 'https://api.github.com';
|
||||
|
||||
// HTTP Request Abstraction
|
||||
// =======
|
||||
//
|
||||
// I'm not proud of this and neither should you be if you were responsible for the XMLHttpRequest spec.
|
||||
|
||||
function _request(method, path, data, cb, raw, sync) {
|
||||
function getURL() {
|
||||
var url = path.indexOf('//') >= 0 ? path : API_URL + path;
|
||||
return url + ((/\?/).test(url) ? '&' : '?') + (new Date()).getTime();
|
||||
}
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
|
||||
xhr.open(method, getURL(), !sync);
|
||||
if (!sync) {
|
||||
xhr.onreadystatechange = function () {
|
||||
if (this.readyState === 4) {
|
||||
if (this.status >= 200 && this.status < 300 || this.status === 304) {
|
||||
cb(null, raw ? this.responseText : this.responseText ? JSON.parse(this.responseText) : true, this);
|
||||
} else {
|
||||
cb({path: path, request: this, error: this.status});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (!raw) {
|
||||
xhr.dataType = 'json';
|
||||
xhr.setRequestHeader('Accept','application/vnd.github.v3+json');
|
||||
} else {
|
||||
xhr.setRequestHeader('Accept','application/vnd.github.v3.raw+json');
|
||||
}
|
||||
|
||||
xhr.setRequestHeader('Content-Type','application/json;charset=UTF-8');
|
||||
if ((options.token) || (options.username && options.password)) {
|
||||
var authorization = options.token ? 'token ' + options.token : 'Basic ' + btoa(options.username + ':' + options.password);
|
||||
xhr.setRequestHeader('Authorization', authorization);
|
||||
}
|
||||
if (data) {
|
||||
xhr.send(JSON.stringify(data));
|
||||
} else {
|
||||
xhr.send();
|
||||
}
|
||||
if (sync) {
|
||||
return xhr.response;
|
||||
}
|
||||
}
|
||||
|
||||
function _requestAllPages(path, cb) {
|
||||
var results = [];
|
||||
(function iterate() {
|
||||
_request('GET', path, null, function(err, res, xhr) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
results.push.apply(results, res);
|
||||
|
||||
var links = (xhr.getResponseHeader('link') || '').split(/\s*,\s*/g),
|
||||
next = _.find(links, function(link) { return /rel="next"/.test(link); });
|
||||
|
||||
if (next) {
|
||||
next = (/<(.*)>/.exec(next) || [])[1];
|
||||
}
|
||||
|
||||
if (!next) {
|
||||
cb(err, results);
|
||||
} else {
|
||||
path = next;
|
||||
iterate();
|
||||
}
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
// User API
|
||||
// =======
|
||||
|
||||
Github.User = function() {
|
||||
this.repos = function(cb) {
|
||||
// Github does not always honor the 1000 limit so we want to iterate over the data set.
|
||||
_requestAllPages('/user/repos?type=all&per_page=1000&sort=updated', function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List user organizations
|
||||
// -------
|
||||
|
||||
this.orgs = function(cb) {
|
||||
_request("GET", '/user/orgs', null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List authenticated user's gists
|
||||
// -------
|
||||
|
||||
this.gists = function(cb) {
|
||||
_request("GET", '/gists', null, function(err, res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// List authenticated user's unread notifications
|
||||
// -------
|
||||
|
||||
this.notifications = function(cb) {
|
||||
_request("GET", '/notifications', null, function(err, res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Show user information
|
||||
// -------
|
||||
|
||||
this.show = function(username, cb) {
|
||||
var command = username ? '/users/' + username : '/user';
|
||||
|
||||
_request('GET', command, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List user repositories
|
||||
// -------
|
||||
|
||||
this.userRepos = function(username, cb) {
|
||||
// Github does not always honor the 1000 limit so we want to iterate over the data set.
|
||||
_requestAllPages('/users/' + username + '/repos?type=all&per_page=1000&sort=updated', function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// List a user's gists
|
||||
// -------
|
||||
|
||||
this.userGists = function(username, cb) {
|
||||
_request('GET', '/users/' + username + '/gists', null, function(err, res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// List organization repositories
|
||||
// -------
|
||||
|
||||
this.orgRepos = function(orgname, cb) {
|
||||
// Github does not always honor the 1000 limit so we want to iterate over the data set.
|
||||
_requestAllPages('/orgs/' + orgname + '/repos?type=all&&page_num=1000&sort=updated&direction=desc', function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// Follow user
|
||||
// -------
|
||||
|
||||
this.follow = function(username, cb) {
|
||||
_request('PUT', '/user/following/' + username, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// Unfollow user
|
||||
// -------
|
||||
|
||||
this.unfollow = function(username, cb) {
|
||||
_request('DELETE', '/user/following/' + username, null, function(err, res) {
|
||||
cb(err, res);
|
||||
});
|
||||
};
|
||||
|
||||
// Create a repo
|
||||
// -------
|
||||
this.createRepo = function(options, cb) {
|
||||
_request('POST', '/user/repos', options, cb);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// Repository API
|
||||
// =======
|
||||
|
||||
Github.Repository = function(options) {
|
||||
var repo = options.name;
|
||||
var user = options.user;
|
||||
|
||||
var that = this;
|
||||
var repoPath = '/repos/' + user + '/' + repo;
|
||||
|
||||
var currentTree = {
|
||||
'branch': null,
|
||||
'sha': null
|
||||
};
|
||||
|
||||
|
||||
// Delete a repo
|
||||
// --------
|
||||
|
||||
this.deleteRepo = function(cb) {
|
||||
_request('DELETE', repoPath, options, cb);
|
||||
};
|
||||
|
||||
// Uses the cache if branch has not been changed
|
||||
// -------
|
||||
|
||||
function updateTree(branch, cb) {
|
||||
if (branch === currentTree.branch && currentTree.sha) {
|
||||
return cb(null, currentTree.sha);
|
||||
}
|
||||
|
||||
that.getRef('heads/' + branch, function(err, sha) {
|
||||
currentTree.branch = branch;
|
||||
currentTree.sha = sha;
|
||||
cb(err, sha);
|
||||
});
|
||||
}
|
||||
|
||||
// Get a particular reference
|
||||
// -------
|
||||
|
||||
this.getRef = function(ref, cb) {
|
||||
_request('GET', repoPath + '/git/refs/' + ref, null, function(err, res) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
cb(null, res.object.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Create a new reference
|
||||
// --------
|
||||
//
|
||||
// {
|
||||
// "ref": "refs/heads/my-new-branch-name",
|
||||
// "sha": "827efc6d56897b048c772eb4087f854f46256132"
|
||||
// }
|
||||
|
||||
this.createRef = function(options, cb) {
|
||||
_request('POST', repoPath + '/git/refs', options, cb);
|
||||
};
|
||||
|
||||
// Delete a reference
|
||||
// --------
|
||||
//
|
||||
// repo.deleteRef('heads/gh-pages')
|
||||
// repo.deleteRef('tags/v1.0')
|
||||
|
||||
this.deleteRef = function(ref, cb) {
|
||||
_request('DELETE', repoPath + '/git/refs/' + ref, options, cb);
|
||||
};
|
||||
|
||||
// Create a repo
|
||||
// -------
|
||||
|
||||
this.createRepo = function(options, cb) {
|
||||
_request('POST', '/user/repos', options, cb);
|
||||
};
|
||||
|
||||
// Delete a repo
|
||||
// --------
|
||||
|
||||
this.deleteRepo = function(cb) {
|
||||
_request('DELETE', repoPath, options, cb);
|
||||
};
|
||||
|
||||
// List all tags of a repository
|
||||
// -------
|
||||
|
||||
this.listTags = function(cb) {
|
||||
_request('GET', repoPath + '/tags', null, function(err, tags) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
|
||||
cb(null, tags);
|
||||
});
|
||||
};
|
||||
|
||||
// List all pull requests of a respository
|
||||
// -------
|
||||
|
||||
this.listPulls = function(state, cb) {
|
||||
_request('GET', repoPath + "/pulls" + (state ? '?state=' + state : ''), null, function(err, pulls) {
|
||||
if (err) return cb(err);
|
||||
cb(null, pulls);
|
||||
});
|
||||
};
|
||||
|
||||
// Gets details for a specific pull request
|
||||
// -------
|
||||
|
||||
this.getPull = function(number, cb) {
|
||||
_request("GET", repoPath + "/pulls/" + number, null, function(err, pull) {
|
||||
if (err) return cb(err);
|
||||
cb(null, pull);
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the changes made between base and head
|
||||
// -------
|
||||
|
||||
this.compare = function(base, head, cb) {
|
||||
_request("GET", repoPath + "/compare/" + base + "..." + head, null, function(err, diff) {
|
||||
if (err) return cb(err);
|
||||
cb(null, diff);
|
||||
});
|
||||
};
|
||||
|
||||
// List all branches of a repository
|
||||
// -------
|
||||
|
||||
this.listBranches = function(cb) {
|
||||
_request("GET", repoPath + "/git/refs/heads", null, function(err, heads) {
|
||||
if (err) return cb(err);
|
||||
cb(null, _.map(heads, function(head) { return _.last(head.ref.split('/')); }));
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the contents of a blob
|
||||
// -------
|
||||
|
||||
this.getBlob = function(sha, cb) {
|
||||
_request("GET", repoPath + "/git/blobs/" + sha, null, cb, 'raw');
|
||||
};
|
||||
|
||||
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
|
||||
// -------
|
||||
|
||||
this.getCommit = function(branch, sha, cb) {
|
||||
_request("GET", repoPath + "/git/commits/"+sha, null, function(err, commit) {
|
||||
if (err) return cb(err);
|
||||
cb(null, commit);
|
||||
});
|
||||
};
|
||||
|
||||
// For a given file path, get the corresponding sha (blob for files, tree for dirs)
|
||||
// -------
|
||||
|
||||
this.getSha = function(branch, path, cb) {
|
||||
if (!path || path === "") return that.getRef("heads/"+branch, cb);
|
||||
_request("GET", repoPath + "/contents/"+path, {ref: branch}, function(err, pathContent) {
|
||||
if (err) return cb(err);
|
||||
cb(null, pathContent.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Retrieve the tree a commit points to
|
||||
// -------
|
||||
|
||||
this.getTree = function(tree, cb) {
|
||||
_request("GET", repoPath + "/git/trees/"+tree, null, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.tree);
|
||||
});
|
||||
};
|
||||
|
||||
// Post a new blob object, getting a blob SHA back
|
||||
// -------
|
||||
|
||||
this.postBlob = function(content, cb) {
|
||||
if (typeof(content) === "string") {
|
||||
content = {
|
||||
"content": content,
|
||||
"encoding": "utf-8"
|
||||
};
|
||||
} else {
|
||||
content = {
|
||||
"content": btoa(String.fromCharCode.apply(null, new Uint8Array(content))),
|
||||
"encoding": "base64"
|
||||
};
|
||||
}
|
||||
|
||||
_request("POST", repoPath + "/git/blobs", content, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Update an existing tree adding a new blob object getting a tree SHA back
|
||||
// -------
|
||||
|
||||
this.updateTree = function(baseTree, path, blob, cb) {
|
||||
var data = {
|
||||
"base_tree": baseTree,
|
||||
"tree": [
|
||||
{
|
||||
"path": path,
|
||||
"mode": "100644",
|
||||
"type": "blob",
|
||||
"sha": blob
|
||||
}
|
||||
]
|
||||
};
|
||||
_request("POST", repoPath + "/git/trees", data, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Post a new tree object having a file path pointer replaced
|
||||
// with a new blob SHA getting a tree SHA back
|
||||
// -------
|
||||
|
||||
this.postTree = function(tree, cb) {
|
||||
_request("POST", repoPath + "/git/trees", { "tree": tree }, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
cb(null, res.sha);
|
||||
});
|
||||
};
|
||||
|
||||
// Create a new commit object with the current commit SHA as the parent
|
||||
// and the new tree SHA, getting a commit SHA back
|
||||
// -------
|
||||
|
||||
this.commit = function(parent, tree, message, cb) {
|
||||
var user = new Github.User();
|
||||
user.show(null, function(err, userData){
|
||||
if (err) return cb(err);
|
||||
var data = {
|
||||
"message": message,
|
||||
"author": {
|
||||
"name": options.user,
|
||||
"email": userData.email
|
||||
},
|
||||
"parents": [
|
||||
parent
|
||||
],
|
||||
"tree": tree
|
||||
};
|
||||
_request("POST", repoPath + "/git/commits", data, function(err, res) {
|
||||
if (err) return cb(err);
|
||||
currentTree.sha = res.sha; // update latest commit
|
||||
cb(null, res.sha);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Update the reference of your head to point to the new commit SHA
|
||||
// -------
|
||||
|
||||
this.updateHead = function(head, commit, cb) {
|
||||
_request("PATCH", repoPath + "/git/refs/heads/" + head, { "sha": commit }, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
};
|
||||
|
||||
// Show repository information
|
||||
// -------
|
||||
|
||||
this.show = function(cb) {
|
||||
_request("GET", repoPath, null, cb);
|
||||
};
|
||||
|
||||
// Show repository contributors
|
||||
// -------
|
||||
|
||||
this.contributors = function (cb, retry) {
|
||||
retry = retry || 1000;
|
||||
var self = this;
|
||||
_request("GET", repoPath + "/stats/contributors", null, function (err, data, response) {
|
||||
if (err) return cb(err);
|
||||
if (response.status === 202) {
|
||||
setTimeout(
|
||||
function () {
|
||||
self.contributors(cb, retry);
|
||||
},
|
||||
retry
|
||||
);
|
||||
} else {
|
||||
cb(err, data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Get contents
|
||||
// --------
|
||||
|
||||
this.contents = function(ref, path, cb) {
|
||||
_request("GET", repoPath + "/contents" + (path ? "/" + path : ""), { ref: ref }, cb);
|
||||
};
|
||||
|
||||
// Fork repository
|
||||
// -------
|
||||
|
||||
this.fork = function(cb) {
|
||||
_request("POST", repoPath + "/forks", null, cb);
|
||||
};
|
||||
|
||||
// Branch repository
|
||||
// --------
|
||||
|
||||
this.branch = function(oldBranch,newBranch,cb) {
|
||||
if(arguments.length === 2 && typeof arguments[1] === "function") {
|
||||
cb = newBranch;
|
||||
newBranch = oldBranch;
|
||||
oldBranch = "master";
|
||||
}
|
||||
this.getRef("heads/" + oldBranch, function(err,ref) {
|
||||
if(err && cb) return cb(err);
|
||||
that.createRef({
|
||||
ref: "refs/heads/" + newBranch,
|
||||
sha: ref
|
||||
},cb);
|
||||
});
|
||||
};
|
||||
|
||||
// Create pull request
|
||||
// --------
|
||||
|
||||
this.createPullRequest = function(options, cb) {
|
||||
_request("POST", repoPath + "/pulls", options, cb);
|
||||
};
|
||||
|
||||
// List hooks
|
||||
// --------
|
||||
|
||||
this.listHooks = function(cb) {
|
||||
_request("GET", repoPath + "/hooks", null, cb);
|
||||
};
|
||||
|
||||
// Get a hook
|
||||
// --------
|
||||
|
||||
this.getHook = function(id, cb) {
|
||||
_request("GET", repoPath + "/hooks/" + id, null, cb);
|
||||
};
|
||||
|
||||
// Create a hook
|
||||
// --------
|
||||
|
||||
this.createHook = function(options, cb) {
|
||||
_request("POST", repoPath + "/hooks", options, cb);
|
||||
};
|
||||
|
||||
// Edit a hook
|
||||
// --------
|
||||
|
||||
this.editHook = function(id, options, cb) {
|
||||
_request("PATCH", repoPath + "/hooks/" + id, options, cb);
|
||||
};
|
||||
|
||||
// Delete a hook
|
||||
// --------
|
||||
|
||||
this.deleteHook = function(id, cb) {
|
||||
_request("DELETE", repoPath + "/hooks/" + id, null, cb);
|
||||
};
|
||||
|
||||
// Read file at given path
|
||||
// -------
|
||||
|
||||
this.read = function(branch, path, cb) {
|
||||
_request("GET", repoPath + "/contents/"+path, {ref: branch}, function(err, obj) {
|
||||
if (err && err.error === 404) return cb("not found", null, null);
|
||||
|
||||
if (err) return cb(err);
|
||||
cb(null, obj);
|
||||
}, true);
|
||||
};
|
||||
|
||||
|
||||
// Remove a file
|
||||
// -------
|
||||
|
||||
this.remove = function(branch, path, cb) {
|
||||
that.getSha(branch, path, function(err, sha) {
|
||||
if (err) return cb(err);
|
||||
_request("DELETE", repoPath + "/contents/" + path, {
|
||||
message: path + " is removed",
|
||||
sha: sha,
|
||||
branch: branch
|
||||
}, cb);
|
||||
});
|
||||
};
|
||||
|
||||
// Delete a file from the tree
|
||||
// -------
|
||||
|
||||
this.delete = function(branch, path, cb) {
|
||||
that.getSha(branch, path, function(err, sha) {
|
||||
if (!sha) return cb("not found", null);
|
||||
var delPath = repoPath + "/contents/" + path;
|
||||
var params = {
|
||||
"message": "Deleted " + path,
|
||||
"sha": sha
|
||||
};
|
||||
delPath += "?message=" + encodeURIComponent(params.message);
|
||||
delPath += "&sha=" + encodeURIComponent(params.sha);
|
||||
delPath += '&branch=' + encodeURIComponent(branch);
|
||||
_request("DELETE", delPath, null, cb);
|
||||
});
|
||||
};
|
||||
|
||||
// Move a file to a new location
|
||||
// -------
|
||||
|
||||
this.move = function(branch, path, newPath, cb) {
|
||||
updateTree(branch, function(err, latestCommit) {
|
||||
that.getTree(latestCommit+"?recursive=true", function(err, tree) {
|
||||
// Update Tree
|
||||
_.each(tree, function(ref) {
|
||||
if (ref.path === path) ref.path = newPath;
|
||||
if (ref.type === "tree") delete ref.sha;
|
||||
});
|
||||
|
||||
that.postTree(tree, function(err, rootTree) {
|
||||
that.commit(latestCommit, rootTree, 'Deleted '+path , function(err, commit) {
|
||||
that.updateHead(branch, commit, function(err) {
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Write file contents to a given branch and path
|
||||
// -------
|
||||
|
||||
this.write = function(branch, path, content, message, cb) {
|
||||
that.getSha(branch, path, function(err, sha) {
|
||||
if (err && err.error !== 404) return cb(err);
|
||||
_request("PUT", repoPath + "/contents/" + path, {
|
||||
message: message,
|
||||
content: btoa(content),
|
||||
branch: branch,
|
||||
sha: sha
|
||||
}, cb);
|
||||
});
|
||||
};
|
||||
|
||||
// List commits on a repository. Takes an object of optional paramaters:
|
||||
// sha: SHA or branch to start listing commits from
|
||||
// path: Only commits containing this file path will be returned
|
||||
// since: ISO 8601 date - only commits after this date will be returned
|
||||
// until: ISO 8601 date - only commits before this date will be returned
|
||||
// -------
|
||||
|
||||
this.getCommits = function(options, cb) {
|
||||
options = options || {};
|
||||
var url = repoPath + "/commits";
|
||||
var params = [];
|
||||
if (options.sha) {
|
||||
params.push("sha=" + encodeURIComponent(options.sha));
|
||||
}
|
||||
if (options.path) {
|
||||
params.push("path=" + encodeURIComponent(options.path));
|
||||
}
|
||||
if (options.since) {
|
||||
var since = options.since;
|
||||
if (since.constructor === Date) {
|
||||
since = since.toISOString();
|
||||
}
|
||||
params.push("since=" + encodeURIComponent(since));
|
||||
}
|
||||
if (options.until) {
|
||||
var until = options.until;
|
||||
if (until.constructor === Date) {
|
||||
until = until.toISOString();
|
||||
}
|
||||
params.push("until=" + encodeURIComponent(until));
|
||||
}
|
||||
if (options.page) {
|
||||
params.push("page=" + options.page);
|
||||
}
|
||||
if (options.perpage) {
|
||||
params.push("per_page=" + options.perpage);
|
||||
}
|
||||
if (params.length > 0) {
|
||||
url += "?" + params.join("&");
|
||||
}
|
||||
_request("GET", url, null, cb);
|
||||
};
|
||||
};
|
||||
|
||||
// Gists API
|
||||
// =======
|
||||
|
||||
Github.Gist = function(options) {
|
||||
var id = options.id;
|
||||
var gistPath = "/gists/"+id;
|
||||
|
||||
// Read the gist
|
||||
// --------
|
||||
|
||||
this.read = function(cb) {
|
||||
_request("GET", gistPath, null, function(err, gist) {
|
||||
cb(err, gist);
|
||||
});
|
||||
};
|
||||
|
||||
// Create the gist
|
||||
// --------
|
||||
// {
|
||||
// "description": "the description for this gist",
|
||||
// "public": true,
|
||||
// "files": {
|
||||
// "file1.txt": {
|
||||
// "content": "String file contents"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
this.create = function(options, cb){
|
||||
_request("POST","/gists", options, cb);
|
||||
};
|
||||
|
||||
// Delete the gist
|
||||
// --------
|
||||
|
||||
this.delete = function(cb) {
|
||||
_request("DELETE", gistPath, null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Fork a gist
|
||||
// --------
|
||||
|
||||
this.fork = function(cb) {
|
||||
_request("POST", gistPath+"/fork", null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Update a gist with the new stuff
|
||||
// --------
|
||||
|
||||
this.update = function(options, cb) {
|
||||
_request("PATCH", gistPath, options, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Star a gist
|
||||
// --------
|
||||
|
||||
this.star = function(cb) {
|
||||
_request("PUT", gistPath+"/star", null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Untar a gist
|
||||
// --------
|
||||
|
||||
this.unstar = function(cb) {
|
||||
_request("DELETE", gistPath+"/star", null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
|
||||
// Check if a gist is starred
|
||||
// --------
|
||||
|
||||
this.isStarred = function(cb) {
|
||||
_request("GET", gistPath+"/star", null, function(err,res) {
|
||||
cb(err,res);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
// Issues API
|
||||
// ==========
|
||||
|
||||
Github.Issue = function(options) {
|
||||
var path = "/repos/" + options.user + "/" + options.repo + "/issues";
|
||||
|
||||
this.list = function(options, cb) {
|
||||
var query = [];
|
||||
for (var key in options) {
|
||||
if (options.hasOwnProperty(key)) {
|
||||
query.push(encodeURIComponent(key) + "=" + encodeURIComponent(options[key]));
|
||||
}
|
||||
}
|
||||
_requestAllPages(path + '?' + query.join("&"), cb);
|
||||
};
|
||||
};
|
||||
|
||||
// Top Level API
|
||||
// -------
|
||||
|
||||
this.getIssues = function(user, repo) {
|
||||
return new Github.Issue({user: user, repo: repo});
|
||||
};
|
||||
|
||||
this.getRepo = function(user, repo) {
|
||||
return new Github.Repository({user: user, name: repo});
|
||||
};
|
||||
|
||||
this.getUser = function() {
|
||||
return new Github.User();
|
||||
};
|
||||
|
||||
this.getGist = function(id) {
|
||||
return new Github.Gist({id: id});
|
||||
};
|
||||
};
|
||||
|
||||
/* istanbul ignore else */
|
||||
if (typeof exports !== 'undefined') {
|
||||
module.exports = Github;
|
||||
} else {
|
||||
window.Github = Github;
|
||||
}
|
||||
}).call(this);
|
||||
5
modules/github/lib/underscore-min.js
vendored
Normal file
5
modules/github/lib/underscore-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
59
modules/github/package.json
Normal file
59
modules/github/package.json
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"name": "github-api",
|
||||
"version": "0.10.6",
|
||||
"description": "A higher-level wrapper around the Github API.",
|
||||
"main": "github.js",
|
||||
"dependencies": {
|
||||
"atob": "^1.1.2",
|
||||
"btoa": "^1.1.2",
|
||||
"underscore": "~1.6.0",
|
||||
"xmlhttprequest": "~1.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"argg": "0.0.1",
|
||||
"istanbul": "^0.3.13",
|
||||
"jshint": "^2.5.8",
|
||||
"plato": "^1.4.0",
|
||||
"tape": "^3.0.3",
|
||||
"testling": "^1.7.1"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node node_modules/argg test/*.js && node node_modules/jshint/bin/jshint github.js test/*.js",
|
||||
"jshint": "node node_modules/jshint/bin/jshint github.js test/*.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/michael/github.git"
|
||||
},
|
||||
"keywords": [
|
||||
"github",
|
||||
"api"
|
||||
],
|
||||
"contributors": [
|
||||
"Sergey Klimov <sergey.v.klimov@gmail.com> (http://darvin.github.com/)",
|
||||
"Michael Aufreiter (http://substance.io)",
|
||||
"Ændrew Rininsland <aendrew.rininsland@thetimes.co.uk> (http://www.aendrew.com)"
|
||||
],
|
||||
"license": "BSD",
|
||||
"readmeFilename": "README.md",
|
||||
"gitHead": "aa8aa3c8cd5ce5240373d4fd1d06a7ab4af41a36",
|
||||
"bugs": {
|
||||
"url": "https://github.com/michael/github/issues"
|
||||
},
|
||||
"browser": {
|
||||
"xmlhttprequest": false
|
||||
},
|
||||
"testling": {
|
||||
"files": "test/test.*.js",
|
||||
"browsers": [
|
||||
"iexplore/9.0..latest",
|
||||
"chrome/18.0..latest",
|
||||
"firefox/15.0..latest",
|
||||
"opera/11.0..latest",
|
||||
"safari/5.0.5..latest",
|
||||
"iphone/6.0..latest",
|
||||
"ipad/6.0..latest",
|
||||
"android-browser/4.2..latest"
|
||||
]
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue