time_tree 2.1.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -8,26 +8,26 @@ Timetree is a command line utility that prints a tree-like breakdown of time spe
8
8
 
9
9
  ## Time Log Format
10
10
 
11
- Each day's log should start with a date in YYYY/MM/DD format. Any text following is ignored as comments. Following this are lines starting with a time in 24 hour format - HHMI, followed by an activity which must contain no spaces, any text following is ignored and considered as comments. Activities may have nested subcategories to any level separated by forward slashes - these will be printed as a hierarchy by timetree. Use a dash (-) for the activity to be ignored and not reported on - this means a day's log must always end with a time followed by a dash to denote when the previous line's activity finished.
11
+ Each day's log should start with a date in YYYY/MM/DD format. Any text following is ignored. Following this are lines starting with a time in 24 hour format - HHMI, followed by an activity which must contain no spaces, any text following can be free form and is treated as a description. Activities may have nested subcategories to any level separated by forward slashes - these will be printed as a hierarchy by timetree. Use a dash (-) for the activity to be ignored and not reported on - this means a day's log must always end with a time followed by a dash to denote when the previous line's activity finished.
12
12
 
13
- Blank lines are ignored and lines starting with # are ignored as comments.
13
+ Blank lines are ignored. Sequences starting with # to the end of the line are ignored as comments.
14
14
 
15
15
  Here's an example:
16
16
 
17
- 2013/04/21 A splendid day!
17
+ 2013/04/21 A splendid day! This text after the date will be ignored
18
18
 
19
- 0930 admin some comments
20
- 0945 development/project1 some more comments
19
+ 0930 admin This is a description
20
+ 0945 development/project1 Some more descriptive text
21
21
  1005 -
22
22
  1030 developemnt/project2
23
23
  1115 -
24
24
 
25
- # Did some work in the evening!
26
- 2230 bugfixing/project3 # Use a hash after a time line if you want but not needed
25
+ # Did some work in the evening! This is a comment that will be ignored
26
+ 2230 bugfixing/project3 a description # This will be ignored because it's a comment
27
27
  2315 -
28
28
 
29
29
 
30
- A day's log can't span across more than one file, but a file may contain multiple day's logs. This gives flexibility, all time may be stored in one big file or there may be multiple files, one for each day or week for example. Multiple files may be stored in a nested folder hierarchy - time tree will recursively search for files, ignoring those starting with . (dot).
30
+ A day's log can not span across more than one file, but a file may contain multiple day's logs. This gives flexibility, all time may be stored in one big file or there may be multiple files, one for each day or week for example. Multiple files may be stored in a nested folder hierarchy - time tree will recursively search for files, ignoring those starting with . (dot).
31
31
 
32
32
  ## Usage
33
33
 
@@ -1,3 +1,3 @@
1
1
  1975/06/01
2
- 1200 jun1stuff
2
+ 1200 jun1stuff jun1
3
3
  1201 -
@@ -1,3 +1,3 @@
1
1
  1975/06/02
2
- 1100 jun2stuff
2
+ 1100 jun2stuff jun2
3
3
  1102 -
@@ -1,3 +1,3 @@
1
1
  1975/06/03
2
- 1000 jun3stuff
2
+ 1000 jun3stuff jun3
3
3
  1003 -
@@ -7,19 +7,21 @@ module TimeTree
7
7
  @output = []
8
8
  end
9
9
 
10
- def load(activities, minutes, level = 0, target = @activities)
10
+ def load(activities, minutes, description, level = 0, target = @activities)
11
11
  activities.unshift 'All' if level == 0
12
12
  activity = activities.shift
13
- target[activity] = {:minutes => 0, :children => {}} unless target[activity]
13
+ target[activity] = {:minutes => 0, :children => {}, :descriptions => []} unless target[activity]
14
14
  target[activity][:minutes] += minutes
