git-storyid 0.3.3 → 0.5.1

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
- SHA1:
3
- metadata.gz: 757a81b3f19ee8d91bc9db03cf31703b37497aed
4
- data.tar.gz: 8d066a7703fc70bd9bc87870aac767e3f013f7b2
2
+ SHA256:
3
+ metadata.gz: ca5778a64e707a16aa61b17ff02c4b57b2a84bd502646c4b5206c1dafb551305
4
+ data.tar.gz: 6f2114bf2364445d01bc92a139439981a0be11ea57a802d97003ec2c7c5164f7
5
5
  SHA512:
6
- metadata.gz: 5bf8479a6b9f94c9e8e92639511268525e56d7fd4b0b6ee8bb2c617a5176276d734d8167fb5bc6e6e85f1ff251e2c5d655ced3ae2d232b7cfe4552be962116fb
7
- data.tar.gz: c83427661cfe8e12cec738c976d4083b791be0c24f1d349f6440a56a81f8fe2c808b9a635c5a6af3af0e647595a53dfd233764a26a0224d9a50f2bb7a1484fc2
6
+ metadata.gz: d809ad6e4a55b5eae7319f475f0718a2384779cb8fe776744cc01b7835fc927781598806506690ff5d44ab2e3e52a52cdd458fcef5857f5f2bc71a6480ead8c8
7
+ data.tar.gz: b93e652b501b9542afa41e7c2b406e65d8f8b45d804104de175dfc23610ade2ead6be0ba7aabdb9871d493885492a7d4aaa8c3319309b0458f663a250ca6bdb6
data/Gemfile CHANGED
@@ -1,11 +1,15 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- gem "pivotal-tracker"
3
+ gem "tracker_api"
4
+ gem "jira-ruby"
5
+
4
6
  group :development do
5
7
  gem "webmock"
6
8
  gem "debugger", :platform => "ruby_19"
7
9
  gem "mocha"
8
10
  gem "rspec"
9
- gem "jeweler"
11
+ gem "juwelier", github: 'flajann2/juwelier'
10
12
  gem "hashie"
13
+ gem "pry-byebug", require: false
14
+ gem "http_logger"
11
15
  end
@@ -1,59 +1,158 @@
1
+ GIT
2
+ remote: git://github.com/flajann2/juwelier.git
3
+ revision: de59d5a2ddea00c1f18957ab62129c1c141acce1
4
+ specs:
5
+ juwelier (2.4.9)
6
+ builder
7
+ bundler
8
+ git
9
+ github_api
10
+ highline
11
+ kamelcase (~> 0)
12
+ nokogiri
13
+ psych
14
+ rake
15
+ rdoc
16
+ semver2
17
+
1
18
  GEM
2
19
  remote: http://rubygems.org/
3
20
  specs:
4
- addressable (2.3.2)
5
- builder (3.0.0)
6
- columnize (0.3.6)
7
- crack (0.3.1)
8
- debugger (1.2.1)
21
+ activesupport (6.0.3.2)
22
+ concurrent-ruby (~> 1.0, >= 1.0.2)
23
+ i18n (>= 0.7, < 2)
24
+ minitest (~> 5.1)
25
+ tzinfo (~> 1.1)
26
+ zeitwerk (~> 2.2, >= 2.2.2)
27
+ addressable (2.7.0)
28
+ public_suffix (>= 2.0.2, < 5.0)
29
+ atlassian-jwt (0.2.0)
30
+ jwt (~> 2.1.0)
31
+ axiom-types (0.1.1)
32
+ descendants_tracker (~> 0.0.4)
33
+ ice_nine (~> 0.11.0)
34
+ thread_safe (~> 0.3, >= 0.3.1)
35
+ builder (3.2.4)
36
+ byebug (11.1.3)
37
+ coderay (1.1.3)
38
+ coercible (1.0.0)
39
+ descendants_tracker (~> 0.0.1)
40
+ columnize (0.9.0)
41
+ concurrent-ruby (1.1.7)
42
+ crack (0.4.3)
43
+ safe_yaml (~> 1.0.0)
44
+ debugger (1.6.8)
9
45
  columnize (>= 0.3.1)
