zenhob-hcl 0.1.3 → 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.
- data/README.markdown +10 -1
- data/VERSION.yml +2 -2
- data/hcl.gemspec +4 -3
- data/lib/hcl/day_entry.rb +9 -2
- data/lib/hcl/task.rb +16 -6
- data/lib/hcl/utility.rb +18 -0
- data/lib/hcl.rb +11 -10
- metadata +3 -2
data/README.markdown
CHANGED
@@ -27,7 +27,7 @@ HCl is a command-line tool for interacting with Harvest time sheets using the
|
|
27
27
|
hcl tasks
|
28
28
|
hcl set <key> <value ...>
|
29
29
|
hcl unset <key>
|
30
|
-
hcl start (<task_alias> | <project_id> <task_id>) [msg ...]
|
30
|
+
hcl start (<task_alias> | <project_id> <task_id>) [+time] [msg ...]
|
31
31
|
hcl note <msg ...>
|
32
32
|
hcl stop
|
33
33
|
|
@@ -54,6 +54,15 @@ identify a task, HCl supports task aliases:
|
|
54
54
|
$ hcl set task.xdev 1234 5678
|
55
55
|
$ hcl start xdev adding a new feature
|
56
56
|
|
57
|
+
### Starting a Timer with Initial Time
|
58
|
+
|
59
|
+
You can also provide an initial time when starting a new timer.
|
60
|
+
This can be expressed in floating-point or HH:MM. The following two
|
61
|
+
commands are identical:
|
62
|
+
|
63
|
+
$ hcl start xdev +0:15 adding a new feature
|
64
|
+
$ hcl start +.25 xdev adding a new feature
|
65
|
+
|
57
66
|
### Adding Notes to a Running Task
|
58
67
|
|
59
68
|
While a task is running you can append strings to the note for that task:
|
data/VERSION.yml
CHANGED
data/hcl.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{hcl}
|
5
|
-
s.version = "0.
|
5
|
+
s.version = "0.2.0"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Zack Hobson"]
|
9
|
-
s.date = %q{2009-07-
|
9
|
+
s.date = %q{2009-07-30}
|
10
10
|
s.default_executable = %q{hcl}
|
11
11
|
s.description = %q{HCl is a command-line client for manipulating Harvest time sheets.}
|
12
12
|
s.email = %q{zack@opensourcery.com}
|
@@ -29,7 +29,8 @@ Gem::Specification.new do |s|
|
|
29
29
|
"lib/hcl/day_entry.rb",
|
30
30
|
"lib/hcl/project.rb",
|
31
31
|
"lib/hcl/task.rb",
|
32
|
-
"lib/hcl/timesheet_resource.rb"
|
32
|
+
"lib/hcl/timesheet_resource.rb",
|
33
|
+
"lib/hcl/utility.rb"
|
33
34
|
]
|
34
35
|
s.has_rdoc = true
|
35
36
|
s.homepage = %q{http://github.com/zenhob/hcl}
|
data/lib/hcl/day_entry.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
|
2
2
|
class HCl
|
3
3
|
class DayEntry < TimesheetResource
|
4
|
+
include Utility
|
4
5
|
# Get the time sheet entries for a given day. If no date is provided
|
5
6
|
# defaults to today.
|
6
7
|
def self.all date = nil
|
@@ -9,13 +10,13 @@ class HCl
|
|
9
10
|
end
|
10
11
|
|
11
12
|
def to_s
|
12
|
-
"#{client} #{project} #{task} (#{
|
13
|
+
"#{client} #{project} #{task} (#{formatted_hours})"
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.from_xml xml
|
16
17
|
doc = REXML::Document.new xml
|
17
18
|
Task.cache_tasks doc
|
18
|
-
doc.root.elements.collect('
|
19
|
+
doc.root.elements.collect('//day_entry') do |day|
|
19
20
|
new xml_to_hash(day)
|
20
21
|
end
|
21
22
|
end
|
@@ -49,5 +50,11 @@ class HCl
|
|
49
50
|
DayEntry.get("daily/timer/#{id}")
|
50
51
|
self
|
51
52
|
end
|
53
|
+
|
54
|
+
# Returns the hours formatted as "HH:MM"
|
55
|
+
def formatted_hours
|
56
|
+
as_hours hours
|
57
|
+
end
|
58
|
+
|
52
59
|
end
|
53
60
|
end
|
data/lib/hcl/task.rb
CHANGED
@@ -8,8 +8,10 @@ class HCl
|
|
8
8
|
new xml_to_hash(task).merge(:project => project)
|
9
9
|
end)
|
10
10
|
end
|
11
|
-
|
12
|
-
|
11
|
+
unless tasks.empty?
|
12
|
+
File.open(File.join(ENV['HOME'],'.hcl_tasks'), 'w') do |f|
|
13
|
+
f.write tasks.uniq.to_yaml
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
|
@@ -18,19 +20,22 @@ class HCl
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def self.find project_id, id
|
21
|
-
all.detect
|
23
|
+
all.detect do |t|
|
24
|
+
t.project.id.to_i == project_id.to_i && t.id.to_i == id.to_i
|
25
|
+
end
|
22
26
|
end
|
23
27
|
|
24
28
|
def to_s
|
25
29
|
"#{project.name} #{name}"
|
26
30
|
end
|
27
31
|
|
28
|
-
def
|
29
|
-
notes =
|
32
|
+
def add opts
|
33
|
+
notes = opts[:note]
|
34
|
+
starting_time = opts[:starting_time] || 0
|
30
35
|
days = DayEntry.from_xml Task.post("daily/add", <<-EOT)
|
31
36
|
<request>
|
32
37
|
<notes>#{notes}</notes>
|
33
|
-
<hours
|
38
|
+
<hours>#{starting_time}</hours>
|
34
39
|
<project_id type="integer">#{project.id}</project_id>
|
35
40
|
<task_id type="integer">#{id}</task_id>
|
36
41
|
<spent_at type="date">#{Date.today}</spent_at>
|
@@ -39,6 +44,11 @@ class HCl
|
|
39
44
|
days.first
|
40
45
|
end
|
41
46
|
|
47
|
+
def start opts
|
48
|
+
day = add opts
|
49
|
+
DayEntry.from_xml(Task.get("daily/timer/#{day.id}")).first
|
50
|
+
end
|
51
|
+
|
42
52
|
end
|
43
53
|
end
|
44
54
|
|
data/lib/hcl/utility.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class HCl
|
2
|
+
module Utility
|
3
|
+
# Convert from decimal to a string of the form HH:MM.
|
4
|
+
def as_hours hours
|
5
|
+
minutes = hours.to_f * 60.0
|
6
|
+
sprintf "%d:%02d", (minutes / 60).to_i, (minutes % 60).to_i
|
7
|
+
end
|
8
|
+
|
9
|
+
def time2float time_string
|
10
|
+
if time_string =~ /:/
|
11
|
+
hours, minutes = time_string.split(':')
|
12
|
+
hours.to_f + (minutes.to_f / 60.0)
|
13
|
+
elsif time_string =~ /./
|
14
|
+
time_string.to_f
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/hcl.rb
CHANGED
@@ -7,6 +7,7 @@ require 'chronic'
|
|
7
7
|
require 'trollop'
|
8
8
|
require 'highline/import'
|
9
9
|
|
10
|
+
require 'hcl/utility'
|
10
11
|
require 'hcl/timesheet_resource'
|
11
12
|
require 'hcl/project'
|
12
13
|
require 'hcl/task'
|
@@ -25,6 +26,8 @@ class Net::HTTP
|
|
25
26
|
end
|
26
27
|
|
27
28
|
class HCl
|
29
|
+
include Utility
|
30
|
+
|
28
31
|
VERSION_FILE = File.dirname(__FILE__) + '/../VERSION.yml'
|
29
32
|
SETTINGS_FILE = "#{ENV['HOME']}/.hcl_settings"
|
30
33
|
CONFIG_FILE = "#{ENV['HOME']}/.hcl_config"
|
@@ -172,6 +175,11 @@ EOM
|
|
172
175
|
end
|
173
176
|
|
174
177
|
def start *args
|
178
|
+
starting_time = args.detect {|x| x =~ /^\+\d*(\.|:)\d+$/ }
|
179
|
+
if starting_time
|
180
|
+
args.delete(starting_time)
|
181
|
+
starting_time = time2float starting_time
|
182
|
+
end
|
175
183
|
ident = args.shift
|
176
184
|
task_ids = if @settings.key? "task.#{ident}"
|
177
185
|
@settings["task.#{ident}"].split(/\s+/)
|
@@ -183,8 +191,8 @@ EOM
|
|
183
191
|
puts "Unknown project/task alias, try one of the following: #{aliases.join(', ')}."
|
184
192
|
exit 1
|
185
193
|
end
|
186
|
-
task.start(
|
187
|
-
puts "Started timer for #{
|
194
|
+
timer = task.start(:starting_time => starting_time, :note => args.join(' '))
|
195
|
+
puts "Started timer for #{timer}."
|
188
196
|
end
|
189
197
|
|
190
198
|
def stop
|
@@ -212,20 +220,13 @@ EOM
|
|
212
220
|
date = args.empty? ? nil : Chronic.parse(args.join(' '))
|
213
221
|
total_hours = 0.0
|
214
222
|
DayEntry.all(date).each do |day|
|
215
|
-
# TODO more information and formatting options
|
216
223
|
running = day.running? ? '(running) ' : ''
|
217
|
-
puts "\t#{
|
224
|
+
puts "\t#{day.formatted_hours}\t#{running}#{day.project} #{day.notes}"[0..78]
|
218
225
|
total_hours = total_hours + day.hours.to_f
|
219
226
|
end
|
220
227
|
puts "\t" + '-' * 13
|
221
228
|
puts "\t#{as_hours total_hours}\ttotal"
|
222
229
|
end
|
223
230
|
|
224
|
-
# Convert from decimal to a string of the form HH:MM.
|
225
|
-
def as_hours hours
|
226
|
-
minutes = hours.to_f * 60.0
|
227
|
-
sprintf "%d:%02d", (minutes / 60).to_i, (minutes % 60).to_i
|
228
|
-
end
|
229
|
-
|
230
231
|
end
|
231
232
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zenhob-hcl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zack Hobson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-30 00:00:00 -07:00
|
13
13
|
default_executable: hcl
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -76,6 +76,7 @@ files:
|
|
76
76
|
- lib/hcl/project.rb
|
77
77
|
- lib/hcl/task.rb
|
78
78
|
- lib/hcl/timesheet_resource.rb
|
79
|
+
- lib/hcl/utility.rb
|
79
80
|
has_rdoc: true
|
80
81
|
homepage: http://github.com/zenhob/hcl
|
81
82
|
licenses:
|