git_time_extractor 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,8 @@
1
+ === 0.1.0 / 2012-05-05
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday of this git_time_extractor gem.
6
+
7
+ === 0.1.0 / 2012-02-15
8
+ * Initial code release on https://github.com/rietta/git_time_extractor/ - not a gem.
data/README.txt ADDED
@@ -0,0 +1,76 @@
1
+ = git_time_extractor
2
+
3
+ Project Wiki: https://github.com/rietta/git_time_extractor/wiki
4
+
5
+ == DESCRIPTION:
6
+
7
+ EXTRACT REASONABLE TIME RECORDS FROM A GIT REPOSITORY
8
+
9
+ git_time_extractor is a free tool that goes through a GIT, the popular revision control system, repository's commit log and produces a Comma Seperated Values (CSV) file that indicates the time spent by each developer, per day.
10
+
11
+ The working time estimates are based on three assumptions:
12
+
13
+ 1. A series of commits within a 3 hour window are part of the same development session
14
+ 2. A single commit (or the first commit of the session) is considered to represent 30 minutes of work time
15
+ 3. The more frequent a developer commits to the repository while working, the more accurate the time report will be
16
+
17
+ 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).
18
+
19
+ git_time_extractor is useful for software development companies that want to discover the approximate time spent by developers on particular projects based on real data in the GIT revision control system. This is useful for managers, accountants, and for those who need to back up records for tax purposes.
20
+
21
+ For example, in the United States there is a Research & Development (R&D) tax credit available for companies who build or improve software for certain purposes. To claim this credit requires certain types of records. Check with your accountant to see if the results from this program is appropriate in your particular situation. You can learn more information about this particular credit at http://www.irs.gov/businesses/article/0,,id=156366,00.html.
22
+
23
+ == BENEFITS:
24
+
25
+ * Compute time records based on the timestamps of each code commit by each developer
26
+ * Compare these results with other time-sheets or metrics to measure the effectiveness of your team members
27
+ * Save money on taxes by producing documents required by your accountant to properly apply for certain tax credits
28
+ * It's a Free Open Source Tool
29
+
30
+ == FEATURES:
31
+
32
+ * Easy command-line operation
33
+ * Reads from a local GIT branch in the current directory
34
+ * Writes to a CSV-file that is compatible with Microsoft Excel, OpenOffice Calc, or Google Docs
35
+
36
+ == SYNOPSIS:
37
+
38
+ cd /path/to/your/repository
39
+ git_time_extractor > time_log.csv
40
+
41
+ == REQUIREMENTS:
42
+
43
+ The following GEMS are required as dependencies:
44
+ * git
45
+ * logger
46
+
47
+ == INSTALL:
48
+
49
+ gem install git_time_extractor
50
+
51
+ == UNINSTALL:
52
+
53
+ gem install git_time_extractor
54
+
55
+ == DEVELOPERS:
56
+
57
+ After checking out the source, run:
58
+
59
+ $ rake newb
60
+
61
+ This task will install any missing dependencies, run the tests/specs,
62
+ and generate the RDoc.
63
+
64
+ == LICENSE:
65
+
66
+ (The BSD License)
67
+
68
+ Copyright (c) 2012 Rietta Inc. All rights reserved.
69
+
70
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
71
+
72
+ Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
73
+ Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
74
+
75
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
76
+
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env ruby
2
+ # Extract Reasonable Developer Time Records from a GIT Repository's Commit Log
3
+ #
4
+ # This is inspired by a RAKE task publicly posted by Sharad at
5
+ # http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/.
6
+ # However, it has been adapted to run without Rails from the command line.
7
+ #
8
+ # Portions (C) 2012 Rietta Inc. and licensed under the terms of the BSD license.
9
+
10
+ # Adjust path in case called directly and not through gem
11
+ $:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
12
+
13
+ require 'git_time_extractor'
14
+
15
+ #puts "\n# Arguments #{ARGV.length}\n"
16
+
17
+ valid_usage = false
18
+
19
+ if ARGV.empty?
20
+ output_file = "-"
21
+ path_to_repo = Dir.pwd
22
+ project_name = ""
23
+ valid_usage = true
24
+ elsif "-h" == ARGV[0].downcase || "--help" == ARGV[0].downcase
25
+ # Show help
26
+ elsif ARGV.length == 2
27
+ output_file = ARGV.pop
28
+ path_to_repo = ARGV.pop
29
+ valid_usage = true
30
+ elsif ARGV.length == 1
31
+ output_file = "-"
32
+ path_to_repo = ARGV.pop
33
+ valid_usage = true
34
+ end
35
+
36
+ unless valid_usage
37
+ puts "Usage: git_time_extractor PROJECT_NAME [PATH_TO_REPO] [OUTPUT_FILE]"
38
+ puts "Copyright 2012 Rietta Inc. http://www.rietta.com"
39
+ exit 0
40
+ else
41
+ #path_to_repo = File.expand_path(File.dirname(path_to_repo)) if nil != path_to_repo && "" != path_to_repo
42
+ #puts "\n\nGit Repo Path: #{path_to_repo}\nOutput: #{output_file}\n"
43
+ GitTimeExtractor.process_git_log_into_time(path_to_repo, output_file)
44
+ end
45
+
@@ -0,0 +1,109 @@
1
+ #
2
+ # Extract Reasonable Developer Time Records from a GIT Repository's Commit Log
3
+ #
4
+ # This is inspired by a RAKE task publicly posted by Sharad at
5
+ # http://www.tatvartha.com/2010/01/generating-time-entry-from-git-log/.
6
+ # However, it has been adapted to run without Rails from the command line.
7
+ #
8
+ # Portions (C) 2012 Rietta Inc. and licensed under the terms of the BSD license.
9
+ #
10
+ class GitTimeExtractor
11
+ VERSION = '0.2.0'
12
+
13
+ require 'rubygems'
14
+ require 'ostruct'
15
+ require 'logger'
16
+ require 'git'
17
+ require 'csv'
18
+
19
+ #
20
+ # Go through the GIT commit log, to compute the elapsed working time of each committing developer, based
21
+ # on a few assumptions:
22
+ #
23
+ # (1) A series of commits within a 3 hour window are part of the same development session
24
+ # (2) A single commit (or the first commit of the session) is considered to represent 30 minutes of work time
25
+ # (3) The more frequent a developer commits to the repository while working, the more accurate the time report will be
26
+ #
27
+ #
28
+ def self.process_git_log_into_time(path_to_git_repo = "./", path_to_output_file = "-", project_name = "")
29
+
30
+ if "-" != path_to_output_file
31
+ raise "Output path not yet implemented. Use a Unix pipe to write to your desired file. For example: git_time_extractor ./ > my_result.csv\n"
32
+ end
33
+
34
+ # Open the GIT Repository for Reading
35
+ logger = Logger.new(STDOUT)
36
+ logger.level = Logger::WARN
37
+ g = Git.open(path_to_git_repo, :log => logger)
38
+ logs = g.log(1000)
39
+ log_entries = logs.entries.reverse
40
+ worklog = {}
41
+
42
+ # Go through the GIT commit records and construct the time
43
+ log_entries.each_with_index do |commit, index|
44
+ author_date = commit.author_date.to_date
45
+ daylog = worklog[author_date] || OpenStruct.new(:date => author_date, :duration => 0)
46
+ daylog.author = commit.author
47
+ daylog.message = "#{daylog.message} --- #{commit.message}"
48
+ daylog.duration = daylog.duration + calc_duration_in_minutes(log_entries, index)
49
+ worklog[author_date] = daylog
50
+ end # log_entries.each_with_index
51
+
52
+ # Print the header row for the CSV
53
+ puts [
54
+ 'Date',
55
+ 'Minutes',
56
+ 'Hours',
57
+ 'Person',
58
+ 'Email',
59
+ 'Project',
60
+ 'Notes',
61
+ 'Week Number',
62
+ 'Year'
63
+ ].to_csv
64
+
65
+ # Go through the work log
66
+ worklog.keys.sort.each do |date|
67
+
68
+ start_time = DateTime.parse(date.to_s)
69
+ duration_in_seconds = (worklog[date].duration.to_f * 60.0).round(0)
70
+ duration_in_minutes = worklog[date].duration.to_i
71
+ duration_in_hours = (worklog[date].duration / 60.0).round(1)
72
+
73
+ stop_time = start_time + duration_in_seconds
74
+ row = [
75
+ start_time.strftime("%m/%d/%Y"),
76
+ duration_in_minutes,
77
+ duration_in_hours,
78
+ worklog[date].author.name,
79
+ worklog[date].author.email,
80
+ project_name,
81
+ worklog[date].message,
82
+ start_time.strftime("%W").to_i,
83
+ start_time.strftime("%Y").to_i]
84
+ puts row.to_csv
85
+ end # worklog each
86
+
87
+ end # process_git_log_into_time
88
+
89
+ # Calculate the duration of work in minutes
90
+ def self.calc_duration_in_minutes(log_entries, index)
91
+ commit = log_entries[index]
92
+ if index > 1
93
+ previous_commit = log_entries[index-1]
94
+ # Default duration in Ruby is in seconds
95
+ duration = commit.author_date - previous_commit.author_date
96
+
97
+ # ASSUMPTION: if the gap between 2 commits is more than 3 hours, reduce it to 1/2 hour
98
+ duration = 30 * 60 if duration > 3 * 3600
99
+ else
100
+ # ASSUMPTION: first commit took 1/2 hour
101
+ duration = 30 * 60
102
+ end
103
+ return duration.to_f / 60.0
104
+ end # calc_duration_in_minutes
105
+
106
+ def self.say_hi
107
+ "hi"
108
+ end
109
+ end # class GitTimeExtractor
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git_time_extractor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Frank Rietta
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: git
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: logger
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Compute the estimated time spent by developers working on code within
47
+ a GIT respository. Useful for verifying developer timesheets and for tax purposes.
48
+ email: products@rietta.com
49
+ executables:
50
+ - git_time_extractor
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - bin/git_time_extractor
55
+ - README.txt
56
+ - History.txt
57
+ - lib/git_time_extractor.rb
58
+ homepage: https://github.com/rietta/git_time_extractor
59
+ licenses:
60
+ - BSD
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project:
79
+ rubygems_version: 1.8.24
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Reasonable developer time log extractor that uses a GIT repository's commit
83
+ log history.
84
+ test_files: []