git-whistles 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +4 -4
- data/README.md +2 -0
- data/bin/git-chop +1 -0
- data/bin/git-jira-branch +6 -43
- data/bin/git-jira-pr +164 -0
- data/bin/git-list-branches +1 -0
- data/bin/git-merge-po +1 -0
- data/bin/git-stash-and-checkout +1 -0
- data/lib/git-whistles/jira.rb +62 -0
- data/lib/git-whistles/version.rb +1 -1
- metadata +6 -3
- data/bin/git-chop +0 -17
- data/bin/git-list-branches +0 -17
- data/bin/git-merge-po +0 -17
- data/bin/git-stash-and-checkout +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4304a8f417f4f756f4c2522288980894837415ce
|
4
|
+
data.tar.gz: d295f0cbd94e9d4dc09a3ab957928324809c122d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51ad1985a2f3fe9cf36a5eb55672f2a434d522407b0eed62e0fff7daeb1ccaed6ea0636700705b101f32cabddfac24309ef8ffd8059c4659503abc2e69f15e13
|
7
|
+
data.tar.gz: 754aa0292b9ad21327a127b9e1815854fd767f95e1f51b4b021f49ca4a944308a13880222b2791eceb12d4abe7d12833d07a119d070197a37e41df2db69d9513
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
git-whistles (1.0
|
4
|
+
git-whistles (1.1.0)
|
5
5
|
jira-ruby
|
6
6
|
pivotal-tracker (~> 0.5.6)
|
7
7
|
term-ansicolor
|
@@ -9,7 +9,7 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activesupport (4.2.5)
|
12
|
+
activesupport (4.2.5.1)
|
13
13
|
i18n (~> 0.7)
|
14
14
|
json (~> 1.7, >= 1.7.7)
|
15
15
|
minitest (~> 5.1)
|
@@ -20,7 +20,7 @@ GEM
|
|
20
20
|
crack (0.4.3)
|
21
21
|
safe_yaml (~> 1.0.0)
|
22
22
|
diff-lcs (1.2.5)
|
23
|
-
domain_name (0.5.
|
23
|
+
domain_name (0.5.20160128)
|
24
24
|
unf (>= 0.0.5, < 1.0.0)
|
25
25
|
http-cookie (1.0.2)
|
26
26
|
domain_name (~> 0.5)
|
@@ -79,7 +79,7 @@ GEM
|
|
79
79
|
thread_safe (~> 0.1)
|
80
80
|
unf (0.1.4)
|
81
81
|
unf_ext
|
82
|
-
unf_ext (0.0.7.
|
82
|
+
unf_ext (0.0.7.2)
|
83
83
|
|
84
84
|
PLATFORMS
|
85
85
|
ruby
|
data/README.md
CHANGED
@@ -17,6 +17,8 @@ Install with:
|
|
17
17
|
|
18
18
|
`git jira-branch <issue-id>` - Creates a branch name suggestion from the specified JIRA issue ID. It also writes the branch name as a comment on the issue and allows to transition the issue.
|
19
19
|
|
20
|
+
`git jira-pr [--from your-branch] [--to target-branch]` - Open your browser at a Github pull-request page for the specified branch (defaults to the current `head`). If you're using JIRA and your branch has a issue id in its name, populates your pull request with that issue details, else it just creates an empty Pull Request from the current HEAD.
|
21
|
+
|
20
22
|
`git latest-pushes [-n NR_RESULTS] [-p PATTERN]` - Show latest pushed branches to origin. Defaults to 20 results. Pattern is appended to refs/remotes/origin/ so include the team or project name to filter results.
|
21
23
|
|
22
24
|
`git list-branches [-l] [-r] [-i integration-branch]` - Colourful listing of all local or origin branches, and their distance to an integration branch (`master` by default).
|
data/bin/git-chop
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
../libexec/runner.rb
|
data/bin/git-jira-branch
CHANGED
@@ -14,11 +14,15 @@ require 'jira'
|
|
14
14
|
require 'readline'
|
15
15
|
require 'term/ansicolor'
|
16
16
|
require 'git-whistles/app'
|
17
|
+
require 'git-whistles/jira'
|
17
18
|
|
18
19
|
class App < Git::Whistles::App
|
19
20
|
|
20
21
|
def initialize
|
21
22
|
super
|
23
|
+
|
24
|
+
@jira = Git::Whistles::Jira.new
|
25
|
+
@client = @jira.get_client
|
22
26
|
end
|
23
27
|
|
24
28
|
def main(args)
|
@@ -34,7 +38,7 @@ class App < Git::Whistles::App
|
|
34
38
|
# get JIRA Issue info
|
35
39
|
issue = get_jira_info(issue_id)
|
36
40
|
|
37
|
-
branch_name_suggested = "#{issue_id.upcase}
|
41
|
+
branch_name_suggested = "#{issue_id.upcase}/#{issue.fields['summary'].downcase}"
|
38
42
|
branch_name_suggested.gsub!(/[^\w\d\/]/, '-').gsub!(/-+/, '-')
|
39
43
|
|
40
44
|
puts 'The suggested branch name is: ' << Term::ANSIColor.yellow(branch_name_suggested)
|
@@ -105,50 +109,9 @@ class App < Git::Whistles::App
|
|
105
109
|
end
|
106
110
|
|
107
111
|
def get_jira_info(issue_id)
|
108
|
-
if username.empty?
|
109
|
-
puts Term::ANSIColor.yellow %Q{
|
110
|
-
Your branch appears to have a issue ID,
|
111
|
-
but I don't know your JIRA username!
|
112
|
-
Please set it with:
|
113
|
-
$ git config [--global] jira.username <username>
|
114
|
-
}
|
115
|
-
die "Aborting."
|
116
|
-
end
|
117
|
-
|
118
|
-
password = `git config jira.password`.strip
|
119
|
-
if password.empty?
|
120
|
-
puts Term::ANSIColor.yellow %Q{
|
121
|
-
Your branch appears to have a issue ID,
|
122
|
-
but I don't know your JIRA password!
|
123
|
-
Please set it with:
|
124
|
-
$ git config [--global] jira.password <password>
|
125
|
-
}
|
126
|
-
die "Aborting."
|
127
|
-
end
|
128
|
-
|
129
|
-
site = `git config jira.site`.strip
|
130
|
-
if site.empty?
|
131
|
-
puts Term::ANSIColor.yellow %Q{
|
132
|
-
Your branch appears to have a issue ID,
|
133
|
-
but I don't know your JIRA site!
|
134
|
-
Please set it with:
|
135
|
-
$ git config [--global] jira.site <https://mydomain.atlassian.net>
|
136
|
-
}
|
137
|
-
die "Aborting."
|
138
|
-
end
|
139
112
|
log.info "Finding your JIRA Issue¬"
|
140
113
|
|
141
|
-
|
142
|
-
username: username,
|
143
|
-
password: password,
|
144
|
-
site: site,
|
145
|
-
context_path: '',
|
146
|
-
auth_type: :basic,
|
147
|
-
read_timeout: 120
|
148
|
-
}
|
149
|
-
|
150
|
-
client = JIRA::Client.new(options)
|
151
|
-
issue = client.Issue.find(issue_id)
|
114
|
+
issue = @client.Issue.find(issue_id)
|
152
115
|
|
153
116
|
log.info '.'
|
154
117
|
log.info "Found issue #{issue_id} in '#{issue.fields['project']['name']}'"
|
data/bin/git-jira-pr
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: UTF-8
|
3
|
+
#
|
4
|
+
# git-jira-pr --
|
5
|
+
#
|
6
|
+
# Open a pull request for the current branch in your default browser
|
7
|
+
#
|
8
|
+
# Assumes the branches are named
|
9
|
+
# <team>/<branch-title>-<story-id>
|
10
|
+
#
|
11
|
+
require 'rubygems'
|
12
|
+
require 'jira'
|
13
|
+
require 'optparse'
|
14
|
+
require 'cgi'
|
15
|
+
require 'term/ansicolor'
|
16
|
+
require 'git-whistles/app'
|
17
|
+
require 'git-whistles/jira'
|
18
|
+
|
19
|
+
class App < Git::Whistles::App
|
20
|
+
|
21
|
+
BROWSERS = %w(xdg-open open firefox iceweasel)
|
22
|
+
SAFE_QUERY_STRING_SIZE = 8000
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
super
|
26
|
+
|
27
|
+
@client = Git::Whistles::Jira.new.get_client
|
28
|
+
end
|
29
|
+
|
30
|
+
def main(args)
|
31
|
+
super
|
32
|
+
parse_args!(args)
|
33
|
+
|
34
|
+
if args.count > 0
|
35
|
+
die "Too many arguments", :usage => true
|
36
|
+
end
|
37
|
+
|
38
|
+
if options.from == options.to
|
39
|
+
die "You cannot issue a pull request to the same branch (#{options.from})."
|
40
|
+
end
|
41
|
+
|
42
|
+
query = { }
|
43
|
+
|
44
|
+
# guess team name
|
45
|
+
if options.from =~ %r{^(\w+-\w+)/.*}
|
46
|
+
team, issue_id = $1.capitalize.split('-')
|
47
|
+
else
|
48
|
+
issue_id = team = nil
|
49
|
+
end
|
50
|
+
|
51
|
+
# guess title.
|
52
|
+
title = options.from.split('/').last.split(/[_-]/).delete_if { |word| word =~ /^\d+$/ }.join(' ').capitalize
|
53
|
+
query[:"pull_request[title]"] = team ? "#{team}: #{title}" : title
|
54
|
+
|
55
|
+
# add Jira infos
|
56
|
+
add_jira_info(query, "#{team}-#{issue_id}".upcase) if issue_id =~ /(\d+)$/
|
57
|
+
|
58
|
+
query_string = query.map { |key,value|
|
59
|
+
"#{CGI.escape key.to_s}=#{CGI.escape value}"
|
60
|
+
}.join('&')
|
61
|
+
url = "https://github.com/#{repo}/compare/#{options.to}...#{options.from}?#{query_string}"
|
62
|
+
|
63
|
+
puts "Preparing a pull request for branch #{options.from}"
|
64
|
+
|
65
|
+
unless launch_browser(url)
|
66
|
+
log.warn "Sorry, I don't know how to launch a web browser on your system. You can open it yourself and paste this URL:\n#{url}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def defaults
|
73
|
+
{
|
74
|
+
:from => run!('git symbolic-ref HEAD').strip.gsub(%r(^refs/heads/), ""),
|
75
|
+
:to => 'master',
|
76
|
+
:remote => 'origin'
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
def option_parser
|
81
|
+
@option_parser ||= OptionParser.new do |op|
|
82
|
+
op.banner = "Usage: git jira-pr [options]"
|
83
|
+
|
84
|
+
op.on("-f", "--from YOUR_BRANCH", "Branch to issue pull request for [head]") do |v|
|
85
|
+
options.from = v
|
86
|
+
end
|
87
|
+
|
88
|
+
op.on("-to", "--to UPSTREAM_BRANCH", "Branch into which you want your code merged [master]") do |v|
|
89
|
+
options.to = v
|
90
|
+
end
|
91
|
+
|
92
|
+
op.on("-r", "--remote NAME", "The remote you're sending this to [origin]") do |v|
|
93
|
+
options.to = v
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def origin_url
|
99
|
+
@origin_url ||= begin
|
100
|
+
run!("git config --get remote.#{options.remote}.url").strip.tap do |url|
|
101
|
+
url =~ /github\.com/ or die "origin does not have a Github URL !"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def repo
|
107
|
+
@repo ||= origin_url.sub(/.*github\.com[\/:]/,'').sub(/\.git$/,'')
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_jira_info(query, issue_id)
|
111
|
+
log.info "Finding your Jira Issue¬"
|
112
|
+
|
113
|
+
issue = @client.Issue.find(issue_id)
|
114
|
+
log.info '.'
|
115
|
+
|
116
|
+
if issue.nil?
|
117
|
+
log.warn "Apologies... I could not find issue #{issue_id}."
|
118
|
+
return
|
119
|
+
end
|
120
|
+
|
121
|
+
log.info "Found story #{issue_id} in '#{issue.fields['project']['name']}'"
|
122
|
+
|
123
|
+
title = "#{issue_id}: #{issue.summary}"
|
124
|
+
headline = "Jira story [##{issue_id}](#{@client.options[:site]}/browse/#{issue_id}) in project *#{issue.project.name}*:"
|
125
|
+
description = issue.description.split("\n").map do |line|
|
126
|
+
(1..6).each { |i| line.gsub!(/(h#{i}.)/, '#' * i) }
|
127
|
+
line.gsub!(/({{)|(}})/, '`')
|
128
|
+
"> #{line}"
|
129
|
+
end.join("\n")
|
130
|
+
|
131
|
+
query.merge! subject: issue.summary, :"pull_request[title]" => title
|
132
|
+
|
133
|
+
if (headline.length + description.length) > SAFE_QUERY_STRING_SIZE
|
134
|
+
log.warn "Oops looks like your story body exceeds maximum allowed caracters to send a github request"
|
135
|
+
log.warn "Please copy the info below to your pull request body:"
|
136
|
+
puts
|
137
|
+
puts headline
|
138
|
+
puts
|
139
|
+
puts
|
140
|
+
puts description
|
141
|
+
puts
|
142
|
+
puts
|
143
|
+
puts "Press any key to continue..."
|
144
|
+
gets
|
145
|
+
query.merge! :"pull_request[body]" => "Please check your command line for the story body"
|
146
|
+
else
|
147
|
+
body = "TODO: describe your changes\n\n===\n\n#{headline}\n\n#{description}"
|
148
|
+
query.merge! :"pull_request[body]" => body
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def launch_browser(url)
|
153
|
+
BROWSERS.each do |command|
|
154
|
+
next if run("which #{command}").strip.empty?
|
155
|
+
system(command, url) and return true
|
156
|
+
end
|
157
|
+
false
|
158
|
+
end
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
############################################################################
|
163
|
+
|
164
|
+
App.run!
|
@@ -0,0 +1 @@
|
|
1
|
+
../libexec/runner.rb
|
data/bin/git-merge-po
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
../libexec/runner.rb
|
@@ -0,0 +1 @@
|
|
1
|
+
../libexec/runner.rb
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Git
|
2
|
+
module Whistles
|
3
|
+
class Jira
|
4
|
+
attr_reader :username, :password, :site
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
get_config
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_client(opts = {})
|
11
|
+
options = {
|
12
|
+
username: @username,
|
13
|
+
password: @password,
|
14
|
+
site: @site,
|
15
|
+
context_path: '',
|
16
|
+
auth_type: :basic,
|
17
|
+
read_timeout: 120
|
18
|
+
}
|
19
|
+
|
20
|
+
options.merge!(opts)
|
21
|
+
|
22
|
+
JIRA::Client.new(options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_config
|
26
|
+
@username = `git config jira.username`.strip
|
27
|
+
if username.empty?
|
28
|
+
puts Term::ANSIColor.yellow %Q{
|
29
|
+
Your branch appears to have a issue ID,
|
30
|
+
but I don't know your JIRA username!
|
31
|
+
Please set it with:
|
32
|
+
$ git config [--global] jira.username <username>
|
33
|
+
}
|
34
|
+
die "Aborting."
|
35
|
+
end
|
36
|
+
|
37
|
+
@password = `git config jira.password`.strip
|
38
|
+
if password.empty?
|
39
|
+
puts Term::ANSIColor.yellow %Q{
|
40
|
+
Your branch appears to have a issue ID,
|
41
|
+
but I don't know your JIRA password!
|
42
|
+
Please set it with:
|
43
|
+
$ git config [--global] jira.password <password>
|
44
|
+
}
|
45
|
+
die "Aborting."
|
46
|
+
end
|
47
|
+
|
48
|
+
@site = `git config jira.site`.strip
|
49
|
+
if site.empty?
|
50
|
+
puts Term::ANSIColor.yellow %Q{
|
51
|
+
Your branch appears to have a issue ID,
|
52
|
+
but I don't know your JIRA site!
|
53
|
+
Please set it with:
|
54
|
+
$ git config [--global] jira.site <https://mydomain.atlassian.net>
|
55
|
+
}
|
56
|
+
die "Aborting."
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/git-whistles/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-whistles
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julien Letessier
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-02-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -131,6 +131,7 @@ executables:
|
|
131
131
|
- git-explore
|
132
132
|
- git-ff-all-branches
|
133
133
|
- git-jira-branch
|
134
|
+
- git-jira-pr
|
134
135
|
- git-latest-pushes
|
135
136
|
- git-list-branches
|
136
137
|
- git-merge-po
|
@@ -155,6 +156,7 @@ files:
|
|
155
156
|
- bin/git-explore
|
156
157
|
- bin/git-ff-all-branches
|
157
158
|
- bin/git-jira-branch
|
159
|
+
- bin/git-jira-pr
|
158
160
|
- bin/git-latest-pushes
|
159
161
|
- bin/git-list-branches
|
160
162
|
- bin/git-merge-po
|
@@ -168,6 +170,7 @@ files:
|
|
168
170
|
- lib/git-whistles.rb
|
169
171
|
- lib/git-whistles/app.rb
|
170
172
|
- lib/git-whistles/helpers.rb
|
173
|
+
- lib/git-whistles/jira.rb
|
171
174
|
- lib/git-whistles/logger.rb
|
172
175
|
- lib/git-whistles/version.rb
|
173
176
|
- libexec/git-chop.sh
|
@@ -200,7 +203,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
203
|
version: 1.3.6
|
201
204
|
requirements: []
|
202
205
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.
|
206
|
+
rubygems_version: 2.5.1
|
204
207
|
signing_key:
|
205
208
|
specification_version: 4
|
206
209
|
summary: 'A few helpers for classic Git workflows: makes branching and merging, PO
|
data/bin/git-chop
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
#
|
4
|
-
# runner.rb --
|
5
|
-
#
|
6
|
-
# Run shell scripts from a gem.
|
7
|
-
# Symlink to this script to run a script with the same name living in
|
8
|
-
# libexec/.
|
9
|
-
#
|
10
|
-
require 'pathname'
|
11
|
-
require 'rubygems'
|
12
|
-
require 'git-whistles'
|
13
|
-
|
14
|
-
target_script = Pathname.new($0).basename
|
15
|
-
script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath.to_s
|
16
|
-
|
17
|
-
Kernel.exec script_path, *ARGV
|
data/bin/git-list-branches
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
#
|
4
|
-
# runner.rb --
|
5
|
-
#
|
6
|
-
# Run shell scripts from a gem.
|
7
|
-
# Symlink to this script to run a script with the same name living in
|
8
|
-
# libexec/.
|
9
|
-
#
|
10
|
-
require 'pathname'
|
11
|
-
require 'rubygems'
|
12
|
-
require 'git-whistles'
|
13
|
-
|
14
|
-
target_script = Pathname.new($0).basename
|
15
|
-
script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath.to_s
|
16
|
-
|
17
|
-
Kernel.exec script_path, *ARGV
|
data/bin/git-merge-po
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
#
|
4
|
-
# runner.rb --
|
5
|
-
#
|
6
|
-
# Run shell scripts from a gem.
|
7
|
-
# Symlink to this script to run a script with the same name living in
|
8
|
-
# libexec/.
|
9
|
-
#
|
10
|
-
require 'pathname'
|
11
|
-
require 'rubygems'
|
12
|
-
require 'git-whistles'
|
13
|
-
|
14
|
-
target_script = Pathname.new($0).basename
|
15
|
-
script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath.to_s
|
16
|
-
|
17
|
-
Kernel.exec script_path, *ARGV
|
data/bin/git-stash-and-checkout
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# encoding: UTF-8
|
3
|
-
#
|
4
|
-
# runner.rb --
|
5
|
-
#
|
6
|
-
# Run shell scripts from a gem.
|
7
|
-
# Symlink to this script to run a script with the same name living in
|
8
|
-
# libexec/.
|
9
|
-
#
|
10
|
-
require 'pathname'
|
11
|
-
require 'rubygems'
|
12
|
-
require 'git-whistles'
|
13
|
-
|
14
|
-
target_script = Pathname.new($0).basename
|
15
|
-
script_path = Git::Whistles::GEMDIR.join('libexec', "#{target_script}.sh").cleanpath.to_s
|
16
|
-
|
17
|
-
Kernel.exec script_path, *ARGV
|