tempo-cli 0.2.3 → 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea6cc8f7f2251d38ac0f1302e37a0f2cf93fa3d4
4
- data.tar.gz: 2e8cce29f69bbc7468034c872084ff4e0952e5e2
3
+ metadata.gz: 020b9afac83811fcaf37f57bf03ba5553677134f
4
+ data.tar.gz: 90c5735ba9f705f1a8428a7c99cdcb0dcb74cf3f
5
5
  SHA512:
6
- metadata.gz: 516fe4c8216081c83a2ce43436cce83827aecccba3823956e236ed7f1bc0e86f67cde7c63537dab655ae60e4dc7610a1e5649858474bb118926ded4aed3ee5e6
7
- data.tar.gz: 8c0b3784dfd824eb13343662c061eaf6f4f7ec308458a2f706127ee5388d00d1b20983e5cc0df0e13ce0c170204b70720cefc8164135d948caf8bd85ffedfffe
6
+ metadata.gz: f1acba9a88b45b4e2f4ba85a301da99e4b880c4681b46fcb0bf2c552f074c865bc66abeab6919c6687f839d4c00157522abff3fa531b466255a86152f781fcca
7
+ data.tar.gz: e5820580c779d3b956ac57ad7c9d799da3951c1cd9b58682aaecd024cdc0208a708f4b758515fce905a5f55176f537adea024e05658b0f45c336fc7512a14824
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tempo-cli (0.2.2)
4
+ tempo-cli (0.2.3)
5
5
  chronic (~> 0.10)
6
6
  gli (~> 2.10)
7
7
 
data/README.md CHANGED
@@ -150,6 +150,7 @@ New projects are added as root projects by default. Use arrange to arrange exist
150
150
  ##### command options
151
151
  --at=time
152
152
  --end=time
153
+ --restart
153
154
 
154
155
  Starts a new time entry, and closes out any running time entries.
155
156
 
@@ -197,6 +198,7 @@ New projects are added as root projects by default. Use arrange to arrange exist
197
198
  --id=number - Select by Id
198
199
  --on=date - Select On Date
199
200
  --project - Update to the active project
201
+ --running - Set the last project back to running (reopen the end-time)
200
202
  --start=time - Update the Start Time
201
203
 
202
204
  update the project, start time, or end time for a time entry.
data/Rakefile CHANGED
@@ -4,6 +4,7 @@ require 'rubygems/package_task'
4
4
  require 'rdoc/task'
5
5
  require 'cucumber'
6
6
  require 'cucumber/rake/task'
7
+ require "fileutils"
7
8
 
8
9
  Rake::RDocTask.new do |rd|
9
10
  rd.rdoc_files.include("lib/**/*.rb","bin/**/*")
@@ -62,4 +63,4 @@ task :clean => [:tests_setup, :tests_teardown]
62
63
 
63
64
  task :default => [:tests_setup, :run_tests, :features, :tests_teardown]
64
65
 
65
- task 'features:focus' => [:tests_setup, :run_tests, 'cucumber:focus', :tests_teardown]
66
+ task 'features:focus' => [:tests_setup, :run_tests, 'cucumber:focus']
data/bin/tempo CHANGED
@@ -261,6 +261,10 @@ To start a time entry at a time other than the current, pass it in as an argumen
261
261
  to the --at flag. This will accept a number of human readable formats, multiple
262
262
  word time formats should be enclosed in quotes.
263
263
 
264
+ Use the --resume flag to start a new time entry with the last used project and description.
265
+
266
+ To reopen the last time entry (change the end time back to 'running') see `tempo update --running`
267
+
264
268
  examples:
265
269
 
266
270
  # start a new time record at the current time with no description
@@ -275,6 +279,9 @@ $ tempo start learning how to do the Hustle --at 'yesterday at 8:00 in the eveni
275
279
  arg_name 'description'
276
280
  command [:start, :s] do |c|
277
281
 
282
+ c.desc 'start an entry using the last description and project'
283
+ c.switch [:r, :resume], negatable: false
284
+
278
285
  c.desc 'end the entry at a given time'
279
286
  c.arg_name 'time'
280
287
  c.flag [:e, :end]
@@ -432,6 +439,9 @@ command [:update, :u] do |c|
432
439
  c.arg_name 'time'
433
440
  c.flag [:s, :start]
434
441
 
