git-story-workflow 1.5.0 → 1.6.0

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
  SHA256:
3
- metadata.gz: a3ca228230e6df3b78a7666b097cdfb126a3c304f58e437ea5f65cac3341eb1b
4
- data.tar.gz: 24ec3369789ef343dfd3040ba834ca7726605eab327cb9a0f7d4bad7d772d5fe
3
+ metadata.gz: 71a678629ab94d345b9362db3a9632978eecccf4a0b42074b8926a8caa8e7793
4
+ data.tar.gz: c709d15f03f8a751ec2c61626210ec240fbd5ab1e89b4cd314d9548499ab3284
5
5
  SHA512:
6
- metadata.gz: 5081071d98fd353fd9a9a6b6c14339b398d367eafb55509deaf9569871c58892c7d942ecef6eb7a8b989c58909e8dbf9c7c91c09a83bbe137845b52bfd135438
7
- data.tar.gz: b3358fddfce2f7233972397e9bc72091f99d5adb08f6a07bd519cca613103995d06a0fe9099939b9a584c60063c6a9659d0eb94a09701e8d7e3714358983ce99
6
+ metadata.gz: c1b06bbac8125456cb8095081affae06ee3105f3d157ae2b5f24f970d92072cac0b5aa129d6abde397fdf8d91e7040232673dbb43c55e46aebf30b8cddf66fc4
7
+ data.tar.gz: 03b2db927c695b5c16b1c0503ff26dbd570e4fe1e12317cf4dd69e3332c2329b2c8fe6c75709b8c4738bd6a4eec68b8dc71bf60c15728e9a163837f09457c734
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.5.0
1
+ 1.6.0
data/config/story.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  pivotal_token: <%= ENV['PIVOTAL_TOKEN'] %>
3
- pivotal_project: 123456789
3
+ pivotal_project: 1254912
4
4
  pivotal_reference_prefix: pivotal
5
5
  deploy_tag_prefix: production_deploy_
6
6
  semaphore_auth_token: <%= ENV['SEMAPHORE_AUTH_TOKEN'] %>
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: git-story-workflow 1.5.0 ruby lib
2
+ # stub: git-story-workflow 1.6.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "git-story-workflow".freeze
6
- s.version = "1.5.0"
6
+ s.version = "1.6.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2021-10-21"
11
+ s.date = "2021-11-15"
12
12
  s.description = "Gem abstracting a git workflow\u2026".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["git-story".freeze]
data/lib/git/story/app.rb CHANGED
@@ -100,31 +100,9 @@ class Git::Story::App
100
100
  end
101
101
  end
102
102
 
103
- def provide_name(story_id = nil)
104
- until story_id.present?
105
- story_id = ask(prompt: 'Story id? ').strip
106
- end
107
- story_id = story_id.gsub(/[^0-9]+/, '')
108
- @story_id = Integer(story_id)
109
- if stories.any? { |s| s.story_id == @story_id }
110
- @reason = "story for ##@story_id already created"
111
- return
112
- end
113
- if name = fetch_story_name(@story_id)
114
- name = normalize_name(
115
- name,
116
- max_size: 128 - 'story'.size - @story_id.to_s.size - 2 * ?_.size
117
- ).full? || name
118
- [ 'story', name, @story_id ] * ?_
119
- else
120
- @reason = "name for ##@story_id could not be fetched from tracker"
121
- return
122
- end
123
- end
124
-
125
103
  command doc: '[STORY_ID] fetch status of current story, -n SECONDS refreshes'
126
104
  def status(story_id = current(check: true)&.[](/_(\d+)\z/, 1)&.to_i)
127
- if story = fetch_story(story_id)
105
+ if story = fetch_story(story_id, with_owner: true)
128
106
  color_state =
129
107
  case cs = story.current_state
130
108
  when 'unscheduled', 'planned', 'unstarted'
@@ -147,20 +125,21 @@ class Git::Story::App
147
125
  else
