v2gpti 0.2.0.10 → 0.2.1

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
  SHA1:
3
- metadata.gz: 8d70e3a0e7deecec5a5fd74d50caa4e4c2c7f394
4
- data.tar.gz: 48abb41a07c63fa84293af545e16a9bdb8d23b91
3
+ metadata.gz: 2d42ceb59abdcceff2e129b8c7144be02fa73995
4
+ data.tar.gz: ad715bb77d922aa00d920367fbbd53b75d457b90
5
5
  SHA512:
6
- metadata.gz: 7f04a5cab459c672a655853f77a66942bfec74097c98232de30e43330bb124837d07cd4ffc9302e88fa3391d96b2884d62015df220a2274db2edcaa0003eac6b
7
- data.tar.gz: dd6cd2e9bf763c85c002687d6b6bfe0ad42223ca2efb59ac1b6bbb9f17359c31a494ff0835162b3ff97369574ae0f82402273fa1d1dea6d1e32d02fdd922c447
6
+ metadata.gz: c595151e4329039ed4235470dea778b0e0c13e5af5a3c7f59f4a2d1fa20df121acf781bf0ca37d58e2b32dfa87ca66be8aef7c7a5b4b1c2ca8df662a58cd0d5c
7
+ data.tar.gz: 7bd8509a922209ff1edeb5473bd48f69642e1f12429d2b2ebeaa562f82f88249e15f4b900ea6a66480ebb4ee22f93954f76393b099d5a9c94a7f4c4bc4b60eda
@@ -20,7 +20,6 @@ require 'pivotal-tracker'
20
20
  require 'parseconfig'
21
21
  require 'logger'
22
22
 
23
-
24
23
  # An abstract base class for all commands
25
24
  # @abstract Subclass and override {#run} to implement command functionality
26
25
  class GitPivotalTrackerIntegration::Command::Base
@@ -36,13 +35,18 @@ class GitPivotalTrackerIntegration::Command::Base
36
35
  self.check_version
37
36
  @repository_root = GitPivotalTrackerIntegration::Util::Git.repository_root
38
37
  @configuration = GitPivotalTrackerIntegration::Command::Configuration.new
38
+ @toggl = Toggl.new
39
39
 
40
40
  PivotalTracker::Client.token = @configuration.api_token
41
41
  PivotalTracker::Client.use_ssl = true
42
42
 
43
43
  @project = PivotalTracker::Project.find @configuration.project_id
44
44
  end
45
-
45
+ def finish_toggle(configuration, time_spent)
46
+ current_story = @configuration.story(@project)
47
+ @toggl.create_task(parameters(configuration, time_spent))
48
+ @toggl.create_time_entry(parameters(configuration, time_spent))
49
+ end
46
50
  def start_logging
47
51
  $LOG = Logger.new("#{Dir.home}/.v2gpti_local.log", 'weekly')
48
52
  end
@@ -65,4 +69,60 @@ class GitPivotalTrackerIntegration::Command::Base
65
69
  raise NotImplementedError
66
70
  end
67
71
 