10
- debugger-linecache (~> 1.1.1)
11
- debugger-ruby_core_source (~> 1.1.4)
12
- debugger-linecache (1.1.2)
13
- debugger-ruby_core_source (>= 1.1.1)
14
- debugger-ruby_core_source (1.1.4)
15
- diff-lcs (1.2.1)
16
- git (1.2.6)
17
- happymapper (0.4.0)
18
- libxml-ruby (~> 2.0)
19
- hashie (1.2.0)
20
- jeweler (2.0.1)
21
- bundler (~> 1.0)
22
- git (>= 1.2.5)
23
- rake
24
- rdoc
25
- json (1.8.1)
26
- libxml-ruby (2.7.0)
27
- metaclass (0.0.1)
28
- mime-types (1.19)
29
- mocha (0.13.2)
30
- metaclass (~> 0.0.1)
31
- nokogiri (1.5.5)
32
- pivotal-tracker (0.5.4)
33
- builder
34
- builder
35
- happymapper (>= 0.3.2)
36
- happymapper (>= 0.3.2)
37
- nokogiri (>= 1.4.3)
38
- nokogiri (~> 1.4)
39
- rest-client (~> 1.6.0)
40
- rest-client (~> 1.6.0)
41
- rake (10.3.2)
42
- rdoc (4.1.1)
43
- json (~> 1.4)
44
- rest-client (1.6.7)
45
- mime-types (>= 1.16)
46
- rspec (2.13.0)
47
- rspec-core (~> 2.13.0)
48
- rspec-expectations (~> 2.13.0)
49
- rspec-mocks (~> 2.13.0)
50
- rspec-core (2.13.0)
51
- rspec-expectations (2.13.0)
52
- diff-lcs (>= 1.1.3, < 2.0)
53
- rspec-mocks (2.13.0)
54
- webmock (1.8.7)
55
- addressable (>= 2.2.7)
56
- crack (>= 0.1.7)
46
+ debugger-linecache (~> 1.2.0)
47
+ debugger-ruby_core_source (~> 1.3.5)
48
+ debugger-linecache (1.2.0)
49
+ debugger-ruby_core_source (1.3.8)
50
+ declarative (0.0.20)
51
+ declarative-option (0.1.0)
52
+ descendants_tracker (0.0.4)
53
+ thread_safe (~> 0.3, >= 0.3.1)
54
+ diff-lcs (1.4.4)
55
+ equalizer (0.0.11)
56
+ excon (0.76.0)
57
+ faraday (1.0.1)
58
+ multipart-post (>= 1.2, < 3)
59
+ faraday_middleware (1.0.0)
60
+ faraday (~> 1.0)
61
+ git (1.7.0)
62
+ rchardet (~> 1.8)
63
+ github_api (0.19.0)
64
+ addressable (~> 2.4)
65
+ descendants_tracker (~> 0.0.4)
66
+ faraday (>= 0.8, < 2)
67
+ hashie (~> 3.5, >= 3.5.2)
68
+ oauth2 (~> 1.0)
69
+ hashdiff (1.0.1)
70
+ hashie (3.6.0)
71
+ highline (2.0.3)
72
+ http_logger (0.6.0)
73
+ i18n (1.8.5)
74
+ concurrent-ruby (~> 1.0)
75
+ ice_nine (0.11.2)
76
+ jira-ruby (2.1.3)
77
+ activesupport
78
+ atlassian-jwt
79
+ multipart-post
80
+ oauth (~> 0.5, >= 0.5.0)
81
+ jwt (2.1.0)
82
+ kamelcase (0.0.2)
83
+ semver2 (~> 3)
84
+ method_source (1.0.0)
85
+ mimemagic (0.3.5)
86
+ mini_portile2 (2.4.0)
87
+ minitest (5.14.1)
88
+ mocha (1.11.2)
89
+ multi_json (1.15.0)
90
+ multi_xml (0.6.0)
91
+ multipart-post (2.1.1)
92
+ nokogiri (1.10.10)
93
+ mini_portile2 (~> 2.4.0)
94
+ oauth (0.5.4)
95
+ oauth2 (1.4.4)
96
+ faraday (>= 0.8, < 2.0)
97
+ jwt (>= 1.0, < 3.0)
98
+ multi_json (~> 1.3)
99
+ multi_xml (~> 0.5)
100
+ rack (>= 1.2, < 3)
101
+ pry (0.13.1)
102
+ coderay (~> 1.1)
103
+ method_source (~> 1.0)
104
+ pry-byebug (3.9.0)
105
+ byebug (~> 11.0)
106
+ pry (~> 0.13.0)
107
+ psych (3.2.0)
108
+ public_suffix (4.0.5)
109
+ rack (2.2.3)
110
+ rake (13.0.1)
111
+ rchardet (1.8.0)
112
+ rdoc (6.2.1)
113
+ representable (3.0.4)
114
+ declarative (< 0.1.0)
115
+ declarative-option (< 0.2.0)
116
+ uber (< 0.2.0)
117
+ rspec (3.9.0)
118
+ rspec-core (~> 3.9.0)
119
+ rspec-expectations (~> 3.9.0)
120
+ rspec-mocks (~> 3.9.0)
121
+ rspec-core (3.9.2)
122
+ rspec-support (~> 3.9.3)
123
+ rspec-expectations (3.9.2)
124
+ diff-lcs (>= 1.2.0, < 2.0)
125
+ rspec-support (~> 3.9.0)
126
+ rspec-mocks (3.9.1)
127
+ diff-lcs (>= 1.2.0, < 2.0)
128
+ rspec-support (~> 3.9.0)
129
+ rspec-support (3.9.3)
130
+ safe_yaml (1.0.5)
131
+ semver2 (3.4.2)
132
+ thread_safe (0.3.6)
133
+ tracker_api (1.11.0)
134
+ addressable
135
+ equalizer
136
+ excon
137
+ faraday
138
+ faraday_middleware
139
+ mimemagic
140
+ multi_json
141
+ representable
142
+ virtus
143
+ tzinfo (1.2.7)
144
+ thread_safe (~> 0.1)
145
+ uber (0.1.0)
146
+ virtus (1.0.5)
147
+ axiom-types (~> 0.1)
148
+ coercible (~> 1.0)
149
+ descendants_tracker (~> 0.0, >= 0.0.3)
150
+ equalizer (~> 0.0, >= 0.0.9)
151
+ webmock (3.8.3)
152
+ addressable (>= 2.3.6)
153
+ crack (>= 0.3.2)
154
+ hashdiff (>= 0.4.0, < 2.0.0)
155
+ zeitwerk (2.4.0)
57
156
 