442
+ c.desc 'Change the last time entry back to actively running (ignores all other options)'
443
+ c.switch [:r, :running], negatable: false
444
+
435
445
  c.desc 'Update the End Time'
436
446
  c.arg_name 'time'
437
447
  c.flag [:e, :end]
@@ -487,7 +497,7 @@ on_error do |exception|
487
497
  # return false to skip default error handling
488
498
 
489
499
  # remove before distribution:
490
- # puts exception.backtrace
500
+ puts exception.backtrace
491
501
 
492
502
  true
493
503
  end
data/features/end.feature CHANGED
@@ -40,6 +40,7 @@ Feature: End Command ends the current time record
40
40
  And I run `tempo end --at "1-5-2014 15:00"`
41
41
  Then the stdout should contain "time record ended"
42
42
  And the output should match /7:00 - 15:00/
43
+
43
44
  @pending
44
45
  Scenario: Attempting to end after the beginning time
45
46
  Given an existing project file
@@ -59,7 +60,3 @@ Feature: End Command ends the current time record
59
60
  And the time record 20140101 should contain ":end_time: 2014-01-01 23:59" at line 5
60
61
  And the time record 20140102 should contain ":end_time: 2014-01-01 23:59" at line 5
61
62
  And the time record 20140103 should contain ":end_time: 2014-01-01 10:00" at line 5
62
-
63
-
64
-
65
-
@@ -70,6 +70,29 @@ Feature: Start Command starts a new time record
70
70
  Then the stdout should contain "time record started"
71
71
  And the time record 20140101 should contain ":end_time: 2014-01-01 10:00" at line 5
72
72
 
73
+ Scenario: Resuming the last time record
74
+ Given an existing project file
75
+ When I run `tempo start --at "1-1-2014 10:00" tweezing the cactus`
76
+ And I run `tempo end --at "1-1-2014 12:00"`
77
+ And I successfully run `tempo start --resume --at "1-1-2014 13:00"`
78
+ Then the stdout should contain "time record started"
79
+ And the time record 20140101 should contain ":description: tweezing the cactus" at line 11
80
+
81
+ Scenario: Resuming the last time record with a different project checked out ignores current project
82
+ Given an existing project file
83
+ When I run `tempo start --at "1-1-2014 10:00" tweezing the cactus`
84
+ And I run `tempo end --at "1-1-2014 12:00"`
85
+ And I run `tempo checkout basement mushrooms`
86
+ And I successfully run `tempo start --resume --at "1-1-2014 13:00"`
87
+ Then the stdout should contain "time record started"
88
+ And the time record 20140101 should contain ":project_title: horticulture" at line 10
89
+
90
+ Scenario: Attempting to resume the last project when one is running
91
+ Given an existing project file
92
+ When I run `tempo start --at "1-1-2014 10:00"`
93
+ And I run `tempo start --resume`
94
+ Then the stderr should contain "error: cannot resume last time record when it is still running"
95
+
73
96
  Scenario: Adding an earlier day time record should immediately close out
74
97
  Given an existing project file
75
98
  When I run `tempo start --at "1-5-2014 7:00"`
@@ -48,6 +48,14 @@ Feature: Update Command manages edits to the time records
48
48
  Then the stdout should contain "time record updated:\n13:32 - 16:35 [3:03] nano aquarium: trimming the coral"
49
49
  And the time record 20140101 should contain ":end_time: 2014-01-01 16:35:00" at line 37
50
50
 
51
+ Scenario: Restarting the last time record
52
+ Given an existing project file
53
+ When I run `tempo start --at "1-5-2015 7:00"`
54
+ And I run `tempo end --at "1-5-2015 15:00"`
55
+ And I run `tempo update --running`
56
+ Then the stdout should contain "time record updated"
57
+ And the time record 20150105 should contain ":end_time: :running" at line 5
58
+
51
59
  Scenario: Updating to the project for the last time record
52
60
  Given an existing project file
53
61
  And an existing time record file
@@ -73,3 +81,22 @@ Feature: Update Command manages edits to the time records
73
81
  Then the stdout should contain "time record updated:\n07:00 - 08:35 [1:35] horticulture: raking leaves"
74
82
  And the time record 20131201 should contain ":end_time: 2013-12-01 08:35:00" at line 5
75
83
 
