Skip to content

Instantly share code, notes, and snippets.

@iktash
Last active May 31, 2023 16:30
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save iktash/31ccc1d8582bd9dcb15ee468c7326f2d to your computer and use it in GitHub Desktop.
Save iktash/31ccc1d8582bd9dcb15ee468c7326f2d to your computer and use it in GitHub Desktop.
//Uses the https://github.com/github-tools/github library under the hood and exposes it as `gh` property
function GithubAPI(auth) {
let repo;
let filesToCommit = [];
let currentBranch = {};
let newCommit = {};
//the underlying library for making requests
let gh = new GitHub(auth);
/**
* Sets the current repository to make push to
* @public
* @param {string} userName Name of the user who owns the repository
* @param {string} repoName Name of the repository
* @return void
*/
this.setRepo = function(userName, repoName) {
repo = gh.getRepo(userName, repoName);
}
/**
* Sets the current branch to make push to. If the branch doesn't exist yet,
* it will be created first
* @public
* @param {string} branchName The name of the branch
* @return {Promise}
*/
this.setBranch = function(branchName) {
if (!repo) {
throw 'Repository is not initialized';
}
return repo.listBranches().then((branches) => {
let branchExists = branches.data.find( branch => branch.name === branchName );
if (!branchExists) {
return repo.createBranch('master', branchName)
.then(() => {
currentBranch.name = branchName;
});
} else {
currentBranch.name = branchName;
}
});
}
/**
* Makes the push to the currently set branch
* @public
* @param {string} message Message of the commit
* @param {object[]} files Array of objects (with keys 'content' and 'path'),
* containing data to push
* @return {Promise}
*/
this.pushFiles = function(message, files) {
if (!repo) {
throw 'Repository is not initialized';
}
if (!currentBranch.hasOwnProperty('name')) {
throw 'Branch is not set';
}
return getCurrentCommitSHA()
.then(getCurrentTreeSHA)
.then( () => createFiles(files) )
.then(createTree)
.then( () => createCommit(message) )
.then(updateHead)
.catch((e) => {
console.error(e);
});
}
/**
* Sets the current commit's SHA
* @private
* @return {Promise}
*/
function getCurrentCommitSHA() {
return repo.getRef('heads/' + currentBranch.name)
.then((ref) => {
currentBranch.commitSHA = ref.data.object.sha;
});
}
/**
* Sets the current commit tree's SHA
* @private
* @return {Promise}
*/
function getCurrentTreeSHA() {
return repo.getCommit(currentBranch.commitSHA)
.then((commit) => {
currentBranch.treeSHA = commit.data.tree.sha;
});
}
/**
* Creates blobs for all passed files
* @private
* @param {object[]} filesInfo Array of objects (with keys 'content' and 'path'),
* containing data to push
* @return {Promise}
*/
function createFiles(filesInfo) {
let promises = [];
let length = filesInfo.length;
for (let i = 0; i < length; i++) {
promises.push(createFile(filesInfo[i]));
}
return Promise.all(promises);
}
/**
* Creates a blob for a single file
* @private
* @param {object} fileInfo Array of objects (with keys 'content' and 'path'),
* containing data to push
* @return {Promise}
*/
function createFile(fileInfo) {
return repo.createBlob(fileInfo.content)
.then((blob) => {
filesToCommit.push({
sha: blob.data.sha,
path: fileInfo.path,
mode: '100644',
type: 'blob'
});
});
}
/**
* Creates a new tree
* @private
* @return {Promise}
*/
function createTree() {
return repo.createTree(filesToCommit, currentBranch.treeSHA)
.then((tree) => {
newCommit.treeSHA = tree.data.sha;
});
}
/**
* Creates a new commit
* @private
* @param {string} message A message for the commit
* @return {Promise}
*/
function createCommit(message) {
return repo.commit(currentBranch.commitSHA, newCommit.treeSHA, message)
.then((commit) => {
newCommit.sha = commit.data.sha;
});
}
/**
* Updates the pointer of the current branch to point the newly created commit
* @private
* @return {Promise}
*/
function updateHead() {
return repo.updateHead('heads/' + currentBranch.name, newCommit.sha);
}
};
@socmov
Copy link

socmov commented Jan 29, 2018

+! for reading and deleting.

@subversivo58
Copy link

The library GitHub already make CRUD no?

The only difference is that this plugin allows to send a blob with binary file (good for images) of course with the small modification that must be done in the GitHub library as described in the post.

Checkout:

I think this plugin was missing a method to return the instance of GitHub ... it is only returning "repository", in this way the user ends up having to create a new instance to work the other tools of the library (GitHub) ... like this:

/**
* Get current instance of GitHub library (very suggestive method name)
* @public
* @return {Object} instanceof GitHub
*/
this.instanceOfGitHub = gh

And the use case

let api = new GithubAPI({
    token: 'xxxxxxxxxxxxxxxxxx'
})

// with a new marker
let gh = api.instanceOfGitHub
let me = gh.getUser()
me.listNotifications(function(err, notifications) {
     // do some stuff
})

// or direct access (less prone to reuse)
let me = api.instanceOfGitHub.getUser()
me.listNotifications(function(err, notifications) {
     // do some stuff
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment