sah 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 943298c329c6e3796b8831e50e8403212ea0dd4c
4
- data.tar.gz: a0a820abd2f289162d7431fb0fa1da7abe215a3f
3
+ metadata.gz: 1fb7a7617f52d704128e17c620b4835074e87b90
4
+ data.tar.gz: 7c3d6d3dcbd5730780f602e39434d9ad12061355
5
5
  SHA512:
6
- metadata.gz: 206ab03675d1edb8cb801a2fa2365dff6face301a1d64043654a19cdc04b25c783011855004566c5a31d190af940ba2141136330c54e9c9dd0a217eea711a623
7
- data.tar.gz: 1d0bc24733d03825741cf6cb71a2001228d6ab9ebf3066bc3f31d78321123e9c6565050a2bc3edaf90872b2b3295928199282ef4f153c69f9f969207acf5d7c1
6
+ metadata.gz: ad8ff3f7795b283f087839aefe3cf96225c335b0f4dd761f9194f974cbcb37310a0a94994744c7088332141d3a370bd0908f3136e1ef47a933a0e627dc64be15
7
+ data.tar.gz: 83f3ca44626f4353fb2c8fab5ed1a97b7bde94439cdd08f79eac4c2f44219ca76920df95cba34c7b62b325cb840566360f8825eae2823e09cc96216c54fda32c
data/README.md CHANGED
@@ -105,6 +105,12 @@ If you use multiple Bitbucket Server, define profile(s) and specify it.
105
105
  sah project PROJECT
106
106
  # show project detail
107
107
 
108
+ ### pull-request
109
+
110
+ sah pull-request
111
+ # create pull-request to upstream repository's default branch
112
+ # open $EDITOR to edit title and description
113
+
108
114
  ### repository
109
115
 
110
116
  sah repository PROJECT
@@ -115,10 +121,10 @@ If you use multiple Bitbucket Server, define profile(s) and specify it.
115
121
 
116
122
  ### upstream
117
123
 
118
- upstream
124
+ sah upstream
119
125
  # show upstream information
120
126
 
121
- upstream --add-remote [--fetch-pull-request] [--prevent-push]
127
+ sah upstream --add-remote [--fetch-pull-request] [--prevent-push]
122
128
  # add upstream to remote settings
123
129
 
124
130
  #### configutration
data/lib/sah/api.rb CHANGED
@@ -18,6 +18,12 @@ module Sah
18
18
  end
19
19
  end
20
20
 
21
+ def show_branches(project, repository)
22
+ @conn.get do |req|
23
+ req.url @config.url.path + "/rest/api/1.0/projects/#{project}/repos/#{repository}/branches"
24
+ end
25
+ end
26
+
21
27
  def fork_repository(project, repo, name=nil)
22
28
  body = {slug: repo}
23
29
  body = body.merge(name: name) if name
@@ -75,5 +81,41 @@ module Sah
75
81
  req.url @config.url.path + "/rest/api/1.0/projects/#{project}/repos/#{repository}"
76
82
  end
77
83
  end
84
+
85
+ def create_pull_request(source, target, title="", description="", reviewers=[])
86
+ @conn.post do |req|
87
+ req.url @config.url.path +
88
+ "/rest/api/1.0/projects/#{target[:project]}/repos/#{target[:repository]}/pull-requests"
89
+ req.headers['Content-Type'] = 'application/json'
90
+ req.body = {
91
+ title: title,
92
+ description: description,
93
+ state: "OPEN",
94
+ closed: false,
95
+ fromRef: {
96
+ id: "refs/heads/#{source[:branch]}",
97
+ repository: {
98
+ slug: source[:repository],
99
+ name: nil,
100
+ project: {
101
+ key: source[:project]
102
+ }
103
+ }
104
+ },
105
+ toRef: {
106
+ id: "refs/heads/#{target[:branch]}",
107
+ repository: {
108
+ slug: target[:repository],
109
+ name: nil,
110
+ project: {
111
+ key: target[:project]
112
+ }
113
+ }
114
+ },
115
+ locked: false,
116
+ reviewers: reviewers.map{ |r| { user: { name: r } } }
117
+ }.to_json
118
+ end
119
+ end
78
120
  end
79
121
  end
data/lib/sah/cli.rb CHANGED
@@ -3,6 +3,7 @@ require "thor"
3
3
  require "hirb"
4
4
  require "hirb-unicode"
5
5
  require "launchy"
6
+ require "tempfile"
6
7
 
7
8
  module Sah
8
9
  class CLI < Thor
@@ -202,6 +203,86 @@ module Sah
202
203
  end
203
204
  end
204
205
 