84
+ Scenario: Updating the start time on an earlier day passing only time no date
85
+ Given an existing project file
86
+ And an existing time record file
87
+ When I run `tempo start --at "12/1/2013 7:00" --end "12/1/2013 8:00" raking leaves`
88
+ And I run `tempo start --at "12/1/2013 9:00" --end "12/1/2013 10:00" counting rosebuds`
89
+ When I successfully run `tempo update --on "12/1/2013" --id 1 --start "7:35"`
90
+ Then the stdout should contain "time record updated:\n07:35 - 08:00 [0:25] horticulture: raking leaves"
91
+ And the time record 20131201 should contain ":start_time: 2013-12-01 07:35:00" at line 4
92
+
93
+ Scenario: Updating the end time on an earlier day passing only time no date
94
+ Given an existing project file
95
+ And an existing time record file
96
+ When I run `tempo start --at "12/1/2013 7:00" --end "12/1/2013 8:00" raking leaves`
97
+ And I run `tempo start --at "12/1/2013 9:00" --end "12/1/2013 10:00" counting rosebuds`
98
+ When I successfully run `tempo update --on "12/1/2013" --id 1 --end "8:35"`
99
+ Then the stdout should contain "time record updated:\n07:00 - 08:35 [1:35] horticulture: raking leaves"
100
+ And the time record 20131201 should contain ":end_time: 2013-12-01 08:35:00" at line 5
101
+
102
+
@@ -30,7 +30,24 @@ module Tempo
30
30
  end
31
31
 
32
32
  @time_records.load_last_day options
33
- record = @time_records.new(opts)
33
+
34
+ if options[:resume]
35
+ last_record = @time_records.last_record
36
+
37
+ return Views.error("cannot resume last time record when it is still running") if last_record.running?
38
+
39
+ opts[:description] = last_record.description
40
+
41
+ # we use the last used project, but don't save it as current
42
+ # in case a different project has been checked out.
43
+ @projects.current = @projects.find_by_id(last_record.project)
44
+
45
+ record = @time_records.new(opts)
46
+
47
+ else
48
+ record = @time_records.new(opts)
49
+ end
50
+
34
51
  @time_records.save_to_file options
35
52
 
36
53
  Views.start_time_record_view record
@@ -8,12 +8,27 @@ module Tempo
8
8
 
9
9
  class << self
10
10
 
11
+ def running(options, args)
12
+ @time_records.load_last_day options
13
+
14
+ if @time_records.last_record.running?
15
+ Views.message "Last time record is currently running"
16
+ else
17
+ @time_records.last_record.running!
18
+ @time_records.save_to_file options
19
+ Views.update_time_record_view @time_records.last_record
20
+ end
21
+ end
22
+
11
23
  def parse(options, args)
12
24
 
13
25
  reassemble_the args
14
26
 
15
27
  return Views.project_assistance if Model::Project.index.empty?
16
28
 
29
+ # Reopen last record and ignore all other values if passed --running switch
30
+ return running(options, args) if options[:running]
31
+
17
32
  # Load last day, or specific day if options includes an on-date
18
33
  if options[:on]
19
34
  day = Time.parse options[:on]
@@ -52,9 +67,13 @@ module Tempo
52
67
  start_time = Time.parse options[:start]
53
68
  return Views.no_match_error( "valid timeframe", options[:at], false ) if start_time.nil?
54
69
 
55
- # TODO: add "today " to start time and try again if not valid
56
70
  if record.valid_start_time? start_time
57
71
  record.start_time = start_time
72
+
73
+ # try to update the time on the day, to handle updating with time params only
74
+ elsif record.valid_start_time? start_time.on_date(record.start_time)
75
+ record.start_time = start_time.on_date(record.start_time)
76
+
58
77
  else
59
78
  return Views::ViewRecords::Message.new "cannot change start time to #{start_time.strftime('%H:%M')}", category: :error
60
79
  end
@@ -68,6 +87,11 @@ module Tempo
68
87
  # TODO: add "today " to end time and try again if not valid
69
88
  if record.valid_end_time? end_time
70
89
  record.end_time = end_time
90
+
91
+ # try to update the time on the day, to handle updating with time params only
92
+ elsif record.valid_end_time? end_time.on_date(record.end_time)
93
+ record.end_time = end_time.on_date(record.end_time)
94
+
71
95
  else
72
96
  return Views::ViewRecords::Message.new "cannot change end time to #{end_time.strftime('%H:%M')}", category: :error
73
97
  end
