git_time_extractor 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/History.txt +3 -0
- data/bin/git_time_extractor +13 -4
- data/lib/author.rb +19 -0
- data/lib/git_time_extractor.rb +84 -1
- data/readme.md +18 -2
- metadata +9 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4388a37659ca28a30fa8cb863afa2cc43e095019
|
4
|
+
data.tar.gz: d970e6f969cd744b9ff5289c951a342f621bdd06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ad103bd9633bbdac6b7e87aedca20878530317baaa12ec78d94eba986f4b01447770bcc04fb6cb807e4bc53f662d5078b3162c95d2f004645ec6b51813cf08d
|
7
|
+
data.tar.gz: d50da7e0cecc51f5f5e992161da23ff7889ae9b822f788aac4cf24cb953f072fe1554f19cfa721f313236c834765504185132f5fc34c1ce4dc5586a35a1fb6bc
|
data/History.txt
CHANGED
data/bin/git_time_extractor
CHANGED
@@ -13,7 +13,6 @@
|
|
13
13
|
require 'optparse'
|
14
14
|
require 'git_time_extractor'
|
15
15
|
|
16
|
-
|
17
16
|
options = { :project => '',
|
18
17
|
:path_to_repo => Dir.pwd,
|
19
18
|
:output_file => '-',
|
@@ -22,6 +21,8 @@
|
|
22
21
|
:merge_effort_mins => 30,
|
23
22
|
:session_duration_hrs => 3,
|
24
23
|
:filter_by_year => nil,
|
24
|
+
:compact => nil,
|
25
|
+
:project_total => nil,
|
25
26
|
}
|
26
27
|
|
27
28
|
valid_usage = false
|
@@ -68,13 +69,21 @@
|
|
68
69
|
'Session duration, in hours. Default: ' + options[:session_duration_hrs].to_s ) do |session_duration|
|
69
70
|
options[:session_duration_hrs] = session_duration
|
70
71
|
end
|
72
|
+
|
73
|
+
opts.on('--project-total', 'Project commits and time rolled into a single summary line. The field set is total git commit count, total hours, and a list of collaborators.' ) do |project_total|
|
74
|
+
options[:project_total] = project_total
|
75
|
+
end
|
76
|
+
|
77
|
+
opts.on('--compact', 'Compact mode that lists only total git commit count, total hours, person, and email.' ) do |compact|
|
78
|
+
options[:compact] = compact
|
79
|
+
end
|
80
|
+
|
71
81
|
end
|
72
82
|
|
73
83
|
option_parser.parse!
|
74
84
|
|
75
85
|
if options[:project] && options[:path_to_repo] && options[:output_file]
|
76
|
-
|
77
|
-
rows = extractor.process_git_log_into_time
|
86
|
+
rows = GitTimeExtractor.new(options).process
|
78
87
|
if options[:output_file] == '-'
|
79
88
|
rows.each do |row|
|
80
89
|
puts row.map!{|value| value.to_s.gsub('"', '\"').gsub("\n", '\n') }.to_csv
|
@@ -85,7 +94,7 @@
|
|
85
94
|
|
86
95
|
else
|
87
96
|
puts 'Usage: git_time_extractor -p PROJECT_NAME -i [PATH_TO_REPO] -o [OUTPUT_FILE] -c [MAX_COMMITS] -e [INITIAL_EFFORT_MINS] -m [MERGE_EFFORT_MINS] -s [SESSION_DURATION_HRS]'
|
88
|
-
puts 'Copyright
|
97
|
+
puts 'Copyright 2015 Rietta, Inc., and contributors. https://rietta.com'
|
89
98
|
exit 0
|
90
99
|
end # options
|
91
100
|
|
data/lib/author.rb
CHANGED
@@ -14,6 +14,25 @@ class Author
|
|
14
14
|
@commits << commit
|
15
15
|
end
|
16
16
|
|
17
|
+
def total_commits
|
18
|
+
return @commits.length
|
19
|
+
end
|
20
|
+
|
21
|
+
def total_working_minutes
|
22
|
+
# Go through the work log
|
23
|
+
total = 0
|
24
|
+
@worklog.keys.sort.each do |date|
|
25
|
+
if date_in_filter_range(date)
|
26
|
+
total += @worklog[date].duration.to_i
|
27
|
+
end
|
28
|
+
end # worklog each
|
29
|
+
return total
|
30
|
+
end
|
31
|
+
|
32
|
+
def total_working_hours
|
33
|
+
return (total_working_minutes() / 60.0).round(1)
|
34
|
+
end
|
35
|
+
|
17
36
|
# Then the tabulation is called after the commits are added into this author's list
|
18
37
|
def tabulate_days
|
19
38
|
@commits.each_with_index do |commit, index|
|
data/lib/git_time_extractor.rb
CHANGED
@@ -8,7 +8,7 @@
|
|
8
8
|
# Portions (C) 2014 Rietta Inc. and licensed under the terms of the BSD license.
|
9
9
|
#
|
10
10
|
class GitTimeExtractor
|
11
|
-
VERSION = '0.3.
|
11
|
+
VERSION = '0.3.2'
|
12
12
|
|
13
13
|
require 'autoload'
|
14
14
|
require 'set'
|
@@ -102,6 +102,68 @@ class GitTimeExtractor
|
|
102
102
|
end # process_git_log_into_time
|
103
103
|
|
104
104
|
|
105
|
+
def prepare_rows_for_summary_csv
|
106
|
+
rows = Array.new
|
107
|
+
rows << summary_header_row_template()
|
108
|
+
commits = 0
|
109
|
+
hours = 0
|
110
|
+
authors = Array.new
|
111
|
+
@authors.each do |author|
|
112
|
+
commits += author.total_commits()
|
113
|
+
hours += author.total_working_hours()
|
114
|
+
authors << author.commits[0].author.name + " (" + author.commits[0].author.email + ")"
|
115
|
+
end
|
116
|
+
rows << [
|
117
|
+
hours,
|
118
|
+
commits,
|
119
|
+
authors.join(";")
|
120
|
+
]
|
121
|
+
return rows
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# create a summary of the computed times
|
126
|
+
#
|
127
|
+
def process_git_log_into_summary
|
128
|
+
distribute_entries_to_authors( load_git_log_entries( path_to_git_repo ) )
|
129
|
+
return prepare_rows_for_summary_csv
|
130
|
+
end # process_git_log_into_time
|
131
|
+
|
132
|
+
|
133
|
+
def prepare_rows_for_author_summary_csv
|
134
|
+
rows = Array.new
|
135
|
+
rows << author_summary_header_row_template()
|
136
|
+
commits = 0
|
137
|
+
hours = 0
|
138
|
+
authors = Array.new
|
139
|
+
@authors.each do |author|
|
140
|
+
rows << [
|
141
|
+
author.total_commits(),
|
142
|
+
author.total_working_hours(),
|
143
|
+
author.commits[0].author.name,
|
144
|
+
author.commits[0].author.email,
|
145
|
+
]
|
146
|
+
end
|
147
|
+
return rows
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# create a summary per author
|
152
|
+
#
|
153
|
+
def process_git_log_into_author_summary
|
154
|
+
distribute_entries_to_authors( load_git_log_entries( path_to_git_repo ) )
|
155
|
+
return prepare_rows_for_author_summary_csv
|
156
|
+
end # process_git_log_into_time
|
157
|
+
|
158
|
+
def process
|
159
|
+
if options[:project_total]
|
160
|
+
process_git_log_into_summary
|
161
|
+
elsif options[:compact]
|
162
|
+
process_git_log_into_author_summary
|
163
|
+
else
|
164
|
+
process_git_log_into_time
|
165
|
+
end
|
166
|
+
end
|
105
167
|
|
106
168
|
#####################################
|
107
169
|
private
|
@@ -123,4 +185,25 @@ class GitTimeExtractor
|
|
123
185
|
]
|
124
186
|
end # header_row_template
|
125
187
|
|
188
|
+
def author_summary_header_row_template
|
189
|
+
[
|
190
|
+
'Total Git Commits Count',
|
191
|
+
'Total Hours',
|
192
|
+
'Person',
|
193
|
+
'Email',
|
194
|
+
# 'From Date',
|
195
|
+
# 'To Date',
|
196
|
+
]
|
197
|
+
end # summary_header_row_template
|
198
|
+
|
199
|
+
def summary_header_row_template
|
200
|
+
[
|
201
|
+
# 'From Date',
|
202
|
+
# 'To Date',
|
203
|
+
'Total Git Commits Count',
|
204
|
+
'Total Hours',
|
205
|
+
'Collaborators',
|
206
|
+
]
|
207
|
+
end # summary_header_row_template
|
208
|
+
|
126
209
|
end # class GitTimeExtractor
|
data/readme.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
[![Gem Version](https://badge.fury.io/rb/git_time_extractor.png)](http://badge.fury.io/rb/git_time_extractor)
|
2
2
|
[![Code Climate](https://codeclimate.com/github/rietta/git_time_extractor/badges/gpa.svg)](https://codeclimate.com/github/rietta/git_time_extractor)
|
3
|
-
|
3
|
+
|
4
|
+
# Extract Reasonable Time Records from a Git Repository
|
4
5
|
|
5
6
|
This tool goes through a GIT repository's commit log and prints a CSV dump of per developer, per day working time based on a few assumptions:
|
6
7
|
|
@@ -10,6 +11,13 @@ This tool goes through a GIT repository's commit log and prints a CSV dump of pe
|
|
10
11
|
|
11
12
|
This script is based on previous code published publicly by *Sharad* at http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/. However, it has been adapted to run without Rails from the command line. The portions of the code written by Rietta are licensed under the terms of the BSD license (see section 3 below).
|
12
13
|
|
14
|
+
## 0. Installing from Ruby Gems
|
15
|
+
|
16
|
+
To quickly get started, just run:
|
17
|
+
`gem install git_time_extractor`
|
18
|
+
|
19
|
+
You can see it at https://rubygems.org/gems/git_time_extractor.
|
20
|
+
|
13
21
|
## 1. Running
|
14
22
|
|
15
23
|
### Usage
|
@@ -28,6 +36,8 @@ Usage: git_time_extractor [options]
|
|
28
36
|
-m, --merge-effort MERGE_EFFORT Effort spent merging, in minutes. Default: 30
|
29
37
|
-s SESSION_DURATION, Session duration, in hours. Default: 3
|
30
38
|
--session-duration
|
39
|
+
--project-total Project commits and time rolled into a single summary line. The field set is total git commit count, total hours, and a list of collaborators.
|
40
|
+
--compact Compact mode that lists only total git commit count, total hours, person, email.
|
31
41
|
```
|
32
42
|
### Most basic usage
|
33
43
|
|
@@ -46,7 +56,7 @@ Once the you have used Git Time Extractor to prepare a CSV file, you can perform
|
|
46
56
|
|
47
57
|
## 3. License Terms (BSD License)
|
48
58
|
|
49
|
-
©
|
59
|
+
© 2012-2015 Rietta, Inc, and contributors. All rights reserved.
|
50
60
|
|
51
61
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
52
62
|
|
@@ -59,3 +69,9 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
59
69
|
|
60
70
|
- [Kimmo Brunfeldt](https://github.com/kimmobrunfeldt) has written [git-hours](
|
61
71
|
https://github.com/kimmobrunfeldt/git-hours), a NodeJS-based clone that was inspired by this `git_time_extractor`.
|
72
|
+
- [Ad van der Veer](https://github.com/advanderveer) is working on [Timeglass](https://github.com/timeglass/glass) in the Go programming language. Unlike `git_time_extractor` and `git-hours`, both of which are built around analyzing past activity, his approach runs a timer in real time during the developer's work and annotates git commits with the time data.
|
73
|
+
|
74
|
+
## 5. What users say
|
75
|
+
|
76
|
+
[Jason Fieldman: Theseus 3D (2014)](http://www.fieldman.org/theseus-3d/)
|
77
|
+
> git_time_extractor says that there is approximately 120 hours of development time on my repo, from September 19 through October 22. Pretty much all grouped on weekends (and our school’s extended 5-day break). The tool overestimates a bit because it does not compensate for meals or mid-session breaks, but it’s relatively close. So let’s say it’s closer to 90-100 hours – not bad to complete the game, including research and dealing with SceneKit foibles along the way.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git_time_extractor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Frank Rietta
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: git
|
@@ -38,9 +38,11 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.2'
|
41
|
-
description:
|
42
|
-
|
43
|
-
|
41
|
+
description: Analyzes Git repository commit log to compute developer working hours,
|
42
|
+
weekly activity, and to detect death marches in software development. It computes
|
43
|
+
the timing statistics based on the timestamps of each commit and the intervals between
|
44
|
+
them. Useful for verifying developer time sheets and for tax purposes and it supports
|
45
|
+
filtering for a specific tax year. See https://github.com/rietta/git_time_extractor/wiki.
|
44
46
|
email: hello@rietta.com
|
45
47
|
executables:
|
46
48
|
- git_time_extractor
|
@@ -77,6 +79,6 @@ rubyforge_project:
|
|
77
79
|
rubygems_version: 2.4.5
|
78
80
|
signing_key:
|
79
81
|
specification_version: 4
|
80
|
-
summary:
|
81
|
-
|
82
|
+
summary: Analyzes Git repository commit logs to compute developer working hours, weekly
|
83
|
+
activity, and to detect death marches in software development.
|
82
84
|
test_files: []
|