tempo-cli 0.2.6 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +5 -5
  2. data/Gemfile.lock +64 -39
  3. data/README.md +16 -7
  4. data/Rakefile +3 -3
  5. data/bin/tempo +28 -0
  6. data/features/step_definitions/tempo_steps.rb +14 -14
  7. data/features/support/env.rb +1 -1
  8. data/lib/file_record/directory.rb +104 -1
  9. data/lib/file_record/file_utility.rb +50 -8
  10. data/lib/file_record/record.rb +11 -10
  11. data/lib/tempo/controllers/end_controller.rb +1 -1
  12. data/lib/tempo/controllers/projects_controller.rb +1 -1
  13. data/lib/tempo/controllers/records_controller.rb +56 -4
  14. data/lib/tempo/controllers/report_controller.rb +1 -1
  15. data/lib/tempo/controllers/start_controller.rb +2 -2
  16. data/lib/tempo/exceptions.rb +11 -0
  17. data/lib/tempo/models/log.rb +20 -3
  18. data/lib/tempo/models/time_record.rb +7 -1
  19. data/lib/tempo/version.rb +1 -1
  20. data/lib/tempo/views/base.rb +3 -3
  21. data/lib/tempo/views/formatters/interactive.rb +44 -0
  22. data/lib/tempo/views/formatters/screen.rb +9 -10
  23. data/lib/tempo/views/interactive.rb +32 -0
  24. data/lib/tempo/views/reporter.rb +15 -0
  25. data/lib/tempo/views/view_records/base.rb +24 -0
  26. data/lib/tempo/views/view_records/time_record.rb +1 -1
  27. data/tempo-cli.gemspec +6 -8
  28. data/test/lib/file_record/directory_test.rb +17 -14
  29. data/test/lib/file_record/record_test.rb +11 -8
  30. data/test/lib/tempo/models/base_test.rb +3 -3
  31. data/test/lib/tempo/models/composite_test.rb +2 -2
  32. data/test/lib/tempo/models/log_test.rb +17 -7
  33. data/test/lib/tempo/models/project_test.rb +1 -1
  34. data/test/lib/tempo/models/time_record_test.rb +4 -4
  35. data/test/lib/tempo/views/formatters/console_test.rb +32 -0
  36. data/test/lib/tempo/views/reporter_test.rb +7 -1
  37. data/test/support/factories.rb +9 -17
  38. metadata +25 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 59fac2395c13e4a0a58701053e5ed9696146bb44
4
- data.tar.gz: 42df9a9ed12b2a50771cd0b9e64500f346bacef7
2
+ SHA256:
3
+ metadata.gz: 4630648caa1ae6432140a0e621d276836a3a26a248ae7ab80cd8eb2a147af837
4
+ data.tar.gz: cb6ecc56d1cf069b75ff8a3bd54e3de81703dc20ea59b1cf85d36789bedb5254
5
5
  SHA512:
6
- metadata.gz: 26a42ed193477f0dde232ef0209d70899d1fdc1b338e27779c5714d73f1f6b8499db8d1de0f0f81955783067f97ed2b533d336f61aafd3f11a016a18a3fa26d5
7
- data.tar.gz: 77f7093821bd7a097f7cc7df90a7ea4426ff81acf10c776e3799af78a2ec6315744a82eb4e5ffedc7c556d76a32ea65c55bc64096afcfaaff8d5581e5db50d84
6
+ metadata.gz: 1c846d66d6f427e7b8610c298dbb89ae9542adcb1e61eaaaefb7f1bf0479a6be21533e14d0db1c47536339f14ee96e3f98a040418255ab6366235940d64fd883
7
+ data.tar.gz: 1ab3da83905ef323f6edb24d6c581e5d988d50b313d991c568a7c150ad967172f6d0625465d05c87452251dcd9703d49e38e575f27fb92d901060a2c2008f63b
data/Gemfile.lock CHANGED
@@ -1,56 +1,81 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- tempo-cli (0.2.5)
5
- chronic (~> 0.10)
6
- gli (~> 2.10)
4
+ tempo-cli (1.0.1)
5
+ chronic (~> 0.10.2)
6
+ gli (>= 2.21.1)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
10
10
  specs:
11
- ansi (1.4.3)
12
- aruba (0.5.3)
13
- childprocess (>= 0.3.6)
14
- cucumber (>= 1.1.1)
15
- rspec-expectations (>= 2.7.0)
16
- builder (3.2.2)
17
- childprocess (0.3.9)
18
- ffi (~> 1.0, >= 1.0.11)
11
+ ansi (1.5.0)
12
+ aruba (2.2.0)
13
+ bundler (>= 1.17, < 3.0)
14
+ contracts (>= 0.16.0, < 0.18.0)
15
+ cucumber (>= 8.0, < 10.0)
16
+ rspec-expectations (~> 3.4)
17
+ thor (~> 1.0)
18
+ bigdecimal (3.1.7)
19
+ builder (3.2.4)
19
20
  chronic (0.10.2)
20
- coderay (1.0.9)
21
- cucumber (1.3.2)
22
- builder (>= 2.1.2)
23
- diff-lcs (>= 1.1.3)
24
- gherkin (~> 2.12.0)
25
- multi_json (~> 1.3)
26
- diff-lcs (1.2.4)
27
- ffi (1.9.0)
28
- gherkin (2.12.0)
29
- multi_json (~> 1.3)
30
- gli (2.11.0)
31
- json (1.8.1)
32
- method_source (0.8.1)
33
- multi_json (1.7.7)
34
- pry (0.9.12.2)
35
- coderay (~> 1.0.5)
36
- method_source (~> 0.8)
37
- slop (~> 3.4)
21
+ coderay (1.1.3)
22
+ contracts (0.17)
23
+ cucumber (9.2.0)
24
+ builder (~> 3.2)
25
+ cucumber-ci-environment (> 9, < 11)
26
+ cucumber-core (> 13, < 14)
27
+ cucumber-cucumber-expressions (~> 17.0)
28
+ cucumber-gherkin (> 24, < 28)
29
+ cucumber-html-formatter (> 20.3, < 22)
30
+ cucumber-messages (> 19, < 25)
31
+ diff-lcs (~> 1.5)
32
+ mini_mime (~> 1.1)
33
+ multi_test (~> 1.1)
34
+ sys-uname (~> 1.2)
35
+ cucumber-ci-environment (10.0.1)
36
+ cucumber-core (13.0.2)
37
+ cucumber-gherkin (>= 27, < 28)
38
+ cucumber-messages (>= 20, < 23)
39
+ cucumber-tag-expressions (> 5, < 7)
40
+ cucumber-cucumber-expressions (17.1.0)
41
+ bigdecimal
42
+ cucumber-gherkin (27.0.0)
43
+ cucumber-messages (>= 19.1.4, < 23)
44
+ cucumber-html-formatter (21.3.1)
45
+ cucumber-messages (> 19, < 25)
46
+ cucumber-messages (22.0.0)
47
+ cucumber-tag-expressions (6.1.0)
48
+ diff-lcs (1.5.1)
49
+ ffi (1.16.3)
50
+ gli (2.21.1)
51
+ method_source (1.0.0)
52
+ mini_mime (1.1.5)
53
+ minitest (4.7.5)
54
+ multi_test (1.1.0)
55
+ pry (0.14.2)
56
+ coderay (~> 1.1)
57
+ method_source (~> 1.0)
38
58
  rake (10.3.2)
39
- rdoc (4.1.1)
40
- json (~> 1.4)
41
- rspec-expectations (2.13.0)
42
- diff-lcs (>= 1.1.3, < 2.0)
43
- slop (3.4.5)
44
- turn (0.9.6)
59
+ rspec-expectations (3.13.0)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.13.0)
62
+ rspec-support (3.13.1)
63
+ sys-uname (1.2.3)
64
+ ffi (~> 1.1)
65
+ thor (1.3.1)
66
+ turn (0.9.7)
45
67
  ansi
68
+ minitest (~> 4)
46
69
 
47
70
  PLATFORMS
48
71
  ruby
49
72
 
50
73
  DEPENDENCIES
51
- aruba (~> 0.5)
52
- pry (~> 0.9)
74
+ aruba (~> 2.2)
75
+ pry (~> 0.14.2)
53
76
  rake (~> 10.3)
54
- rdoc (~> 4.1)
55
77
  tempo-cli!
56
- turn (~> 0.9)
78
+ turn (~> 0.9.7)
79
+
80
+ BUNDLED WITH
81
+ 2.4.20
data/README.md CHANGED
@@ -2,9 +2,16 @@
2
2
 