148
126
  t
149
127
  end
150
- owners = Array(fetch_story_owners(story_id)).map { |o| "#{o.name} <#{o.email}>" }
151
128
  result = <<~end
152
129
  Id: #{(?# + story.id.to_s).green}
153
130
  Name: #{story.name.inspect.bold}
154
131
  Type: #{color_type}
155
132
  Estimate: #{story.estimate.to_s.full? { |e| e.yellow.bold } || 'n/a'}
156
133
  State: #{color_state}
157
- Branch: #{current_branch_checked?&.color('#ff5f00')}
158
134
  Labels: #{story.labels.map { |l| l.name.on_color(91) }.join(' ')}
159
- Owners: #{owners.join(', ').yellow}
135
+ Owners: #{story.owners.map { |o| "%s <%s>" % [ o.name, o.email ] }.join(', ').yellow}
160
136
  Pivotal: #{story.url.color(33)}
161
137
  end
162
- if url = github_url(current_branch_checked?)
163
- result << "Github: #{url.color(33)}\n"
138
+ if branch = current_branch_checked? and url = github_url(current_branch_checked?)
139
+ result << <<~end
140
+ Github: #{url.color(33)}
141
+ Branch: #{branch.color('#ff5f00')}
142
+ end
164
143
  end
165
144
  result
166
145
  end
@@ -234,18 +213,44 @@ class Git::Story::App
234
213
  fetch_statuses(pivotal_ids) * (?┄ * Tins::Terminal.cols << ?\n)
235
214
  end
236
215
 
