timesheet 0.2.0

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.
@@ -0,0 +1,235 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+ require 'chronic'
3
+
4
+ describe TimesheetParser do
5
+
6
+ context "when given empty parameters" do
7
+
8
+ before :each do
9
+ end
10
+
11
+ it "should show usage" do
12
+ lambda {TimesheetParser.parse([])}.should raise_error SystemExit
13
+ end
14
+
15
+ end
16
+
17
+ context "when parsing in general" do
18
+
19
+ it "should dump the options hash if the debug flag is set" do
20
+
21
+ outstream = StringIO.new
22
+ hash = TimesheetParser.parse(%w[--debug add -p a\ project\ name --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment], outstream)
23
+ outstream.string().should include("Command-line options hash...")
24
+ end
25
+
26
+ it "should report an error if the entire command line is not parsed" do
27
+ lambda {TimesheetParser.parse(%w[edit -r 100 -p a\ project\ name fiddle-dee-dee])}.should raise_error ArgumentError
28
+ end
29
+
30
+ end
31
+
32
+ context "when parsing add command" do
33
+
34
+ before :each do
35
+ end
36
+
37
+ it "should fail on a bare add" do
38
+ lambda {TimesheetParser.parse(["add"])}.should raise_error SystemExit
39
+ end
40
+
41
+ it "should parse a valid complete add command" do
42
+ hash = TimesheetParser.parse(%w[add -p a\ project\ name --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment])
43
+ hash[:command].should eql(:add)
44
+ hash[:project].should eql("a project name")
45
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
46
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
47
+ hash[:comment].should eql("a comment")
48
+ end
49
+
50
+ it "should allow comment to be optional" do
51
+ hash = TimesheetParser.parse(%w[add -p a\ project\ name --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
52
+ hash[:command].should eql(:add)
53
+ hash[:project].should eql("a project name")
54
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
55
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
56
+ end
57
+
58
+ it "should require project" do
59
+ lambda {TimesheetParser.parse(%w[add --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])}.should raise_error SystemExit
60
+ end
61
+
62
+ it "should require start time" do
63
+ lambda {TimesheetParser.parse(%w[add -p a\ project\ name --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment])}.should raise_error SystemExit
64
+ end
65
+
66
+ it "should require end time" do
67
+ lambda {TimesheetParser.parse(%w[add -p a\ project\ name --start 12/1/2009\at\ 11:00\ am --comment a\ comment])}.should raise_error SystemExit
68
+ end
69
+
70
+ end
71
+
72
+ context "when parsing list command" do
73
+
74
+ before :each do
75
+ end
76
+
77
+ it "should accept a bare list" do
78
+ lambda {TimesheetParser.parse(["list"])}.should_not raise_error SystemExit
79
+ end
80
+
81
+ it "should accept a start and end time" do
82
+ hash = TimesheetParser.parse(%w[list --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
83
+ hash[:command].should eql(:report)
84
+ hash[:detail].should be_true
85
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
86
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
87
+ end
88
+
89
+ it "should accept --today" do
90
+ hash = TimesheetParser.parse(%w[list --today])
91
+ hash[:command].should eql(:report)
92
+ hash[:detail].should be_true
93
+ hash[:start].should eql(Chronic.parse('today at 12 am'))
94
+ hash[:end].should eql(Chronic.parse('tomorrow at 12 am'))
95
+ end
96
+
97
+ it "should fail if start date and --today are used" do
98
+ lambda {TimesheetParser.parse(%w[list --today --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])}.should raise_error SystemExit
99
+ end
100
+
101
+ it "should fail if start date is missing end date" do
102
+ lambda {TimesheetParser.parse(%w[list --start 12/1/2009\at\ 11:00\ am])}.should raise_error SystemExit
103
+ end
104
+
105
+ end
106
+
107
+ context "when parsing edit command" do
108
+
109
+ before :each do
110
+ end
111
+
112
+ it "should fail on a bare edit" do
113
+ lambda {TimesheetParser.parse(["edit"])}.should raise_error SystemExit
114
+ end
115
+
116
+ it "should parse a valid complete edit command" do
117
+ hash = TimesheetParser.parse(%w[edit -r 100 -p a\ project\ name --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment])
118
+ hash[:command].should eql(:edit)
119
+ hash[:record_number].should eql(100)
120
+ hash[:project].should eql("a project name")
121
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
122
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
123
+ hash[:comment].should eql("a comment")
124
+ end
125
+
126
+ it "should allow just comment" do
127
+ hash = TimesheetParser.parse(%w[edit -r 12 -c a\ new\ comment])
128
+ hash[:command].should eql(:edit)
129
+ hash[:record_number].should eql(12)
130
+ hash[:project].should be_nil
131
+ hash[:start].should be_nil
132
+ hash[:end].should be_nil
133
+ hash[:comment].should eql("a new comment")
134
+ end
135
+
136
+ it "should allow just project" do
137
+ hash = TimesheetParser.parse(%w[edit --record-number 200 --project a\ new\ project])
138
+ hash[:command].should eql(:edit)
139
+ hash[:record_number].should eql(200)
140
+ hash[:project].should eql("a new project")
141
+ hash[:start].should be_nil
142
+ hash[:end].should be_nil
143
+ hash[:comment].should be_nil
144
+ end
145
+
146
+ it "should allow just start time" do
147
+ hash = TimesheetParser.parse(%w[edit -r 1 -s 12/1/2009\at\ 11:00\ am])
148
+ hash[:command].should eql(:edit)
149
+ hash[:record_number].should eql(1)
150
+ hash[:project].should be_nil
151
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
152
+ hash[:end].should be_nil
153
+ hash[:comment].should be_nil
154
+ end
155
+
156
+ it "should allow just end time" do
157
+ hash = TimesheetParser.parse(%w[edit -r 1 -e 12/1/2009\at\ 2:00\ pm])
158
+ hash[:command].should eql(:edit)
159
+ hash[:record_number].should eql(1)
160
+ hash[:project].should be_nil
161
+ hash[:start].should be_nil
162
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
163
+ hash[:comment].should be_nil
164
+ end
165
+
166
+ end
167
+
168
+ context "when parsing delete command" do
169
+
170
+ before :each do
171
+ end
172
+
173
+ it "should fail on a bare delete" do
174
+ lambda {TimesheetParser.parse(["delete"])}.should raise_error SystemExit
175
+ end
176
+
177
+ it "should parse a valid delete command" do
178
+ hash = TimesheetParser.parse(%w[delete -r 100])
179
+ hash[:command].should eql(:delete)
180
+ hash[:record_number].should eql(100)
181
+ end
182
+
183
+ end
184
+
185
+ context "when parsing report command" do
186
+
187
+ before :each do
188
+ end
189
+
190
+ it "should accept a bare report" do
191
+ lambda {TimesheetParser.parse(["report"])}.should_not raise_error SystemExit
192
+ end
193
+
194
+ it "should parse a valid complete report command" do
195
+ hash = TimesheetParser.parse(%w[report --summary --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
196
+ hash[:command].should eql(:report)
197
+ hash[:summary].should be_true
198
+ hash[:detail].should be_false
199
+ hash[:byday].should be_false
200
+ hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
201
+ hash[:end].should eql(Time.local(2009, 12, 1, 14, 0, 0))
202
+ end
203
+
204
+ it "should reject conflicting parameters" do
205
+ lambda {TimesheetParser.parse(%w[report --summary --detail])}.should raise_error SystemExit
206
+ end
207
+
208
+ it "should reject start without end" do
209
+ lambda {TimesheetParser.parse(%w[report --summary --start 12/1/2009\at\ 11:00\ am ])}.should raise_error SystemExit
210
+ end
211
+
212
+ it "should allow shortcuts" do
213
+ hash = TimesheetParser.parse(%w[report --byday --yesterday])
214
+ hash[:command].should eql(:report)
215
+ hash[:summary].should be_false
216
+ hash[:detail].should be_false
217
+ hash[:byday].should be_true
218
+ hash[:start].should eql(Chronic.parse('yesterday at 12 am'))
219
+ hash[:end].should eql(Chronic.parse('today at 12 am'))
220
+ end
221
+
222
+ end
223
+
224
+ context "when given nonsense" do
225
+
226
+ before :each do
227
+ end
228
+
229
+ it "should reject unknown commands" do
230
+ lambda {TimesheetParser.parse(%w[trundlebug])}.should raise_error SystemExit
231
+ end
232
+
233
+ end
234
+
235
+ end
@@ -0,0 +1,188 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe Timesheet do
4
+
5
+ context "when being invoked" do
6
+
7
+ it "should print an error when no environment values are defined" do
8
+
9
+ params = mock("ARGV")
10
+ command_hash = mock("command_hash")
11
+
12
+ TimesheetParser.should_receive(:parse).with(params).once.and_return(command_hash)
13
+
14
+ ENV.should_receive(:[]).with("TIMESHEET_DATA_FILE").once.and_return(nil)
15
+ ENV.should_receive(:[]).with("HOME").once.and_return(nil)
16
+
17
+ command_hash.should_receive(:[]).with(:debug).once.and_return(nil)
18
+
19
+ Timesheet.should_receive(:puts).with("Cannot determine location for data. Try timesheet --help for details.").once.and_return(nil)
20
+
21
+ Timesheet.run(params)
22
+
23
+ end
24
+
25
+ it "should use the environment value for TIMESHEET_DATA_FILE if it is defined" do
26
+
27
+ params = mock("ARGV")
28
+ command_hash = mock("command_hash")
29
+ store = mock("store")
30
+ time_log = mock("time_log")
31
+ time_sheet = mock("time_sheet")
32
+ timesheet_data_file = mock('ENV["TIMESHEET_DATA_FILE"]')
33
+
34
+ expected_timesheet_data_file = "/somepath/someotherpath/somefile.someext"
35
+ expected_timesheet_data_file_path = "/somepath/someotherpath"
36
+
37
+ TimesheetParser.should_receive(:parse).with(params).once.and_return(command_hash)
38
+
39
+ ENV.should_receive(:[]).with("TIMESHEET_DATA_FILE").twice.and_return(expected_timesheet_data_file)
40
+
41
+ File.should_receive(:dirname).with(expected_timesheet_data_file).once.and_return(expected_timesheet_data_file_path)
42
+ FileUtils.should_receive(:makedirs).with(expected_timesheet_data_file_path).once.and_return(expected_timesheet_data_file_path)
43
+
44
+ YAML::Store.should_receive(:new).with(expected_timesheet_data_file).once.and_return(store)
45
+ TimeLog.should_receive(:new).with(store).once.and_return(time_log)
46
+ Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
47
+ time_sheet.should_receive(:process).with(command_hash)
48
+
49
+ Timesheet.run(params)
50
+
51
+ end
52
+
53
+ it "should use the environment value for HOME if it is defined and TIMESHEET_DATA_FILE is not" do
54
+
55
+ params = mock("ARGV")
56
+ command_hash = mock("command_hash")
57
+ store = mock("store")
58
+ time_log = mock("time_log")
59
+ time_sheet = mock("time_sheet")
60
+
61
+ expected_home = "/Users/someuser"
62
+ expected_data_file = "/Users/someuser/.timesheet/store.yaml"
63
+ expected_data_file_path = "/Users/someuser/.timesheet"
64
+
65
+ TimesheetParser.should_receive(:parse).with(params).once.and_return(command_hash)
66
+
67
+ ENV.should_receive(:[]).with("TIMESHEET_DATA_FILE").twice.and_return(nil)
68
+ ENV.should_receive(:[]).with("HOME").twice.and_return(expected_home)
69
+
70
+ File.should_receive(:dirname).with(expected_data_file).once.and_return(expected_data_file_path)
71
+ FileUtils.should_receive(:makedirs).with(expected_data_file_path).once.and_return(expected_data_file_path)
72
+
73
+ YAML::Store.should_receive(:new).with(expected_data_file).once.and_return(store)
74
+ TimeLog.should_receive(:new).with(store).once.and_return(time_log)
75
+ Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
76
+ time_sheet.should_receive(:process).with(command_hash)
77
+
78
+ Timesheet.run(params)
79
+
80
+ end
81
+
82
+ end
83
+
84
+ context "when processing command" do
85
+
86
+ before :each do
87
+ @command = mock("command")
88
+ @timelog = mock("timelog")
89
+ @timesheet = Timesheet.new(@timelog)
90
+ end
91
+
92
+ it "should dispatch to the proper command handler" do
93
+ valid_dispatch_cases = {
94
+ :add => :process_add_command,
95
+ :edit => :process_edit_command,
96
+ :report => :process_report_command}
97
+
98
+ valid_dispatch_cases.each do |key, value|
99
+ @command.should_receive(:[]).with(:command).once.and_return(key)
100
+ @timesheet.should_receive(value).with(@command).once
101
+ @timesheet.process(@command)
102
+ end
103
+ end
104
+
105
+ it "should raise error when the command is not understood" do
106
+ @command.should_receive(:[]).with(:command).once.and_return("invalid_command")
107
+ lambda { @timesheet.process(@command) }.should raise_error RuntimeError
108
+ end
109
+
110
+ end
111
+
112
+ context "when processing add command" do
113
+
114
+ it "should perform an add" do
115
+ command = mock("add command")
116
+ timelog = mock("timelog")
117
+ timesheet = Timesheet.new(timelog)
118
+
119
+ project = mock("project")
120
+ start_time = mock("start time")
121
+ end_time = mock("end time")
122
+ entry = mock("time entry")
123
+
124
+ command.should_receive(:[]).with(:project).once.and_return(project)
125
+ command.should_receive(:[]).with(:start).once.and_return(start_time)
126
+ command.should_receive(:[]).with(:end).once.and_return(end_time)
127
+ command.should_receive(:[]).with(:comment).once.and_return(nil)
128
+ TimeEntry.should_receive(:new).with(project, start_time, end_time, nil).and_return(entry)
129
+ timelog.should_receive(:add).with(entry)
130
+
131
+ timesheet.process_add_command(command)
132
+ end
133
+
134
+ end
135
+
136
+ context "when processing edit command" do
137
+
138
+ it "should perform an edit" do
139
+ command = mock("edit command")
140
+ timelog = mock("timelog")
141
+ timesheet = Timesheet.new(timelog)
142
+
143
+ command.should_receive(:delete).with(:record_number).once.and_return(100)
144
+ timelog.should_receive(:update).with(100, command)
145
+
146
+ timesheet.process_edit_command(command)
147
+ end
148
+
149
+ end
150
+
151
+ context "when processing delete command" do
152
+
153
+ it "should perform a delete" do
154
+ command = mock("delete command")
155
+ timelog = mock("timelog")
156
+ timesheet = Timesheet.new(timelog)
157
+
158
+ command.should_receive(:delete).with(:record_number).once.and_return(100)
159
+ timelog.should_receive(:delete).with(100)
160
+
161
+ timesheet.process_delete_command(command)
162
+ end
163
+
164
+ end
165
+
166
+ context "when processing report command" do
167
+
168
+ it "should produce a report" do
169
+ command = mock("report command")
170
+ timelog = mock("timelog")
171
+ start_time = mock("start time")
172
+ end_time = mock("end time")
173
+ entries = mock("entries")
174
+ time_report = mock("time report")
175
+ timesheet = Timesheet.new(timelog)
176
+
177
+ command.should_receive(:[]).with(:start).once.and_return(start_time)
178
+ command.should_receive(:[]).with(:end).once.and_return(end_time)
179
+ timelog.should_receive(:extract_entries).with(start_time, end_time).once.and_return(entries)
180
+ TimeReport.should_receive(:new).with(entries).once.and_return(time_report)
181
+ time_report.should_receive(:report).with(command)
182
+
183
+ timesheet.process_report_command(command)
184
+ end
185
+
186
+ end
187
+
188
+ end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems' unless ENV['NO_RUBYGEMS']
5
+ require 'spec'
6
+ end
7
+ begin
8
+ require 'spec/rake/spectask'
9
+ rescue LoadError
10
+ puts <<-EOS
11
+ To use rspec for testing you must install rspec gem:
12
+ gem install rspec
13
+ EOS
14
+ exit(0)
15
+ end
16
+
17
+ desc "Run the specs under spec/models"
18
+ Spec::Rake::SpecTask.new do |t|
19
+ t.spec_opts = ['--options', "spec/spec.opts"]
20
+ t.spec_files = FileList['spec/**/*_spec.rb']
21
+ end
metadata ADDED
@@ -0,0 +1,274 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timesheet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - John F. Schank III
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-05 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: activesupport
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ - !ruby/object:Gem::Dependency
26
+ name: archive-tar-minitar
27
+ type: :runtime
28
+ version_requirement:
29
+ version_requirements: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: "0"
34
+ version:
35
+ - !ruby/object:Gem::Dependency
36
+ name: chronic
37
+ type: :runtime
38
+ version_requirement:
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: color
47
+ type: :runtime
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ - !ruby/object:Gem::Dependency
56
+ name: fastercsv
57
+ type: :runtime
58
+ version_requirement:
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: "0"
64
+ version:
65
+ - !ruby/object:Gem::Dependency
66
+ name: hoe
67
+ type: :runtime
68
+ version_requirement:
69
+ version_requirements: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ - !ruby/object:Gem::Dependency
76
+ name: json_pure
77
+ type: :runtime
78
+ version_requirement:
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: "0"
84
+ version:
85
+ - !ruby/object:Gem::Dependency
86
+ name: newgem
87
+ type: :runtime
88
+ version_requirement:
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: "0"
94
+ version:
95
+ - !ruby/object:Gem::Dependency
96
+ name: pdf-writer
97
+ type: :runtime
98
+ version_requirement:
99
+ version_requirements: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: "0"
104
+ version:
105
+ - !ruby/object:Gem::Dependency
106
+ name: rake
107
+ type: :runtime
108
+ version_requirement:
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: "0"
114
+ version:
115
+ - !ruby/object:Gem::Dependency
116
+ name: RedCloth
117
+ type: :runtime
118
+ version_requirement:
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: "0"
124
+ version:
125
+ - !ruby/object:Gem::Dependency
126
+ name: rich_units
127
+ type: :runtime
128
+ version_requirement:
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: "0"
134
+ version:
135
+ - !ruby/object:Gem::Dependency
136
+ name: rspec
137
+ type: :runtime
138
+ version_requirement:
139
+ version_requirements: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: "0"
144
+ version:
145
+ - !ruby/object:Gem::Dependency
146
+ name: rubigen
147
+ type: :runtime
148
+ version_requirement:
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: "0"
154
+ version:
155
+ - !ruby/object:Gem::Dependency
156
+ name: rubyforge
157
+ type: :runtime
158
+ version_requirement:
159
+ version_requirements: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: "0"
164
+ version:
165
+ - !ruby/object:Gem::Dependency
166
+ name: ruport
167
+ type: :runtime
168
+ version_requirement:
169
+ version_requirements: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: "0"
174
+ version:
175
+ - !ruby/object:Gem::Dependency
176
+ name: syntax
177
+ type: :runtime
178
+ version_requirement:
179
+ version_requirements: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: "0"
184
+ version:
185
+ - !ruby/object:Gem::Dependency
186
+ name: transaction-simple
187
+ type: :runtime
188
+ version_requirement:
189
+ version_requirements: !ruby/object:Gem::Requirement
190
+ requirements:
191
+ - - ">="
192
+ - !ruby/object:Gem::Version
193
+ version: "0"
194
+ version:
195
+ - !ruby/object:Gem::Dependency
196
+ name: hoe
197
+ type: :development
198
+ version_requirement:
199
+ version_requirements: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: 2.4.0
204
+ version:
205
+ description: |-
206
+ <i>Timesheet</i> is simple ruby application for tracking time spent on projects.
207
+ It is a console application that uses a simple text file storage back-end (YAML::Store)
208
+
209
+ The main idea is to be able to produce reports of hours spent, such that I can use geektool to display the reports.
210
+ email:
211
+ - jschank@mac.com
212
+ executables:
213
+ - timesheet
214
+ extensions: []
215
+
216
+ extra_rdoc_files:
217
+ - History.txt
218
+ - Manifest.txt
219
+ files:
220
+ - History.txt
221
+ - Manifest.txt
222
+ - README.rdoc
223
+ - Rakefile
224
+ - bin/timesheet
225
+ - lib/timesheet.rb
226
+ - lib/timesheet/range_extensions.rb
227
+ - lib/timesheet/time_entry.rb
228
+ - lib/timesheet/time_log.rb
229
+ - lib/timesheet/time_report.rb
230
+ - lib/timesheet/timesheet_parser.rb
231
+ - lib/timesheet/trollop.rb
232
+ - script/console
233
+ - script/destroy
234
+ - script/generate
235
+ - spec/range_extensions_spec.rb
236
+ - spec/spec.opts
237
+ - spec/spec_helper.rb
238
+ - spec/time_entry_spec.rb
239
+ - spec/time_log_spec.rb
240
+ - spec/time_report_spec.rb
241
+ - spec/timesheet_parser_spec.rb
242
+ - spec/timesheet_spec.rb
243
+ - tasks/rspec.rake
244
+ has_rdoc: true
245
+ homepage: http://github.com/jschank/timesheet
246
+ licenses: []
247
+
248
+ post_install_message:
249
+ rdoc_options:
250
+ - --main
251
+ - README.rdoc
252
+ require_paths:
253
+ - lib
254
+ required_ruby_version: !ruby/object:Gem::Requirement
255
+ requirements:
256
+ - - ">="
257
+ - !ruby/object:Gem::Version
258
+ version: "0"
259
+ version:
260
+ required_rubygems_version: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: "0"
265
+ version:
266
+ requirements: []
267
+
268
+ rubyforge_project: timesheet
269
+ rubygems_version: 1.3.5
270
+ signing_key:
271
+ specification_version: 3
272
+ summary: <i>Timesheet</i> is simple ruby application for tracking time spent on projects
273
+ test_files: []
274
+