git-pull-request
Advanced tools
Comparing version 1.0.0 to 2.0.0
151
gpr.js
#!/usr/bin/env node | ||
/** | ||
*`git pull` from the repo and branch that a PR originates from. | ||
* Copyright 2018 Matthew Brookes. License: MIT | ||
* Copyright 2019 Matthew Brookes. License: MIT | ||
*/ | ||
@@ -11,35 +11,30 @@ | ||
var version = 'git-pull-request 1.0.0'; | ||
var version = 'git-pull-request 2.0.0'; | ||
var use = '\n ' + version + '\n\n gpr [-i | -l [-r] | -p | -f | -b [<name>] | -n | -d | -D | -v | -h] <pr#>'; | ||
var help = use + '\n\n' + | ||
' By default, gpr will fetch the remote branch for <pr#> and checkout on a detached HEAD.\n\n' + | ||
' [-i | info] <pr#> Show the PR title and requestor for <pr#>.\n' + | ||
' [-l | ls | list] [-r | remote] List local gpr branches. / List 30 most recent open PRs.\n\n' + | ||
var hint = ' By default, `gpr <pr#>` will fetch the remote branch for <pr#> and checkout on a detached HEAD.'; | ||
' [-p | pull] <pr#> Pull the remote branch for <pr#> to the current branch.\n' + | ||
' [-f | force] <pr#> Force overwrite the local branch and checkout on a detached HEAD.\n' + | ||
' [-b | branch] [<name>] <pr#> Create new branch [name] from master and pull. Defaults to \'gpr/<pr#>\'.\n' + | ||
' [-n] [user:branch] Fetch from the named ref and checkout on a detached HEAD.\n\n' + | ||
var usage = use + '\n\n' + hint + '\n\n gpr [-h | --help] for detailed usage.'; | ||
var help = use + | ||
' [-d | delete] <pr#> Delete the gpr/<pr#> branch.\n' + | ||
' [-D | Delete] <pr#> Force delete the gpr/<pr#> branch.\n\n' + | ||
'\n\n [-i | info] <pr#> Show the PR title and requestor for <pr#>.\n\ | ||
[-l | ls | list] [-r | remote] List local gpr branches. / List 30 most recent open PRs.\n\ | ||
\n\ | ||
[-u | |update | pull] <pr#> Pull the remote branch for <pr#> to the current branch.\n\ | ||
[-f | force] <pr#> Force overwrite the local branch and checkout on a detached HEAD.\n\ | ||
[-b | branch] [<name>] <pr#> Create new branch [name] from master and pull. Defaults to \'gpr/<pr#>\'.\n\ | ||
[-n | named] <user:branch> Fetch from the named ref and checkout on a detached HEAD.\n\ | ||
\n\ | ||
[-p | push] <user:branch> Push the current branch or detached HEAD to the remote branch.\n\ | ||
[-P | Push] <<user:branch> Force push the current branch or detached HEAD to the remote branch.\n\ | ||
\n\ | ||
[-d | delete] <pr#> Delete the gpr/<pr#> branch.\n\ | ||
[-D | Delete] <pr#> Force delete the gpr/<pr#> branch.\n\ | ||
\n\ | ||
[-v | version] Show git-pull-request version.\n\ | ||
[-h | help] This help.\n\ | ||
\n\ | ||
<pr#> PR number to apply the command to.\n\n' + hint; | ||
' [-v | version] Show git-pull-request version.\n' + | ||
' [-h | help] This help.\n\n' + | ||
' <pr#> PR number to apply the command to.'; | ||
var usage = use + '\n\n gpr [-h | --help] for detailed usage'; | ||
// Get the repo name from the package.jaon in the nearest parent directory | ||
var npmPrefix = execSync('npm prefix', {cwd: process.cwd(), encoding: 'utf8'}).replace(/\s+/g, ''); | ||
// Read the package.json and extract the repo name | ||
var packageFile = JSON.parse(fs.readFileSync(npmPrefix + '/package.json', 'utf8')); | ||
var repo = packageFile.repository.url.split('/'); | ||
var repoName = repo[4].slice(0, -4); | ||
repo = repo[3]+ '/' + repoName; | ||
var path = '/repos/' + repo + '/pulls'; | ||
// Read the command-line args | ||
@@ -54,3 +49,3 @@ var args = process.argv; | ||
function exit(error) { | ||
console.log(error,'\n'); | ||
console.error(error,'\n'); | ||
process.exit(); | ||
@@ -69,2 +64,52 @@ }; | ||
try { | ||
var npmPrefix = execSync('npm prefix', {cwd: process.cwd(), encoding: 'utf8'}).replace(/\s+/g, ''); | ||
} catch (error) {} | ||
// Read the package.json and extract the repo name | ||
if (fs.existsSync(npmPrefix + '/package.json')) { | ||
var packageFile = JSON.parse(fs.readFileSync(npmPrefix + '/package.json', 'utf8')); | ||
// repo: [ 'https:', '', 'github.com', 'mui-org', 'material-ui.git' ], | ||
var repo = packageFile.repository.url.split('/'); | ||
// repoName: 'material-ui' | ||
var repoName = repo[4].slice(0, -4); | ||
// path: '/repos/mui-org/material-ui/pulls' | ||
var path = '/repos/' + repo[3]+ '/' + repoName + '/pulls'; | ||
// If there's no package.json, try .git config upstream / origin | ||
} else { | ||
try { | ||
var gitPrefix = execSync('git rev-parse --show-toplevel', {cwd: process.cwd(), encoding: 'utf8'}).replace(/\s+/g, ''); | ||
} catch (error) { | ||
exit(error.output[1]); | ||
} | ||
if (fs.existsSync(gitPrefix + '/.git/config')) { | ||
var gitConfig = fs.readFileSync(gitPrefix + '/.git/config', 'utf8'); | ||
// repo: [ 'https:', '', 'github.com', 'mui-org', 'material-ui.git' ], | ||
var repo = gitConfig.match(/\[remote "upstream"\][\r\n|\r|\n]\s*url\s=\s(.*)/); | ||
if (!repo) { | ||
repo = gitConfig.match(/\[remote "origin"\][\r\n|\r|\n]\s*url\s=\s(.*)/); | ||
if (!repo) { | ||
exit('No "upstream" or "origin" remote found in .git/config') | ||
} | ||
} | ||
repo = repo[1].split('/'); | ||
// repoName: 'material-ui' | ||
var repoName = repo[4].slice(0, -4); | ||
// path: '/repos/mui-org/material-ui/pulls' | ||
var path = '/repos/' + repo[3]+ '/' + repoName + '/pulls'; | ||
console.log("git without package") | ||
} else { | ||
exit('No package.json or .git/config found in any ancestor directory') | ||
} | ||
} | ||
// Process args that don't require the API, or setup those that do | ||
@@ -85,3 +130,3 @@ switch(args[2]) { | ||
case '-n': | ||
case '-n': case 'named': | ||
if (args.length < 4) { | ||
@@ -95,3 +140,3 @@ exit(usage); | ||
exit(usage); | ||
}; | ||
} | ||
@@ -102,7 +147,35 @@ execho('git fetch ' + 'https://github.com/' + ref[0] + '/' + repoName + ' \'' + ref[1] + '\''); | ||
case '-p': case 'push': | ||
if (args.length < 4) { | ||
exit(usage); | ||
} | ||
ref = args[3].split(':'); | ||
if (ref.length !== 2) { | ||
exit(usage); | ||
} | ||
execho('git push ' + 'https://github.com/' + ref[0] + '/' + repoName + ' \'' + 'HEAD:' + ref[1] + '\''); | ||
process.exit(); | ||
case '-P': case 'Push': | ||
if (args.length < 4) { | ||
exit(usage); | ||
} | ||
ref = args[3].split(':'); | ||
if (ref.length !== 2) { | ||
exit(usage); | ||
}; | ||
execho('git push -f ' + 'https://github.com/' + ref[0] + '/' + repoName + ' \'' + 'HEAD:' + ref[1] + '\''); | ||
process.exit(); | ||
default: | ||
var prNumber = args[args.length - 1]; | ||
if (~~prNumber === 0) { exit(usage + '\n\n <pr> must be a number.'); } | ||
var path = path + '/' + prNumber; | ||
}; | ||
path += '/' + prNumber; | ||
} | ||
@@ -139,14 +212,14 @@ // https options | ||
exit('\n Couldn\'t read data.'); | ||
}; | ||
}; | ||
} | ||
} | ||
if (response.head.repo == null) { | ||
exit('\n Couldn\'t find source repo. It may have been deleted.'); | ||
}; | ||
} | ||
var remote = response.head.repo.clone_url + ' \'' + response.head.ref + '\''; | ||
}; | ||
} | ||
// Colors | ||
var reset = '\x1b[0m', red = '\x1b[31m#', green = '\x1b[32m', yellow = '\x1b[33m', | ||
blue = "\x1b[34m", magenta = "\x1b[35m", cyan = '\x1b[36m' | ||
blue = "\x1b[34m", magenta = "\x1b[35m", cyan = '\x1b[36m'; | ||
@@ -178,3 +251,3 @@ | ||
case 'pull': case '-p': | ||
case 'update': case 'pull': case '-u': | ||
execho('git pull ' + remote); | ||
@@ -181,0 +254,0 @@ break; |
{ | ||
"name": "git-pull-request", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "A cli utility to pull a remote branch based on a github PR number", | ||
@@ -9,4 +9,4 @@ "main": "index.js", | ||
}, | ||
"bin" : { | ||
"gpr" : "./gpr.js" | ||
"bin": { | ||
"gpr": "./gpr.js" | ||
}, | ||
@@ -32,3 +32,4 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/mbrookes/git-pull-request#readme" | ||
"homepage": "https://github.com/mbrookes/git-pull-request#readme", | ||
"dependencies": {} | ||
} |
@@ -1,20 +0,32 @@ | ||
## git-pull-request [![npm version](https://badge.fury.io/js/git-pull-request.svg)](https://badge.fury.io/js/git-pull-request) | ||
# git-pull-request [![npm version](https://badge.fury.io/js/git-pull-request.svg)](https://badge.fury.io/js/git-pull-request) | ||
A node based cli utility to pull a remote branch based on a github PR number | ||
### Installation | ||
##ls NB v2.x.x breaking change | ||
`-p` is now used to push, for `pull` (`update`), use `-u` | ||
## Installation | ||
`npm install -g git-pull-request` | ||
You must have [Node.js](https://nodejs.org) installed to use `gpr`. (You don't need to be using node or npm for your project.) | ||
You must have [Node.js](https://nodejs.org) installed to use `gpr`. | ||
(However, you don't need to be using node or npm for your project.) | ||
`gpr` reads your repository information from the `package.json` file for your project in the current directory, | ||
or an ancestor directory. If you don't have one, you can create one in the root of your project using this template: | ||
`gpr` reads your repository information from the either the git remotes named `upstream` or `origin` (in that order), | ||
or the `package.json` file if it is present. | ||
If you have neither a remote called "upstream" nor "origin", nor repository url in your `package.json` file, | ||
then you will need to configure git, or update your package.json: | ||
```json | ||
{ | ||
"repository": { | ||
"url": "git+https://github.com/your/repository.git" | ||
} | ||
} | ||
``` | ||
{"repository": {"url": "git+https://github.com/your/repository.git"}} | ||
``` | ||
Paste into package.json and edit the github URL. This isn't a fully formed package.json, but is sufficient for `gpr`. | ||
### Usage | ||
## Usage | ||
@@ -29,3 +41,3 @@ ``` | ||
[-p | pull] <pr#> Pull the remote branch for <pr#> to the current branch. | ||
[-u | update | pull] <pr#> Pull the remote branch for <pr#> to the current branch. | ||
[-f | force] <pr#> Force overwrite the local branch and checkout on a detached HEAD. | ||
@@ -35,2 +47,5 @@ [-b | branch] [<name>] <pr#> Create new branch [name] from master and pull. Defaults to 'gpr/<pr#>'. | ||
' [-p | push] <user:branch> Push the current branch or detached HEAD to the remote branch.\n' + | ||
' [-P | Push] <<user:branch> Force push the current branch or detached HEAD to the remote branch.\n' + | ||
[-d | delete] <pr#> Delete the gpr/<pr#> branch. | ||
@@ -42,3 +57,16 @@ [-D | Delete] <pr#> Force delete the gpr/<pr#> branch. | ||
<pr#> PR number to apply the command to. | ||
<pr#> PR number to apply the command to. | ||
``` | ||
### Example usage | ||
The simplest use case, this pulls the remote branch for PR # 123 to a detached HEAD | ||
```sh | ||
> grp 123 | ||
``` | ||
### Usage notes | ||
`gpr -p <user:branch>` can also be used to create a new branch on your own repo from a detached HEAD. :tada: |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
225
70
12545
5
2