15
- load(activities, minutes, level+1, target[activity][:children]) if activities.any?
15
+ target[activity][:descriptions] << description if activities.size == 0 && description
16
+ load(activities, minutes, description, level+1, target[activity][:children]) if activities.any?
16
17
  end
17
18
 
18
19
  def process(level = 0, target = activities)
19
- target.each do |activity, values|
20
- output << "%-25s %4d min (%s)" % ["#{(1..level*2).to_a.map{' '}.join}#{activity}",
20
+ target.sort.each do |activity, values|
21
+ output << "%-25s %4d min (%s) %s" % ["#{(1..level*2).to_a.map{' '}.join}#{activity}",
21
22
  values[:minutes],
22
- to_hrs_mins(values[:minutes])]
23
+ to_hrs_mins(values[:minutes]),
24
+ values[:descriptions].uniq.join(' - ')]
23
25
  process(level+1, values[:children]) if values[:children].any?
24
26
  end
25
27
  end
@@ -30,6 +30,7 @@ module TimeTree
30
30
  @date = date
31
31
  @prev_mins = nil
32
32
  @prev_activities = nil
33
+ @prev_comment = nil
33
34
  end
34
35
 
35
36
  def process_file(path)
@@ -65,12 +66,12 @@ module TimeTree
65
66
  set_date($1)
66
67
  true
67
68
 
68
- when /^(\d\d\d\d) +([^ ]+) *.*$/
69
+ when /^(\d\d\d\d) +([-\w\/]+) *(.*)$/
69
70
  if minutes = mins($1)
70
71
  unless @prev_mins.nil?
71
72
  if minutes > @prev_mins
72
73
  if @prev_activities != '-' && selected?(@date, @prev_activities)
73
- process_line(minutes, @prev_activities)
74
+ process_line(minutes, @prev_activities, @prev_comment)
74
75
  end
75
76
  else
76
77
  add_error(line, 'time does not advance')
@@ -79,7 +80,8 @@ module TimeTree
79
80
  end
80
81
 
81
82
  @prev_mins = minutes
82
- @prev_activities = $2
83
+ @prev_activities = $2.strip
84
+ @prev_comment = $3.size > 0 ? $3 : nil
83
85
  true
84
86
  else
85
87
  false
@@ -122,9 +124,9 @@ module TimeTree
122
124
 
123
125
  private
124
126
 
125
- def process_line(minutes, activities)
127
+ def process_line(minutes, activities, comment)
126
128
  duration = minutes - @prev_mins
127
- @activity_tree.load(activities.split('/'), duration)
129
+ @activity_tree.load(activities.split('/'), duration, comment)
128
130
  end
129
131
 
130
132
  def mins(str)
@@ -1,3 +1,3 @@
1
1
  module TimeTree
2
- VERSION = "2.1.0"
2
+ VERSION = "2.2.1"
3
3
  end
@@ -5,12 +5,14 @@ module TimeTree
5
5
  let(:tree) { ActivityTree.new }
6
6
 
7
7
  before do
8
- tree.load(%w{foo bar baz}, 10)
9
- tree.load(%w{foo bar bam}, 5)
10
- tree.load(%w{blah}, 12)
8
+ tree.load(%w{foo bar baz}, 9, 'did baz')
9
+ tree.load(%w{foo bar baz}, 1, nil)
10
+ tree.load(%w{foo bar bam}, 5, 'did some bam')
11
+ tree.load(%w{blah}, 11, 'did serious blah')
12
+ tree.load(%w{blah}, 1, 'did more blah')
11
13
  end
12
14
 
13
- it "should have 2 root activities" do
15
+ it "All should have 2 root activities" do
14
16
  tree.activities['All'][:children].size.should == 2
15
17
  end
16
18
 
@@ -18,6 +20,10 @@ module TimeTree
18
20
  tree.activities['All'][:children]['foo'][:minutes].should == 15
19
21
  end
20
22
 
23
+ it "foo should have no descriptions" do
24
+ tree.activities['All'][:children]['foo'][:descriptions].size.should == 0
25
+ end
26
+
21
27
  it "bar should have 15 mins" do
