clockout 0.3 → 0.3.1
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/bin/clock +41 -15
- data/lib/clockout.rb +46 -28
- metadata +2 -2
data/bin/clock
CHANGED
@@ -3,18 +3,20 @@
|
|
3
3
|
require 'clockout'
|
4
4
|
|
5
5
|
HELP_BANNER = <<-EOS
|
6
|
-
|
6
|
+
|
7
7
|
See hours:
|
8
|
-
|
8
|
+
$ clock [options]
|
9
9
|
|
10
10
|
Options:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
11
|
+
--estimations, -e: Show estimations made, if any
|
12
|
+
--condensed, -c: Condense output (don't show the timeline for each day)
|
13
|
+
--generate-config, -g: Generate config file (clock.yaml)
|
14
|
+
--user, -u (<email>): Only count current user's commits (or specified user)
|
15
|
+
--help, -h: Show this message
|
16
|
+
|
17
|
+
Other:
|
18
|
+
$ clock in Clock-in (when you start working, preceding a commit)
|
19
|
+
$ clock out Clock-out (after you keep working overtime after a commit)
|
18
20
|
EOS
|
19
21
|
|
20
22
|
TEMPLATE_CLOCKFILE = <<-EOF
|
@@ -76,20 +78,31 @@ EOF
|
|
76
78
|
def parse_options(args)
|
77
79
|
opts = {}
|
78
80
|
|
79
|
-
|
81
|
+
i = 0
|
82
|
+
while i < args.length
|
83
|
+
arg = args[i]
|
80
84
|
if (arg == "-h" || arg == "--help")
|
81
85
|
opts[:help] = true
|
82
86
|
elsif (arg == "-e" || arg == "--estimations")
|
83
87
|
opts[:estimations] = true
|
84
88
|
elsif (arg == "-c" || arg == "--condensed")
|
85
89
|
opts[:condensed] = true
|
86
|
-
elsif (arg == "-g" || arg == "--generate-
|
87
|
-
opts[:
|
90
|
+
elsif (arg == "-g" || arg == "--generate-config")
|
91
|
+
opts[:generate_config] = true
|
92
|
+
elsif (arg == "-u" || arg == "--user")
|
93
|
+
next_arg = args[i+1]
|
94
|
+
if next_arg && next_arg[0] != '-'
|
95
|
+
opts[:user] = next_arg
|
96
|
+
i += 1
|
97
|
+
else
|
98
|
+
opts[:user] = true
|
99
|
+
end
|
88
100
|
else
|
89
101
|
puts_error "invalid option '#{arg}'."
|
90
102
|
puts "Try --help for help."
|
91
103
|
exit
|
92
104
|
end
|
105
|
+
i += 1
|
93
106
|
end
|
94
107
|
|
95
108
|
opts
|
@@ -112,6 +125,10 @@ def generate_clock_file(path)
|
|
112
125
|
end
|
113
126
|
end
|
114
127
|
|
128
|
+
def current_git_user
|
129
|
+
`git config user.email`.strip
|
130
|
+
end
|
131
|
+
|
115
132
|
path = Dir.pwd
|
116
133
|
|
117
134
|
if (ARGV[0] == "in" || ARGV[0] == "out")
|
@@ -122,7 +139,7 @@ if (ARGV[0] == "in" || ARGV[0] == "out")
|
|
122
139
|
buf = ""
|
123
140
|
mod = false
|
124
141
|
seek_line = ARGV[0] + ":"
|
125
|
-
time_line =
|
142
|
+
time_line = '- ' + Time.new.to_s + ': ' + current_git_user + "\n"
|
126
143
|
File.foreach(clock_path) do |line|
|
127
144
|
buf += line
|
128
145
|
if line.strip == seek_line
|
@@ -143,14 +160,23 @@ else
|
|
143
160
|
exit
|
144
161
|
end
|
145
162
|
|
146
|
-
if opts[:
|
163
|
+
if opts[:generate_config]
|
147
164
|
if !generate_clock_file(path) && clock_path
|
148
165
|
puts_error "config file already exists for this repo: #{clock_path}"
|
149
166
|
end
|
150
167
|
exit
|
151
168
|
end
|
152
169
|
|
153
|
-
|
170
|
+
if opts[:user]
|
171
|
+
if opts[:user] == true
|
172
|
+
user = current_git_user
|
173
|
+
else
|
174
|
+
user = opts[:user]
|
175
|
+
end
|
176
|
+
puts "Showing hours for #{user}"
|
177
|
+
end
|
178
|
+
|
179
|
+
clock = Clockout.new(path, user)
|
154
180
|
|
155
181
|
if (opts[:estimations])
|
156
182
|
clock.print_estimations
|
data/lib/clockout.rb
CHANGED
@@ -6,10 +6,11 @@ COLS = 80
|
|
6
6
|
DAY_FORMAT = '%B %e, %Y'
|
7
7
|
|
8
8
|
class Commit
|
9
|
-
attr_accessor :message, :minutes, :date, :diffs, :sha, :clocked_in, :clocked_out, :addition, :overriden
|
9
|
+
attr_accessor :message, :minutes, :date, :diffs, :sha, :clocked_in, :clocked_out, :addition, :overriden, :author, :estimated
|
10
10
|
def initialize(commit = nil)
|
11
11
|
@addition = 0
|
12
12
|
if commit
|
13
|
+
@author = commit.author.email
|
13
14
|
@date = commit.committed_date
|
14
15
|
@message = commit.message.gsub("\n",' ')
|
15
16
|
@sha = commit.id
|
@@ -18,11 +19,12 @@ class Commit
|
|
18
19
|
end
|
19
20
|
|
20
21
|
class Clock
|
21
|
-
attr_accessor :in, :out, :date
|
22
|
-
def initialize(type, date)
|
22
|
+
attr_accessor :in, :out, :date, :author
|
23
|
+
def initialize(type, date, auth)
|
23
24
|
@in = (type == :in)
|
24
25
|
@out = (type == :out)
|
25
26
|
@date = date
|
27
|
+
@author = auth
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
@@ -104,13 +106,14 @@ class Clockout
|
|
104
106
|
plus+minus/2
|
105
107
|
end
|
106
108
|
|
107
|
-
def prepare_data(commits_in)
|
108
|
-
clockins = $opts[:in] ||
|
109
|
-
clockouts = $opts[:out] ||
|
109
|
+
def prepare_data(commits_in, author)
|
110
|
+
clockins = $opts[:in] || {}
|
111
|
+
clockouts = $opts[:out] || {}
|
110
112
|
|
111
113
|
# Convert clock-in/-outs into Clock objs & commits into Commit objs
|
112
|
-
|
113
|
-
|
114
|
+
clocks = []
|
115
|
+
clockins.each { |c| clocks << Clock.new(:in, c.first[0], c.first[1]) }
|
116
|
+
clockouts.each { |c| clocks << Clock.new(:out, c.first[0], c.first[1]) }
|
114
117
|
commits_in.map! do |commit|
|
115
118
|
c = Commit.new(commit)
|
116
119
|
c.diffs = diffs(commit)
|
@@ -118,7 +121,10 @@ class Clockout
|
|
118
121
|
end
|
119
122
|
|
120
123
|
# Merge & sort everything by date
|
121
|
-
data = (commits_in +
|
124
|
+
data = (commits_in + clocks).sort { |a,b| a.date <=> b.date }
|
125
|
+
|
126
|
+
# If author is specified, delete everything not by that author
|
127
|
+
data.delete_if { |c| c.author != author } if author
|
122
128
|
|
123
129
|
blocks = []
|
124
130
|
total_diffs, total_mins = 0, 0
|
@@ -219,17 +225,21 @@ class Clockout
|
|
219
225
|
end
|
220
226
|
|
221
227
|
diffs_per_min = (1.0*total_diffs/total_mins)
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
228
|
+
|
229
|
+
# Do estimation for all `nil` minutes.
|
230
|
+
blocks.each do |block|
|
231
|
+
first = block.first
|
232
|
+
if !first.minutes
|
233
|
+
first.estimated = true
|
234
|
+
if diffs_per_min.nan? || diffs_per_min.infinite?
|
235
|
+
first.minutes = 0
|
236
|
+
else
|
227
237
|
first.minutes = first.diffs/diffs_per_min * $opts[:estimation_factor] + first.addition
|
228
|
-
add_time_to_day.call(first.minutes, first.date)
|
229
238
|
end
|
239
|
+
add_time_to_day.call(first.minutes, first.date)
|
230
240
|
end
|
231
241
|
end
|
232
|
-
|
242
|
+
|
233
243
|
blocks
|
234
244
|
end
|
235
245
|
|
@@ -240,7 +250,7 @@ class Clockout
|
|
240
250
|
@blocks.each do |block|
|
241
251
|
date = block.first.date.strftime(DAY_FORMAT)
|
242
252
|
if date != current_day
|
243
|
-
puts if (!condensed)
|
253
|
+
puts if (!condensed && current_day)
|
244
254
|
|
245
255
|
current_day = date
|
246
256
|
|
@@ -288,19 +298,27 @@ class Clockout
|
|
288
298
|
|
289
299
|
def print_estimations
|
290
300
|
sum = 0
|
301
|
+
estimations = []
|
291
302
|
@blocks.each do |block|
|
292
|
-
first
|
293
|
-
|
294
|
-
sha = first.sha[0..7]
|
295
|
-
time = first.minutes.as_time
|
303
|
+
estimations << block.first if block.first.estimated
|
304
|
+
end
|
296
305
|
|
297
|
-
|
306
|
+
if estimations.empty?
|
307
|
+
puts "No estimations made."
|
308
|
+
else
|
309
|
+
estimations.each do |c|
|
310
|
+
date = c.date.strftime('%b %e')+":"
|
311
|
+
sha = c.sha[0..7]
|
312
|
+
time = c.minutes.as_time
|
298
313
|
|
299
|
-
|
300
|
-
end
|
314
|
+
puts align({date => :yellow, sha => :red, c.message => :to_s, time => :light_blue})
|
301
315
|
|
302
|
-
|
303
|
-
|
316
|
+
sum += c.minutes
|
317
|
+
end
|
318
|
+
|
319
|
+
puts align({"-"*10 => :light_blue})
|
320
|
+
puts align({sum.as_time(:hours) => :light_blue})
|
321
|
+
end
|
304
322
|
end
|
305
323
|
|
306
324
|
def self.get_repo(path, original_path = nil)
|
@@ -351,7 +369,7 @@ class Clockout
|
|
351
369
|
root_path
|
352
370
|
end
|
353
371
|
|
354
|
-
def initialize(path)
|
372
|
+
def initialize(path, author = nil)
|
355
373
|
repo, root_path = Clockout.get_repo(path) || exit
|
356
374
|
|
357
375
|
# Default options
|
@@ -367,6 +385,6 @@ class Clockout
|
|
367
385
|
commits.reverse!
|
368
386
|
|
369
387
|
@time_per_day = Hash.new(0)
|
370
|
-
@blocks = prepare_data(commits)
|
388
|
+
@blocks = prepare_data(commits, author)
|
371
389
|
end
|
372
390
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clockout
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-05-
|
12
|
+
date: 2013-05-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: grit
|