3
3
  A command line interface for time tracking by project.
4
4
 
5
+ ## A note on Version 1.0
6
+
7
+ If you are updatging from version ~> 0.2.6 to 1.0, there is a new structure to the time records - time records are now kept in sub-folders by year.
8
+
9
+ Run `tempo clean` to make a backup of your old directory, move files into the proper folders, and check all earlier records for errors.
10
+
11
+
5
12
  ## Installation
6
13
 
7
- gem install tempo-cli
14
+ gem install tempo-cli
8
15
 
9
16
  ### binary
10
17
 
@@ -18,11 +25,9 @@ Tempo cli runs with the binary `tempo`, but you can alias a shorter binary for y
18
25
 
19
26
  Tempo tracks time against projects. Projects can be nested, and tagged, and each time entry can have an additional description. Time reports are produced by day.
20
27
 
21
- Future enhancements will include reports by project and time totals by day or by project.
22
-
23
28
  ### Records
24
29
 
25
- All records are produced in YAML files. These reports can be edited by hand, but keep in mind that any invalid data could cause problems when it is read back into the app. Make sure time formatting is valid and that they don't overlap, and that all ids are unique per page.
30
+ All records are produced in YAML files. These records can be edited by hand, but keep in mind that any invalid data could cause problems when it is read back into the app. Make sure time formatting is valid and that they don't overlap, and that all ids are unique per page.
26
31
 
27
32
  Each day's time records are designed to work independently. When adding or updating time records, only the records for the days in question are loaded into the app. The most recent day's records will also always be read in, to assure no running records are created earlier than existing records.
28
33
 
@@ -235,8 +240,9 @@ The description, if passed in, will be used to replace the existing description.
235
240
 
236
241
  ##### command options
237
242
 
238
- --from=time - begin time records on this date
239
- --to=time - end time records on this date
243
+ -f, --from=time - begin time records on this date
244
+ -o, --order=[project, date] - order reports by date or project
245
+ -t, --to=time - end time records on this date
240
246
 
241
247
  Reports time entries for a day or a period of days. By default, lists the last recorded day's entries. To list a different day, supply a day as the args. To list a series of records, include a --from and --to value
242
248
 
@@ -254,6 +260,9 @@ The description, if passed in, will be used to replace the existing description.
254
260
  # report a period of days
255
261
  $ tempo report -f 'last monday' -t 'last friday'
256
262
 
263
+ # organize reports as bullet lists under each project
264
+ $ tempo report --o p
265
+
257
266
  ## Assumptions and Limitations
258
267
 
259
268
  Before you begin using tempo, you must have at least one project. Projects can be tagged, and organized as sub-projects. See project in the commands section below, for more information. To view your projects file, look at ~/tempo/tempo_projects.yaml
@@ -336,7 +345,7 @@ You can cleanup the testing directories with `bundle exec rake clean`
336
345
 
337
346
  This is a very opinionated time tracking app, you may find others that suit your working method better:
338
347
 
339
- If you would prefer to keep your data in a database, or run independant time sheets by project, here is a utility that uses SQLite:
348
+ If you would prefer to keep your data in a database, or run independent time sheets by project, here is a utility that uses SQLite:
340
349
 
341
350
  [timetrap](https://github.com/samg/timetrap)
342
351
 
data/Rakefile CHANGED
@@ -39,15 +39,15 @@ task :cucumber => :features
39
39
  task :tests_setup do
40
40
  @ORIGINAL_HOME = ENV['HOME']
41
41
  ENV['HOME'] = ENV['HOME'] + "/testing"
42
- Dir.mkdir(ENV['HOME'], 0700) unless File.exists?(ENV['HOME'])
42
+ Dir.mkdir(ENV['HOME'], 0700) unless File.exist?(ENV['HOME'])
43
43
  dir = File.join(Dir.home,"tempo")
44
- Dir.mkdir(dir, 0700) unless File.exists?(dir)
44
+ Dir.mkdir(dir, 0700) unless File.exist?(dir)
45
45
  end
46
46
 
47
47
  task :tests_teardown do
48
48
  ENV['HOME'] = @ORIGINAL_HOME
49
49
  dir = File.join(Dir.home, "testing")
50
- FileUtils.rm_r dir if File.exists?(dir)
50
+ FileUtils.rm_r dir if File.exist?(dir)
51
51
  end
52
52
 
53
53
  require 'rake/testtask'
data/bin/tempo CHANGED
@@ -464,6 +464,34 @@ command [:update, :u] do |c|
464
464
  end
465
465
  end
466
466
 
467
+ # COMMAND: CLEAN
468
+
469
+ desc 'Clean the tempo file structure'
470
+ long_desc "Creates a backup of the existing tempo directory,
471
+ and then clean all files in the current directory.
472
+
473
+ Cleaning the projects assures that:
474
+
475
+ 1. All projects that have been renamed have been updated in the files.
476
+
477
+ 2. Any files with time record conflicts are caught and can be corrected."
478
+
479
+ command [:clean] do |c|
480
+ require 'readline'
481
+ c.action do |global_options, options, args|
482
+ controller = Tempo::Controllers::Records
483
+
484
+ confirm = Tempo::Views::interactive_confirm_clean
485
+
486
+ if confirm.positive_response?
487
+ controller.backup_records options, args
488
+ controller.clean_records options, args
489
+ else
490
+ Tempo::Views::message "Cancelling clean"
491
+ end
492
+ end
493
+ end
494
+
467
495
  pre do |global,command,options,args|
468
496
 
469
497
  # add reporting of all arguments
@@ -5,16 +5,16 @@ end
5
5
 
6
6
  Given /^a clean installation$/ do
7
7
  @testing_env = File.join(ENV['HOME'], 'tempo')
8
- FileUtils.rm_r(@testing_env) if File.exists?(@testing_env)
8
+ FileUtils.rm_r(@testing_env) if File.exist?(@testing_env)
9
9
 
10
10
  # Testing global --directory argument in /alt_dir
11
11
  @alt_dir = File.join(ENV['HOME'], 'alt_dir')
12
- FileUtils.rm_r(@alt_dir) if File.exists?(@alt_dir)
12
+ FileUtils.rm_r(@alt_dir) if File.exist?(@alt_dir)
13
13
  end
14
14
 
15
15
  Given /^an existing project file$/ do
16
16
  @testing_env = File.join(ENV['HOME'], 'tempo')
17
- FileUtils.rm_r(@testing_env) if File.exists?(@testing_env)
17
+ FileUtils.rm_r(@testing_env) if File.exist?(@testing_env)
18
18
  Dir.mkdir(@testing_env, 0700)
19
19
  projects_file = File.join(@testing_env, 'tempo_projects.yaml')
20
20
 
@@ -34,7 +34,7 @@ end
34
34
 
35
35
  Given /^an alternate directory and an existing project file$/ do
36
36
  @testing_env = File.join(ENV['HOME'], 'alt_dir', 'tempo')
37
- FileUtils.rm_r(@testing_env) if File.exists?(@testing_env)
37
+ FileUtils.rm_r(@testing_env) if File.exist?(@testing_env)
38
38
  FileUtils.mkdir_p(@testing_env)
39
39
  projects_file = File.join(@testing_env, 'tempo_projects.yaml')
40
40
 
@@ -53,9 +53,9 @@ Given /^an alternate directory and an existing project file$/ do
53
53
  end
54
54
 
55
55
  Given /^an existing time record file$/ do
56
- @records_directory = File.join(ENV['HOME'], 'tempo/tempo_time_records')
57
- FileUtils.rm_r(@records_directory) if File.exists?(@records_directory)
58
- Dir.mkdir(@records_directory, 0700)
56
+ @records_directory = File.join(ENV['HOME'], 'tempo/tempo_time_records', '2014')
57
+ FileUtils.rm_r(@records_directory) if File.exist?(@records_directory)
58
+ FileUtils.mkdir_p @records_directory
59
59
  projects_file = File.join(@records_directory, '20140101.yaml')
60
60
 
61
61
  File.open(projects_file,'w') do |f|
@@ -107,7 +107,7 @@ end
107
107
 
108
108
 
109
109
  Then /^the time record (.*?) should contain "(.*?)" at line (\d+)$/ do |arg1, arg2, arg3|
110
- file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1}.yaml")
110
+ file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1[0..3]}", "#{arg1}.yaml")
111
111
  contents = []
112
112
  File.open(file, "r") do |f|
113
113
  f.readlines.each do |line|
@@ -118,7 +118,7 @@ Then /^the time record (.*?) should contain "(.*?)" at line (\d+)$/ do |arg1, ar
118
118
  end
119
119
 
120
120
  Then /^the time record (.*?) should not contain "(.*?)"$/ do |arg1, arg2|
121
- file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1}.yaml")
121
+ file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1[0..3]}", "#{arg1}.yaml")
122
122
  contents = []
123
123
  File.open(file, "r") do |f|
124
124
  f.readlines.each do |line|
@@ -129,8 +129,8 @@ Then /^the time record (.*?) should not contain "(.*?)"$/ do |arg1, arg2|
129
129
  end
130
130
 
131
131
  Then /^the time record (.*?) should not exist$/ do |arg1|
132
- file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1}.yaml")
133
- File.exists?(file).should == false
132
+ file = File.join(ENV['HOME'], 'tempo/tempo_time_records', "#{arg1[0..3]}", "#{arg1}.yaml")
133
+ File.exist?(file).should == false
134
134
  end
135
135
 
136
136
  Then /^the (\S*) file should contain "(.*?)" at line (\d+)$/ do |arg1, arg2, arg3|
@@ -200,7 +200,7 @@ Then /^the alternate directory (.*?) file should not contain "(.*?)"$/ do |arg1,
200
200
  end
201
201
 
202
202
  Then /^the alternate directory time record (\d+) should contain "(.*?)" at line (\d+)$/ do |arg1, arg2, arg3|
203
- file = File.join(ENV['HOME'], 'alt_dir', 'tempo', 'tempo_time_records', "#{arg1}.yaml")
203
+ file = File.join(ENV['HOME'], 'alt_dir', 'tempo', 'tempo_time_records', "#{arg1[0..3]}", "#{arg1}.yaml")
204
204
  contents = []
205
205
  File.open(file, "r") do |f|
206
206
  f.readlines.each do |line|
@@ -211,7 +211,7 @@ Then /^the alternate directory time record (\d+) should contain "(.*?)" at line
211
211
  end
212
212
 
213
213
  Then /^the alternate directory time record (.*?) should not exist$/ do |arg1|
214
- file = File.join(ENV['HOME'], 'alt_dir', 'tempo/tempo_time_records', "#{arg1}.yaml")
215
- File.exists?(file).should == false
214
+ file = File.join(ENV['HOME'], 'alt_dir', 'tempo/tempo_time_records', "#{arg1[0..3]}", "#{arg1}.yaml")
215
+ File.exist?(file).should == false
216
216
  end
217
217
 
@@ -16,7 +16,7 @@ Before do
16
16
  @real_home = ENV['HOME']
17
17
  @testing_env = File.join(ENV['HOME'], 'testing_features')
18
18
  #FileUtils.rm_rf @testing_env, :secure => true
19
- Dir.mkdir(@testing_env, 0700) unless File.exists?(@testing_env)
19
+ Dir.mkdir(@testing_env, 0700) unless File.exist?(@testing_env)
20
20
  ENV['HOME'] = @testing_env
21
21
  end
22
22
 
@@ -1,3 +1,9 @@
1
+ require 'stringio'
2
+ require 'rubygems/package'
3
+ require 'rubygems/package'
4
+ require 'zlib'
5
+
6
+
1
7
  module FileRecord
2
8
  class Directory
3
9
 
@@ -14,7 +20,7 @@ module FileRecord
14
20
 
15
21
  def create_new(options={})
16
22
 
17
- directory = options.fetch( :directory, Dir.home )
23
+ directory = options.fetch(:directory, Dir.home)
18
24
  cwd = File.expand_path File.dirname(__FILE__)
19
25
  source = File.join(cwd, "directory_structure/tempo")
20
26
  if ! Dir.exists? directory
@@ -22,6 +28,103 @@ module FileRecord
22
28
  end
23
29
  FileUtils.cp_r source, directory
24
30
  end
31
+
32
+ # Backup the tempo directory to tempo_backup/tempo_backup_20140101_HrMnS.tar.gz
33
+ # pass in an optional directory (see create_new)
34
+ # Pass in a timestamp, or default to 20140101_120000
35
+ def backup(options={})
36
+ directory = options.fetch(:directory, Dir.home)
37
+ timestamp = options.fetch(:timestamp, Time.new.strftime("%Y%m%d_%H%M%S"))
38
+ source = File.join(directory, "tempo")
39
+ dest = File.join(directory, "tempo_backups")
40
+ Dir.mkdir dest unless Dir.exists? dest
41
+ destination = File.join(directory, "tempo_backups", "tempo_backup_#{timestamp}.tar.gz")
42
+
43
+ io = tar(source)
44
+ gz = gzip(io)
45
+
46
+ File.open(destination,"w") do |file|
47
+ file.binmode
48
+ file.write gz.read
49
+ end
50
+
51
+ # return the new directory name
52
+ destination
53
+ end
54
+
55
+ private
56
+
57
+ # COMPRESSION / DECOMPRESSION
58
+ # From: https://gist.github.com/sinisterchipmunk/1335041
59
+
60
+ # Creates a tar file in memory recursively
61
+ # from the given dir.
62
+ #
63
+ # Returns a StringIO whose underlying String
64
+ # is the contents of the tar file.
65
+ def tar(dir)
66
+ tarfile = StringIO.new("")
67
+ Gem::Package::TarWriter.new(tarfile) do |tar|
68
+ Dir[File.join(dir, "**/*")].each do |file|
69
+ mode = File.stat(file).mode
70
+ relative_file = file.sub /^#{Regexp::escape dir}\/?/, ''
71
+
72
+ if File.directory?(file)
73
+ tar.mkdir relative_file, mode
74
+ else
75
+ tar.add_file relative_file, mode do |tf|
76
+ File.open(file, "rb") { |f| tf.write f.read }
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ tarfile.rewind
83
+ tarfile
84
+ end
85
+
86
+ # gzips the underlying string in the given StringIO,
87
+ # returning a new StringIO representing the
88
+ # compressed file.
89
+ def gzip(tarfile)
90
+ gz = StringIO.new("")
91
+ z = Zlib::GzipWriter.new(gz)
92
+ z.write tarfile.string
93
+ z.close # this is necessary!
94
+
95
+ # z was closed to write the gzip footer, so
96
+ # now we need a new StringIO
97
+ StringIO.new gz.string
98
+ end
99
+
100
+ # un-gzips the given IO, returning the
101
+ # decompressed version as a StringIO
102
+ def ungzip(tarfile)
103
+ z = Zlib::GzipReader.new(tarfile)
104
+ unzipped = StringIO.new(z.read)
105
+ z.close
106
+ unzipped
107
+ end
108
+
109
+ # untars the given IO into the specified
110
+ # directory
111
+ def untar(io, destination)
112
+ Gem::Package::TarReader.new io do |tar|
113
+ tar.each do |tarfile|
114
+ destination_file = File.join destination, tarfile.full_name
115
+
116
+ if tarfile.directory?
117
+ FileUtils.mkdir_p destination_file
118
+ else
119
+ destination_directory = File.dirname(destination_file)
120
+ FileUtils.mkdir_p destination_directory unless File.directory?(destination_directory)
121
+ File.open destination_file, "wb" do |f|
122
+ f.print tarfile.read
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
25
128
  end
26
129
  end
27
130
  end
@@ -73,14 +73,28 @@ module FileRecord
73
73
  "#{sn[0]}_#{sn[-1]}s"
74
74
  end
75
75
 
76
- # Tempo::Model::Log -> Users/usrname/(alternate_directory/)tempo/tempo_logs/
76
+
77
+ def log_year_directory
78
+ if @time.kind_of? Time
79
+ @time.strftime("%Y")
80
+ else
81
+ @time[0..3]
82
+ end
83
+ end
84
+
85
+ # Tempo::Model::Log -> Users/usrname/(alternate_directory/)tempo/tempo_logs'
77
86
  # Will also create the directory if not found
78
- # This method does not require time to be present in options
79
- def log_directory_path
87
+ def log_main_directory_path
80
88
  dir = File.join(@directory, module_name, log_directory)
89
+ end
81
90
 
82
- if @create and !File.exists?(dir)
83
- Dir.mkdir(dir, 0700)
91
+ # Tempo::Model::Log -> Users/usrname/(alternate_directory/)tempo/tempo_logs/20XX
92
+ # Will also create the directory if not found
93
+ def log_directory_path
94
+ dir = File.join(log_main_directory_path, log_year_directory)
95
+
96
+ if @create and !File.exist?(dir)
97
+ FileUtils.mkdir_p dir
84
98
  end