237
- def fetch_statuses(pivotal_ids)
238
- tg = ThreadGroup.new
239
- pivotal_ids.each do |pid|
240
- tg.add Thread.new { Thread.current[:status] = status(pid) }
216
+ command doc: '[REF] Create some parts of deploy document'
217
+ def deploy_document(ref = default_ref, rest: [])
218
+ ref = build_ref_range(ref)
219
+ fetch_commits
220
+ fetch_tags
221
+ opts = ([
222
+ '--color=never',
223
+ '--pretty=%B'
224
+ ] | rest) * ' '
225
+ output = capture("git log #{opts} #{ref}")
226
+ pivotal_ids = SortedSet[]
227
+ output.scan(/\[\s*#\s*(\d+)\s*\]/) { pivotal_ids << $1.to_i }
228
+ stories = ''
229
+ attendees = Set[]
230
+ fetch_stories(pivotal_ids) do |pid|
231
+ story = fetch_story(pid, with_owner: true)
232
+ attendees.merge story.owners
233
+ stories << <<~end
234
+ • [##{story.id}] #{story.name}
235
+ ○ Pivotal: https://www.pivotaltracker.com/story/show/#{pid}
236
+ ○ Type: #{story.story_type}
237
+ ○ Status: #{story.current_state}
238
+ ○ Owners: #{story.owners.map { |o| "%s <%s>" % [ o.name, o.email ] }.join(', ')}
239
+ ○ Tasks to be done before deployment:
240
+ ☐ …
241
+ ○ Tasks to be done after deployment:
242
+ ☐ …
243
+ end
241
244
  end
242
- tg.list.with_infobar(label: 'Story').map do |t|
243
- +infobar
244
- t.join
245
- t[:status]
245
+ attendees.map! { |a| "• @#{a.email}" }
246
+ <<~end
247
+ #{attendees.join(?\n)}
248
+
249
+ #{stories}
246
250
  end
247
251
  end
248
252
 
253
+
249
254
  command doc: '[REF] output diff since last production deploy tag'
250
255
  def deploy_diff(ref = default_ref, rest: [])
251
256
  ref = build_ref_range(ref)
@@ -276,8 +281,8 @@ class Git::Story::App
276
281
  "Story #{name} created.".green
277
282
  end
278
283
 
279
- command doc: '[PATTERN] switch to story matching PATTERN'
280
- def switch(pattern = nil)
284
+ command doc: 'switch to selected story branch'
285
+ def switch
281
286
  fetch_commits
282
287
  if branch = pick_branch(prompt: 'Switch to story? %s')
283
288
  sh "git checkout #{branch}"
@@ -285,7 +290,7 @@ class Git::Story::App
285
290
  end
286
291
  end
287
292
 
288
- command doc: '[PATTERN] delete story branch matching PATTERN'
293
+ command doc: 'delete selected story branch'
289
294
  def delete(pattern = nil)
290
295
  fetch_commits
291
296
  if branch = pick_branch(prompt: 'Delete story branch? %s', symbol: ?⌦)
@@ -337,6 +342,28 @@ class Git::Story::App
337
342
 
338
343
  private
339
344
 
345
+ def provide_name(story_id = nil)
346
+ until story_id.present?
347
+ story_id = ask(prompt: 'Story id? ').strip
348
+ end
349
+ story_id = story_id.gsub(/[^0-9]+/, '')
350
+ @story_id = Integer(story_id)
351
+ if stories.any? { |s| s.story_id == @story_id }
352
+ @reason = "story for ##@story_id already created"
353
+ return
354
+ end
355
+ if name = fetch_story_name(@story_id)
356
+ name = normalize_name(
357
+ name,
358
+ max_size: 128 - 'story'.size - @story_id.to_s.size - 2 * ?_.size
359
+ ).full? || name
360
+ [ 'story', name, @story_id ] * ?_
361
+ else
362
+ @reason = "name for ##@story_id could not be fetched from tracker"
363
+ return
364
+ end
365
+ end
366
+
340
367
  def determine_command
341
368
  c, command = [], nil
342
369
  possible_commands = []
@@ -448,11 +475,6 @@ class Git::Story::App
448
475
  name
449
476
  end
450
477
 
451
- def apply_pattern(pattern, stories)
452
- pattern = pattern.gsub(?#, '')
453
- stories.grep(/#{Regexp.quote(pattern)}/)
454
- end
455
-
456
478
  def error(msg)
457
479
  puts msg.red
458
480
  exit 1
@@ -470,8 +492,10 @@ class Git::Story::App
470
492
  fetch_story(story_id)&.name
471
493
  end
472
494
 
473
- def fetch_story(story_id)
474
- pivotal_get("projects/#{pivotal_project}/stories/#{story_id}").full?
495
+ def fetch_story(story_id, with_owner: false)
496
+ story = pivotal_get("projects/#{pivotal_project}/stories/#{story_id}").full?
497
+ story.owners = Array((fetch_story_owners(story_id) if with_owner))
498
+ story
475
499
  end
476
500
 
477
501
  def fetch_story_owners(story_id)
@@ -586,4 +610,23 @@ class Git::Story::App
586
610
  url = url.sub('git@github.com:', 'https://github.com/')
587
611
  url = url.sub(/(\.git)\z/, "/tree/#{branch}")
588
612
  end
613
+
614
+ def fetch_stories(pivotal_ids, &block)
615
+ block or raise ArgumentError, '&block parameter is required'
616
+ tg = ThreadGroup.new
617
+ pivotal_ids.each do |pid|
618
+ tg.add Thread.new { Thread.current[:result] = block.(pid) }
619
+ end
620
+ tg.list.with_infobar(label: 'Story').map do |t|
621
+ t.join
622
+ +infobar
623
+ t[:result]
624
+ end
625
+ end
626
+
627
+ def fetch_statuses(pivotal_ids)
628
+ fetch_stories(pivotal_ids) do |pid|
629
+ status(pid)
630
+ end
631
+ end
589
632
  end
@@ -1,6 +1,6 @@
1
1
  module Git::Story
2
2
  # Git::Story version
3
- VERSION = '1.5.0'
3
+ VERSION = '1.6.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-story-workflow
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-10-21 00:00:00.000000000 Z
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar