hcl 0.4.4 → 0.4.5
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.
- checksums.yaml +4 -4
- data/CHANGELOG +5 -0
- data/HACKING.markdown +8 -13
- data/README.markdown +6 -8
- data/lib/hcl/app.rb +9 -6
- data/lib/hcl/commands.rb +19 -14
- data/lib/hcl/task.rb +5 -1
- data/lib/hcl/version.rb +1 -1
- data/test/app_test.rb +10 -1
- data/test/command_test.rb +99 -0
- data/test/day_entry_test.rb +3 -3
- data/test/task_test.rb +26 -0
- data/test/test_helper.rb +17 -4
- data/test/utility_test.rb +3 -3
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db61484751f4f46ad0e78d1221bd7c6291812ed8
|
4
|
+
data.tar.gz: 835db00cb847562bb1bfdd32156ce14bae753d36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 842e229a4dc43d0931f2fed478ec12e78576ad073095994ca71ff9fb9d79c24af4f592af479c0a8d01ae360e69a0a81c4e8084ee30c3d0ad694fe011345c14c8
|
7
|
+
data.tar.gz: 298c413ac8be9f93bd0910ca7da08bb8a7d006ec86078ed1e30317e672d9f7cb13598a87e47caa10f61d1783feef16219bcec5300faa0733598df0e8a1cd84d8
|
data/CHANGELOG
CHANGED
data/HACKING.markdown
CHANGED
@@ -1,21 +1,16 @@
|
|
1
1
|
# Hacking HCl
|
2
2
|
|
3
|
-
##
|
3
|
+
## Running the tests
|
4
4
|
|
5
|
-
|
6
|
-
explicitly include rubygems in the app. That's up the system to decide. Don't
|
7
|
-
require rubygems in the code.
|
5
|
+
Use Bundler to install dependencies before you run the tests:
|
8
6
|
|
9
|
-
|
7
|
+
gem install bundler
|
8
|
+
bundle
|
9
|
+
rake test
|
10
10
|
|
11
|
-
## Running HCl
|
11
|
+
## Running HCl during development
|
12
12
|
|
13
|
-
|
13
|
+
To run HCl in place (e.g. for testing out local changes) you can use bundle exec:
|
14
14
|
|
15
|
-
|
15
|
+
bundle exec bin/hcl
|
16
16
|
|
17
|
-
Don't add dir(__FILE__)/lib to the load path in the binary. Bad manners.
|
18
|
-
|
19
|
-
## That's it
|
20
|
-
|
21
|
-
That's it. I mostly wrote this to explain why I rolled back certain changes.
|
data/README.markdown
CHANGED
@@ -15,20 +15,15 @@ or you can install from source:
|
|
15
15
|
|
16
16
|
$ rake install
|
17
17
|
|
18
|
-
If you're using HCl for the first time, the show command sets up your
|
19
|
-
Harvest credentials:
|
20
|
-
|
21
|
-
$ hcl show
|
22
|
-
|
23
18
|
## Usage
|
24
19
|
|
25
20
|
hcl [start] @<task_alias> [+<time>] [<message>]
|
26
21
|
hcl note <message>
|
27
|
-
hcl stop [message]
|
22
|
+
hcl stop [<message>]
|
28
23
|
hcl resume [@<task_alias>]
|
29
24
|
hcl log @<task_alias> [+<time>] [<message>]
|
30
|
-
hcl show [date]
|
31
|
-
hcl tasks
|
25
|
+
hcl show [<date>]
|
26
|
+
hcl tasks [<project_code>]
|
32
27
|
hcl alias <task_alias> <project_id> <task_id>
|
33
28
|
hcl aliases
|
34
29
|
hcl (cancel | nvm | oops)
|
@@ -41,6 +36,9 @@ available tasks.
|
|
41
36
|
|
42
37
|
$ hcl tasks
|
43
38
|
|
39
|
+
You can also pass a project code (this is the short optional code associated
|
40
|
+
with each project) to list only the tasks for that project.
|
41
|
+
|
44
42
|
### Starting a Timer
|
45
43
|
|
46
44
|
Since it's not practical to enter two long numbers every time you want to
|
data/lib/hcl/app.rb
CHANGED
@@ -9,20 +9,23 @@ module HCl
|
|
9
9
|
include HCl::Utility
|
10
10
|
include HCl::Commands
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
|
13
|
+
HCL_DIR = ENV['HCL_DIR'] || "#{ENV['HOME']}/.hcl"
|
14
|
+
SETTINGS_FILE = "#{HCL_DIR}/settings.yml"
|
15
|
+
CONFIG_FILE = "#{HCL_DIR}/config.yml"
|
14
16
|
OLD_SETTINGS_FILE = "#{ENV['HOME']}/.hcl_settings"
|
15
17
|
OLD_CONFIG_FILE = "#{ENV['HOME']}/.hcl_config"
|
16
18
|
|
17
|
-
def
|
19
|
+
def configure
|
18
20
|
FileUtils.mkdir_p(File.join(ENV['HOME'], ".hcl"))
|
19
21
|
read_config
|
20
22
|
read_settings
|
23
|
+
self
|
21
24
|
end
|
22
25
|
|
23
26
|
# Run the given command and arguments.
|
24
27
|
def self.command *args
|
25
|
-
|
28
|
+
new.configure.process_args(*args).run
|
26
29
|
end
|
27
30
|
|
28
31
|
# Return true if the string is a known command, false otherwise.
|
@@ -47,10 +50,10 @@ module HCl
|
|
47
50
|
end
|
48
51
|
end
|
49
52
|
else
|
50
|
-
start
|
53
|
+
puts start(@command, *@args)
|
51
54
|
end
|
52
55
|
else
|
53
|
-
show
|
56
|
+
puts show
|
54
57
|
end
|
55
58
|
rescue RuntimeError => e
|
56
59
|
STDERR.puts "Error: #{e}"
|
data/lib/hcl/commands.rb
CHANGED
@@ -3,14 +3,18 @@ require 'highline'
|
|
3
3
|
|
4
4
|
module HCl
|
5
5
|
module Commands
|
6
|
-
def tasks
|
6
|
+
def tasks project_code=nil
|
7
7
|
tasks = Task.all
|
8
|
+
if tasks.empty? # cache tasks
|
9
|
+
DayEntry.all
|
10
|
+
tasks = Task.all
|
11
|
+
end
|
12
|
+
tasks.select! {|t| t.project.code == project_code } if project_code
|
8
13
|
if tasks.empty?
|
9
|
-
puts "No
|
10
|
-
|
11
|
-
tasks.each { |task| puts "#{task.project.id} #{task.id}\t#{task}" }
|
14
|
+
puts "No matching tasks."
|
15
|
+
exit 1
|
12
16
|
end
|
13
|
-
|
17
|
+
tasks.map { |task| "#{task.project.id} #{task.id}\t#{task}" }.join("\n")
|
14
18
|
end
|
15
19
|
|
16
20
|
def set key = nil, *args
|
@@ -31,7 +35,7 @@ module HCl
|
|
31
35
|
entry = DayEntry.with_timer || DayEntry.last
|
32
36
|
if entry
|
33
37
|
if entry.cancel
|
34
|
-
|
38
|
+
"Deleted entry #{entry}."
|
35
39
|
else
|
36
40
|
puts "Failed to delete #{entry}!"
|
37
41
|
exit 1
|
@@ -51,14 +55,14 @@ module HCl
|
|
51
55
|
|
52
56
|
def unalias task
|
53
57
|
unset "task.#{task}"
|
54
|
-
|
58
|
+
"Removed task alias @#{task}."
|
55
59
|
end
|
56
60
|
|
57
61
|
def alias task_name, *value
|
58
62
|
task = Task.find *value
|
59
63
|
if task
|
60
64
|
set "task.#{task_name}", *value
|
61
|
-
|
65
|
+
"Added alias @#{task_name} for #{task}."
|
62
66
|
else
|
63
67
|
puts "Unrecognized project and task ID: #{value.inspect}"
|
64
68
|
exit 1
|
@@ -83,7 +87,7 @@ module HCl
|
|
83
87
|
timer = task.start \
|
84
88
|
:starting_time => starting_time,
|
85
89
|
:note => args.join(' ')
|
86
|
-
|
90
|
+
"Started timer for #{timer} (at #{current_time})"
|
87
91
|
end
|
88
92
|
|
89
93
|
def log *args
|
@@ -96,7 +100,7 @@ module HCl
|
|
96
100
|
if entry
|
97
101
|
entry.append_note(args.join(' ')) if args.any?
|
98
102
|
entry.toggle
|
99
|
-
|
103
|
+
"Stopped #{entry} (at #{current_time})"
|
100
104
|
else
|
101
105
|
puts "No running timers found."
|
102
106
|
exit 1
|
@@ -108,7 +112,7 @@ module HCl
|
|
108
112
|
entry = DayEntry.with_timer
|
109
113
|
if entry
|
110
114
|
entry.append_note message
|
111
|
-
|
115
|
+
"Added note to #{entry}."
|
112
116
|
else
|
113
117
|
puts "No running timers found."
|
114
118
|
exit 1
|
@@ -118,14 +122,15 @@ module HCl
|
|
118
122
|
def show *args
|
119
123
|
date = args.empty? ? nil : Chronic.parse(args.join(' '))
|
120
124
|
total_hours = 0.0
|
125
|
+
result = ''
|
121
126
|
DayEntry.all(date).each do |day|
|
122
127
|
running = day.running? ? '(running) ' : ''
|
123
128
|
columns = HighLine::SystemExtensions.terminal_size[0]
|
124
|
-
|
129
|
+
result << "\t#{day.formatted_hours}\t#{running}#{day.project}: #{day.notes.lines.last}\n"[0..columns-1]
|
125
130
|
total_hours = total_hours + day.hours.to_f
|
126
131
|
end
|
127
|
-
|
128
|
-
|
132
|
+
result << ("\t" + '-' * 13) << "\n"
|
133
|
+
result << "\t#{as_hours total_hours}\ttotal (as of #{current_time})\n"
|
129
134
|
end
|
130
135
|
|
131
136
|
def resume *args
|
data/lib/hcl/task.rb
CHANGED
@@ -45,7 +45,11 @@ module HCl
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def to_s
|
48
|
-
|
48
|
+
if project.code.empty?
|
49
|
+
"#{project.client} - #{project.name} - #{name}"
|
50
|
+
else
|
51
|
+
"#{project.client} - [#{project.code}] #{project.name} - #{name}"
|
52
|
+
end
|
49
53
|
end
|
50
54
|
|
51
55
|
def add opts
|
data/lib/hcl/version.rb
CHANGED
data/test/app_test.rb
CHANGED
@@ -1,8 +1,17 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
class AppTest < Test::Unit::TestCase
|
3
3
|
|
4
|
-
|
4
|
+
def test_commands
|
5
5
|
app = HCl::App.new
|
6
6
|
assert HCl::Commands.instance_methods.all? { |c| app.command? c }, 'all methods are commands'
|
7
7
|
end
|
8
|
+
|
9
|
+
def test_command_show
|
10
|
+
HCl::DayEntry.expects(:all).returns([HCl::DayEntry.new({
|
11
|
+
hours:'2.06',
|
12
|
+
notes: 'hi world',
|
13
|
+
project: 'App'
|
14
|
+
})])
|
15
|
+
HCl::App.command 'show'
|
16
|
+
end
|
8
17
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
class CommandTest < Test::Unit::TestCase
|
3
|
+
include HCl::Commands
|
4
|
+
include HCl::Utility
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@settings = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
# the current_time utility method needs to be deterministic
|
11
|
+
def current_time
|
12
|
+
'high noon'
|
13
|
+
end
|
14
|
+
|
15
|
+
# stub settings helpers
|
16
|
+
def write_settings; end
|
17
|
+
def read_settings
|
18
|
+
@settings
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_tasks
|
22
|
+
HCl::Task.expects(:all).returns([HCl::Task.new(
|
23
|
+
id:123,
|
24
|
+
name: 'Dev',
|
25
|
+
project: HCl::Project.new(id:456, name:'App', client:'Bob', code:'b')
|
26
|
+
)])
|
27
|
+
result = tasks
|
28
|
+
assert_equal "456 123\tBob - [b] App - Dev", result
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_show
|
32
|
+
HCl::DayEntry.expects(:all).returns([HCl::DayEntry.new({
|
33
|
+
hours:'2.06',
|
34
|
+
notes: 'hi world',
|
35
|
+
project: 'App'
|
36
|
+
})])
|
37
|
+
result = show
|
38
|
+
assert_equal \
|
39
|
+
"\t2:03\tApp: hi world\n\t-------------\n\t2:03\ttotal (as of high noon)\n",
|
40
|
+
result
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_aliases
|
44
|
+
HCl::Task.expects(:all).returns([HCl::Task.new(
|
45
|
+
id:123,
|
46
|
+
name: 'Dev',
|
47
|
+
project: HCl::Project.new(id:456, name:'App', client:'Bob', code:'b')
|
48
|
+
)])
|
49
|
+
result = send :alias, *%w[ hcl 456 123 ]
|
50
|
+
assert_equal '456 123', @settings['task.hcl']
|
51
|
+
|
52
|
+
result = aliases
|
53
|
+
assert_equal ["@hcl"], result
|
54
|
+
|
55
|
+
result = unalias 'hcl'
|
56
|
+
assert !@settings.key?('task.hcl'), 'hcl alias is no longer defined'
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_start
|
60
|
+
task = HCl::Task.new(
|
61
|
+
id:123,
|
62
|
+
name: 'Dev',
|
63
|
+
project: HCl::Project.new(id:456, name:'App', client:'Bob', code:'b')
|
64
|
+
)
|
65
|
+
HCl::Task.expects(:find).with('456','123').returns(task)
|
66
|
+
task.expects(:start).with(starting_time:nil, note:'do stuff')
|
67
|
+
start *%w[ 456 123 do stuff ]
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_stop
|
71
|
+
entry = stub
|
72
|
+
HCl::DayEntry.expects(:with_timer).returns(entry)
|
73
|
+
entry.expects(:append_note).with('all done')
|
74
|
+
entry.expects(:toggle)
|
75
|
+
stop 'all done'
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_resume
|
79
|
+
entry = stub
|
80
|
+
HCl::DayEntry.expects(:last).returns(entry)
|
81
|
+
entry.expects(:toggle)
|
82
|
+
resume
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_cancel
|
86
|
+
entry = stub
|
87
|
+
HCl::DayEntry.expects(:with_timer).returns(entry)
|
88
|
+
entry.expects(:cancel).returns(true)
|
89
|
+
cancel
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_note
|
93
|
+
entry = stub
|
94
|
+
HCl::DayEntry.expects(:with_timer).returns(entry)
|
95
|
+
entry.expects(:append_note).with('hi world')
|
96
|
+
note 'hi world'
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
data/test/day_entry_test.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
class DayEntryTest < Test::Unit::TestCase
|
4
|
-
|
4
|
+
def test_from_xml
|
5
5
|
entries = HCl::DayEntry.from_xml(<<-EOD)
|
6
6
|
<daily>
|
7
7
|
<for_day type="date">Wed, 18 Oct 2006</for_day>
|
@@ -33,14 +33,14 @@ class DayEntryTest < Test::Unit::TestCase
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
def test_append_note
|
37
37
|
entry = HCl::DayEntry.new(:id => '1', :notes => 'yourmom.', :hours => '1.0')
|
38
38
|
HCl::DayEntry.stubs(:post)
|
39
39
|
entry.append_note('hi world')
|
40
40
|
assert_equal "yourmom.\nhi world", entry.notes
|
41
41
|
end
|
42
42
|
|
43
|
-
|
43
|
+
def test_append_note_to_empty
|
44
44
|
entry = HCl::DayEntry.new(:id => '1', :notes => nil, :hours => '1.0')
|
45
45
|
HCl::DayEntry.stubs(:post)
|
46
46
|
entry.append_note('hi world')
|
data/test/task_test.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
class Task < Test::Unit::TestCase
|
3
|
+
def test_cache_tasks
|
4
|
+
HCl::Task.cache_tasks(REXML::Document.new(<<-EOD))
|
5
|
+
<daily>
|
6
|
+
<projects>
|
7
|
+
<project>
|
8
|
+
<name>Click and Type</name>
|
9
|
+
<code></code>
|
10
|
+
<id type="integer">3</id>
|
11
|
+
<client>AFS</client>
|
12
|
+
<tasks>
|
13
|
+
<task>
|
14
|
+
<name>Security support</name>
|
15
|
+
<id type="integer">14</id>
|
16
|
+
<billable type="boolean">true</billable>
|
17
|
+
</task>
|
18
|
+
</tasks>
|
19
|
+
</project>
|
20
|
+
</projects>
|
21
|
+
</daily>
|
22
|
+
EOD
|
23
|
+
assert_equal 1, HCl::Task.all.size
|
24
|
+
assert_equal 'Security support', HCl::Task.all.first.name
|
25
|
+
end
|
26
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -1,7 +1,20 @@
|
|
1
|
-
|
1
|
+
require 'bundler'
|
2
|
+
require 'simplecov'
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter '/test/'
|
5
|
+
add_filter do |source_file|
|
6
|
+
source_file.lines.count < 15
|
7
|
+
end
|
8
|
+
end
|
2
9
|
|
3
|
-
require 'rubygems'
|
4
10
|
require 'test/unit'
|
5
|
-
require 'hcl'
|
6
|
-
require 'shoulda'
|
7
11
|
require 'mocha/setup'
|
12
|
+
require 'fileutils'
|
13
|
+
|
14
|
+
# override the default hcl dir
|
15
|
+
FileUtils.mkdir_p __dir__+"/dot_hcl"
|
16
|
+
ENV['HCL_DIR'] = __dir__+"/dot_hcl"
|
17
|
+
|
18
|
+
require 'hcl'
|
19
|
+
|
20
|
+
|
data/test/utility_test.rb
CHANGED
@@ -3,15 +3,15 @@ require 'test_helper'
|
|
3
3
|
class UtilityTest < Test::Unit::TestCase
|
4
4
|
include HCl::Utility
|
5
5
|
|
6
|
-
|
6
|
+
def test_time2float_decimal
|
7
7
|
assert_equal 2.5, time2float("2.5")
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
def test_time2float_hhmm
|
11
11
|
assert_equal 2.5, time2float("2:30")
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
def test_time2float_assume_decimal
|
15
15
|
assert_equal 2.0, time2float("2")
|
16
16
|
end
|
17
17
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hcl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Zack Hobson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trollop
|
@@ -67,7 +67,7 @@ dependencies:
|
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
70
|
+
name: mocha
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
73
|
- - '>='
|
@@ -81,7 +81,7 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: yard
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
87
|
- - '>='
|
@@ -95,7 +95,7 @@ dependencies:
|
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
101
|
- - '>='
|
@@ -131,7 +131,9 @@ files:
|
|
131
131
|
- lib/hcl/version.rb
|
132
132
|
- lib/hcl.rb
|
133
133
|
- test/app_test.rb
|
134
|
+
- test/command_test.rb
|
134
135
|
- test/day_entry_test.rb
|
136
|
+
- test/task_test.rb
|
135
137
|
- test/test_helper.rb
|
136
138
|
- test/utility_test.rb
|
137
139
|
homepage: http://zackhobson.com/hcl/
|