58
157
  PLATFORMS
59
158
  ruby
@@ -61,8 +160,14 @@ PLATFORMS
61
160
  DEPENDENCIES
62
161
  debugger
63
162
  hashie
64
- jeweler
163
+ http_logger
164
+ jira-ruby
165
+ juwelier!
65
166
  mocha
66
- pivotal-tracker
167
+ pry-byebug
67
168
  rspec
169
+ tracker_api
68
170
  webmock
171
+
172
+ BUNDLED WITH
173
+ 1.17.3
data/README.md CHANGED
@@ -47,3 +47,11 @@ Feature: Tag campaign insertion points and
47
47
  campaigns with an identifier,
48
48
  so only campaigns with matching identifier will get shown
49
49
  ```
50
+
51
+ ## Supported options
52
+
53
+ ```
54
+ -m, --message [MESSAGE] Add addional MESSAGE to comit
55
+ -f, --finish Specify that this commit finishes a story or fixes a bug
56
+ -d, --deliver Specify that this commit delivers a story or a bug
57
+ ```
data/Rakefile CHANGED
@@ -11,8 +11,8 @@ rescue Bundler::BundlerError => e
11
11
  end
12
12
  require 'rake'
13
13
 
14
- require 'jeweler'
15
- Jeweler::Tasks.new do |gem|
14
+ require 'juwelier'
15
+ Juwelier::Tasks.new do |gem|
16
16
  # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
17
  gem.name = "git-storyid"
18
18
  gem.executables = ['git-storyid']
@@ -24,7 +24,7 @@ Jeweler::Tasks.new do |gem|
24
24
  gem.authors = ["Bogdan Gusiev"]
25
25
  # dependencies defined in Gemfile
26
26
  end
27
- Jeweler::RubygemsDotOrgTasks.new
27
+ Juwelier::RubygemsDotOrgTasks.new
28
28
 
29
29
  require 'rspec/core'
30
30
  require 'rspec/core/rake_task'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.5.1
@@ -1,20 +1,20 @@
1
- # Generated by jeweler
1
+ # Generated by juwelier
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
3
+ # Instead, edit Juwelier::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: git-storyid 0.3.3 ruby lib
5
+ # stub: git-storyid 0.5.1 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
- s.name = "git-storyid"
9
- s.version = "0.3.3"
8
+ s.name = "git-storyid".freeze
9
+ s.version = "0.5.1"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
- s.require_paths = ["lib"]
13
- s.authors = ["Bogdan Gusiev"]
14
- s.date = "2015-02-06"
15
- s.description = "Helps include pivotal story id and description in commit"
16
- s.email = "agresso@gmail.com"
17
- s.executables = ["git-storyid"]
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib".freeze]
13
+ s.authors = ["Bogdan Gusiev".freeze]
14
+ s.date = "2020-08-31"
15
+ s.description = "Helps include pivotal story id and description in commit".freeze
16
+ s.email = "agresso@gmail.com".freeze
17
+ s.executables = ["git-storyid".freeze]
18
18
  s.extra_rdoc_files = [
19
19
  "LICENSE.txt",
20
20
  "README.md"
@@ -32,42 +32,52 @@ Gem::Specification.new do |s|
32
32
  "git-storyid.gemspec",
33
33
  "lib/git-storyid.rb",
34
34
  "lib/git_storyid.rb",
35
+ "spec/git_storyid/jira_spec.rb",
35
36
  "spec/git_storyid_spec.rb",
36
37
  "spec/spec_helper.rb"
37
38
  ]
38
- s.homepage = "http://github.com/bogdan/git-storyid"
39
- s.licenses = ["MIT"]
40
- s.rubygems_version = "2.4.5"
41
- s.summary = "Attach commits to pivotal stories"
39
+ s.homepage = "http://github.com/bogdan/git-storyid".freeze
40
+ s.licenses = ["MIT".freeze]
41
+ s.rubygems_version = "3.0.8".freeze
42
+ s.summary = "Attach commits to pivotal stories".freeze
42
43
 
43
44
  if s.respond_to? :specification_version then
44
45
  s.specification_version = 4
45
46
 
46
47
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
- s.add_runtime_dependency(%q<pivotal-tracker>, [">= 0"])
48
- s.add_development_dependency(%q<webmock>, [">= 0"])
49
- s.add_development_dependency(%q<debugger>, [">= 0"])
50
- s.add_development_dependency(%q<mocha>, [">= 0"])
51
- s.add_development_dependency(%q<rspec>, [">= 0"])
52
- s.add_development_dependency(%q<jeweler>, [">= 0"])
53
- s.add_development_dependency(%q<hashie>, [">= 0"])
48
+ s.add_runtime_dependency(%q<tracker_api>.freeze, [">= 0"])
49
+ s.add_runtime_dependency(%q<jira-ruby>.freeze, [">= 0"])
50
+ s.add_development_dependency(%q<webmock>.freeze, [">= 0"])
51
+ s.add_development_dependency(%q<debugger>.freeze, [">= 0"])
52
+ s.add_development_dependency(%q<mocha>.freeze, [">= 0"])
53
+ s.add_development_dependency(%q<rspec>.freeze, [">= 0"])
54
+ s.add_development_dependency(%q<juwelier>.freeze, [">= 0"])
55
+ s.add_development_dependency(%q<hashie>.freeze, [">= 0"])
56
+ s.add_development_dependency(%q<pry-byebug>.freeze, [">= 0"])
57
+ s.add_development_dependency(%q<http_logger>.freeze, [">= 0"])
54
58
  else
55
- s.add_dependency(%q<pivotal-tracker>, [">= 0"])
56
- s.add_dependency(%q<webmock>, [">= 0"])
57
- s.add_dependency(%q<debugger>, [">= 0"])
58
- s.add_dependency(%q<mocha>, [">= 0"])
59
- s.add_dependency(%q<rspec>, [">= 0"])
60
- s.add_dependency(%q<jeweler>, [">= 0"])
61
- s.add_dependency(%q<hashie>, [">= 0"])
59
+ s.add_dependency(%q<tracker_api>.freeze, [">= 0"])
60
+ s.add_dependency(%q<jira-ruby>.freeze, [">= 0"])
61
+ s.add_dependency(%q<webmock>.freeze, [">= 0"])
62
+ s.add_dependency(%q<debugger>.freeze, [">= 0"])
63
+ s.add_dependency(%q<mocha>.freeze, [">= 0"])
64
+ s.add_dependency(%q<rspec>.freeze, [">= 0"])
65
+ s.add_dependency(%q<juwelier>.freeze, [">= 0"])
66
+ s.add_dependency(%q<hashie>.freeze, [">= 0"])
67
+ s.add_dependency(%q<pry-byebug>.freeze, [">= 0"])
68
+ s.add_dependency(%q<http_logger>.freeze, [">= 0"])
62
69
  end
63
70
  else
64
- s.add_dependency(%q<pivotal-tracker>, [">= 0"])
65
- s.add_dependency(%q<webmock>, [">= 0"])
66
- s.add_dependency(%q<debugger>, [">= 0"])
67
- s.add_dependency(%q<mocha>, [">= 0"])
68
- s.add_dependency(%q<rspec>, [">= 0"])
69
- s.add_dependency(%q<jeweler>, [">= 0"])
70
- s.add_dependency(%q<hashie>, [">= 0"])
71
+ s.add_dependency(%q<tracker_api>.freeze, [">= 0"])
72
+ s.add_dependency(%q<jira-ruby>.freeze, [">= 0"])
73
+ s.add_dependency(%q<webmock>.freeze, [">= 0"])
74
+ s.add_dependency(%q<debugger>.freeze, [">= 0"])
75
+ s.add_dependency(%q<mocha>.freeze, [">= 0"])
76
+ s.add_dependency(%q<rspec>.freeze, [">= 0"])
77
+ s.add_dependency(%q<juwelier>.freeze, [">= 0"])
78
+ s.add_dependency(%q<hashie>.freeze, [">= 0"])
79
+ s.add_dependency(%q<pry-byebug>.freeze, [">= 0"])
80
+ s.add_dependency(%q<http_logger>.freeze, [">= 0"])
71
81
  end
72
82
  end
73
83
 
@@ -1,8 +1,8 @@
1
1
  require "readline"
2
2
  require "optparse"
3
- require "pivotal_tracker"
4
3
  require "yaml"
5
4
  require "open3"
5
+ require 'io/console'
6
6
 
7
7
  class GitStoryid
8
8
 
@@ -10,62 +10,71 @@ class GitStoryid
10
10
  new(*args).run
11
11
  end
12
12
 
13
+ def self.output(message)
14
+ puts message
15
+ end
16
+
17
+ def output(message)
18
+ self.class.output(message)
19
+ end
20
+
21
+
13
22
  def initialize(*arguments)
23
+ @tracker = Configuration.build
14
24
  @git_options = []
15
25
  parser = OptionParser.new do |opts|
16
26
  opts.banner = "Do git commit with information from pivotal story"
17
27
  opts.on("-m", "--message [MESSAGE]", "Add addional MESSAGE to comit") do |custom_message|
18
28
  @custom_message = custom_message
19
29
  end
20
- opts.on("-f", "--finish", "Specify that this commit finishes a story or fixes a bug") do
30
+ opts.on("-f", "--finish", "Specify that this commit finishes a story or fixes a bug") do
21
31
  @finish_stories = true
22
32
  end
33
+ opts.on("-d", "--deliver", "Specify that this commit delivers a story or a bug") do
34
+ @deliver_stories = true
35
+ end
23
36
  end
24
37
  parser.parse!(arguments)
25
38
 
26
39
  unless arguments.empty?
27
40
  @stories = arguments.map do |argument|
28
- Configuration.project.stories.find(argument)
41
+ @tracker.find_story_by_id(argument)
29
42
  end
30
43
  end
31
44
  end
32
45
 
33
- def all_stories
34
- @all_stories ||= Configuration.project.stories.all(
35
- :owner => Configuration.me,
36
- :state => %w(started finished delivered),
37
- :limit => 30
38
- )
39
- end
40
-
41
46
  def readline_stories_if_not_present
42
47
  if !@stories || @stories.empty?
43
48
  quit_if_no_stories
44
49
  output stories_menu
45
50
  @stories = readline_story_ids.map do |index|
46
- if index > 1_000_000
47
- # Consider it a direct story id
48
- Configuration.project.stories.find(index)
49
- else
50
- all_stories[index - 1] || (quit("Story index #{index} not found."))
51
- end
51
+ fetch_story(index) || quit("Story #{index} was not found.")
52
52
  end
53
53
  end
54
+ rescue RefetchStories
55
+ @tracker.reset
56
+ @stories = nil
57
+ readline_stories_if_not_present
54
58
  end
55
59
 
56
- def output(message)
57
- puts message
60
+ def fetch_story(index)
61
+ if (1..100).include?(index.to_i)
62
+ @tracker.all_stories[index.to_i - 1]
63
+ else
64
+ # Consider it a direct story id
65
+ @tracker.find_story_by_id(index)
66
+ end
58
67
  end
59
68
 
60
69
  def quit_if_no_stories
61
- if all_stories.empty?
70
+ if @tracker.all_stories.empty?
62
71
  quit "No stories started and owned by you."
63
72
  end
64
73
  end
65
74
 
66
75
  def stories_menu
67
76
  result = ""
68
- all_stories.each_with_index do |story, index|
77
+ @tracker.all_stories.each_with_index do |story, index|
69
78
  result << "[#{index + 1}] #{story.name}\n"
70
79
  end
71
80
  result << "\n"
@@ -73,15 +82,22 @@ class GitStoryid
73
82
  end
74
83
 
75
84
  def readline_story_ids
76
- ids = readline.split(/\s*,\s*/).reject do |string|
85
+ input = readline
86
+ if input =~ /\A\s*re?f?r?e?s?h?\s*\z/
87
+ raise RefetchStories
88
+ end
89
+ ids = input.split(/\s*,\s*/).reject do |string|
77
90
  string.empty?
78
91
  end
79
- quit("Cancelling.") if ids.empty?
80
- ids.map {|id| id.to_i }
92
+ if ids.empty?
93
+ quit("Cancelling.")
94
+ else
95
+ ids
96
+ end
81
97
  end
82
98
 
83
99
  def readline
84
- Readline.readline("Indexes(csv): ", true)
100
+ Readline.readline("Indexes: ", true)
85
101
  end
86
102
 
87
103
  def quit(message)
@@ -108,14 +124,15 @@ class GitStoryid
108
124
  message += @custom_message.to_s + "\n\n"
109
125
  end
110
126
  message += @stories.map do |story|
111
- "#{story.story_type.capitalize}: " + story.name.strip
127
+ "#{story.type.capitalize}: " + story.name.strip
112
128
  end.join("\n\n")
113
129
  message
114
130
  end
115
131
 
116
132
  def finish_story_prefix(story)
133
+ return "Delivers " if @deliver_stories
117
134
  return "" unless @finish_stories
118
- story.story_type == "bug" ? "Fixes " : "Finishes "
135
+ story.type == "bug" ? "Fixes " : "Finishes "
119
136
  end
120
137
 
121
138
  def execute(*args)
@@ -128,113 +145,213 @@ class GitStoryid
128
145
  end
129
146
  end
130
147
 
148
+ class Configuration
131
149
 
132
- module Configuration
133
- class << self
134
-
135
- def config=(config)
136
- @config = config
137
- end
138
-
139
- def read
140
- return if @loaded
150
+ def self.build
141
151
  load_config
142
152
  ensure_full_config
143
- setup_api_client
144
- @loaded = true
153
+ TRACKER_CONFIG[engine][:class].new(@config)
145
154
  end
146
155
 
147
- def load_config
148
- @config ||= {}
149
- @config.merge!(load_config_from(global_config_path))
150
- @project_config = load_config_from(project_config_path)
151
- @config.merge!(@project_config)
152
- end
156
+ class << self
153
157
 
154
- def setup_api_client
155
- PivotalTracker::Client.token = @config['api_token']
156
- PivotalTracker::Client.use_ssl = @config['use_ssl'] ? @config['use_ssl'] : false
157
- end
158
-
159
- def ensure_full_config
160
- changed = false
161
- {
162
- "api_token" => "Api token (https://www.pivotaltracker.com/profile)",
163
- "use_ssl" => "Use SSL (y/n)",
164
- "me" => "Your pivotal initials (e.g. BG)",
165
- "project_id" => "Project ID"
166
- }.each do |key, label|
167
- if @config[key].nil?
168
- changed = true
169
- value = Readline.readline("#{label}: ", true)
170
- @project_config[key] = format_config_value(value)
158
+ def load_config
159
+ @config ||= load_config_from
160
+ end
161
+
162
+ def engine
163
+ e = @config[:engine]
164
+ e ? e.to_sym : nil
165
+ end
166
+
167
+ def ensure_full_config
168
+ @config[:engine] = read_configuration_value("Engine (pivotal/jira)") unless engine
169
+ tracker_config = TRACKER_CONFIG[engine]
170
+
171
+ return if tracker_config && @config.keys.sort == (tracker_config[:options].keys + [:engine]).sort
172
+
173
+ tracker_config[:options].each do |key, label|
174
+ @config[key] = read_configuration_value(label, key == :password)
171
175
  end
176
+
177
+ File.open(project_config_path, "w") do |file|
178
+ file.write YAML.dump(@config)
179
+ end
180
+ output "Writing config to #{project_config_path}"
172
181
  end
173
- if changed
174
- File.open("./.pivotalrc", "w") do |file|
175
- file.write YAML.dump(@project_config)
182
+
183
+ def read_configuration_value(label, hidden = false)
184
+ label = "#{label}: "
185
+ if hidden
186
+ print label
187
+ password = STDIN.noecho(&:gets).chomp
188
+ puts ''
189
+ password
190
+ else
191
+ Readline.readline(label, true)
176
192
  end
177
- @config.merge!(@project_config)
178
- #output "Writing config to .pivotalrc"
179
193
  end
180
- end
181
194
 
182
- def format_config_value(value)
183
- case value
184
- when "y"
185
- true
186
- when "n"
187
- false
188
- else
189
- value
195
+ def load_config_from
196
+ return {} unless project_config_path
197
+ if File.exists?(project_config_path)
198
+ YAML.load(File.read(project_config_path)) || {}
199
+ else
200
+ {}
201
+ end
202
+ end
203
+
204
+ def project_config_path
205
+ @project_config_path ||= find_project_config
206
+ end
207
+ def find_project_config
208
+ dirs = File.split(Dir.pwd)
209
+ until dirs.empty? || File.exists?(File.join(dirs, FILENAME))
210
+ dirs.pop
211
+ end
212
+ unless dirs.empty?
213
+ File.join(dirs, FILENAME)
214
+ else
215
+ File.join(Dir.pwd, FILENAME)
216
+ end
190
217
  end
191
218
  end
192
219
 
193
- def load_config_from(path)
194
- return {} unless path
195
- file = File.join path,'.pivotalrc'
196
- if File.exists?(file)
197
- YAML.load(File.read(file)) || {}
198
- else
199
- {}
220
+ def initialize(config)
221
+ @config = config
222
+ setup_api_client
223
+ end
224
+
225
+ def all_stories
226
+ @all_stories ||= fetch_all_stories.map do |story|
227
+ serialize_issue(story)
200
228
  end
201
229
  end
202
230
 
203
- def project
204
- read
205
- @project ||= PivotalTracker::Project.find(@config['project_id'])
231
+ def reset
232
+ @all_stories = nil
233
+ end
234
+
235
+ def self.output(message)
236
+ GitStoryid.output(message)
237
+ end
238
+
239
+
240
+ FILENAME = %w(.git-storyid)
241
+
242
+ end
243
+
244
+ class SerializedIssue < Struct.new(:id, :type, :name)
245
+ end
246
+ class PivotalConfiguration < Configuration
247
+
248
+ def setup_api_client
249
+ require "tracker_api"
250
+ @client ||= TrackerApi::Client.new(token: @config[:api_token])
206
251
  end
207
252
 
208
253
  def me
209
- read
210
254
  @me ||= @config['me']
211
255
  end
212
256
 
213
- def global_config_path
214
- @global_config_path ||= File.expand_path('~')
257
+ def fetch_all_stories
258
+ project.stories(
259
+ filter: "mywork:#{me} state:started,finished,delivered",
260
+ # :owner => me,
261
+ # :with_state => %w(started finished delivered),
262
+ :limit => 30
263
+ )
264
+ end
265
+
266
+ def find_story_by_id(id)
267
+ serialize_issue(project.story(id))
268
+ end
269
+
270
+ def serialize_issue(issue)
271
+ SerializedIssue.new(issue.id, issue.story_type, issue.name)
272
+ end
273
+
274
+ protected
275
+ def project
276
+ @project ||= @client.project(@config[:project_id])
277
+ end
278
+
279
+ end
280
+
281
+
282
+ class JiraConfiguration < Configuration
283
+
284
+ def initialize(config)
285
+ super(config)
286
+ end
287
+
288
+ def setup_api_client
289
+ require 'jira-ruby'
290
+ @client ||= JIRA::Client.new(
291
+ :username => username,
292
+ :password => @config[:password],
293
+ :site => @config[:site],
294
+ :context_path => '',
295
+ :auth_type => :basic,
296
+ )
215
297
  end
216
298
 
217
- def project_config_path
218
- @project_config_path ||= find_project_config
299
+ def client
300
+ @client
219
301
  end
220
302
 
303
+ def username
304
+ @username ||= @config[:username]
305
+ end
221
306
 
222
- private
307
+ def fetch_all_stories
308
+ client.Issue.jql("assignee=#{username} and status not in (done) and project = #{@config[:project_id]}")
309
+ end
223
310
 
224
- def find_project_config
225
- dirs = File.split(Dir.pwd)
226
- until dirs.empty? || File.exists?(File.join(dirs, '.pivotalrc'))
227
- dirs.pop
311
+ def find_story_by_id(key)
312
+ if key.to_i.to_s == key.to_s # no project_id in key
313
+ key = [@config[:project_id], key].join("-")
228
314
  end
229
- if dirs.empty? || File.join(dirs, '.pivotalrc')==global_config_path
315
+ serialize_issue(client.Issue.find(key))
316
+ rescue JIRA::HTTPError => e
317
+ if e.code.to_i == 404
230
318
  nil
231
319
  else
232
- File.join(dirs)
320
+ raise e
233
321
  end
234
322
  end
323
+
324
+ def serialize_issue(issue)
325
+ SerializedIssue.new(issue.key, issue.issuetype.name, issue.summary)
235
326
  end
327
+
236
328
  end
237
329
 
238
330
  class Error < StandardError
239
331
  end
332
+
333
+ class RefetchStories < StandardError
334
+ end
335
+
336
+ TRACKER_CONFIG = {
337
+ pivotal: {
338
+ class: PivotalConfiguration,
339
+ options: {
340
+ :api_token => "Api token (https://www.pivotaltracker.com/profile)",
341
+ :me => "Your pivotal initials (e.g. BG)",
342
+ :project_id => "Project ID",
343
+ },
344
+ },
345
+ jira: {
346
+ class: JiraConfiguration,
347
+ options: {
348
+ :site => 'Site URL',
349
+ project_id: "Project ID",
350
+ :username => 'Username',
351
+ :password => 'Password',
352
+ }
353
+ }
354
+ }
355
+
356
+
240
357
  end
@@ -0,0 +1,108 @@
1
+
2
+ require "spec_helper"
3
+ require "fileutils"
4
+
5
+ describe GitStoryid do
6
+
7
+ let(:commands) { []}
8
+
9
+ def run(*args)
10
+ GitStoryid.run(*args)
11
+ end
12
+
13
+ def should_quit_with(expected)
14
+ actual = nil
15
+ GitStoryid.send(:define_method, :quit) do |message|
16
+ actual = message
17
+ end
18
+ yield
19
+ actual.should_not be_nil
20
+ actual.should == expected
21
+
22
+ end
23
+
24
+
25
+ describe "Pivotal" do
26
+
27
+ before(:each) do
28
+
29
+ GitStoryid::Configuration.stubs(:load_config_from).
30
+ returns(
31
+ "api_token" => "a2b4e",
32
+ "use_ssl" => false,
33
+ "me" => "BG",
34
+ "project_id" => "1234"
35
+ )
36
+ commands = self.commands
37
+ GitStoryid.send(:define_method, :execute) do |*args|
38
+ commands << args
39
+ ""
40
+ end
41
+ GitStoryid.any_instance.stubs(:ensure_changes_stashed!).returns(true)
42
+ GitStoryid.any_instance.stubs(:output).returns(true)
43
+
44
+ GitStoryid::Configuration.stubs(:project).returns(Hashie::Mash.new(
45
+ :initial_velocity => 10,
46
+ :labels => "bonobos,true&co,website",
47
+ :id => 135657,
48
+ :week_start_day => "Monday",
49
+ :use_https => false,
50
+ :iteration_length => 1,
51
+ :account => "Allan Grant",
52
+ :name => "Curebit Marketing",
53
+ :stories => PivotalTracker::Story,
54
+ :last_activity_at => DateTime.now,
55
+ :velocity_scheme => "Average of 3 iterations",
56
+ :current_iteration_number => 122,
57
+ :current_velocity => 19,
58
+ :point_scale => "0,1,2,3",
59
+ :first_iteration_start_time => DateTime.now
60
+ ))
61
+
62
+ GitStoryid::PivotalConfiguration.any_instance.stubs(:fetch_all_stories).returns([
63
+ Hashie::Mash.new(
64
+ :deadline => nil,
65
+ :labels => "paypal",
66
+ :accepted_at => nil,
67
+ :id => 44647731,
68
+ :jira_id => nil,
69
+ :estimate => 1,
70
+ :integration_id => nil,
71
+ :owned_by => "Bogdan Gusiev",
72
+ :name => "Strip Default paypal credentials",
73
+ :created_at => DateTime.now,
74
+ :story_type => "feature",
75
+ :other_id => nil,
76
+ :description => "",
77
+ :requested_by => "Dominic Coryell",
78
+ :url => "http://www.pivotaltracker.com/story/show/44647731",
79
+ :attachments => [],
80
+ :project_id => 135657,
81
+ :jira_url => nil,
82
+ :current_state => "finished"
83
+ ),
84
+ Hashie::Mash.new(
85
+ :deadline => nil,
86
+ :labels => "paypal",
87
+ :accepted_at => nil,
88
+ :id => 44647732,
89
+ :jira_id => nil,
90
+ :estimate => 1,
91
+ :integration_id => nil,
92
+ :owned_by => "Bogdan Gusiev",
93
+ :name => "Require pro paypal account for mass payments",
94
+ :created_at => DateTime.now,
95
+ :story_type => "feature",
96
+ :other_id => nil,
97
+ :description => "",
98
+ :requested_by => "Dominic Coryell",
99
+ :url => "http://www.pivotaltracker.com/story/show/44647732",
100
+ :attachments => [],
101
+ :project_id => 135657,
102
+ :jira_url => nil,
103
+ :current_state => "finished"
104
+ )
105
+ ])
106
+ end
107
+ end
108
+ end
@@ -9,26 +9,35 @@ describe GitStoryid do
9
9
  GitStoryid.run(*args)
10
10
  end
11
11
 
12
+ class ForceQuit < StandardError
13
+ end
14
+
12
15
  def should_quit_with(expected)
13
16
  actual = nil
14
17
  GitStoryid.send(:define_method, :quit) do |message|
15
18
  actual = message
19
+ raise ForceQuit
16
20
  end
17
21
  yield
22
+ true.should eq(false)
23
+ rescue ForceQuit
18
24
  actual.should_not be_nil
19
25
  actual.should == expected
20
26
 
21
27
  end
22
28
 
23
29
 
30
+ describe "Pivotal" do
31
+
24
32
  before(:each) do
25
-
26
- GitStoryid::Configuration.config = {
27
- "api_token" => "a2b4e",
28
- "use_ssl" => false,
29
- "me" => "BG",
30
- "project_id" => "1234"
31
- }
33
+
34
+ GitStoryid::Configuration.stubs(:load_config_from).
35
+ returns(
36
+ engine: "pivotal",
37
+ api_token: "a2b4e",
38
+ me: "BG",
39
+ project_id: "1234",
40
+ )
32
41
  commands = self.commands
33
42
  GitStoryid.send(:define_method, :execute) do |*args|
34
43
  commands << args
@@ -37,25 +46,7 @@ describe GitStoryid do
37
46
  GitStoryid.any_instance.stubs(:ensure_changes_stashed!).returns(true)
38
47
  GitStoryid.any_instance.stubs(:output).returns(true)
39
48
 
40
- GitStoryid::Configuration.stubs(:project).returns(Hashie::Mash.new(
41
- :initial_velocity => 10,
42
- :labels => "bonobos,true&co,website",
43
- :id => 135657,
44
- :week_start_day => "Monday",
45
- :use_https => false,
46
- :iteration_length => 1,
47
- :account => "Allan Grant",
48
- :name => "Curebit Marketing",
49
- :stories => PivotalTracker::Story,
50
- :last_activity_at => DateTime.now,
51
- :velocity_scheme => "Average of 3 iterations",
52
- :current_iteration_number => 122,
53
- :current_velocity => 19,
54
- :point_scale => "0,1,2,3",
55
- :first_iteration_start_time => DateTime.now
56
- ))
57
-
58
- GitStoryid.any_instance.stubs(:all_stories).returns([
49
+ GitStoryid::PivotalConfiguration.any_instance.stubs(:fetch_all_stories).returns([
59
50
  Hashie::Mash.new(
60
51
  :deadline => nil,
61
52
  :labels => "paypal",
@@ -131,6 +122,12 @@ EOI
131
122
  run('-f')
132
123
  commands.should include(["git", "commit", "-m", "[Finishes #44647731] Feature: Strip Default paypal credentials"])
133
124
  end
125
+
126
+ it "should support delivering" do
127
+ GitStoryid.any_instance.stubs(:readline).returns('1')
128
+ run('-d')
129
+ commands.should include(["git", "commit", "-m", "[Delivers #44647731] Feature: Strip Default paypal credentials"])
130
+ end
134
131
  end
135
132
 
136
133
  it "should quit if no stories specified" do
@@ -141,6 +138,7 @@ EOI
141
138
  end
142
139
 
143
140
 
141
+ end
144
142
 
145
143
 
146
144
  end
@@ -3,6 +3,8 @@ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
3
  require 'rspec'
4
4
  require "webmock"
5
5
  require "hashie"
6
+ require "tracker_api"
7
+ require 'jira-ruby'
6
8
  require 'git-storyid'
7
9
 
8
10
  # Requires supporting files with custom matchers and macros, etc,
@@ -13,5 +15,5 @@ WebMock.disable_net_connect!
13
15
 
14
16
  RSpec.configure do |config|
15
17
  config.mock_with :mocha
16
-
18
+
17
19
  end
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: git-storyid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bogdan Gusiev
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-06 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: pivotal-tracker
14
+ name: tracker_api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jira-ruby
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -81,7 +95,7 @@ dependencies:
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
83
97
  - !ruby/object:Gem::Dependency
84
- name: jeweler
98
+ name: juwelier
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
101
  - - ">="
@@ -108,6 +122,34 @@ dependencies:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
110
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: pry-byebug
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: http_logger
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
111
153
  description: Helps include pivotal story id and description in commit
112
154
  email: agresso@gmail.com
113
155
  executables:
@@ -129,13 +171,14 @@ files:
129
171
  - git-storyid.gemspec
130
172
  - lib/git-storyid.rb
131
173
  - lib/git_storyid.rb
174
+ - spec/git_storyid/jira_spec.rb
132
175
  - spec/git_storyid_spec.rb
133
176
  - spec/spec_helper.rb
134
177
  homepage: http://github.com/bogdan/git-storyid
135
178
  licenses:
136
179
  - MIT
137
180
  metadata: {}
138
- post_install_message:
181
+ post_install_message:
139
182
  rdoc_options: []
140
183
  require_paths:
141
184
  - lib
@@ -150,9 +193,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
150
193
  - !ruby/object:Gem::Version
151
194
  version: '0'
152
195
  requirements: []
153
- rubyforge_project:
154
- rubygems_version: 2.4.5
155
- signing_key:
196
+ rubygems_version: 3.0.8
197
+ signing_key:
156
198
  specification_version: 4
157
199
  summary: Attach commits to pivotal stories
158
200
  test_files: []