68
- end
72
+ # name : The name of the task (string, required, unique in project)
73
+ # pid : project ID for the task (integer, required)
74
+ # wid : workspace ID, where the task will be saved (integer, project's workspace id is used when not supplied)
75
+ # uid : user ID, to whom the task is assigned to (integer, not required)
76
+ # estimated_seconds : estimated duration of task in seconds (integer, not required)
77
+ # active : whether the task is done or not (boolean, by default true)
78
+ # at : timestamp that is sent in the response for PUT, indicates the time task was last updated
79
+ # -- Additional fields --
80
+ # done_seconds : duration (in seconds) of all the time entries registered for this task
81
+ # uname : full name of the person to whom the task is assigned to
82
+ TIMER_TOKENS = {
83
+ "m" => (60),
84
+ "h" => (60 * 60),
85
+ "d" => (60 * 60 * 8) # a work day is 8 hours
86
+ }
87
+ def parameters(configuration, time_spent)
88
+ current_story = configuration.story(@project)
89
+ params = Hash.new
90
+ params[:name] = "#{current_story.id}" + " - " + "#{current_story.name}"
91
+ params[:estimated_seconds] = estimated_seconds current_story
92
+ params[:pid] = configuration.toggl_project_id
93
+ params[:uid] = @toggl.me["id"]
94
+ params[:description] = "#{current_story.id}" + " commit:" + "#{(GitPivotalTrackerIntegration::Util::Shell.exec "git rev-parse HEAD").chomp[0..6]}"
95
+ params[:created_with] = "v2gpti"
96
+ params[:start] = current_story.created_at.iso8601
97
+ params[:duration] = seconds_spent(time_spent)
98
+ task = @toggl.get_project_task_with_name(configuration.toggl_project_id, "#{current_story.id}")
99
+ if !task.nil?
100
+ params[:tid] = task['id']
101
+ end
102
+ params
103
+ end
104
+ def seconds_spent(time_spent)
105
+ seconds = 0
106
+ time_spent.scan(/(\d+)(\w)/).each do |amount, measure|
107
+ seconds += amount.to_i * TIMER_TOKENS[measure]
108
+ end
109
+ seconds
110
+ end
111
+ def estimated_seconds(story)
112
+ estimate = story.estimate
113
+ seconds = 0
114
+ case estimate
115
+ when 0
116
+ estimate = 15 * 60
117
+ when 1
118
+ estimate = 1.25 * 60 * 60
119
+ when 2
120
+ estiamte = 3 * 60 * 60
121
+ when 3
122
+ estimate = 8 * 60 * 60
123
+ else
124
+ estimate = -1 * 60 * 60
125
+ end
126
+ estimate
127
+ end
128
+ end
@@ -17,6 +17,8 @@ require 'git-pivotal-tracker-integration/command/command'
17
17
  require 'git-pivotal-tracker-integration/util/git'
18
18
  require 'highline/import'
19
19
  require 'pivotal-tracker'
20
+ require 'git-pivotal-tracker-integration/util/togglV8'
21
+ require 'time'
20
22
 
21
23
  # A class that exposes configuration that commands can use
22
24
  class GitPivotalTrackerIntegration::Command::Configuration
@@ -39,16 +41,28 @@ class GitPivotalTrackerIntegration::Command::Configuration
39
41
  api_token
40
42
  end
41
43
 
42
- def check_config_project_id
43
- repo_root = GitPivotalTrackerIntegration::Util::Git.repository_root
44
- config_filename = "#{repo_root}/.v2gpti/config"
45
- if File.file?(config_filename)
46
- pconfig = ParseConfig.new(config_filename)
47
- GitPivotalTrackerIntegration::Util::Git.set_config("pivotal.project-id", pconfig["pivotal-tracker"]["project-id"])
44
+ def toggl_project_id
45
+ toggle_config = self.pconfig["toggl"]
46
+ if toggle_config.nil?
47
+ abort "toggle project id not set"
48
+ else
49
+ toggle_config["project-id"]
48
50
  end
51
+ end
52
+
53
+ def check_config_project_id
54
+ GitPivotalTrackerIntegration::Util::Git.set_config("pivotal.project-id", self.pconfig["pivotal-tracker"]["project-id"])
49
55
  nil
50
56
  end
51
57
 
58
+ def pconfig
59
+ pc = nil
60
+ config_filename = "#{GitPivotalTrackerIntegration::Util::Git.repository_root}/.v2gpti/config"
61
+ if File.file?(config_filename)
62
+ pc = ParseConfig.new(config_filename)
63
+ end
64
+ pc
65
+ end
52
66
  # Returns the Pivotal Tracker project id for this repository. If this id
53
67
  # has not been configuration, prompts the user for the value. The value is
54
68
  # checked for in the _inherited_ Git configuration, but is stored in the
@@ -30,7 +30,15 @@ class GitPivotalTrackerIntegration::Command::Finish < GitPivotalTrackerIntegrati
30
30
  def run(argument)
31
31
  $LOG.debug("#{self.class} in project:#{@project.name} pwd:#{(GitPivotalTrackerIntegration::Util::Shell.exec 'pwd').chop} branch:#{GitPivotalTrackerIntegration::Util::Git.branch_name}")
