v2gpti 1.1.9 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/bin/git-deliver +1 -1
  3. data/bin/git-finish +1 -1
  4. data/bin/git-newbug +1 -1
  5. data/bin/git-newfeature +1 -1
  6. data/bin/git-qa +1 -1
  7. data/bin/git-release +1 -1
  8. data/bin/git-report +1 -1
  9. data/bin/git-start +1 -1
  10. data/bin/git-uat +1 -1
  11. data/config_template +16 -0
  12. data/lib/git-pivotal-tracker-integration/command/base.rb +235 -322
  13. data/lib/git-pivotal-tracker-integration/command/configuration.rb +183 -109
  14. data/lib/git-pivotal-tracker-integration/command/deliver.rb +145 -200
  15. data/lib/git-pivotal-tracker-integration/command/finish.rb +70 -63
  16. data/lib/git-pivotal-tracker-integration/command/newbug.rb +36 -39
  17. data/lib/git-pivotal-tracker-integration/command/newfeature.rb +43 -42
  18. data/lib/git-pivotal-tracker-integration/command/release.rb +171 -203
  19. data/lib/git-pivotal-tracker-integration/command/report.rb +33 -36
  20. data/lib/git-pivotal-tracker-integration/command/start.rb +74 -78
  21. data/lib/git-pivotal-tracker-integration/util/git.rb +202 -204
  22. data/lib/git-pivotal-tracker-integration/util/shell.rb +19 -16
  23. data/lib/git-pivotal-tracker-integration/util/story.rb +155 -177
  24. data/lib/git-pivotal-tracker-integration/version-update/gradle.rb +44 -40
  25. data/lib/git-pivotal-tracker-integration.rb +44 -0
  26. data/spec/git-pivotal-tracker-integration/command/configuration_spec.rb +1 -2
  27. data/spec/git-pivotal-tracker-integration/command/finish_spec.rb +1 -1
  28. data/spec/git-pivotal-tracker-integration/command/release_spec.rb +1 -1
  29. data/spec/git-pivotal-tracker-integration/command/start_spec.rb +1 -1
  30. data/spec/git-pivotal-tracker-integration/util/story_spec.rb +21 -32
  31. data/tracker_api/lib/tracker_api/client.rb +241 -0
  32. data/tracker_api/lib/tracker_api/endpoints/activity.rb +38 -0
  33. data/tracker_api/lib/tracker_api/endpoints/comments.rb +27 -0
  34. data/tracker_api/lib/tracker_api/endpoints/epic.rb +17 -0
  35. data/tracker_api/lib/tracker_api/endpoints/epics.rb +20 -0
  36. data/tracker_api/lib/tracker_api/endpoints/file_attachment.rb +18 -0
  37. data/tracker_api/lib/tracker_api/endpoints/iterations.rb +20 -0
  38. data/tracker_api/lib/tracker_api/endpoints/me.rb +17 -0
  39. data/tracker_api/lib/tracker_api/endpoints/memberships.rb +20 -0
  40. data/tracker_api/lib/tracker_api/endpoints/notifications.rb +20 -0
  41. data/tracker_api/lib/tracker_api/endpoints/project.rb +17 -0
  42. data/tracker_api/lib/tracker_api/endpoints/projects.rb +18 -0
  43. data/tracker_api/lib/tracker_api/endpoints/stories.rb +20 -0
  44. data/tracker_api/lib/tracker_api/endpoints/story.rb +37 -0
  45. data/tracker_api/lib/tracker_api/endpoints/tasks.rb +20 -0
  46. data/tracker_api/lib/tracker_api/error.rb +18 -0
  47. data/tracker_api/lib/tracker_api/logger.rb +31 -0
  48. data/tracker_api/lib/tracker_api/resources/account.rb +18 -0
  49. data/tracker_api/lib/tracker_api/resources/activity.rb +24 -0
  50. data/tracker_api/lib/tracker_api/resources/base.rb +71 -0
  51. data/tracker_api/lib/tracker_api/resources/change.rb +15 -0
  52. data/tracker_api/lib/tracker_api/resources/comment.rb +20 -0
  53. data/tracker_api/lib/tracker_api/resources/epic.rb +17 -0
  54. data/tracker_api/lib/tracker_api/resources/file_attachment.rb +23 -0
  55. data/tracker_api/lib/tracker_api/resources/iteration.rb +24 -0
  56. data/tracker_api/lib/tracker_api/resources/label.rb +14 -0
  57. data/tracker_api/lib/tracker_api/resources/me.rb +21 -0
  58. data/tracker_api/lib/tracker_api/resources/membership_summary.rb +15 -0
  59. data/tracker_api/lib/tracker_api/resources/notification.rb +26 -0
  60. data/tracker_api/lib/tracker_api/resources/person.rb +14 -0
  61. data/tracker_api/lib/tracker_api/resources/primary_resource.rb +13 -0
  62. data/tracker_api/lib/tracker_api/resources/project.rb +131 -0
  63. data/tracker_api/lib/tracker_api/resources/project_membership.rb +16 -0
  64. data/tracker_api/lib/tracker_api/resources/story.rb +102 -0
  65. data/tracker_api/lib/tracker_api/resources/task.rb +16 -0
  66. data/tracker_api/lib/tracker_api/resources/time_zone.rb +13 -0
  67. data/tracker_api/lib/tracker_api/version.rb +3 -0
  68. data/tracker_api/lib/tracker_api.rb +60 -0
  69. metadata +202 -53
  70. data/lib/git-pivotal-tracker-integration/command/command.rb +0 -20
  71. data/lib/git-pivotal-tracker-integration/util/util.rb +0 -20
  72. data/lib/git-pivotal-tracker-integration/version-update/version_update.rb +0 -20
  73. data/lib/git_pivotal_tracker_integration.rb +0 -18