@@ -58,6 +58,13 @@ module Tempo
58
58
  FileRecord::FileUtility.new(self, options).log_records
59
59
  end
60
60
 
61
+ # returns the loaded record with the latest start time
62
+ # Only loads records if options[:load] is true
63
+ def last_record(options={})
64
+ load_last_day(options) if options[:load]
65
+ sort_by_start_time.last
66
+ end
67
+
61
68
  # send alternate directory through options
62
69
  def save_to_file(options={})
63
70
  FileRecord::Record.save_log(self, options)
@@ -65,6 +65,7 @@ module Tempo
65
65
 
66
66
  # end time cannot be set to :running, only to a
67
67
  # valid Time object
68
+ # Use running! to restart a time record
68
69
  #
69
70
  def end_time=time
70
71
  raise ArgumentError if !time.kind_of? Time
@@ -154,6 +155,11 @@ module Tempo
154
155
  @end_time == :running
155
156
  end
156
157
 
158
+ def running!
159
+ raise "only the most recent record can be reopened" unless self == self.class.last_record
160
+ @end_time = :running
161
+ end
162
+
157
163
  def freeze_dry
158
164
  record = super
159
165
  record[:project_title] = project_title
@@ -181,7 +187,7 @@ module Tempo
181
187
 
182
188
  private
183
189
 
184
- #close current at the end time, or on the last minute
190
+ # close current at the end time, or on the last minute
185
191
  # of the day if end time is another day
186
192
  #
187
193
  def self.close_current(end_time)
data/lib/tempo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Tempo
2
- VERSION = '0.2.3'
2
+ VERSION = '0.2.4'
3
3
  end
@@ -48,6 +48,14 @@ module Tempo
48
48
  end
49
49
  end
50
50
 
51
+ def message(message)
52
+ ViewRecords::Message.new message, category: :info
53
+ end
54
+
55
+ def error(message)
56
+ ViewRecords::Message.new message, category: :error
57
+ end
58
+
51
59
  def no_match_error(items, request, plural=true)
52
60
  match = plural ? "match" : "matches"
53
61
  ViewRecords::Message.new "no #{items} #{match} the request: #{request}", category: :error
@@ -27,4 +27,9 @@ class Time
27
27
  def add_days(days)
28
28
  t = self + days * 86400 # 24 * 60 * 60
29
29
  end
30
+
31
+ def on_date(date)
32
+ raise ArgumentError if ! date.kind_of? Time
33
+ Time.new(date.year, date.month, date.day, self.hour, self.min, self.sec)
34
+ end
30
35
  end
@@ -11,21 +11,21 @@ describe Tempo::TimeConflictError do
11
11
 
12
12
  it "can create a message with a target duration" do
13
13
  @exception = Tempo::TimeConflictError.new @start_time, @end_time, @target_start_time, @target_end_time
14
- @exception.to_s.must_equal "time <08:15 - 08:45> conflicts with existing record: 07:15 - 09:15"
14
+ @exception.to_s.must_equal "time <08:15 - 08:45> conflicts with existing record: 07:15 - 09:15 on Jan 02, 2014"
15
15
  end
16
16
 
17
17
  it "can create a message with a target time" do
18
18
  @exception = Tempo::TimeConflictError.new @start_time, @end_time, @target_start_time
19
- @exception.to_s.must_equal "time <08:15> conflicts with existing record: 07:15 - 09:15"
19
+ @exception.to_s.must_equal "time <08:15> conflicts with existing record: 07:15 - 09:15 on Jan 02, 2014"
20
20
  end
21
21
 
22
22
  it "can create a message without a target time" do
23
23
  @exception = Tempo::TimeConflictError.new @start_time, @end_time
24
- @exception.to_s.must_equal "time conflicts with existing record: 07:15 - 09:15"
24
+ @exception.to_s.must_equal "time conflicts with existing record: 07:15 - 09:15 on Jan 02, 2014"
25
25
  end
26
26
 
27
27
  it "can handle running time entries" do
28
28
  @exception = Tempo::TimeConflictError.new @start_time, :running, @target_start_time
29
- @exception.to_s.must_equal "time <08:15> conflicts with existing record: 07:15 - running"
29
+ @exception.to_s.must_equal "time <08:15> conflicts with existing record: 07:15 - running on Jan 02, 2014"
30
30
  end
31
- end
31
+ end
@@ -17,7 +17,6 @@ describe Tempo do
17
17
  it "inherits the freeze-dry method" do