85
99
 
86
100
  dir
@@ -97,22 +111,50 @@ module FileRecord
97
111
 
98
112
  dir = File.join(@directory, module_name)
99
113
 
100
- if @create and !File.exists?(dir)
114
+ if @create and !File.exist?(dir)
101
115
  Dir.mkdir(dir, 0700)
102
116
  end
103
117
 
104
118
  clean_path File.join(dir, filename)
105
119
  end
106
120
 
121
+ def old_style_log_records_exists?
122
+ return false if !File.exist?(log_main_directory_path)
123
+ Pathname.new(log_main_directory_path).children.each do |c|
124
+ return true if c.to_s.match(/\.yaml/)
125
+ end
126
+ false
127
+ end
128
+
129
+ def move_old_records
130
+ return false if !File.exist?(log_main_directory_path)
131
+ puts "moving files in #{log_main_directory_path}"
132
+ Pathname.new(log_main_directory_path).children.each do |c|
133
+ if c.to_s.match(/\.yaml/)
134
+ year = File.basename(c).match(/(^\d{4})/)[1]
135
+ raise Tempo::DuplicateRecordError.new(File.join(log_main_directory_path,year,File.basename(c))) if File.exist?(File.join(log_main_directory_path,year,File.basename(c)))
136
+ FileUtils.mkdir_p File.join(log_main_directory_path,year) if !File.exist? File.join(log_main_directory_path,year)
137
+ FileUtils.cp c, File.join(log_main_directory_path,year,File.basename(c))
138
+ FileUtils.rm c
139
+ end
140
+ end
141
+ end
142
+
107
143
  # Returns the list of log records from a log directory
108
144
  def log_records
109
- Dir[log_directory_path + "/*.yaml"].sort!
145
+ records = []
146
+ return records if !File.exist?(log_main_directory_path)
147
+ years = Pathname.new(log_main_directory_path).children.select { |c| c.directory? }
148
+ years.each do |dir|
149
+ records = records | Dir[dir.to_s + "/*.yaml"]
150
+ end
151
+ records.sort!
110
152
  end
111
153
 
112
154
  # remove existing file when passed destroy:true in options
113
155
  def clean_path(file_path)
114
156
 
115
- if @destroy and File.exists?(file_path)
157
+ if @destroy and File.exist?(file_path)
116
158
  File.delete(file_path)
117
159
  end
118
160
 
@@ -42,15 +42,6 @@ module FileRecord
42
42
  end
43
43
  end
44
44
 
45
- # Used by read_model and read_log to load all instances from a file
46
- #
47
- def read_instances( model, file, options={} )
48
- instances = YAML::load_stream( File.open( file ) )
49
- instances.each do |i|
50
- model.new( i )
51
- end
52
- end
53
-
54
45
  # Read in all models instances from the model file
55
46
  def read_model( model, options={} )
56
47
 
@@ -64,10 +55,20 @@ module FileRecord
64
55
  options[:time] = time
65
56
  file_path = FileUtility.new(model, options).file_path
66
57
 
67
- if File.exists? file_path
58
+ if File.exist? file_path
68
59
  read_instances model, file_path
69
60
  end
70
61
  end
62
+
63
+ protected
64
+
65
+ # Used by read_model and read_log to load all instances from a file
66
+ def read_instances( model, file, options={} )
67
+ instances = YAML::load_stream( File.open( file ) )
68
+ instances.each do |i|
69
+ model.new( i )
70
+ end
71
+ end
71
72
  end
72
73
  end
73
74
  end
@@ -13,7 +13,7 @@ module Tempo
13
13
  return Views.project_assistance if Model::Project.index.empty?
14
14
 
15
15
  if not options[:at]
16
- time_out = Time.new()
16
+ time_out = Time.new().round
17
17
  else
18
18
  time_out = Time.parse options[:at]
19
19
  end
@@ -9,7 +9,7 @@ module Tempo
9
9
 
10
10
  directory = options.fetch( :directory, ENV['HOME'])
11
11
 
12
- if File.exists?( File.join( directory, 'tempo', @projects.file ))
12
+ if File.exist?( File.join( directory, 'tempo', @projects.file ))
13
13
  @projects.read_from_file options
14
14
  end
15
15
  end