@@ -13,361 +13,274 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License.
15
15
 
16
- require 'git-pivotal-tracker-integration/command/command'
17
- require 'git-pivotal-tracker-integration/command/configuration'
18
- require 'git-pivotal-tracker-integration/util/git'
19
- require 'pivotal-tracker'
20
- require 'parseconfig'
21
- require 'logger'
22
- require 'os'
23
-
24
- # An abstract base class for all commands
25
- # @abstract Subclass and override {#run} to implement command functionality
26
- class GitPivotalTrackerIntegration::Command::Base
27
-
28
- # Common initialization functionality for all command classes. This
29
- # enforces that:
30
- # * the command is being run within a valid Git repository
31
- # * the user has specified their Pivotal Tracker API token
32
- # * all communication with Pivotal Tracker will be protected with SSL
33
- # * the user has configured the project id for this repository
34
- def initialize
35
- self.start_logging
36
- self.check_version
37
-
38
- git_global_push_default = (GitPivotalTrackerIntegration::Util::Shell.exec "git config --global push.default", false).chomp
39
- if git_global_push_default != "simple"
40
- puts "git config --global push.default simple"
41
- puts GitPivotalTrackerIntegration::Util::Shell.exec "git config --global push.default simple"
42
- end
43
-
44
- @repository_root = GitPivotalTrackerIntegration::Util::Git.repository_root
45
- @configuration = GitPivotalTrackerIntegration::Command::Configuration.new
46
- @toggl = Toggl.new
47
-
48
- PivotalTracker::Client.token = @configuration.api_token
49
- PivotalTracker::Client.use_ssl = true
16
+ module GitPivotalTrackerIntegration
17
+ module Command
18
+
19
+ # An abstract base class for all commands
20
+ # @abstract Subclass and override {#run} to implement command functionality
21
+ class Base
22
+
23
+ # Common initialization functionality for all command classes. This
24
+ # enforces that:
25
+ # * the command is being run within a valid Git repository
26
+ # * the user has specified their Pivotal Tracker API token
27
+ # * all communication with Pivotal Tracker will be protected with SSL
28
+ # * the user has configured the project id for this repository
29
+ def initialize
30
+ self.start_logging
31
+ self.check_version
32
+
33
+ git_global_push_default = (Util::Shell.exec "git config --global push.default", false).chomp
34
+ if git_global_push_default != "simple"
35
+ puts "git config --global push.default simple"
36
+ puts Util::Shell.exec "git config --global push.default simple"
37
+ end
38
+
39
+ @repository_root = Util::Git.repository_root
40
+ @toggl = Toggl.new
41
+ @configuration = Command::Configuration.new
42
+
43
+ @configuration.check_for_config_file
44
+ @configuration.check_for_config_contents
45
+
46
+ @client = TrackerApi::Client.new(:token => @configuration.api_token)
47
+ @platform = @configuration.platform_name
48
+
49
+ current_project_id = @configuration.project_id.to_i
50
+ @project = @client.project current_project_id
51
+ my_projects = @client.projects
52
+
53
+ unless my_projects && my_projects.map(&:id).include?(current_project_id)
54
+ project_manager_name = @configuration.pconfig["project"]["project-manager"]
55
+ project_manager_email = @configuration.pconfig["project"]["project-manager-email"]
56
+ project_name = @configuration.pconfig["project"]["project-name"]
57
+ abort "This project requires access to the Pivotal Tracker project [#{project_name} - #{current_project_id}]. Please speak with project manager [#{project_manager_name} - #{project_manager_email}] and ask him to add you to the project in Pivotal Tracker."
58
+ end
59
+ end
50
60
 
