tlog 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NDE3OGNjNzJlOGFjNmZiYmMxZWQ5ZGJkMmI0ZTE5NDZmZGE5ZGFlNw==
4
+ MGExZGJhMGE1OTc4ZTRkNTVjMGZhNjhjNDEzYjdhZmQ4MGMwMTRmYQ==
5
5
  data.tar.gz: !binary |-
6
- NjVmYTY3OTExZjhmZWEzODhkMTI4NTkwNDUwZDc0NmUwY2Q3ZDk3OQ==
6
+ NzIwMGE5NDQ5ZmFkY2RhOTkxNGEzNDA0NmNkZjdiN2Y3N2RhNDg5Zg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- OGM2NDFkNDFhNTExMWM5ZmQ1NmY1M2U0MTRmM2I2NzY5NGM0ZDBjNDFhMzRl
10
- OTBkYzYwYjI5YmMyOTJhNzhkYTFiZDMyYzg5NWU0NzczNjVjZmM2NzkwM2Rm
11
- NTM1YWExN2EwMGQ0NjU4MDAzZDM5YWJmYmRjNjQ1NjUyMGFjYmI=
9
+ NjE1MTg1N2FmNzY3Y2QwZTIxOWFhNzk4MDgwZmRhMDlhNTRiZWVlYTZlMDg5
10
+ MDhiOWFlNjQyMDc0ZWIzOGQ0NjdlNjY4MmIyNWVlZDQ4ZmNhZDEzMjliMzFj
11
+ YTE4NWExYWI0NDNjMzk5M2JjNTZhNjEzNmZhMGJhMTc4NThhMTc=
12
12
  data.tar.gz: !binary |-
13
- Zjk5NTIwODE3ODYxMzBiMzQ0YTY4MzdmODIxYjE1YzQyMjE5MjhjNjcyY2Y2
14
- ZWY3ZTI5NmRiZTBiYzI4ZTIwODM1YWI4ZDhjNTIzZmU0MzAxMTQ4OWY3ZGQ0
15
- ZGNkZjI3Y2UzNjNiYzhkYWI2M2IzMmU4MDE2ZDdiZTkyOTU4Y2Y=
13
+ M2RmMDI5NGNkZDFlNTIwMTUyN2EyZDAyNjkyYWYwZjRhNWMzMjBjOWIyMGZi
14
+ YjcwMTBiZDE5ZjcyYzc1OWFiN2JkOWE5ODY4YjdkOTdiOGRhNjcwNDBiMTYw
15
+ MTBjNjlkZDgwMjUxNzdlNTllMjA2NzcyN2Q2MDUyNzMwOGVmYWU=
data/README.md CHANGED
@@ -1,9 +1,80 @@
1
1
  tlog
2
- ====
2
+ ============================================
3
3
 
4
- CLI time tracking tool
4
+ A git-based CLI to help you with time tracking on your projects.
5
5
 
6
- ##TODO
7
- - write a read me lol
6
+ ## Installing
7
+ ```bash
8
+ $ sudo gem install tlog
9
+ ```
8
10
 
11
+ ## Usage
12
+ * Navigate to a directory that has a git repo
9
13
 
14
+ ### Create a time log
15
+ ```bash
16
+ $ tlog create example
17
+ ```
18
+
19
+ ### Check out a time log
20
+ ```bash
21
+ $ tlog checkout example
22
+ ```
23
+
24
+ ### Create a time log with a time goal
25
+ ```bash
26
+ $ tlog create example --goal 4hr
27
+ ```
28
+
29
+ ### Start a new task on a time log
30
+ ```bash
31
+ $ tlog start example -d "My task description"
32
+ ```
33
+
34
+ ### Stop the current task
35
+ ```bash
36
+ $ tlog stop example
37
+ ```
38
+
39
+ ### Show active time logs and label the current one, if it exists
40
+ ```bash
41
+ $ tlog active
42
+ All Time Logs:
43
+ testing
44
+ feature1(current)
45
+ bug fix
46
+ feature2
47
+ ```
48
+
49
+ ### Display all the current time logs and their tasks, total time logged and time left.
50
+ ```bash
51
+ $ tlog display
52
+ Log: example1
53
+ Start End Duration Owner Description
54
+ May 29, 11:57PM May 29, 11:58PM 0:01:13 chriwend My Description
55
+ ----------------------------------------------------------------------------------------------------
56
+ Total 0:01:13
57
+ Log: example2
58
+ Start End Duration Owner Description
59
+ May 30, 12:00AM 0:02:26 chriwend Fixing bug
60
+ May 30, 12:00AM May 30, 12:00AM 0:00:10 chriwend (no description)
61
+ ----------------------------------------------------------------------------------------------------
62
+ Total 0:02:36
63
+ Time left: 3:57:24
64
+ ```
65
+
66
+ ### Delete a time log
67
+ ```bash
68
+ $ tlog delete example
69
+ ```
70
+
71
+ ## Collaboration
72
+ More to come on this after I test it...
73
+
74
+ ## Contributing
75
+
76
+ Please look at the TODO for possible additional features. Use [Github issues](https://github.com/cewendel/tlog/issues) to track bugs and feature requests.
77
+
78
+ ## Licence
79
+
80
+ GNU GENERAL PUBLIC LICENCE Version 2
@@ -24,14 +24,20 @@ require 'chronic'
24
24
  require "optparse"
25
25
  require "colorize"
26
26
 
27
+ require 'tlog/command_suite'
28
+
27
29
  require 'tlog/command'
28
- require 'tlog/command/init'
29
30
  require 'tlog/command/start'
30
31
  require 'tlog/command/stop'
31
32
  require 'tlog/command/active'
32
33
  require 'tlog/command/delete'
33
34
  require 'tlog/command/display'
34
35
  require 'tlog/command/create'
36
+ require 'tlog/command/help'
37
+ require 'tlog/command/checkout'
38
+ require 'tlog/command/state'
39
+ require 'tlog/command/owner'
40
+ require 'tlog/command/points'
35
41
 
36
42
  require 'tlog/storage/disk'
37
43
 
@@ -18,44 +18,26 @@ class Tlog::Application
18
18
  @output.error($!)
19
19
  @output.error(@optparse.to_s)
20
20
  rescue Tlog::Error::CommandInvalid
21
- @output.error(command_name + " syntax invalid: " + $!.message)
21
+ @output.error(command_name + " command invalid: " + $!.message)
22
+ @output.error(@optparse.to_s)
23
+ rescue Tlog::Error::CommandNotFound, OptionParser::MissingArgument
24
+ @output.error($!)
22
25
  @output.error(@optparse.to_s)
23
- rescue Tlog::Error::CommandNotFound
24
- @output.error(command_name +": " + $!.message) # format class?
25
26
  rescue
26
27
  @output.error($!)
27
28
  end
28
29
  return outcome
29
30
  end
30
31
 
31
- def all_commands
32
- storage = working_dir_storage
33
- commands = [
34
- Tlog::Command::Init.new,
35
- Tlog::Command::Start.new,
36
- Tlog::Command::Stop.new,
37
- Tlog::Command::Active.new,
38
- Tlog::Command::Delete.new,
39
- Tlog::Command::Display.new,
40
- Tlog::Command::Create.new,
41
- ]
42
- commands.each do |command|
43
- command.storage = storage
44
- command.seconds_format = Tlog::Format::Seconds
45
- command.date_time_format = Tlog::Format::DateTime
46
- end
47
- return commands
48
- end
49
-
50
-
51
32
  private
52
33
 
53
- def working_dir_storage
54
- Tlog::Storage::Disk.new('.')
55
- end
56
-
57
34
  def find(command_name)
58
- all_commands.select { |command| command.name == command_name }.first
35
+ commands = Tlog::Command_Suite.commands
36
+ command = nil
37
+ commands.each do |cmd|
38
+ return cmd if cmd.name == command_name
39
+ end
40
+ command
59
41
  end
60
42
 
61
43
  def prepare_command(command)
@@ -72,7 +54,7 @@ class Tlog::Application
72
54
  command.execute(@input, @output)
73
55
  true
74
56
  else
75
- raise Tlog::Error::CommandNotFound, "Command not found"
57
+ raise Tlog::Error::CommandNotFound, "Command not found, use 'tlog help' for list of commands"
76
58
  end
77
59
  end
78
60
 
@@ -1,11 +1,15 @@
1
+
1
2
  class Tlog::Command::Active < Tlog::Command
2
3
 
3
4
  def name
4
5
  "active"
5
6
  end
6
7
 
8
+ def description
9
+ "prints out all active time logs, the time log in-progress if there is one. Or the currently checked-out time log"
10
+ end
11
+
7
12
  def execute(input, output)
8
- output.line("execute on active command") #change to out
9
13
  print_time_entry(output)
10
14
  end
11
15
 
@@ -23,6 +27,7 @@ class Tlog::Command::Active < Tlog::Command
23
27
  log_name = log.basename.to_s
24
28
  active_log = Tlog::Entity::Active_Log.new(log_name)
25
29
  active_log.current = true if storage.current_log_name == log_name
30
+ active_log.checked_out = true if storage.checkout_value == log_name
26
31
  active_logs.push(active_log)
27
32
  end
28
33
  output.line_yellow("All Time Logs:")
@@ -32,12 +37,15 @@ class Tlog::Command::Active < Tlog::Command
32
37
 
33
38
  def print_logs(active_logs, output)
34
39
  active_logs.each do |active_log|
40
+ out_line = active_log.name
35
41
  if active_log.current
36
- out_line = active_log.name
37
- out_line << " (current)"
42
+ out_line << " (in-progress)"
38
43
  output.line_red(out_line);
44
+ elsif active_log.checked_out
45
+ out_line << " (checked_out)"
46
+ output.line_blue(out_line)
39
47
  else
40
- output.line(active_log.name)
48
+ output.line(out_line)
41
49
  end
42
50
  end
43
51
  end
@@ -0,0 +1,31 @@
1
+
2
+ class Tlog::Command::Checkout < Tlog::Command
3
+
4
+ def name
5
+ "checkout"
6
+ end
7
+
8
+ def description
9
+ "checkouts a time log in order to start tasks on"
10
+ end
11
+
12
+ def execute(input, output)
13
+ raise Tlog::Error::CommandInvalid, "Must specify log name" unless input.args[0]
14
+ checkout(input.args[0])
15
+ end
16
+
17
+ def options(parser, options)
18
+ parser.banner = "usage: tlog checkout <log_name>"
19
+ end
20
+
21
+ private
22
+
23
+ def checkout(log_name)
24
+ storage.in_branch do |wd|
25
+ log = storage.require_log(log_name)
26
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{log_name}' does not exist" unless log
27
+ storage.checkout_log(log)
28
+ end
29
+ end
30
+
31
+ end
@@ -5,13 +5,17 @@ class Tlog::Command::Create < Tlog::Command
5
5
  "create"
6
6
  end
7
7
 
8
+ def description
9
+ "creates a new time log either with no goal or with a goal"
10
+ end
11
+
8
12
  def execute(input, output)
9
13
  raise Tlog::Error::CommandInvalid, "Must specify log name" unless input.args[0]
10
14
 
11
15
  log = Tlog::Entity::Log.new
12
16
  log.name = input.args[0];
13
17
  log.goal = ChronicDuration.parse(input.options[:goal]) if input.options[:goal]
14
- raise Tlog::Error::CommandNotFound, "Could create log: Log already exists" unless create_log(log)
18
+ raise Tlog::Error::CommandInvalid, "Could create log: Log already exists" unless create_log(log)
15
19
  end
16
20
 
17
21
  def options(parser, options)
@@ -26,7 +30,7 @@ class Tlog::Command::Create < Tlog::Command
26
30
 
27
31
  def create_log(log)
28
32
  storage.in_branch do |wd|
29
- storage.create_log(log)
33
+ raise Tlog::Error::CommandInvalid, "Time log '#{log.name}' already exists" unless storage.create_log(log)
30
34
  end
31
35
  end
32
36
  end
@@ -4,6 +4,10 @@ class Tlog::Command::Delete < Tlog::Command
4
4
  "delete"
5
5
  end
6
6
 
7
+ def description
8
+ "deletes a time log"
9
+ end
10
+
7
11
  def execute(input, output)
8
12
  raise Tlog::Error::CommandInvalid, "Task does not exist" unless delete(input.args[0])
9
13
  end
@@ -17,7 +21,8 @@ class Tlog::Command::Delete < Tlog::Command
17
21
  def delete(log_name)
18
22
  storage.in_branch do |wd|
19
23
  log = storage.require_log(log_name)
20
- storage.delete_log(log) if log
24
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{log_name}' does not exist" unless log
25
+ storage.delete_log(log)
21
26
  end
22
27
  end
23
28
 
@@ -1,10 +1,15 @@
1
1
 
2
+ # I will forever love whoever re-writes this class (badly needed)
2
3
  class Tlog::Command::Display < Tlog::Command
3
4
 
4
5
  def name
5
6
  "display"
6
7
  end
7
8
 
9
+ def description
10
+ "displays shit"
11
+ end
12
+
8
13
  def execute(input, output)
9
14
  raise Tlog::Error::CommandInvalid, "Logging invalid" unless display(input.args[0], input.options[:length], output)
10
15
  end
@@ -37,7 +42,7 @@ class Tlog::Command::Display < Tlog::Command
37
42
  start_time = Time.parse(storage.start_time_string)
38
43
  end
39
44
  return if length_exceeds_threshold?(log_length, length_threshold)
40
- print_log_name(log_name, output)
45
+ print_log_info(log, output)
41
46
  print_header(output)
42
47
  print_current(log_name, log_length, start_time, output)
43
48
  display_entries(entries, output) if entries
@@ -54,11 +59,10 @@ class Tlog::Command::Display < Tlog::Command
54
59
  def display_entries(entries, output)
55
60
  if entries.size > 0
56
61
  entries.each do |entry|
57
- out_str = "\t%-4s %16s %14s %14s %s" % [
62
+ out_str = "\t%-4s %16s %14s %s" % [
58
63
  date_time_format.timestamp(entry.time[:start]),
59
64
  date_time_format.timestamp(entry.time[:end]),
60
65
  seconds_format.duration(entry.length.to_s),
61
- entry.owner,
62
66
  entry.description,
63
67
  ]
64
68
  output.line(out_str)
@@ -73,7 +77,7 @@ class Tlog::Command::Display < Tlog::Command
73
77
  end
74
78
 
75
79
  def print_header(output)
76
- output.line("\tStart End Duration Owner Description")
80
+ output.line("\tStart End Duration Description")
77
81
  end
78
82
 
79
83
  def print_total(log, output)
@@ -85,8 +89,9 @@ class Tlog::Command::Display < Tlog::Command
85
89
  output.line("\tTotal%45s " % seconds_format.duration(duration))
86
90
  end
87
91
 
88
- def print_log_name(log_name, output)
89
- output.line_yellow("Log: #{log_name}")
92
+ def print_log_info(log, output)
93
+ out_str = "Log: #{log.name}\nState: #{log.state}\nPoints: #{log.points}\nOwner: #{log.owner}"
94
+ output.line_yellow(out_str)
90
95
  end
91
96
 
92
97
  def print_time_left(log, output)
@@ -105,11 +110,10 @@ class Tlog::Command::Display < Tlog::Command
105
110
  def print_current(log_name, log_length, current_start_time, output)
106
111
  if is_current_log_name?(log_name)
107
112
  formatted_length = seconds_format.duration storage.time_since_start
108
- out_str = out_str = "\t%-4s %16s %14s %14s %s" % [
113
+ out_str = out_str = "\t%-4s %16s %14s %s" % [
109
114
  date_time_format.timestamp(current_start_time),
110
115
  nil,
111
116
  formatted_length,
112
- storage.cur_entry_owner,
113
117
  storage.cur_entry_description,
114
118
  ]
115
119
  output.line(out_str)
@@ -0,0 +1,38 @@
1
+
2
+ class Tlog::Command::Help < Tlog::Command
3
+
4
+ def name
5
+ "help"
6
+ end
7
+
8
+ def description
9
+ "outputs lists of commands and their descriptions"
10
+ end
11
+
12
+ def execute(input, output)
13
+ commands = Tlog::Command_Suite.commands
14
+ commands.sort! {|a,b| a.name <=> b.name}
15
+ max_name_length = 0
16
+
17
+ commands.each do |command|
18
+ name_length = command.name.length
19
+ max_name_length = name_length if name_length > max_name_length
20
+ end
21
+
22
+ output.line("usage: tlog <command>")
23
+ output.line(nil)
24
+
25
+ commands.each do |command|
26
+ line = sprintf("%-#{max_name_length}s %s", command.name, command.description)
27
+ output.line(line)
28
+ end
29
+
30
+ output.line(nil)
31
+ return true
32
+ end
33
+
34
+ def options(parser, options)
35
+ parser.banner = "usage: tlog help"
36
+ end
37
+
38
+ end
@@ -5,6 +5,10 @@ class Tlog::Command::Init < Tlog::Command
5
5
  "init"
6
6
  end
7
7
 
8
+ def description
9
+ "fuck"
10
+ end
11
+
8
12
  def execute(input,output)
9
13
  if input.args[0].nil?
10
14
  raise Tlog::Error::CommandInvalid, "Project already initialized" unless @storage.init_project
@@ -0,0 +1,32 @@
1
+
2
+ class Tlog::Command::Owner < Tlog::Command
3
+
4
+ def name
5
+ "owner"
6
+ end
7
+
8
+ def description
9
+ "changes the owner of the checked-out time log"
10
+ end
11
+
12
+ def execute(input, output)
13
+ new_owner = input.args[0]
14
+ change_owner(new_owner)
15
+ end
16
+
17
+ def options(parser, options)
18
+ parser.banner = "usage: tlog owner <new_owner>"
19
+ end
20
+
21
+ private
22
+
23
+ def change_owner(new_owner)
24
+ storage.in_branch do |wd|
25
+ checked_out_log = storage.checkout_value
26
+ raise Tlog::Error::CheckoutInvalid, "No time log is checked out" unless checked_out_log
27
+ log = storage.require_log(checked_out_log)
28
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{checked_out_log}' does not exist" unless log
29
+ storage.change_log_owner(log, new_owner)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+
2
+ class Tlog::Command::Points < Tlog::Command
3
+
4
+ def name
5
+ "points"
6
+ end
7
+
8
+ def description
9
+ "changes the point value of the checked-out time log"
10
+ end
11
+
12
+ def execute(input, output)
13
+ new_points_value = input.args[0]
14
+ change_state(new_points_value)
15
+ end
16
+
17
+ def options(parser, options)
18
+ parser.banner = "usage: tlog points <new_points_value>"
19
+ end
20
+
21
+ private
22
+
23
+ def change_state(points)
24
+ storage.in_branch do |wd|
25
+ checked_out_log = storage.checkout_value
26
+ raise Tlog::Error::CheckoutInvalid, "No time log is checked out" unless checked_out_log
27
+ log = storage.require_log(checked_out_log)
28
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{checked_out_log}' does not exist" unless log
29
+ storage.change_log_points(log, points)
30
+ end
31
+ end
32
+ end
@@ -5,13 +5,16 @@ class Tlog::Command::Start < Tlog::Command
5
5
  "start"
6
6
  end
7
7
 
8
+ def description
9
+ "starts a new task for a time log"
10
+ end
11
+
8
12
  def execute(input, output)
9
- raise Tlog::Error::CommandInvalid, "Must specify log name" unless input.args[0]
10
- start(input.args[0], input.options[:description])
13
+ start(input.options[:description])
11
14
  end
12
15
 
13
16
  def options(parser, options)
14
- parser.banner = "usage: tlog start <log_name>"
17
+ parser.banner = "usage: tlog start"
15
18
 
16
19
  parser.on("-d", "--description <description>") do |description|
17
20
  options[:description] = description
@@ -20,12 +23,15 @@ class Tlog::Command::Start < Tlog::Command
20
23
 
21
24
  private
22
25
 
23
- def start(log_name, entry_description)
26
+ def start(entry_description)
24
27
  storage.in_branch do |wd|
25
- log = storage.require_log(log_name)
26
- raise Tlog::Error::CommandNotFound, "Time log '#{log_name}' does not exist" unless log
27
- current_owner = storage.cur_entry_owner
28
- storage.start_log(log, entry_description)
28
+ checked_out_log = storage.checkout_value
29
+ raise Tlog::Error::CheckoutInvalid, "No time log is checked out" unless checked_out_log
30
+ log = storage.require_log(checked_out_log)
31
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{checked_out_log}' does not exist" unless log
32
+ unless storage.start_log(log, entry_description)
33
+ raise Tlog::Error::CommandInvalid, "Time log '#{checked_out_log}' is already in progress"
34
+ end
29
35
  end
30
36
  end
31
37
  end
@@ -0,0 +1,32 @@
1
+
2
+ class Tlog::Command::State < Tlog::Command
3
+
4
+ def name
5
+ "state"
6
+ end
7
+
8
+ def description
9
+ "changes the state of the checked-out time log"
10
+ end
11
+
12
+ def execute(input, output)
13
+ new_state = input.args[0]
14
+ change_state(new_state)
15
+ end
16
+
17
+ def options(parser, options)
18
+ parser.banner = "usage: tlog state <new_state>"
19
+ end
20
+
21
+ private
22
+
23
+ def change_state(new_state)
24
+ storage.in_branch do |wd|
25
+ checked_out_log = storage.checkout_value
26
+ raise Tlog::Error::CheckoutInvalid, "No time log is checked out" unless checked_out_log
27
+ log = storage.require_log(checked_out_log)
28
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{checked_out_log}' does not exist" unless log
29
+ storage.change_log_state(log, new_state)
30
+ end
31
+ end
32
+ end
@@ -4,21 +4,29 @@ class Tlog::Command::Stop < Tlog::Command
4
4
  "stop"
5
5
  end
6
6
 
7
+ def description
8
+ "ends a task for a time log"
9
+ end
10
+
7
11
  def execute(input, output)
8
- raise Tlog::Error::CommandInvalid, "Must specify log name" unless input.args[0]
9
- stop(input.args[0])
12
+ stop
10
13
  end
11
14
 
12
15
  def options(parser, options)
13
- parser.banner = "usage: tlog stop <log_name>"
16
+ parser.banner = "usage: tlog stop"
14
17
  end
15
18
 
16
19
  private
17
20
 
18
- def stop(log_name)
21
+ def stop
19
22
  storage.in_branch do |wd|
20
- log = storage.require_log(log_name)
21
- storage.stop_log(log)
23
+ checked_out_log = storage.checkout_value
24
+ raise Tlog::Error::CheckoutInvalid, "No time log is checked out" unless checked_out_log
25
+ log = storage.require_log(checked_out_log)
26
+ raise Tlog::Error::TimeLogNotFound, "Time log '#{checked_out_log}' does not exist" unless log
27
+ unless storage.stop_log(log)
28
+ raise Tlog::Error::CommandInvalid, "Failed to stop log '#{checked_out_log}': This time log is not in progress"
29
+ end
22
30
  end
23
31
  end
24
32
 
@@ -0,0 +1,34 @@
1
+
2
+ # Simple helper class that handles an array of commands
3
+ class Tlog::Command_Suite
4
+
5
+ class << self
6
+ def commands
7
+ storage = self.working_dir_storage
8
+ commands = [
9
+ Tlog::Command::Start.new,
10
+ Tlog::Command::Stop.new,
11
+ Tlog::Command::Help.new,
12
+ Tlog::Command::Active.new,
13
+ Tlog::Command::Delete.new,
14
+ Tlog::Command::Display.new,
15
+ Tlog::Command::Create.new,
16
+ Tlog::Command::Checkout.new,
17
+ Tlog::Command::State.new,
18
+ Tlog::Command::Points.new,
19
+ Tlog::Command::Owner.new
20
+ ]
21
+ commands.each do |command|
22
+ command.storage = storage
23
+ command.seconds_format = Tlog::Format::Seconds
24
+ command.date_time_format = Tlog::Format::DateTime
25
+ end
26
+ commands
27
+ end
28
+
29
+ def working_dir_storage
30
+ Tlog::Storage::Disk.new('.')
31
+ end
32
+ end
33
+
34
+ end
@@ -1,11 +1,13 @@
1
1
 
2
2
  # Helper class for printing out active time logs
3
3
  class Tlog::Entity::Active_Log
4
- attr_accessor :name
4
+ attr_reader :name
5
5
  attr_accessor :current
6
+ attr_accessor :checked_out
6
7
 
7
8
  def initialize(name)
8
9
  @name = name
9
10
  @current = false
11
+ @checked_out = false
10
12
  end
11
13
  end
@@ -19,7 +19,7 @@ class Tlog::Entity::Entry
19
19
  write_file(parent_path, parent)
20
20
  write_file(time_path, time_log.strip)
21
21
  write_file(description_path, current[:description])
22
- write_file(owner_path, current[:owner])
22
+ #write_file(owner_path, current[:owner])
23
23
  end
24
24
 
25
25
  def parent_hex
@@ -48,10 +48,6 @@ class Tlog::Entity::Entry
48
48
  read_file(description_path)
49
49
  end
50
50
 
51
- def owner
52
- read_file(owner_path)
53
- end
54
-
55
51
  private
56
52
 
57
53
  def write_file(path, content)
@@ -83,8 +79,4 @@ class Tlog::Entity::Entry
83
79
  File.join(@path, 'DESCRIPTION')
84
80
  end
85
81
 
86
- def owner_path
87
- File.join(@path, 'OWNER')
88
- end
89
-
90
82
  end
@@ -15,6 +15,20 @@ class Tlog::Entity::Log
15
15
  end
16
16
  end
17
17
 
18
+ def create(options)
19
+ unless Dir.exists?(@path)
20
+ FileUtils.mkdir_p(@path)
21
+ state = 'open'
22
+ points = 0
23
+ owner = 'none'
24
+ state = options[:state] if options[:state]
25
+ points = options[:points] if options[:point]
26
+ owner = options[:owner] if options[:owner]
27
+ write_log(state, points, owner)
28
+ true
29
+ end
30
+ end
31
+
18
32
  def goal_length
19
33
  if File.exists?(goal_path)
20
34
  contents = File.read(goal_path)
@@ -22,7 +36,6 @@ class Tlog::Entity::Log
22
36
  contents.to_i
23
37
  end
24
38
  end
25
-
26
39
 
27
40
  def entries
28
41
  log_entries = []
@@ -44,15 +57,30 @@ class Tlog::Entity::Log
44
57
  dur
45
58
  end
46
59
 
47
- def create
48
- unless Dir.exists?(@path)
49
- FileUtils.mkdir_p(@path)
50
- File.open(hold_path, 'w+'){|f| f.write('hold')}
51
- File.open(goal_path, 'w'){|f| f.write(@goal)} if @goal
52
- true
53
- end
60
+ def owner
61
+ read_file(owner_path) if File.exists?(owner_path)
62
+ end
63
+
64
+ def state
65
+ read_file(state_path) if File.exists?(state_path)
66
+ end
67
+
68
+ def points
69
+ read_file(points_path) if File.exists?(points_path)
70
+ end
71
+
72
+ def update_state(state)
73
+ File.open(state_path, 'w'){|f| f.write(state)}
54
74
  end
55
75
 
76
+ def update_points(points)
77
+ File.open(points_path, 'w'){|f| f.write(points)}
78
+ end
79
+
80
+ def update_owner(owner)
81
+ File.open(owner_path, 'w'){|f| f.write(owner)}
82
+ end
83
+
56
84
  def add_entry(current)
57
85
  entry_hex = generate_random_hex
58
86
  new_entry = Tlog::Entity::Entry.new(entry_path(entry_hex), entry_hex)
@@ -78,6 +106,21 @@ class Tlog::Entity::Log
78
106
 
79
107
  private
80
108
 
109
+ def write_log(state, points, owner)
110
+ File.open(points_path, 'w'){|f| f.write(points)}
111
+ File.open(state_path, 'w'){|f| f.write(state)}
112
+ File.open(owner_path, 'w'){|f| f.write(owner)}
113
+ File.open(hold_path, 'w+'){|f| f.write('hold')}
114
+ File.open(goal_path, 'w'){|f| f.write(@goal)} if @goal
115
+ end
116
+
117
+ def read_file(path)
118
+ if File.exists?(path)
119
+ contents = File.read(path)
120
+ contents.strip
121
+ end
122
+ end
123
+
81
124
  def head_hex_value
82
125
  if File.exists?(head_path)
83
126
  head_content = File.read(head_path)
@@ -85,6 +128,18 @@ class Tlog::Entity::Log
85
128
  end
86
129
  end
87
130
 
131
+ def points_path
132
+ File.join(@path, 'POINTS')
133
+ end
134
+
135
+ def state_path
136
+ File.join(@path, 'STATE')
137
+ end
138
+
139
+ def owner_path
140
+ File.join(@path, 'OWNER')
141
+ end
142
+
88
143
  def goal_path
89
144
  File.join(@path, 'GOAL')
90
145
  end
@@ -3,4 +3,10 @@ class Tlog::Error::CommandNotFound < StandardError
3
3
  end
4
4
 
5
5
  class Tlog::Error::CommandInvalid < StandardError
6
+ end
7
+
8
+ class Tlog::Error::TimeLogNotFound < StandardError
9
+ end
10
+
11
+ class Tlog::Error::CheckoutInvalid < StandardError
6
12
  end
@@ -26,4 +26,8 @@ class Tlog::Output
26
26
  @stdout.puts out.red
27
27
  end
28
28
 
29
+ def line_blue(out)
30
+ @stdout.puts out.blue
31
+ end
32
+
29
33
  end
@@ -7,8 +7,6 @@ class Tlog::Storage::Disk
7
7
  attr_accessor :tlog_index
8
8
  attr_accessor :working_dir
9
9
 
10
- # Class methods 'create_repo' 'all_logs', also 'create' command
11
-
12
10
  def initialize(git_dir)
13
11
  @git = Git.open(find_repo(git_dir))
14
12
  # Format class?
@@ -25,11 +23,21 @@ class Tlog::Storage::Disk
25
23
  end
26
24
  end
27
25
 
28
- def create_log(log)
26
+ def checkout_log(log)
27
+ File.open(checkout_path, 'w'){|f| f.write(log.name)}
28
+ git.add
29
+ git.commit("Checking out time log '#{log.name}'")
30
+ end
31
+
32
+ def checkout_value
33
+ read_file(checkout_path) if File.exists?(checkout_path)
34
+ end
35
+
36
+ def create_log(log, options = {})
29
37
  log.path = log_path(log.name)
30
- if log.create
38
+ if log.create(options)
31
39
  git.add
32
- git.commit("Created log #{log.name}")
40
+ git.commit("Created log '#{log.name}'")
33
41
  true
34
42
  else
35
43
  false
@@ -38,14 +46,13 @@ class Tlog::Storage::Disk
38
46
 
39
47
  def delete_log(log)
40
48
  log.path = log_path(log.name)
41
- if log.delete
42
- delete_current(log.name)
43
- git.remove(log.path, {:recursive => "-r"})
44
- git.commit("Deleted log #{log.name}")
45
- true
46
- else
47
- false
48
- end
49
+ log.delete
50
+ delete_current(log.name)
51
+ delete_checkout(log.name)
52
+
53
+ # Recursively removes the directory that stores the time log
54
+ git.remove(log.path, {:recursive => "-r"})
55
+ git.commit("Deleted log '#{log.name}'")
49
56
  end
50
57
 
51
58
  def require_log(log_name)
@@ -57,7 +64,7 @@ class Tlog::Storage::Disk
57
64
  if update_current(log.name, entry_description)
58
65
  create_log(log) # Creates directory if it has not already been created
59
66
  git.add
60
- git.commit("Started log #{log.name}")
67
+ git.commit("Started log '#{log.name}'")
61
68
  true
62
69
  else
63
70
  false
@@ -65,23 +72,37 @@ class Tlog::Storage::Disk
65
72
  end
66
73
 
67
74
  def stop_log(log)
68
- if Dir.exists?(current_path)
75
+ if Dir.exists?(current_path) and log.name == checkout_value
69
76
  current_hash = {
70
77
  :name => current_log_name,
71
78
  :start_time => current_start_time,
72
79
  :description => current_entry_description,
73
- :owner => cur_entry_owner
74
80
  }
75
81
  delete_current(current_hash[:name])
76
82
  log.add_entry(current_hash)
77
83
  git.add
78
- git.commit("Stopped log #{log.name}")
84
+ git.commit("Stopped log '#{log.name}'")
79
85
  true
80
86
  else
81
87
  false
82
88
  end
83
89
  end
84
90
 
91
+ def change_log_state(log, new_state)
92
+ log.path = log_path(log.name)
93
+ log.update_state(new_state)
94
+ end
95
+
96
+ def change_log_points(log, new_points_value)
97
+ log.path = log_path(log.name)
98
+ log.update_points(new_points_value)
99
+ end
100
+
101
+ def change_log_owner(log, new_owner)
102
+ log.path = log_path(log.name)
103
+ log.update_owner(new_owner)
104
+ end
105
+
85
106
  def log_duration(log_name)
86
107
  duration = 0
87
108
  if current_log_name == log_name
@@ -105,6 +126,10 @@ class Tlog::Storage::Disk
105
126
  current_start_time
106
127
  end
107
128
 
129
+ def cur_user
130
+ git.config["user.email"].split('@').first rescue ''
131
+ end
132
+
108
133
  def time_since_start
109
134
  if Dir.exists?(current_path)
110
135
  difference = Time.now - Time.parse(current_start_time)
@@ -118,10 +143,6 @@ class Tlog::Storage::Disk
118
143
  Time.parse(current_start_time) if current_start_path
119
144
  end
120
145
 
121
- def cur_entry_owner
122
- git.config["user.email"].split('@').first rescue ''
123
- end
124
-
125
146
  def cur_entry_description
126
147
  current_entry_description
127
148
  end
@@ -190,17 +211,27 @@ class Tlog::Storage::Disk
190
211
  end
191
212
  end
192
213
 
193
- def delete_current(log_name) # Change this method name or add one
214
+ def delete_current(log_name)
194
215
  if Dir.exists?(current_path)
195
216
  if current_log_name == log_name
196
217
  FileUtils.rm_rf(current_path)
197
- git.remove(current_path, {:recursive => 'r'})
218
+ #git.remove(current_path, {:recursive => 'r'})
198
219
  end
199
220
  else
200
221
  false
201
222
  end
202
223
  end
203
224
 
225
+ def delete_checkout(log_name)
226
+ if File.exists?(checkout_path)
227
+ if checkout_value == log_name
228
+ FileUtils.rm(checkout_path)
229
+ end
230
+ else
231
+ fals
232
+ end
233
+ end
234
+
204
235
  def write_to_current(log_name, entry_description)
205
236
  # Create a current object, with a "read" method
206
237
  File.open(current_name_path, 'w'){ |f| f.write(log_name)}
@@ -255,6 +286,10 @@ class Tlog::Storage::Disk
255
286
  File.expand_path(File.join('tasks'))
256
287
  end
257
288
 
289
+ def checkout_path
290
+ File.join(logs_path, 'CHECKOUT');
291
+ end
292
+
258
293
  def current_path
259
294
  File.expand_path(File.join('current'))
260
295
  end
@@ -2,13 +2,13 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  spec.name = "tlog"
5
- spec.version = "0.0.8"
6
- spec.date = "2013-05-27"
5
+ spec.version = "0.0.9"
6
+ spec.date = "2013-06-02"
7
7
 
8
8
  spec.required_ruby_version = ">=1.9.3"
9
9
 
10
10
  spec.summary = "CLI Project Time Logger"
11
- spec.description = "tlog is a git-based command-line time logger that keeps track the time you've spend on different parts of a project"
11
+ spec.description = "tlog is a distributed project time and ticket tracker"
12
12
  spec.license = "GPL-2"
13
13
 
14
14
  spec.add_dependency("commander", "4.0")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tlog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Wendel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-27 00:00:00.000000000 Z
11
+ date: 2013-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -80,8 +80,7 @@ dependencies:
80
80
  - - '='
81
81
  - !ruby/object:Gem::Version
82
82
  version: 0.5.8
83
- description: tlog is a git-based command-line time logger that keeps track the time
84
- you've spend on different parts of a project
83
+ description: tlog is a distributed project time and ticket tracker
85
84
  email: chriwend@umich.edu
86
85
  executables:
87
86
  - tlog
@@ -97,13 +96,18 @@ files:
97
96
  - lib/tlog/application.rb
98
97
  - lib/tlog/command.rb
99
98
  - lib/tlog/command/active.rb
99
+ - lib/tlog/command/checkout.rb
100
100
  - lib/tlog/command/create.rb
101
101
  - lib/tlog/command/delete.rb
102
102
  - lib/tlog/command/display.rb
103
+ - lib/tlog/command/help.rb
103
104
  - lib/tlog/command/init.rb
105
+ - lib/tlog/command/owner.rb
106
+ - lib/tlog/command/points.rb
104
107
  - lib/tlog/command/start.rb
108
+ - lib/tlog/command/state.rb
105
109
  - lib/tlog/command/stop.rb
106
- - lib/tlog/command/test.rb
110
+ - lib/tlog/command_suite.rb
107
111
  - lib/tlog/entity/active_log.rb
108
112
  - lib/tlog/entity/entry.rb
109
113
  - lib/tlog/entity/log.rb
@@ -1,32 +0,0 @@
1
-
2
- class Tlog::Command::Test < Tlog::Command
3
-
4
- def name
5
- "test"
6
- end
7
-
8
- def execute(input,output)
9
- output.line("execute on test called")
10
- if input.args[0].nil?
11
- output.line("args at 0 was nil")
12
- elsif input.args[1].nil?
13
- arg1 = input.args.shift
14
- output.line("arg at 0 was #{arg1}")
15
- else
16
- arg1 = input.args.shift
17
- arg2 = input.args.shift
18
- output.line("arg at 0 was #{arg1}")
19
- output.line("arg at 1 was #{arg2}")
20
- raise Tlog::Error::CommandInvalid, "Command invalid"
21
- end
22
- end
23
-
24
- def options(parser, options)
25
- parser.banner = "usage: tlog test <project>"
26
- end
27
-
28
- private
29
-
30
-
31
-
32
- end