18
18
  log_factory
19
19
  frozen = @log_4.freeze_dry
20
- binding.pry if @log_4.id != 1
21
20
  frozen.must_equal({ :start_time=>Time.new(2014, 01, 02, 07, 15),
22
21
  :id=>1, :message=>"day 2 pet the sheep"})
23
22
  end
@@ -182,5 +181,10 @@ describe Tempo do
182
181
  Tempo::Model::MessageLog.days_index[:"20140101"].length.must_equal 2
183
182
  Tempo::Model::MessageLog.days_index[:"20140102"].length.must_equal 3
184
183
  end
184
+
185
+ it "can return the last record" do
186
+ log_factory
187
+ Tempo::Model::MessageLog.last_record.must_equal @log_6
188
+ end
185
189
  end
186
190
  end
@@ -73,6 +73,19 @@ describe Tempo do
73
73
  @record_6.running?.must_equal true
74
74
  end
75
75
 
76
+ it "has a running! method for last record only" do
77
+ time_record_factory
78
+ @record_6.end_time = Time.new(2014, 1, 2, 19, 00 )
79
+ @record_6.running!
80
+ Tempo::Model::TimeRecord.current.must_equal @record_6
81
+ end
82
+
83
+ it "running! method succeeds on last record only" do
84
+ time_record_factory
85
+ proc { @record_1.running!}.must_raise RuntimeError
86
+ end
87
+
88
+
76
89
  it "has a next record method" do
77
90
  time_record_factory
78
91
  @record_1.next_record.must_equal @record_2
@@ -155,7 +168,7 @@ describe Tempo do
155
168
 
156
169
  it "errors when end time is before start time" do
157
170
  Tempo::Model::TimeRecord.clear_all
158
- proc { Tempo::Model::TimeRecord.new({ start_time: Time.new(2014, 1, 1, 12 ), end_time: Time.new(2014, 1, 1, 10 ) }) }.must_raise ArgumentError
171
+ proc { Tempo::Model::TimeRecord.new({ start_time: Time.new(2014, 1, 1, 12 ), end_time: Time.new(2014, 1, 1, 10 ) }) }.must_raise Tempo::EndTimeError
159
172
  end
160
173
 
161
174
  it "accepts and end time equal to start time" do
@@ -173,7 +186,7 @@ describe Tempo do
173
186
 
174
187
  it "errors when end time is on a different day" do
175
188
  Tempo::Model::TimeRecord.clear_all
176
- proc { Tempo::Model::TimeRecord.new({ start_time: Time.new(2014, 1, 1, 10 ), end_time: Time.new(2014, 1, 2, 12 ) }) }.must_raise ArgumentError
189
+ proc { Tempo::Model::TimeRecord.new({ start_time: Time.new(2014, 1, 1, 10 ), end_time: Time.new(2014, 1, 2, 12 ) }) }.must_raise Tempo::DifferentDaysError
177
190
  end
178
191
 
179
192
  it "errors when end time in existing record" do
@@ -212,7 +225,7 @@ describe Tempo do
212
225
  @record = Tempo::Model::TimeRecord.new({project: @project_1,
213
226
  start_time: Time.new(2014, 1, 1, 8 ),
214
227
  end_time: Time.new(2014, 1, 1, 10 ) })
215
- proc { @record.start_time = Time.new(2014, 1, 1, 11 )}.must_raise ArgumentError
228
+ proc { @record.start_time = Time.new(2014, 1, 1, 11 )}.must_raise Tempo::EndTimeError
216
229
 
217
230
  @record.start_time = Time.new(2014, 1, 1, 9 )
218
231
  @record.start_time.must_equal Time.new(2014, 1, 1, 9 )
@@ -225,7 +238,7 @@ describe Tempo do
225
238
  start_time: Time.new(2014, 1, 1, 8 ),
226
239
  end_time: Time.new(2014, 1, 1, 10 ) })
227
240
 
228
- proc { @record.end_time = Time.new(2014, 1, 1, 7 )}.must_raise ArgumentError
241
+ proc { @record.end_time = Time.new(2014, 1, 1, 7 )}.must_raise Tempo::EndTimeError
229
242
  @record.end_time = Time.new(2014, 1, 1, 11 )
230
243
  @record.end_time.must_equal Time.new(2014, 1, 1, 11 )
231
244
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tempo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Gabel