summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorZack Hobson2013-11-18 12:20:08 -0800
committerZack Hobson2013-11-18 12:20:08 -0800
commit392034ccb82add25c97c8175abbc6422aa871b27 (patch)
tree0a95069bd1de35d0b51dd4de0ef775cb53421f71 /lib
parent27bc3cef233dd4f50c9957bae0ac90392ea99023 (diff)
downloadhcl-392034ccb82add25c97c8175abbc6422aa871b27.tar.bz2
version 0.4.0
* added alias and unalias commands * note and start commands are now optional/contextual * note adds a new line
Diffstat (limited to 'lib')
-rw-r--r--lib/hcl/app.rb66
-rw-r--r--lib/hcl/commands.rb56
-rw-r--r--lib/hcl/day_entry.rb9
-rw-r--r--lib/hcl/task.rb9
4 files changed, 102 insertions, 38 deletions
diff --git a/lib/hcl/app.rb b/lib/hcl/app.rb
index 9569dc5..6b3e428 100644
--- a/lib/hcl/app.rb
+++ b/lib/hcl/app.rb
@@ -3,6 +3,7 @@ require 'yaml'
require 'rexml/document'
require 'net/http'
require 'net/https'
+require 'fileutils'
## gem dependencies
require 'chronic'
@@ -36,10 +37,13 @@ module HCl
include HCl::Utility
include HCl::Commands
- SETTINGS_FILE = "#{ENV['HOME']}/.hcl_settings"
- CONFIG_FILE = "#{ENV['HOME']}/.hcl_config"
+ SETTINGS_FILE = "#{ENV['HOME']}/.hcl/settings.yml"
+ CONFIG_FILE = "#{ENV['HOME']}/.hcl/config.yml"
+ OLD_SETTINGS_FILE = "#{ENV['HOME']}/.hcl_settings"
+ OLD_CONFIG_FILE = "#{ENV['HOME']}/.hcl_config"
def initialize
+ FileUtils.mkdir_p(File.join(ENV['HOME'], ".hcl"))
read_config
read_settings
end
@@ -57,6 +61,14 @@ module HCl
Commands.method_defined? command
end
+ def start_or_note *args
+ if DayEntry.with_timer
+ note *args
+ else
+ start *args
+ end
+ end
+
# Start the application.
def run
begin
@@ -71,8 +83,7 @@ module HCl
end
end
else
- STDERR.puts "unrecognized command `#{@command}'"
- exit 1
+ start_or_note @command, *@args
end
else
show
@@ -97,23 +108,38 @@ module HCl
HCl is a command-line client for manipulating Harvest time sheets.
Commands:
- hcl show [date]
+ # show all available tasks
hcl tasks
+
+ # set a task alias
+ hcl alias <task> <project_id> <task_id>
+
+ # list task aliases
hcl aliases
- hcl set <key> <value ...>
- hcl unset <key>
- hcl start <task> [msg]
- hcl stop [msg]
+
+ # start a task using an alias
+ hcl @<task> [+time] [message]
+
+ # display the daily timesheet
+ hcl show [date]
+
+ # stop a running timer
+ hcl stop [message]
+
+ # resume the last stopped timer
hcl resume
- hcl note <msg>
+
+ # add a line to your running timer
+ hcl note <message>
Examples:
- $ hcl tasks
- $ hcl start 1234 4567 this is my log message
- $ hcl set task.mytask 1234 4567
- $ hcl start mytask this is my next log message
- $ hcl show yesterday
- $ hcl show last tuesday
+ hcl alias mytask 1234 4567
+ hcl @mytask +:15 Doing a thing that I started 15 minutes ago.
+ hcl Adding a note to my running task.
+ hcl stop That's enough for now.
+ hcl resume
+ hcl show yesterday
+ hcl show last tuesday
Options:
EOM
@@ -129,8 +155,8 @@ EOM
if File.exists? CONFIG_FILE
config = YAML::load File.read(CONFIG_FILE)
TimesheetResource.configure config
- elsif File.exists? old_conf = File.dirname(__FILE__) + "/../hcl_conf.yml"
- config = YAML::load File.read(old_conf)
+ elsif File.exists? OLD_CONFIG_FILE
+ config = YAML::load File.read(OLD_CONFIG_FILE)
TimesheetResource.configure config
write_config config
else
@@ -150,11 +176,15 @@ EOM
File.open(CONFIG_FILE, 'w') do |f|
f.write config.to_yaml
end
+ FileUtils.chmod 0400, CONFIG_FILE
end
def read_settings
if File.exists? SETTINGS_FILE
@settings = YAML.load(File.read(SETTINGS_FILE))
+ elsif File.exists? OLD_SETTINGS_FILE
+ @settings = YAML.load(File.read(OLD_SETTINGS_FILE))
+ write_settings
else
@settings = {}
end
diff --git a/lib/hcl/commands.rb b/lib/hcl/commands.rb
index fdc50a3..2ca3742 100644
--- a/lib/hcl/commands.rb
+++ b/lib/hcl/commands.rb
@@ -29,8 +29,23 @@ module HCl
write_settings
end
+ def unalias task
+ unset "task.#{task}"
+ puts "Removed task alias @#{task}."
+ end
+
+ def alias task_name, *value
+ task = Task.find *value
+ if task
+ set "task.#{task_name}", *value
+ puts "Added alias @#{task_name} for #{task}."
+ else
+ puts "Unrecognized project and task ID: #{value.inspect}"
+ end
+ end
+
def aliases
- @settings.keys.select { |s| s =~ /^task\./ }.map { |s| s.slice(5..-1) }
+ @settings.keys.select { |s| s =~ /^task\./ }.map { |s| "@"+s.slice(5..-1) }
end
def start *args
@@ -39,19 +54,33 @@ module HCl
args.delete(starting_time)
starting_time = time2float starting_time
end
- ident = args.shift
- task_ids = if @settings.key? "task.#{ident}"
- @settings["task.#{ident}"].split(/\s+/)
- else
- [ident, args.shift]
+ ident = args.detect {|a| a[0] == '@' }
+ if ident
+ args.delete(ident)
+ ident = ident.slice(1..-1)
+ else
+ ident = args.shift
+ end
+ if ident
+ task_ids = if @settings.key? "task.#{ident}"
+ @settings["task.#{ident}"].split(/\s+/)
+ else
+ [ident, args.shift]
+ end
+ task = Task.find *task_ids
+ if task.nil?
+ puts "Unknown task alias, try one of the following: ", aliases.join(', ')
+ exit 1
end
- task = Task.find *task_ids
- if task.nil?
- puts "Unknown project/task alias, try one of the following: #{aliases.join(', ')}."
+ timer = task.start(
+ :starting_time => starting_time,
+ :note => args.join(' ')
+ )
+ puts "Started timer for #{timer} (at #{current_time})"
+ else
+ puts "You must provide a task alias to start a timer:", aliases.join(', ')
exit 1
end
- timer = task.start(:starting_time => starting_time, :note => args.join(' '))
- puts "Started timer for #{timer} (at #{current_time})"
end
def stop *args
@@ -70,7 +99,7 @@ module HCl
entry = DayEntry.with_timer
if entry
entry.append_note message
- puts "Added note '#{message}' to #{entry}."
+ puts "Added note to #{entry}."
else
puts "No running timers found."
end
@@ -81,7 +110,8 @@ module HCl
total_hours = 0.0
DayEntry.all(date).each do |day|
running = day.running? ? '(running) ' : ''
- puts "\t#{day.formatted_hours}\t#{running}#{day.project} #{day.notes}"[0..78]
+ columns = HighLine::SystemExtensions.terminal_size[0]
+ puts "\t#{day.formatted_hours}\t#{running}#{day.project}: #{day.notes.lines.last}"[0..columns-1]
total_hours = total_hours + day.hours.to_f
end
puts "\t" + '-' * 13
diff --git a/lib/hcl/day_entry.rb b/lib/hcl/day_entry.rb
index c274126..afcdf08 100644
--- a/lib/hcl/day_entry.rb
+++ b/lib/hcl/day_entry.rb
@@ -31,12 +31,9 @@ module HCl
def append_note new_notes
# If I don't include hours it gets reset.
# This doens't appear to be the case for task and project.
- DayEntry.post("daily/update/#{id}", <<-EOD)
- <request>
- <notes>#{notes << " #{new_notes}"}</notes>
- <hours>#{hours}</hours>
- </request>
- EOD
+ (self.notes << "\n#{new_notes}").lstrip!
+ DayEntry.post "daily/update/#{id}",
+ %{<request><notes>#{notes}</notes><hours>#{hours}</hours></request>}
end
def self.with_timer
diff --git a/lib/hcl/task.rb b/lib/hcl/task.rb
index 3922600..8a5a833 100644
--- a/lib/hcl/task.rb
+++ b/lib/hcl/task.rb
@@ -1,3 +1,5 @@
+require 'fileutils'
+
module HCl
class Task < TimesheetResource
def self.cache_tasks doc
@@ -9,6 +11,7 @@ module HCl
end)
end
unless tasks.empty?
+ FileUtils.mkdir_p(cache_dir)
File.open(cache_file, 'w') do |f|
f.write tasks.uniq.to_yaml
end
@@ -16,7 +19,11 @@ module HCl
end
def self.cache_file
- File.join(ENV['HOME'],'.hcl_tasks')
+ File.join(cache_dir, 'tasks.yml')
+ end
+
+ def self.cache_dir
+ File.join(ENV['HOME'],'.hcl/cache')
end
def self.all