22
28
  tree.activities['All'][:children]['foo'][:children]['bar'][:minutes].should == 15
23
29
  end
@@ -26,6 +32,11 @@ module TimeTree
26
32
  tree.activities['All'][:children]['foo'][:children]['bar'][:children]['baz'][:minutes].should == 10
27
33
  end
28
34
 
35
+ it "baz should have 1 description" do
36
+ tree.activities['All'][:children]['foo'][:children]['bar'][:children]['baz'][:descriptions].size.should == 1
37
+ tree.activities['All'][:children]['foo'][:children]['bar'][:children]['baz'][:descriptions].first.should == 'did baz'
38
+ end
39
+
29
40
  it "bam should have 5 mins" do
30
41
  tree.activities['All'][:children]['foo'][:children]['bar'][:children]['bam'][:minutes].should == 5
31
42
  end
@@ -34,11 +45,18 @@ module TimeTree
34
45
  tree.activities['All'][:children]['blah'][:minutes].should == 12
35
46
  end
36
47
 
48
+ it "blah should have 2 descriptions" do
49
+ tree.activities['All'][:children]['blah'][:descriptions].size.should == 2
50
+ tree.activities['All'][:children]['blah'][:descriptions].first.should == 'did serious blah'
51
+ tree.activities['All'][:children]['blah'][:descriptions].last.should == 'did more blah'
52
+ end
53
+
37
54
  it "blah should have no children" do
38
55
  tree.activities['All'][:children]['blah'][:children].size.should == 0
39
56
  end
40
57
 
41
58
  it "should print" do
59
+ tree.process
42
60
  tree.print
43
61
  end
44
62
  end
@@ -42,7 +42,7 @@ module TimeTree
42
42
  parser.process_file(fixtures('time.txt')).should be_true
43
43
  end
44
44
 
45
- it "calls process_line for each line of the file" do
45
+ it "calls parse_line for each line of the file" do
46
46
  parser.should_receive(:parse_line).exactly(3).times
47
47
  parser.process_file(fixtures('time.txt'))
48
48
  end
@@ -142,10 +142,16 @@ module TimeTree
142
142
  end
143
143
 
144
144
  it "calls ActivityTree#load after first line" do
145
- tree.should_receive(:load).with(%w{adm foo bar}, 1).once
146
- parser.parse_line("1634 adm/foo/bar dhffhkdhsdhjdf")
145
+ tree.should_receive(:load).with(%w{adm foo bar}, 1, 'blart flange').once
146
+ parser.parse_line("1634 adm/foo/bar blart flange")
147
147
  parser.parse_line("1635 -")
148
148
  end
149
+
150
+ it "handles absent descriptions" do
151
+ tree.should_receive(:load).with(%w{adm foo bar}, 1, nil).once
152
+ parser.parse_line("1734 adm/foo/bar")
153
+ parser.parse_line("1735 -")
154
+ end
149
155
 
150
156
  it "flags invalid times" do
151
157
  parser.parse_line("2435 - df sdfsdg").should be_false
@@ -11,9 +11,9 @@ module TimeTree
11
11
  parser.process_file(fixtures('time'))
12
12
  tree.process
13
13
  tree.output[0].should =~ /All +6 min/
14
- tree.output[1].should =~ /jun1stuff +1 min/
15
- tree.output[2].should =~ /jun2stuff +2 min/
16
- tree.output[3].should =~ /jun3stuff +3 min/
14
+ tree.output[1].should =~ /jun1stuff +1 min \(0:01\) +jun1/
15
+ tree.output[2].should =~ /jun2stuff +2 min \(0:02\) +jun2/
16
+ tree.output[3].should =~ /jun3stuff +3 min \(0:03\) +jun3/
17
17
  tree.output.size.should == 4
18
18
  end
19
19
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: time_tree
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-05-09 00:00:00.000000000 Z
12
+ date: 2013-07-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec