git-story-workflow 0.11.0 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c437719bf4e7298ee339477a48e37e6652a028876c7c1ef524953a24792b4099
4
- data.tar.gz: 2dfe54728f5d8ad1d0655ad6e9c1706e905ae952af8678812002bb2fc6b20f46
3
+ metadata.gz: 7db0a45891bcce9a80051da5c583b30218ef6ad2881006440c6995e6ba95ad40
4
+ data.tar.gz: abcb5921d4d65d818c39ff0ee8af5c77e8b3fd517506db141e0c25e8cd1ca8ac
5
5
  SHA512:
6
- metadata.gz: d32bb92036c60fbea1492caa8c79fc211d96aa60adc389386d9e8ed585d3613c8a3abf8562c19fafdf68450a6a21a3b4ff297a0df94ac111ff7a5317aa3b1942
7
- data.tar.gz: 571614a5c236d81ea10bbe3628ff5bbf2812d6d1b2f68b479fcb2c0d02c6b2c55d54cbb367e3b3bf49592c8ef4e5b03cbc58f8098df6e7f276d018716135b85c
6
+ metadata.gz: e69e2cfd05235940649f29100fa36acfb3edfec918c673e7a79f5468b1ee529db3a54c9d00cd0eca3e0cec12df0578b6b185cef6e45fe0af747664eac897a7f9
7
+ data.tar.gz: 13f82228787833511601d676f2a648d3e0cc00f31b6462794a8f99c062309cbfd66e362d4647e24c8d70154a0f0e651c3c463881e726f8f2f22c61aa9de432f0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.11.0
1
+ 1.1.0
@@ -1,23 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: git-story-workflow 0.11.0 ruby lib
2
+ # stub: git-story-workflow 1.1.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "git-story-workflow".freeze
6
- s.version = "0.11.0"
6
+ s.version = "1.1.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 = "2020-02-28"
11
+ s.date = "2020-11-27"
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]
15
- s.extra_rdoc_files = ["README.md".freeze, "lib/git/story.rb".freeze, "lib/git/story/app.rb".freeze, "lib/git/story/semaphore.rb".freeze, "lib/git/story/setup.rb".freeze, "lib/git/story/utils.rb".freeze, "lib/git/story/version.rb".freeze]
16
- s.files = [".gitignore".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/git-story".freeze, "config/story.yml".freeze, "git-story-workflow.gemspec".freeze, "lib/git/story.rb".freeze, "lib/git/story/app.rb".freeze, "lib/git/story/prepare-commit-msg".freeze, "lib/git/story/semaphore.rb".freeze, "lib/git/story/setup.rb".freeze, "lib/git/story/utils.rb".freeze, "lib/git/story/version.rb".freeze, "spec/git/story/app_spec.rb".freeze, "spec/spec_helper.rb".freeze]
15
+ s.extra_rdoc_files = ["README.md".freeze, "lib/git/story.rb".freeze, "lib/git/story/app.rb".freeze, "lib/git/story/setup.rb".freeze, "lib/git/story/utils.rb".freeze, "lib/git/story/version.rb".freeze]
16
+ s.files = [".gitignore".freeze, "COPYING".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/git-story".freeze, "config/story.yml".freeze, "git-story-workflow.gemspec".freeze, "lib/git/story.rb".freeze, "lib/git/story/app.rb".freeze, "lib/git/story/pre-push".freeze, "lib/git/story/prepare-commit-msg".freeze, "lib/git/story/setup.rb".freeze, "lib/git/story/utils.rb".freeze, "lib/git/story/version.rb".freeze, "spec/git/story/app_spec.rb".freeze, "spec/spec_helper.rb".freeze]
17
17
  s.homepage = "http://flori.github.com/git-story-workflow".freeze
18
18
  s.licenses = ["Apache-2.0".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "Git-story-workflow".freeze, "--main".freeze, "README.md".freeze]
20
- s.rubygems_version = "3.1.2".freeze
20
+ s.rubygems_version = "3.1.4".freeze
21
21
  s.summary = "Gem abstracting a git workflow".freeze
22
22
  s.test_files = ["spec/git/story/app_spec.rb".freeze, "spec/spec_helper.rb".freeze]
23
23
 
@@ -21,5 +21,4 @@ end
21
21
  require 'git/story/version'
22
22
  require 'git/story/utils'
23
23
  require 'git/story/setup'
24
- require 'git/story/semaphore'
25
24
  require 'git/story/app'
@@ -36,13 +36,13 @@ class Git::Story::App
36
36
  def initialize(argv = ARGV.dup, debug: ENV['DEBUG'].to_i == 1)
37
37
  @rest_argv = (sep = argv.index('--')) ? argv.slice!(sep..-1).tap(&:shift) : []
38
38
  @argv = argv
39
- @opts = go 'n:', @argv
40
- @command = @argv.shift&.to_sym
41
- @debug = debug
39
+ @opts = go 'n:', @argv
40
+ @debug = debug
41
+ determine_command
42
+ Git::Story::Setup.perform
42
43
  end
43
44
 
44
45
  def run
45
- Git::Story::Setup.perform
46
46
  if command_of(@command)
47
47
  if method(@command).parameters.include?(%i[key rest])
48
48
  puts __send__(@command, *@argv, rest: @rest_argv)
@@ -50,8 +50,11 @@ class Git::Story::App
50
50
  puts __send__(@command, *@argv)
51
51
  end
52
52
  else
53
- @command and @command = @command.inspect
54
- @command ||= 'n/a'
53
+ if @command
54
+ @command = @command.inspect
55
+ else
56
+ @command = 'n/a'
57
+ end
55
58
  STDERR.puts "Unknown command #{@command}\n\n#{help.join(?\n)}"
56
59
  exit 1
57
60
  end
@@ -64,7 +67,7 @@ class Git::Story::App
64
67
  longest = command_annotations.keys.map(&:size).max
65
68
  result.concat(
66
69
  command_annotations.map { |name, a|
67
- "#{name.to_s.ljust(longest)} #{a[:doc]}"
70
+ "#{name.to_s.gsub(?_, ' ').ljust(longest)} #{a[:doc]}"
68
71
  }
69
72
  )
70
73
  end
@@ -104,62 +107,6 @@ class Git::Story::App
104
107
  end
105
108
  end
106
109
 
107
- command doc: '[BRANCH] display test status of branch, -n SECONDS refreshes'
108
- def test_status(branch = current(check: false))
109
- url = nil
110
- watch do
111
- auth_token = complex_config.story.semaphore_auth_token
112
- project = complex_config.story.semaphore_test_project
113
- url = "https://semaphoreci.com/api/v1/projects/#{project}/#{branch}/status?auth_token=#{auth_token}"
114
- Git::Story::SemaphoreResponse.get(url, debug: @debug)
115
- end
116
- rescue => e
117
- "Getting #{url.inspect} => #{e.class}: #{e}".red
118
- end
119
-
120
- command doc: '[SERVER] display deploy status of branch, -n SECONDS refreshes'
121
- def deploy_status(server = complex_config.story.semaphore_default_server)
122
- url = nil
123
- watch do
124
- auth_token = complex_config.story.semaphore_auth_token
125
- project = complex_config.story.semaphore_test_project
126
- url = "https://semaphoreci.com/api/v1/projects/#{project}/servers/#{server}?auth_token=#{auth_token}"
127
- server = Git::Story::SemaphoreResponse.get(url, debug: @debug)
128
- deploys = server.deploys
129
- upcoming = deploys.select(&:pending?)&.last
130
- passed = deploys.select(&:passed?)
131
- current = passed.first
132
- if !passed.empty? && upcoming
133
- upcoming.estimated_duration = passed.sum { |d| d.duration.to_f } / passed.size
134
- end
135
- <<~end
136
- Server: #{server.server_name&.green}
137
- Branch: #{server.branch_name&.color('#ff5f00')}
138
- Semaphore: #{server.server_url}
139
- Strategy: #{server.strategy}
140
- Upcoming:
141
- #{upcoming}
142
- Current:
143
- #{current}
144
- end
145
- end
146
- rescue => e
147
- "Getting #{url.inspect} => #{e.class}: #{e}".red
148
- end
149
-
150
- command doc: '[BRANCH] display build status for branch, -n SECONDS refreshes'
151
- def build_status(branch = current(check: false))
152
- watch do
153
- [
154
- "Test Status".bold,
155
- test_status(branch) || 'n/a',
156
- "Deploy Status".bold,
157
- deploy_status || 'n/a',
158
- ] * "\n\n"
159
- end
160
- end
161
-
162
-
163
110
  command doc: '[STORY_ID] fetch status of current story, -n SECONDS refreshes'
164
111
  def status(story_id = current(check: true)&.[](/_(\d+)\z/, 1)&.to_i)
165
112
  if story = fetch_story(story_id)
@@ -355,6 +302,23 @@ class Git::Story::App
355
302
 
356
303
  private
357
304
 
305
+ def determine_command
306
+ c, command = [], nil
307
+ possible_commands = []
308
+ until @argv.empty?
309
+ c << @argv.shift
310
+ command = c.join(?_).to_sym
311
+ if command_of(command)
312
+ possible_commands << [ command, @argv.dup ]
313
+ end
314
+ end
315
+ unless possible_commands.empty?
316
+ @command, argv = possible_commands.last
317
+ @argv.replace(argv)
318
+ end
319
+ self
320
+ end
321
+
358
322
  def pick_branch(prompt:, symbol: ?⏻)
359
323
  ss = stories.map(&:story_base_name)
360
324
  branch = Search.new(
@@ -0,0 +1,35 @@
1
+ #!/bin/sh
2
+ # Installed by the git-story gem
3
+
4
+ remote="$1"
5
+ url="$2"
6
+
7
+ z40=0000000000000000000000000000000000000000
8
+
9
+ while read local_ref local_sha remote_ref remote_sha
10
+ do
11
+ if [ "$local_sha" = $z40 ]
12
+ then
13
+ # Handle delete
14
+ :
15
+ else
16
+ if [ "$remote_sha" = $z40 ]
17
+ then
18
+ # New branch, examine all commits
19
+ range="$local_sha"
20
+ else
21
+ # Update to existing branch, examine new commits
22
+ range="$remote_sha..$local_sha"
23
+ fi
24
+
25
+ # Check for WIP or [TODO] commit
26
+ commit=`git rev-list -n 1 --pretty=%B "$range" | egrep -i 'WIP|\[TODO\]'`
27
+ if [ -n "$commit" -a "$FORCE" != "1" ]
28
+ then
29
+ echo >&2 "Found WIP / [TODO] commit in $local_ref, not pushing"
30
+ exit 1
31
+ fi
32
+ fi
33
+ done
34
+
35
+ exit 0
@@ -11,30 +11,38 @@ module Git::Story::Setup
11
11
  module_function
12
12
 
13
13
  def perform(force: false)
14
- pcm = PREPARE_COMMIT_MESSAGE_DST
15
- if File.exist?(pcm)
16
- if force
17
- install_prepare_commit_msg
18
- elsif File.read(pcm).match?(MARKER)
19
- ;
20
- else
21
- ask(
22
- prompt: "File #{pcm.inspect} not created by git-story."\
23
- " Overwrite? (y/n, default is %s)",
24
- default: ?n,
25
- ) do |response|
26
- if response == ?y
27
- install_prepare_commit_msg
14
+ for filename in %w[ prepare-commit-msg pre-push ]
15
+ if path = file_installed?(filename)
16
+ if force
17
+ install_file filename
18
+ elsif File.read(path).match?(MARKER)
19
+ ;
20
+ else
21
+ ask(
22
+ prompt: "File #{path.inspect} not created by git-story."\
23
+ " Overwrite? (y/n, default is %s) ",
24
+ default: ?n,
25
+ ) do |response|
26
+ if response == ?y
27
+ install_file filename
28
+ end
28
29
  end
29
30
  end
31
+ else
32
+ install_file filename
30
33
  end
31
- else
32
- install_prepare_commit_msg
33
34
  end
34
35
  end
35
36
 
36
- def install_prepare_commit_msg
37
+ def file_installed?(filename)
38
+ path = File.join(HOOKS_DIR, filename)
39
+ if File.exist?(path)
40
+ path
41
+ end
42
+ end
43
+
44
+ def install_file(filename)
37
45
  File.exist?(HOOKS_DIR) or mkdir_p(HOOKS_DIR)
38
- cp PREPARE_COMMIT_MESSAGE_SRC, PREPARE_COMMIT_MESSAGE_DST
46
+ cp File.join(__dir__, filename), File.join(HOOKS_DIR, filename)
39
47
  end
40
48
  end
@@ -1,6 +1,6 @@
1
1
  module Git::Story
2
2
  # Git::Story version
3
- VERSION = '0.11.0'
3
+ VERSION = '1.1.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: 0.11.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-28 00:00:00.000000000 Z
11
+ date: 2020-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar
@@ -159,7 +159,6 @@ extra_rdoc_files:
159
159
  - README.md
160
160
  - lib/git/story.rb
161
161
  - lib/git/story/app.rb
162
- - lib/git/story/semaphore.rb
163
162
  - lib/git/story/setup.rb
164
163
  - lib/git/story/utils.rb
165
164
  - lib/git/story/version.rb
@@ -175,8 +174,8 @@ files:
175
174
  - git-story-workflow.gemspec
176
175
  - lib/git/story.rb
177
176
  - lib/git/story/app.rb
177
+ - lib/git/story/pre-push
178
178
  - lib/git/story/prepare-commit-msg
179
- - lib/git/story/semaphore.rb
180
179
  - lib/git/story/setup.rb
181
180
  - lib/git/story/utils.rb
182
181
  - lib/git/story/version.rb
@@ -186,7 +185,7 @@ homepage: http://flori.github.com/git-story-workflow
186
185
  licenses:
187
186
  - Apache-2.0
188
187
  metadata: {}
189
- post_install_message:
188
+ post_install_message:
190
189
  rdoc_options:
191
190
  - "--title"
192
191
  - Git-story-workflow
@@ -205,8 +204,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
204
  - !ruby/object:Gem::Version
206
205
  version: '0'
207
206
  requirements: []
208
- rubygems_version: 3.1.2
209
- signing_key:
207
+ rubygems_version: 3.1.4
208
+ signing_key:
210
209
  specification_version: 4
211
210
  summary: Gem abstracting a git workflow
212
211
  test_files:
@@ -1,141 +0,0 @@
1
- require 'json'
2
- require 'time'
3
- require 'open-uri'
4
- require 'infobar'
5
-
6
- class Git::Story::SemaphoreResponse < JSON::GenericObject
7
- def self.get(url, debug: false)
8
- data = URI.open(url).read
9
- debug and STDERR.puts JSON.pretty_generate(JSON(data))
10
- result = JSON(data, object_class: self)
11
- result.debug = debug
12
- result
13
- end
14
-
15
- def duration(time = nil)
16
- unless time
17
- if finished_at.nil?
18
- time = Time.now
19
- else
20
- time = Time.parse(finished_at)
21
- end
22
- end
23
- if started_at
24
- Tins::Duration.new(time - Time.parse(started_at))
25
- else
26
- Tins::Duration.new(0)
27
- end
28
- end
29
-
30
- def pending?
31
- result == 'pending'
32
- end
33
-
34
- def building?
35
- !started_at.nil?
36
- end
37
-
38
- def passed?
39
- result == 'passed'
40
- end
41
-
42
- def failed?
43
- result == 'failed'
44
- end
45
-
46
- def canceled?
47
- result == 'canceled'
48
- end
49
-
50
- def finished?
51
- finished_at.blank?
52
- end
53
-
54
- def sha1
55
- commit.id[0,10]
56
- end
57
-
58
- def entity_url
59
- server_html_url || build_url
60
- end
61
-
62
- def entity_name
63
- branch_name || server_name
64
- end
65
-
66
- def branch_history
67
- if branch_history_url
68
- self.class.get(branch_history_url, debug: debug)&.builds
69
- else
70
- []
71
- end
72
- end
73
-
74
- def estimated_duration
75
- if ed = super
76
- ed
77
- else
78
- times = branch_history.select(&:passed?).map { |b|
79
- Time.parse(b.finished_at) - Time.parse(b.started_at)
80
- }
81
- if times.empty?
82
- duration
83
- else
84
- times.sum / times.size
85
- end.to_f
86
- end
87
- end
88
-
89
- def infobar_style
90
- case
91
- when passed?, pending?
92
- {
93
- done_fg_color: '#005f00',
94
- done_bg_color: '#00d700',
95
- todo_fg_color: '#00d700',
96
- todo_bg_color: '#005f00',
97
- }
98
- else
99
- {
100
- done_fg_color: '#5f0000',
101
- done_bg_color: '#d70000',
102
- todo_fg_color: '#d70000',
103
- todo_bg_color: '#5f0000',
104
- }
105
- end
106
- end
107
-
108
- def to_s
109
- r = case
110
- when pending? && building?
111
- "#{entity_name} ##{sha1} building for #{duration(Time.now)}".yellow.bold
112
- when pending?
113
- "#{entity_name} ##{sha1} pending at the moment".yellow
114
- when passed?
115
- "#{entity_name} ##{sha1} passed after #{duration}".green
116
- when failed?
117
- "#{entity_name} ##{sha1} failed after #{duration}".red
118
- else
119
- "#{entity_name} ##{sha1} in state #{result}".blue
120
- end
121
- r = StringIO.new(r)
122
- duration_seconds = duration.to_f.to_i
123
- if passed? || failed?
124
- total_seconds = duration_seconds
125
- else
126
- total_seconds = estimated_duration.to_i
127
- end
128
- Infobar(
129
- current: duration_seconds,
130
- total: total_seconds,
131
- message: ' %l %c/%t seconds ',
132
- style: infobar_style,
133
- output: r
134
- ).update
135
- r <<
136
- "\n Semaphore: #{entity_url}" <<
137
- "\n Commit: #{commit.url}\n#{commit.message&.gsub(/^/, " " * 10)&.color(33)}" <<
138
- "\n Authored: #{(commit.author_name + ' <' + commit.author_email + ?>).bold} @#{commit.timestamp}"
139
- r.tap(&:rewind).read
140
- end
141
- end