32
32
  no_complete = argument =~ /--no-complete/
33
-
33
+ time_spent = ""
34
+ while 1
35
+ time_spent = ask("How much time did you spend on this task? (example: 15m, 2.5h)")
36
+ if (/\d/.match( time_spent )) && /[mhd]/.match(time_spent)
37
+ break
38
+ end
39
+ end
40
+ finish_toggle(@configuration, time_spent)
41
+ # ask("pause")
34
42
  GitPivotalTrackerIntegration::Util::Git.trivial_merge?
35
43
  $LOG.debug("configuration:#{@configuration}")
36
44
  $LOG.debug("project:#{@project}")
@@ -39,4 +47,6 @@ class GitPivotalTrackerIntegration::Command::Finish < GitPivotalTrackerIntegrati
39
47
  GitPivotalTrackerIntegration::Util::Git.push GitPivotalTrackerIntegration::Util::Git.branch_name
40
48
  end
41
49
 
50
+
51
+
42
52
  end
@@ -43,6 +43,7 @@ class GitPivotalTrackerIntegration::Util::Story
43
43
  puts
44
44
  end
45
45
 
46
+
46
47
  # Selects a Pivotal Tracker story by doing the following steps:
47
48
  #
48
49
  # @param [PivotalTracker::Project] project the project to select stories from
@@ -0,0 +1,417 @@
1
+ #! /usr/bin/env rvm ruby-1.9.3-head do ruby
2
+ # encoding: utf-8
3
+
4
+ require 'rubygems'
5
+ require 'logger'
6
+ require 'faraday'
7
+ require 'json'
8
+
9
+ require 'awesome_print' # for debug output
10
+
11
+ class Toggl
12
+ attr_accessor :conn, :debug
13
+
14
+ def initialize(username=nil, password='api_token', debug=nil)
15
+ self.debug_on(debug) if !debug.nil?
16
+ if (password.to_s == 'api_token' && username.to_s == '')
17
+ toggl_api_file = self.toggl_file
18
+ username = IO.read(toggl_api_file)
19
+
20
+ end
21
+
22
+ @conn = connection(username, password)
23
+ end
24
+
25
+ def toggl_file
26
+ t_file = ENV['HOME']+'/.toggl'
27
+ if !FileTest.exist?(t_file) then
28
+ puts "\n\nIt looks like this is the first time you have used Toggl on this machine.\n"
29
+ t_API_key = ask("Please enter your Toggl API key:")
30
+ output = File.open( t_file, "w")
31
+ output << t_API_key
32
+ output.close
33
+ end
34
+
35
+ t_file
36
+ end
37
+ def connection(username, password)
38
+ Faraday.new(url: 'https://www.toggl.com/api/v8') do |faraday|
39
+ faraday.request :url_encoded
40
+ faraday.response :logger, Logger.new('faraday.log')
41
+ faraday.adapter Faraday.default_adapter
42
+ faraday.headers = {"Content-Type" => "application/json"}
43
+ faraday.basic_auth username, password
44
+ end
45
+ end
46
+
47
+ def debug_on(debug=true)
48
+ puts "debugging is %s" % [debug ? "ON" : "OFF"]
49
+ @debug = debug
50
+ end
51
+
52
+ def checkParams(params, fields=[])
53
+ raise ArgumentError, 'params is not a Hash' unless params.is_a? Hash
54
+ return if fields.empty?
55
+ errors = []
56
+ for f in fields
57
+ errors.push("params[#{f}] is required") unless params.has_key?(f)
58
+ end
59
+ raise ArgumentError, errors.join(', ') if !errors.empty?
60
+ end
61
+
62
+ #----------#
63
+ #--- Me ---#
64
+ #----------#
65
+
66
+ def me(all=nil)
67
+ # TODO: Reconcile this with get_client_projects
68
+ res = get "me%s" % [all.nil? ? "" : "?with_related_data=#{all}"]
69
+ end
70
+
71
+ def my_clients(user)
72
+ user['projects']
73
+ end
74
+
75
+ def my_projects(user)
76
+ user['projects']
77
+ end
78
+
79
+ def my_tags(user)
80
+ user['tags']
81
+ end
82
+
83
+ def my_time_entries(user)
84
+ user['time_entries']
85
+ end
86
+
87
+ def my_workspaces(user)
88
+ user['workspaces']
89
+ end
90
+
91
+ #---------------#
92
+ #--- Clients ---#
93
+ #---------------#
94
+
95
+ # name : The name of the client (string, required, unique in workspace)
96
+ # wid : workspace ID, where the client will be used (integer, required)
97
+ # notes : Notes for the client (string, not required)
98
+ # hrate : The hourly rate for this client (float, not required, available only for pro workspaces)
99
+ # cur : The name of the client's currency (string, not required, available only for pro workspaces)
100
+ # at : timestamp that is sent in the response, indicates the time client was last updated
101
+
102
+ def create_client(params)
103
+ checkParams(params, [:name, :wid])
104
+ post "clients", {client: params}
105
+ end
106
+
107
+ def get_client(client_id)
108
+ get "clients/#{client_id}"
109
+ end
110
+
111
+ def update_client(client_id, params)
112
+ put "clients/#{client_id}", {client: params}
113
+ end
114
+
115
+ def delete_client(client_id)
116
+ delete "clients/#{client_id}"
117
+ end
118
+
119
+ def get_client_projects(client_id, params={})
120
+ active = params.has_key?(:active) ? "?active=#{params[:active]}" : ""
121
+ get "clients/#{client_id}/projects#{active}"
122
+ end
123
+
124
+
125
+ #----------------#
126
+ #--- Projects ---#
127
+ #----------------#
128
+
129
+ # name : The name of the project (string, required, unique for client and workspace)
130
+ # wid : workspace ID, where the project will be saved (integer, required)
131
+ # cid : client ID(integer, not required)
132
+ # active : whether the project is archived or not (boolean, by default true)
133
+ # is_private : whether project is accessible for only project users or for all workspace users (boolean, default true)
134
+ # template : whether the project can be used as a template (boolean, not required)
135
+ # template_id : id of the template project used on current project's creation
136
+ # billable : whether the project is billable or not (boolean, default true, available only for pro workspaces)
137
+ # at : timestamp that is sent in the response for PUT, indicates the time task was last updated
138
+ # -- Undocumented --
139
+ # color : number (in the range 0-23?)
140
+
141
+ def create_project(params)
142
+ checkParams(params, [:name, :wid])
143
+ post "projects", {project: params}
144
+ end
145
+
146
+ def get_project(project_id)
147
+ get "projects/#{project_id}"
148
+ end
149
+
150
+ def update_project(project_id, params)
151
+ put "projects/#{project_id}", {project: params}
152
+ end
153
+
154
+ def get_project_users(project_id)
155
+ get "projects/#{project_id}/project_users"
156
+ end
157
+
158
+ def get_project_tasks(project_id)
159
+ get "projects/#{project_id}/tasks"
160
+ end
161
+
162
+ def get_project_task_with_name(project_id, task_name)
163
+ task = nil
164
+ project_tasks = get_project_tasks(project_id)
165
+ project_tasks.each { |a_task|
166
+ a_task_name = "#{a_task["name"]}"
167
+ if (a_task_name.include?task_name)
168
+ task = a_task
169
+ break
170
+ end
171
+ }
172
+ task
173
+ end
174
+ #---------------------#
175
+ #--- Project users ---#
176
+ #---------------------#
177
+
178
+ # pid : project ID (integer, required)
179
+ # uid : user ID, who is added to the project (integer, required)
180
+ # wid : workspace ID, where the project belongs to (integer, not-required, project's workspace id is used)
181
+ # manager : admin rights for this project (boolean, default false)
182
+ # rate : hourly rate for the project user (float, not-required, only for pro workspaces) in the currency of the project's client or in workspace default currency.
183
+ # at : timestamp that is sent in the response, indicates when the project user was last updated
184
+ # -- Additional fields --
185
+ # fullname : full name of the user, who is added to the project
186
+
187
+ def create_project_user(params)
188
+ checkParams(params, [:pid, :uid])
189
+ params[:fields] = "fullname" # for simplicity, always request fullname field
190
+ post "project_users", {project_user: params}
191
+ end
192
+
193
+ def update_project_user(project_user_id, params)
194
+ params[:fields] = "fullname" # for simplicity, always request fullname field
195
+ put "project_users/#{project_user_id}", {project_user: params}
196
+ end
197
+
198
+ def delete_project_user(project_user_id)
199
+ delete "project_users/#{project_user_id}"
200
+ end
201
+
202
+ #------------#
203
+ #--- Tags ---#
204
+ #------------#
205
+
206
+ # name : The name of the tag (string, required, unique in workspace)
207
+ # wid : workspace ID, where the tag will be used (integer, required)
208
+
209
+ def create_tag(params)
210
+ checkParams(params, [:name, :wid])
211
+ post "tags", {tag: params}
212
+ end
213
+
214
+ # ex: update_tag(12345, {name: "same tame game"})
215
+ def update_tag(tag_id, params)
216
+ put "tags/#{tag_id}", {tag: params}
217
+ end
218
+
219
+ def delete_tag(tag_id)
220
+ delete "tags/#{tag_id}"
221
+ end
222
+
223
+ #-------------#
224
+ #--- Tasks ---#
225
+ #-------------#
226
+
227
+ # name : The name of the task (string, required, unique in project)
228
+ # pid : project ID for the task (integer, required)
229
+ # wid : workspace ID, where the task will be saved (integer, project's workspace id is used when not supplied)
230
+ # uid : user ID, to whom the task is assigned to (integer, not required)
231
+ # estimated_seconds : estimated duration of task in seconds (integer, not required)
232
+ # active : whether the task is done or not (boolean, by default true)
233
+ # at : timestamp that is sent in the response for PUT, indicates the time task was last updated
234
+ # -- Additional fields --
235
+ # done_seconds : duration (in seconds) of all the time entries registered for this task
236
+ # uname : full name of the person to whom the task is assigned to
237
+
238
+ def create_task(params)
239
+ checkParams(params, [:name, :pid])
240
+ post "tasks", {task: params}
241
+ end
242
+
243
+ def get_task(task_id)
244
+ get "tasks/#{task_id}"
245
+ end
246
+
247
+ # ex: update_task(1894675, {active: true, estimated_seconds: 4500, fields: "done_seconds,uname"})
248
+ def update_task(*task_id, params)
249
+ put "tasks/#{task_id.join(',')}", {task: params}
250
+ end
251
+
252
+ def delete_task(*task_id)
253
+ delete "tasks/#{task_id.join(',')}"
254
+ end
255
+
256
+ #--------------------#
257
+ #--- Time entries ---#
258
+ #--------------------#
259
+
260
+ # description : (string, required)
261
+ # wid : workspace ID (integer, required if pid or tid not supplied)
262
+ # pid : project ID (integer, not required)
263
+ # tid : task ID (integer, not required)
264
+ # billable : (boolean, not required, default false, available for pro workspaces)
265
+ # start : time entry start time (string, required, ISO 8601 date and time)
266
+ # stop : time entry stop time (string, not required, ISO 8601 date and time)
267
+ # duration : time entry duration in seconds. If the time entry is currently running, the duration attribute contains a negative value, denoting the start of the time entry in seconds since epoch (Jan 1 1970). The correct duration can be calculated as current_time + duration, where current_time is the current time in seconds since epoch. (integer, required)
268
+ # created_with : the name of your client app (string, required)
269
+ # tags : a list of tag names (array of strings, not required)
270
+ # duronly : should Toggl show the start and stop time of this time entry? (boolean, not required)
271
+ # at : timestamp that is sent in the response, indicates the time item was last updated
272
+
273
+ def create_time_entry(params)
274
+ checkParams(params, [:description, :start, :created_with])
275
+ if !params.has_key?(:wid) and !params.has_key?(:pid) and !params.has_key?(:tid) then
276
+ raise ArgumentError, "one of params['wid'], params['pid'], params['tid'] is required"
277
+ end
278
+ post "time_entries", {time_entry: params}
279
+ end
280
+
281
+ def start_time_entry(params)
282
+ if !params.has_key?(:wid) and !params.has_key?(:pid) and !params.has_key?(:tid) then
283
+ raise ArgumentError, "one of params['wid'], params['pid'], params['tid'] is required"
284
+ end
285
+ post "time_entries/start", {time_entry: params}
286
+ end
287
+
288
+ def stop_time_entry(time_entry_id)
289
+ put "time_entries/#{time_entry_id}/stop", {}
290
+ end
291
+
292
+ def get_time_entry(time_entry_id)
293
+ get "time_entries/#{time_entry_id}"
294
+ end
295
+
296
+ def update_time_entry(time_entry_id, params)
297
+ put "time_entries/#{time_entry_id}", {time_entry: params}
298
+ end
299
+
300
+ def delete_time_entry(time_entry_id)
301
+ delete "time_entries/#{time_entry_id}"
302
+ end
303
+
304
+ def iso8601(date)
305
+ return nil if date.nil?
306
+ if date.is_a?(Time) or date.is_a?(Date)
307
+ iso = date.iso8601
308
+ elsif date.is_a?(String)
309
+ iso = DateTime.parse(date).iso8601
310
+ else
311
+ raise ArgumentError, "Can't convert #{date.class} to ISO-8601 Date/Time"
312
+ end
313
+ return Faraday::Utils.escape(iso)
314
+ end
315
+
316
+ def get_time_entries(start_date=nil, end_date=nil)
317
+ params = []
318
+ params.push("start_date=#{iso8601(start_date)}") if !start_date.nil?
319
+ params.push("end_date=#{iso8601(end_date)}") if !end_date.nil?
320
+ get "time_entries%s" % [params.empty? ? "" : "?#{params.join('&')}"]
321
+ end
322
+
323
+ #-------------#
324
+ #--- Users ---#
325
+ #-------------#
326
+
327
+ # api_token : (string)
328
+ # default_wid : default workspace id (integer)
329
+ # email : (string)
330
+ # jquery_timeofday_format : (string)
331
+ # jquery_date_format :(string)
332
+ # timeofday_format : (string)
333
+ # date_format : (string)
334
+ # store_start_and_stop_time : whether start and stop time are saved on time entry (boolean)
335
+ # beginning_of_week : (integer, Sunday=0)
336
+ # language : user's language (string)
337
+ # image_url : url with the user's profile picture(string)
338
+ # sidebar_piechart : should a piechart be shown on the sidebar (boolean)
339
+ # at : timestamp of last changes
340
+ # new_blog_post : an object with toggl blog post title and link
341
+
342
+ #------------------#
343
+ #--- Workspaces ---#
344
+ #------------------#
345
+
346
+ # name : (string, required)
347
+ # premium : If it's a pro workspace or not. Shows if someone is paying for the workspace or not (boolean, not required)
348
+ # at : timestamp that is sent in the response, indicates the time item was last updated
349
+
350
+ def workspaces
351
+ get "workspaces"
352
+ end
353
+
354
+ def clients(workspace=nil)
355
+ if workspace.nil?
356
+ get "clients"
357
+ else
358
+ get "workspaces/#{workspace}/clients"
359
+ end
360
+ end
361
+
362
+ def projects(workspace, params={})
363
+ active = params.has_key?(:active) ? "?active=#{params[:active]}" : ""
364
+ get "workspaces/#{workspace}/projects#{active}"
365
+ end
366
+
367
+ def users(workspace)
368
+ get "workspaces/#{workspace}/users"
369
+ end
370
+
371
+ def tasks(workspace, params={})
372
+ active = params.has_key?(:active) ? "?active=#{params[:active]}" : ""
373
+ get "workspaces/#{workspace}/tasks#{active}"
374
+ end
375
+
376
+ #---------------#
377
+ #--- Private ---#
378
+ #---------------#
379
+
380
+ private
381
+
382
+ def get(resource)
383
+ puts "GET #{resource}" if @debug
384
+ full_res = self.conn.get(resource)
385
+ # ap full_res.env if @debug
386
+ res = JSON.parse(full_res.env[:body])
387
+ res.is_a?(Array) || res['data'].nil? ? res : res['data']
388
+ end
389
+
390
+ def post(resource, data)
391
+ puts "POST #{resource} / #{data}" if @debug
392
+ full_res = self.conn.post(resource, JSON.generate(data))
393
+ ap full_res.env if @debug
394
+ if (200 == full_res.env[:status]) then
395
+ res = JSON.parse(full_res.env[:body])
396
+ res['data'].nil? ? res : res['data']
397
+ else
398
+ puts(full_res.env[:body])
399
+ end
400
+ end
401
+
402
+ def put(resource, data)
403
+ puts "PUT #{resource} / #{data}" if @debug
404
+ full_res = self.conn.put(resource, JSON.generate(data))
405
+ # ap full_res.env if @debug
406
+ res = JSON.parse(full_res.env[:body])
407
+ res['data'].nil? ? res : res['data']
408
+ end
409
+
410
+ def delete(resource)
411
+ puts "DELETE #{resource}" if @debug
412
+ full_res = self.conn.delete(resource)
413
+ # ap full_res.env if @debug
414
+ (200 == full_res.env[:status]) ? "" : puts(full_res.env[:body])
415
+ end
416
+
417
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: v2gpti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.10
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Hale
@@ -9,132 +9,202 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-04 00:00:00.000000000 Z
12
+ date: 2014-06-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: highline
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ~>
19
19
  - !ruby/object:Gem::Version
20
20
  version: '1.6'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ~>
26
26
  - !ruby/object:Gem::Version
27
27
  version: '1.6'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: pivotal-tracker
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ~>
33
33
  - !ruby/object:Gem::Version
34
34
  version: '0.5'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ~>
40
40
  - !ruby/object:Gem::Version
41
41
  version: '0.5'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: parseconfig
44
44
  requirement: !ruby/object:Gem::Requirement
45
45
  requirements:
46
- - - "~>"
46
+ - - ~>
47
47
  - !ruby/object:Gem::Version
48
48
  version: '1.0'
49
49
  type: :runtime
50
50
  prerelease: false
51
51
  version_requirements: !ruby/object:Gem::Requirement
52
52
  requirements:
53
- - - "~>"
53
+ - - ~>
54
54
  - !ruby/object:Gem::Version
55
55
  version: '1.0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: faraday
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ~>
61
+ - !ruby/object:Gem::Version
62
+ version: 0.9.0
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.0
70
+ - !ruby/object:Gem::Dependency
71
+ name: awesome_print
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.1.0
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ~>
82
+ - !ruby/object:Gem::Version
83
+ version: 1.1.0
84
+ - !ruby/object:Gem::Dependency
85
+ name: json
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ~>
89
+ - !ruby/object:Gem::Version
90
+ version: 1.8.0
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ~>
96
+ - !ruby/object:Gem::Version
97
+ version: 1.8.0
98
+ - !ruby/object:Gem::Dependency
99
+ name: logger
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ~>
103
+ - !ruby/object:Gem::Version
104
+ version: 1.2.8
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: 1.2.8
112
+ - !ruby/object:Gem::Dependency
113
+ name: jazor
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ~>
117
+ - !ruby/object:Gem::Version
118
+ version: 0.1.8
119
+ type: :runtime
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: 0.1.8
56
126
  - !ruby/object:Gem::Dependency
