tlog 0.0.8 → 0.0.9

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 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