51
- @project = PivotalTracker::Project.find @configuration.project_id
52
- @platform = @configuration.platform_name
61
+ def finish_toggle(configuration, time_spent)
62
+ current_story = @configuration.story(@project)
63
+
64
+ # If a story gets rejected and the developer works on it, then we need to check if the task is already created or not.
65
+ params = parameters(configuration, time_spent)
66
+ if params[:tid].nil?
67
+ begin
68
+ @toggl.create_task(parameters(configuration, time_spent))
69
+ rescue TogglException => te
70
+ puts ""
71
+ end
72
+ end
73
+
74
+ #If for some reason time entry cannot be done, then catch exception and continue.
75
+ begin
76
+ @toggl.create_time_entry(parameters(configuration, time_spent))
77
+ rescue TogglException => te
78
+ puts "Unable to log the time."
79
+ end
80
+ end
53
81
 
54
- my_projects = PivotalTracker::Project.all
55
- my_all_projects_ids = Array.new
56
- my_projects.collect{|project| my_all_projects_ids.push project.id.to_i }
57
- current_project_id = @configuration.project_id.to_i
58
- project_manager_name = @configuration.pconfig["project"]["project-manager"]
59
- project_manager_email = @configuration.pconfig["project"]["project-manager-email"]
60
- project_name = @configuration.pconfig["project"]["project-name"]
61
- abort "This project requires access to the Pivotal Tracker project [#{project_name} - #{current_project_id}]. Please speak with project manager [#{project_manager_name} - #{project_manager_email}] and ask him to add you to the project in Pivotal Tracker." unless my_all_projects_ids.include?(current_project_id)
62
- end
82
+ def start_logging
83
+ $LOG = Logger.new("#{logger_filename}", 'weekly')
84
+ end
63
85
 
64
- def finish_toggle(configuration, time_spent)
65
- current_story = @configuration.story(@project)
86
+ def logger_filename
87
+ return "#{Dir.home}/.v2gpti_local.log"
88
+ end
66
89
 
67
- # If a story gets rejected and the developer works on it, then we need to check if the task is already created or not.
68
- params = parameters(configuration, time_spent)
69
- if params[:tid].nil?
70
- begin
71
- @toggl.create_task(parameters(configuration, time_spent))
72
- rescue TogglException => te
90
+ def check_version
91
+ gem_latest_version = (Util::Shell.exec "gem list v2gpti --remote")[/\(.*?\)/].delete "()"
92
+ gem_installed_version = Gem.loaded_specs["v2gpti"].version.version
93
+ if (gem_installed_version == gem_latest_version)
94
+ $LOG.info("v2gpti verison #{gem_installed_version} is up to date.")
95
+ else
96
+ $LOG.fatal("Out of date")
97
+ if OS.windows?
98
+ abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n gem update v2gpti\n\n"
99
+ else
100
+ abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n sudo gem update v2gpti\n\n"
101
+ end
102
+ end
103
+ rescue StandardError => se
73
104
  puts ""
74
105
  end
75
- end
76
106
 
77
- #If for some reason time entry cannot be done, then catch exception and continue.
78
- begin
79
- @toggl.create_time_entry(parameters(configuration, time_spent))
80
- rescue TogglException => te
81
- puts "Unable to log the time."
82
- end
83
- end
84
-
85
- def start_logging
86
- $LOG = Logger.new("#{logger_filename}", 'weekly')
87
- end
107
+ # The main entry point to the command's execution
108
+ # @abstract Override this method to implement command functionality
109
+ def run
110
+ raise NotImplementedError
111
+ end
88
112
 
89
- def logger_filename
90
- return "#{Dir.home}/.v2gpti_local.log"
91
- end
113
+ # Toggl keys
114
+ # name : The name of the task (string, required, unique in project)
115
+ # pid : project ID for the task (integer, required)
116
+ # wid : workspace ID, where the task will be saved (integer, project's workspace id is used when not supplied)
117
+ # uid : user ID, to whom the task is assigned to (integer, not required)
118
+ # estimated_seconds : estimated duration of task in seconds (integer, not required)
119
+ # active : whether the task is done or not (boolean, by default true)
120
+ # at : timestamp that is sent in the response for PUT, indicates the time task was last updated
121
+ # -- Additional fields --
122
+ # done_seconds : duration (in seconds) of all the time entries registered for this task
123
+ # uname : full name of the person to whom the task is assigned to
124
+ TIMER_TOKENS = {
125
+ "m" => (60),
126
+ "h" => (60 * 60),
127
+ "d" => (60 * 60 * 8) # a work day is 8 hours
128
+ }
129
+ def parameters(configuration, time_spent)
130
+ current_story = configuration.story(@project)
131
+ params = Hash.new
132
+ params[:name] = "#{current_story.id}" + " - " + "#{current_story.name}"
133
+ params[:estimated_seconds] = estimated_seconds current_story
134
+ params[:pid] = configuration.toggl_project_id
135
+ params[:uid] = @toggl.me["id"]
136
+ params[:tags] = [current_story.story_type]
137
+ params[:active] = false
138
+ params[:description] = "#{current_story.id}" + " commit:" + "#{(Util::Shell.exec "git rev-parse HEAD").chomp[0..6]}"
139
+ params[:created_with] = "v2gpti"
140
+ params[:duration] = seconds_spent(time_spent)
141
+ params[:start] = (Time.now - params[:duration]).iso8601
142
+ task = @toggl.get_project_task_with_name(configuration.toggl_project_id, "#{current_story.id}")
143
+ if !task.nil?
144
+ params[:tid] = task['id']
145
+ end
146
+ params
147
+ end
148
+ def seconds_spent(time_spent)
149
+ seconds = 0
150
+ time_spent.scan(/(\d+)(\w)/).each do |amount, measure|
151
+ seconds += amount.to_i * TIMER_TOKENS[measure]
152
+ end
153
+ seconds
154
+ end
155
+ def estimated_seconds(story)
156
+ estimate = story.estimate
157
+ seconds = 0
158
+ case estimate
159
+ when 0
160
+ estimate = 15 * 60
161
+ when 1
162
+ estimate = 1.25 * 60 * 60
163
+ when 2
164
+ estimate = 3 * 60 * 60
165
+ when 3
166
+ estimate = 8 * 60 * 60
167
+ else
168
+ estimate = -1 * 60 * 60
169
+ end
170
+ estimate
171
+ end
92
172
 
93
- def check_version
94
- gem_latest_version = (GitPivotalTrackerIntegration::Util::Shell.exec "gem list v2gpti --remote")[/\(.*?\)/].delete "()"
95
- gem_installed_version = Gem.loaded_specs["v2gpti"].version.version
96
- if (gem_installed_version == gem_latest_version)
97
- $LOG.info("v2gpti verison #{gem_installed_version} is up to date.")
98
- else
99
- $LOG.fatal("Out of date")
100
- if OS.windows?
101
- abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n gem update v2gpti\n\n"
102
- else
103
- abort "\n\nYou are using v2gpti version #{gem_installed_version}, but the current version is #{gem_latest_version}.\nPlease update your gem with the following command.\n\n sudo gem update v2gpti\n\n"
104
- end
105
- end
106
- rescue StandardError => se
107
- puts ""
108
- end
173
+ def create_story(args)
174
+ story_types = {"f" => "feature", "b" => "bug", "c" => "chore"}
175
+ new_story_type = nil
176
+ new_story_title = nil
177
+ new_story_estimate = -1
178
+ args.each do |arg|
179
+ new_story_type = story_types[arg[-1]] if arg.include? '-n'
180
+ new_story_title = arg if arg[0] != "-"
181
+ end
109
182
 
110
- # The main entry point to the command's execution
111
- # @abstract Override this method to implement command functionality
112
- def run
113
- raise NotImplementedError
114
- end
183
+ while new_story_type.nil?
184
+ nst = ask("Please enter f for feature, b for bug, or c for chore")
185
+ new_story_type = story_types[nst]
186
+ end
115
187
 
116
- # Toggl keys
117
- # name : The name of the task (string, required, unique in project)
118
- # pid : project ID for the task (integer, required)
119
- # wid : workspace ID, where the task will be saved (integer, project's workspace id is used when not supplied)
120
- # uid : user ID, to whom the task is assigned to (integer, not required)
121
- # estimated_seconds : estimated duration of task in seconds (integer, not required)
122
- # active : whether the task is done or not (boolean, by default true)
123
- # at : timestamp that is sent in the response for PUT, indicates the time task was last updated
124
- # -- Additional fields --
125
- # done_seconds : duration (in seconds) of all the time entries registered for this task
126
- # uname : full name of the person to whom the task is assigned to
127
- TIMER_TOKENS = {
128
- "m" => (60),
129
- "h" => (60 * 60),
130
- "d" => (60 * 60 * 8) # a work day is 8 hours
131
- }
132
- def parameters(configuration, time_spent)
133
- current_story = configuration.story(@project)
134
- params = Hash.new
135
- params[:name] = "#{current_story.id}" + " - " + "#{current_story.name}"
136
- params[:estimated_seconds] = estimated_seconds current_story
137
- params[:pid] = configuration.toggl_project_id
138
- params[:uid] = @toggl.me["id"]
139
- params[:tags] = [current_story.story_type]
140
- params[:active] = false
141
- params[:description] = "#{current_story.id}" + " commit:" + "#{(GitPivotalTrackerIntegration::Util::Shell.exec "git rev-parse HEAD").chomp[0..6]}"
142
- params[:created_with] = "v2gpti"
143
- params[:duration] = seconds_spent(time_spent)
144
- params[:start] = (Time.now - params[:duration]).iso8601
145
- task = @toggl.get_project_task_with_name(configuration.toggl_project_id, "#{current_story.id}")
146
- if !task.nil?
147
- params[:tid] = task['id']
148
- end
149
- params
150
- end
151
- def seconds_spent(time_spent)
152
- seconds = 0
153
- time_spent.scan(/(\d+)(\w)/).each do |amount, measure|
154
- seconds += amount.to_i * TIMER_TOKENS[measure]
155
- end
156
- seconds
157
- end
158
- def estimated_seconds(story)
159
- estimate = story.estimate
160
- seconds = 0
161
- case estimate
162
- when 0
163
- estimate = 15 * 60
164
- when 1
165
- estimate = 1.25 * 60 * 60
166
- when 2
167
- estimate = 3 * 60 * 60
168
- when 3
169
- estimate = 8 * 60 * 60
170
- else
171
- estimate = -1 * 60 * 60
172
- end
173
- estimate
174
- end
188
+ while (new_story_title.nil? || new_story_title.empty?)
189
+ new_story_title = ask("Please enter the title for this #{new_story_type}.")
190
+ end
175
191
 
176
- def create_story(args)
177
- story_types = {"f" => "feature", "b" => "bug", "c" => "chore"}
178
- new_story_type = nil
179
- new_story_title = nil
180
- new_story_estimate = -1
181
- args.each do |arg|
182
- new_story_type = story_types[arg[-1]] if arg.include? '-n'
183
- new_story_title = arg if arg[0] != "-"
184
- end
192
+ if (new_story_type == "feature" && (new_story_estimate < 0 || new_story_estimate > 3))
193
+ new_story_estimate = estimate_story
194
+ end
185
195
 
186
- while new_story_type.nil?
187
- nst = ask("Please enter f for feature, b for bug, or c for chore")
188
- new_story_type = story_types[nst]
189
- end
196
+ attrs = {:story_type => new_story_type, :current_state => 'unstarted', :name => new_story_title}
197
+ attrs[:estimate] = new_story_estimate if new_story_type == "feature"
190
198
 
191
- while (new_story_title.nil? || new_story_title.empty?)
192
- new_story_title = ask("Please enter the title for this #{new_story_type}.")
193
- end
199
+ @project.create_story(attrs)
194
200
 
195
- while (new_story_type == "feature" && (new_story_estimate < 0 || new_story_estimate > 3))
196
- nse = ask("Please enter an estimate for this #{new_story_type}. (0,1,2,3)")
197
- if !nse.empty?
198
- new_story_estimate = nse.to_i
199
201
  end
200
- end
201
202
 
202
- new_story = PivotalTracker::Story.new
203
- new_story.project_id = @project.id
204
- new_story.story_type = new_story_type
205
- new_story.current_state = "unstarted"
206
- new_story.name = new_story_title
207
- if new_story_type == "feature"
208
- new_story.estimate = new_story_estimate
209
- end
203
+ def create_icebox_bug_story(args)
204
+ create_story_with_type_state("bug", "unscheduled", args)
205
+ end
210
206
 
211
- uploaded_story = new_story.create
207
+ def create_backlog_bug_story(args)
208
+ create_story_with_type_state("bug", "unstarted", args)
209
+ end
212
210
 
213
- end
211
+ def create_icebox_feature_story(args)
212
+ create_story_with_type_state("feature", "unscheduled", args)
213
+ end
214
214
 
215
- def create_icebox_bug_story(args)
216
- new_bug_story_title = nil
217
- args.each do |arg|
218
- new_bug_story_title = arg if arg[0] != "-"
215
+ def create_backlog_feature_story(args)
216
+ create_story_with_type_state("feature", "unstarted", args)
219
217
  end
220
- while (new_bug_story_title.nil? || new_bug_story_title.empty?)
221
- new_bug_story_title = ask("Please enter the title for this bug story")
222
- end
223
- icebox_stories = Array.new
224
- @project.stories.all.collect{|story| icebox_stories.push story if story.current_state == "unscheduled"}
225
- new_bug_story = PivotalTracker::Story.new
226
- new_bug_story.project_id = @project.id
227
- new_bug_story.story_type = "bug"
228
- new_bug_story.current_state = "unscheduled"
229
- new_bug_story.name = new_bug_story_title
230
-
231
- if args.any?{|arg| arg.include?("-tl") } && !(icebox_stories.empty? || icebox_stories.nil?)
232
- icebox_first_story = icebox_stories.first
233
- (new_bug_story.create).move(:before, icebox_first_story)
234
- elsif args.any?{|arg| arg.include?("-bl")} && !(icebox_stories.empty? || icebox_stories.nil?)
235
- icebox_last_story = icebox_stories.last
236
- (new_bug_story.create).move(:after, icebox_last_story)
237
- else
238
- new_bug_story.create
239
- end
240
- end
241
218
 
242
- def create_backlog_bug_story(args)
243
- new_bug_story_title = nil
244
- args.each do |arg|
245
- new_bug_story_title = arg if arg[0] != "-"
246
- end
247
- while (new_bug_story_title.nil? || new_bug_story_title.empty?)
248
- new_bug_story_title = ask("Please enter the title for this bug story")
249
- end
250
- backlog_stories = Array.new
251
- @project.stories.all.collect{|story| backlog_stories.push story if story.current_state == "unstarted" && story.story_type != "release"}
252
- new_bug_story = PivotalTracker::Story.new
253
- new_bug_story.project_id = @project.id
254
- new_bug_story.story_type = "bug"
255
- new_bug_story.current_state = "unstarted"
256
- new_bug_story.name = new_bug_story_title
257
- if args.any?{|arg| arg.include?("-tl")} && !(backlog_stories.empty? || backlog_stories.nil?)
258
- backlog_first_story = backlog_stories.first
259
- (new_bug_story.create).move(:before, backlog_first_story)
260
- elsif args.any?{|arg| arg.include?("-bl")} && !(backlog_stories.empty? || backlog_stories.nil?)
261
- backlog_last_story = backlog_stories.last
262
- (new_bug_story.create).move(:after, backlog_last_story)
263
- else
264
- new_bug_story.create
265
- end
266
- end
219
+ private
267
220
 
268
- def create_icebox_feature_story(args)
269
- new_feature_story_title = nil
270
- new_feature_story_points = nil
271
- args.each do |arg|
272
- new_feature_story_title = arg if arg[0] != "-"
273
- end
274
- while (new_feature_story_title.nil? || new_feature_story_title.empty?)
275
- new_feature_story_title = ask("\nPlease enter the title for this feature story")
221
+ def pwd
222
+ command = OS.windows? ? 'echo %cd%': 'pwd'
223
+ Util::Shell.exec(command).chop
276
224
  end
277
- icebox_stories = Array.new
278
- @project.stories.all.collect{|story| icebox_stories.push story if story.current_state == "unscheduled"}
279
- new_feature_story = PivotalTracker::Story.new
280
- new_feature_story.project_id = @project.id
281
- new_feature_story.story_type = "feature"
282
- new_feature_story.current_state = "unscheduled"
283
- new_feature_story.name = new_feature_story_title
284
-
285
- args.each do |arg|
286
- new_feature_story_points = arg[2] if arg[0] == "-" && arg[1].downcase == "p"
287
- end
288
- while (new_feature_story_points.nil? || new_feature_story_points.empty?)
289
- new_feature_story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
290
- end
291
- while (!["0","1","2","3","n"].include?(new_feature_story_points.downcase))
292
- new_feature_story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
225
+
226
+ def estimate_story
227
+ estimate = ask("Please enter the estimate points(0/1/2/3) for this story.") do |q|
228
+ q.in = ["0", "1", "2", "3"]
229
+ q.responses[:not_in_range] = "Invalid entry...Please enter the estimate points(0/1/2/3) for this story."
230
+ end
231
+ estimate.to_i
293
232
  end
294
- if new_feature_story_points.downcase == "n"
295
- new_feature_story.estimate = -1
296
- else
297
- new_feature_story.estimate = new_feature_story_points
233
+
234
+ def estimate_story_optional
235
+ estimate = ask("Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n") do |q|
236
+ q.in = ["0", "1", "2", "3", "n"]
237
+ q.responses[:not_in_range] = "Invalid entry...Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n"
238
+ end
239
+ if estimate == "n"
240
+ estimate = nil
241
+ else
242
+ estimate.to_i
243
+ end
298
244
  end
299
245
 
246
+ def create_story_with_type_state(type, state, args)
247
+ story_title = nil
248
+ story_points = nil
300
249
 
301
- if args.any?{|arg| arg.include?("-tl") } && !(icebox_stories.empty? || icebox_stories.nil?)
302
- icebox_first_story = icebox_stories.first
303
- (new_feature_story.create).move(:before, icebox_first_story)
304
- elsif args.any?{|arg| arg.include?("-bl")} && !(icebox_stories.empty? || icebox_stories.nil?)
305
- icebox_last_story = icebox_stories.last
306
- (new_feature_story.create).move(:after, icebox_last_story)
307
- else
308
- new_feature_story.create
309
- end
310
- end
250
+ args.each {|arg| story_title = arg if arg[0] != "-" }
311
251
 
312
- def create_backlog_feature_story(args)
313
- new_feature_story_title = nil
314
- new_feature_story_points = nil
315
- args.each do |arg|
316
- new_feature_story_title = arg if arg[0] != "-"
317
- end
318
- while (new_feature_story_title.nil? || new_feature_story_title.empty?)
319
- new_feature_story_title = ask("\nPlease enter the title for this feature story")
320
- end
321
- backlog_stories = Array.new
322
- @project.stories.all.collect{|story| backlog_stories.push story if story.current_state == "unstarted" && story.story_type != "release"}
323
- new_feature_story = PivotalTracker::Story.new
324
- new_feature_story.project_id = @project.id
325
- new_feature_story.story_type = "feature"
326
- new_feature_story.current_state = "unstarted"
327
- new_feature_story.name = new_feature_story_title
328
-
329
- args.each do |arg|
330
- new_feature_story_points = arg[2] if arg[0] == "-" && arg[1].downcase == "p"
331
- end
332
- while (new_feature_story_points.nil? || new_feature_story_points.empty?)
333
- new_feature_story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
334
- end
335
- while (!["0","1","2","3","n"].include?(new_feature_story_points.downcase))
336
- new_feature_story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this feature story.\nIf you don't want to estimate then enter n")
337
- end
338
- if new_feature_story_points.downcase == "n"
339
- new_feature_story.estimate = -1
340
- else
341
- new_feature_story.estimate = new_feature_story_points
342
- end
252
+ while (story_title.nil? || story_title.empty?)
253
+ story_title = ask("Please enter the title for the story")
254
+ end
343
255
 
344
- if args.any?{|arg| arg.include?("-tl")} && !(backlog_stories.empty? || backlog_stories.nil?)
345
- backlog_first_story = backlog_stories.first
346
- (new_feature_story.create).move(:before, backlog_first_story)
347
- elsif args.any?{|arg| arg.include?("-bl")} && !(backlog_stories.empty? || backlog_stories.nil?)
348
- backlog_last_story = backlog_stories.last
349
- (new_feature_story.create).move(:after, backlog_last_story)
350
- else
351
- new_feature_story.create
352
- end
353
- end
256
+ story_params = {:story_type => type, :current_state => state, :name => story_title}
354
257
 
355
- private
258
+ # if it is a feature, get the estimate for the story.
259
+ # if it is not provided in the command line, ask for it
260
+ if type == "feature" #set the story points if it is feature story
261
+ args.each do |arg|
262
+ story_points = arg[2] if arg[0] == "-" && arg[1].downcase == "p"
263
+ end
264
+ story_points = estimate_story_optional if story_points.nil? || story_points.empty?
265
+ story_params[:estimate] = story_points unless story_points.nil?
266
+ end
356
267
 
357
- def pwd
358
- command = OS.windows? ? 'echo %cd%': 'pwd'
359
- GitPivotalTrackerIntegration::Util::Shell.exec(command).chop
360
- end
268
+ story = @project.create_story(story_params)
269
+
270
+ #move the story
271
+ stories = @project.stories(:with_state => state, :fields => 'name')
272
+
273
+ if args.any?{|arg| arg.include?("-tl") } && !(stories.empty? || stories.nil?)
274
+ story.before_id = stories.first.id
275
+ elsif args.any?{|arg| arg.include?("-bl")} && !(stories.empty? || stories.nil?)
276
+ story.after_id = stories.last.id
277
+ end
278
+
279
+ story.save
280
+ story
281
+ end
361
282
 
362
- def estimate_story(story)
363
- story_points = nil
364
- while (story_points.nil? || story_points.empty?)
365
- story_points = ask("\nPlease enter the estimate points(0/1/2/3) for this story.")
366
- end
367
- while (!["0","1","2","3"].include?(story_points))
368
- story_points = ask("\nInvalid entry...Please enter the estimate points(0/1/2/3) for this story.")
369
283
  end
370
- story.update(:estimate => story_points)
371
- end
372
284
 
285
+ end
373
286
  end