57
127
  name: bundler
58
128
  requirement: !ruby/object:Gem::Requirement
59
129
  requirements:
60
- - - "~>"
130
+ - - ~>
61
131
  - !ruby/object:Gem::Version
62
132
  version: '1.3'
63
133
  type: :development
64
134
  prerelease: false
65
135
  version_requirements: !ruby/object:Gem::Requirement
66
136
  requirements:
67
- - - "~>"
137
+ - - ~>
68
138
  - !ruby/object:Gem::Version
69
139
  version: '1.3'
70
140
  - !ruby/object:Gem::Dependency
71
141
  name: rake
72
142
  requirement: !ruby/object:Gem::Requirement
73
143
  requirements:
74
- - - "~>"
144
+ - - ~>
75
145
  - !ruby/object:Gem::Version
76
146
  version: '10.0'
77
147
  type: :development
78
148
  prerelease: false
79
149
  version_requirements: !ruby/object:Gem::Requirement
80
150
  requirements:
81
- - - "~>"
151
+ - - ~>
82
152
  - !ruby/object:Gem::Version
83
153
  version: '10.0'
84
154
  - !ruby/object:Gem::Dependency
85
155
  name: redcarpet
86
156
  requirement: !ruby/object:Gem::Requirement
87
157
  requirements:
88
- - - "~>"
158
+ - - ~>
89
159
  - !ruby/object:Gem::Version
90
160
  version: '2.2'
91
161
  type: :development
92
162
  prerelease: false
93
163
  version_requirements: !ruby/object:Gem::Requirement
94
164
  requirements:
95
- - - "~>"
165
+ - - ~>
96
166
  - !ruby/object:Gem::Version
97
167
  version: '2.2'
98
168
  - !ruby/object:Gem::Dependency
99
169
  name: rspec
100
170
  requirement: !ruby/object:Gem::Requirement
101
171
  requirements:
102
- - - "~>"
172
+ - - ~>
103
173
  - !ruby/object:Gem::Version
104
174
  version: '2.13'
105
175
  type: :development
106
176
  prerelease: false
107
177
  version_requirements: !ruby/object:Gem::Requirement
108
178
  requirements:
109
- - - "~>"
179
+ - - ~>
110
180
  - !ruby/object:Gem::Version
111
181
  version: '2.13'
112
182
  - !ruby/object:Gem::Dependency
113
183
  name: simplecov
114
184
  requirement: !ruby/object:Gem::Requirement
115
185
  requirements:
116
- - - "~>"
186
+ - - ~>
117
187
  - !ruby/object:Gem::Version
118
188
  version: '0.7'
119
189
  type: :development
120
190
  prerelease: false
121
191
  version_requirements: !ruby/object:Gem::Requirement
122
192
  requirements:
123
- - - "~>"
193
+ - - ~>
124
194
  - !ruby/object:Gem::Version
125
195
  version: '0.7'
126
196
  - !ruby/object:Gem::Dependency
127
197
  name: yard
128
198
  requirement: !ruby/object:Gem::Requirement
129
199
  requirements:
130
- - - "~>"
200
+ - - ~>
131
201
  - !ruby/object:Gem::Version
132
202
  version: '0.8'
133
203
  type: :development
134
204
  prerelease: false
135
205
  version_requirements: !ruby/object:Gem::Requirement
136
206
  requirements:
137
- - - "~>"
207
+ - - ~>
138
208
  - !ruby/object:Gem::Version
139
209
  version: '0.8'
140
210
  description: Provides a set of additional Git commands to help developers when working
@@ -166,6 +236,7 @@ files:
166
236
  - lib/git-pivotal-tracker-integration/util/git.rb
167
237
  - lib/git-pivotal-tracker-integration/util/shell.rb
168
238
  - lib/git-pivotal-tracker-integration/util/story.rb
239
+ - lib/git-pivotal-tracker-integration/util/togglV8.rb
169
240
  - lib/git-pivotal-tracker-integration/util/util.rb
170
241
  - lib/git-pivotal-tracker-integration/version-update/gradle.rb
171
242
  - lib/git-pivotal-tracker-integration/version-update/version_update.rb
@@ -189,12 +260,12 @@ require_paths:
189
260
  - lib
190
261
  required_ruby_version: !ruby/object:Gem::Requirement
191
262
  requirements:
192
- - - ">="
263
+ - - '>='
193
264
  - !ruby/object:Gem::Version
194
265
  version: '1.9'
195
266
  required_rubygems_version: !ruby/object:Gem::Requirement
196
267
  requirements:
197
- - - ">="
268
+ - - '>='
198
269
  - !ruby/object:Gem::Version
199
270
  version: '0'
200
271
  requirements: []