206
+ desc "pull-request", "Create pull request"
207
+ map %w(pr pull-request) => "pull_request"
208
+ long_desc <<-LONG_DESCRIPTION
209
+ sah pull-request
210
+ \x5# create pull-request to upstream repository's default branch
211
+ \x5# open $EDITOR to edit title and body
212
+
213
+ \x5sah pull-request [--source,-s PROJECT/REPOSITORY:BRANCH
214
+ \x5 [--target,-t PROJECT/REPOSITORY:BRANCH
215
+ \x5 [--message,-m MESSAGE]
216
+ \x5 [--reviewer,-r REVIEWER1 REVIEWER2 ...]
217
+ LONG_DESCRIPTION
218
+ method_option :source, aliases: "-s", desc: "Set source project/repository:branch"
219
+ method_option :target, aliases: "-t", desc: "Set target project/repository:branch"
220
+ method_option :title, desc: "Set title"
221
+ method_option :description, desc: "Set description"
222
+ method_option :reviewer,
223
+ aliases: "-r", type: :array, desc: "Set reviwer(s)"
224
+ def pull_request
225
+ source_project, source_repository, source_branch = nil, nil, nil
226
+ if options[:source]
227
+ m = options[:source].match(%r{^([^/:]+)/([^/:]+):([^/:]+)$})
228
+ if m.nil?
229
+ abort "Invalid format: --source #{options[:source]}"
230
+ end
231
+ source_project, source_repository, source_branch = $1, $2, $3
232
+ else
233
+ remote_url = `git config --get remote.origin.url`.chomp
234
+ remote_url.match %r%/([^/]+)/([^/]+?)(?:\.git)?$%
235
+ source_project, source_repository = $1, $2
236
+ source_branch = current_branch
237
+ end
238
+ source = {project: source_project, repository: source_repository,
239
+ branch: source_branch}
240
+
241
+ target_project, target_repository, target_branch = nil, nil, nil
242
+ if options[:target]
243
+ m = options[:target].match(%r{^([^/:]+)/([^/:]+):([^/:]+)$})
244
+ if m.nil?
245
+ abort "Invalid format: --target #{options[:target]}"
246
+ end
247
+ target_project, target_repository, target_branch = $1, $2, $3
248
+ else
249
+ upstream = upstream_repository
250
+ target_project = upstream["origin"]["project"]["key"]
251
+ target_repository = upstream["origin"]["slug"]
252
+ res = api.show_branches(target_project, target_repository)
253
+ if res.body.key? "errors"
254
+ abort res.body["errors"].first["message"]
255
+ end
256
+ branches = res.body
257
+ target_branch = branches["values"].find{|b| b["isDefault"] }["displayId"]
258
+ end
259
+ target = {project: target_project, repository: target_repository,
260
+ branch: target_branch}
261
+
262
+ puts "%s/%s:%s => %s/%s:%s" % [
263
+ source[:project], source[:repository], source[:branch],
264
+ target[:project], target[:repository], target[:branch],
265
+ ]
266
+
267
+ title = options[:title] || (
268
+ puts "Edit title... (press enter key)"
269
+ STDIN.gets
270
+ open_editor.strip
271
+ )
272
+ description = options[:description] || (
273
+ puts "Edit description... (press enter key)"
274
+ STDIN.gets
275
+ open_editor.strip
276
+ )
277
+ reviewers = options[:reviewer] || []
278
+
279
+ res = api.create_pull_request source, target, title, description, reviewers
280
+ if res.body.key? "errors"
281
+ abort res.body["errors"].first["message"]
282
+ end
283
+ puts res.body["links"]["self"].first["href"]
284
+ end
285
+
205
286
  desc "repository PROJECT[/REPOS]", "Show repository information"
206
287
  long_desc <<-LONG_DESCRIPTION
207
288
  sah repository PROJECT
@@ -242,22 +323,8 @@ module Sah
242
323
  method_option :"fetch-pull-request", desc: "Fetch pull requests"
243
324
  method_option :"prevent-push", desc: "Prevent push to upstream"
244
325
  def upstream
245
- remote_url = `git config --get remote.origin.url`.chomp
246
- remote_url.match %r%/([^/]+)/([^/]+?)(?:\.git)?$%
247
- project, repository = $1, $2
248
-
249
- res = api.show_repository(project, repository)
250
- if res.body.key? "errors"
251
- abort res.body["errors"].first["message"]
252
- end
253
-
254
- repository = res.body
255
- unless repository.key? "origin"
256
- abort "Upstream repos does not exist."
257
- end
258
-
259
326
  upstream_url =
260
- repository["origin"]["links"]["clone"].find{ |e| e["name"] == config.protocol }["href"]
327
+ upstream_repository["origin"]["links"]["clone"].find{ |e| e["name"] == config.protocol }["href"]
261
328
 
262
329
  if options[:"add-remote"]
263
330
  system "git", "remote", "add", "upstream", upstream_url
@@ -313,5 +380,34 @@ module Sah
313
380
  def api
314
381
  @api ||= API.new(config)
315
382
  end
383
+
384
+ def open_editor
385
+ tmp = Tempfile.new('sah')
386
+ editor = ENV['GIT_EDITOR'] || ENV['EDITOR'] || 'vi'
387
+ system(editor, tmp.path)
388
+ File.open(tmp.path).read
389
+ end
390
+
391
+ def current_branch
392
+ %x(/usr/local/bin/git rev-parse --abbrev-ref HEAD).chomp
393
+ end
394
+
395
+ def upstream_repository
396
+ remote_url = `git config --get remote.origin.url`.chomp
397
+ remote_url.match %r%/([^/]+)/([^/]+?)(?:\.git)?$%
398
+ project, repository = $1, $2
399
+
400
+ res = api.show_repository(project, repository)
401
+ if res.body.key? "errors"
402
+ abort res.body["errors"].first["message"]
403
+ end
404
+
405
+ repository = res.body
406
+ unless repository.key? "origin"
407
+ abort "Upstream repos does not exist."
408
+ end
409
+
410
+ repository
411
+ end
316
412
  end
317
413
  end
data/lib/sah/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sah
2
- VERSION = "0.0.6"
2
+ VERSION = "0.0.7"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sah
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
4
+ version: 0.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - f440
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2015-10-03 00:00:00.000000000 Z
11
+ date: 2015-10-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -207,9 +207,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
207
207
  version: '0'
208
208
  requirements: []
209
209
  rubyforge_project:
210
- rubygems_version: 2.4.5
210
+ rubygems_version: 2.4.5.1
211
211
  signing_key:
212
212
  specification_version: 4
213
213
  summary: Command line util for Atlassian Bitbucket Server
214
214
  test_files: []
215
- has_rdoc: