timecost 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d4c535194591fac9070a33bf8893093e7f267dad
4
+ data.tar.gz: d8035799854d4d09803f1cef922f4cb2c8af24df
5
+ SHA512:
6
+ metadata.gz: 26a84c83f27764876c536d8a93ccfc3042d57941c7177d86225164e09527cb4cca1e9360df32ca68121d4e76898462cd46b269b1dee6bfe0ef8fe0d01dfce451
7
+ data.tar.gz: cc6a7dae49c57478360e901acee687b633de7515e695b0e7a2aa0dfe699e97e233a649acd9e2060314b52e6c36c84746a426ed6b53b7f46845694ab6899cd0db
data/.gitignore ADDED
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+
4
+ # Specify your gem's dependencies in timecost.gemspec
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,19 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ timecost (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ minitest (4.7.5)
10
+ rake (10.1.0)
11
+
12
+ PLATFORMS
13
+ ruby
14
+
15
+ DEPENDENCIES
16
+ bundler (~> 1.6)
17
+ minitest (~> 4.7.5)
18
+ rake (~> 10.0)
19
+ timecost!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Glenn Y. Rolland
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,56 @@
1
+ TimeCost for Git
2
+ ================
3
+
4
+ Use git logs to give an estimation of spent time & costs of your projects.
5
+
6
+ Installation
7
+ ------------
8
+
9
+ Install the project with:
10
+
11
+ $ gem install timecost
12
+
13
+ Usage
14
+ -----
15
+
16
+ To get the total time spent on your git project
17
+
18
+ ```
19
+ $ git timecost
20
+
21
+ [...]
22
+
23
+ (1.36) 2012-12-31T11:15:31+01:00 - 2012-12-31T12:36:55+01:00
24
+ * Glenn Y. Rolland <glenux@glenux.net>
25
+ Fix filtering.
26
+ * Glenn Y. Rolland <glenux@glenux.net>
27
+ Time range extractor for git.
28
+
29
+ TOTAL: 3.36 hours
30
+ ```
31
+
32
+ To get the time spent on your project since a given date
33
+
34
+ ```
35
+ $ git timecost -d 2013-03-01
36
+ set date filter to 2013-03-01
37
+ (1.0) 2013-09-23T13:02:39+02:00 - 2013-09-23T14:02:39+02:00
38
+ * Glenn Y. Rolland <glenux@glenux.net>
39
+ Add support for import / export / merge of ranges.
40
+
41
+ TOTAL: 1.00 hours
42
+ ```
43
+
44
+ For other possibilities
45
+ ```
46
+ $ git timecost -h
47
+ ```
48
+
49
+ Contributing
50
+ ------------
51
+
52
+ 1. Fork it ( https://github.com/[my-github-username]/timecost/fork )
53
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
54
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
55
+ 4. Push to the branch (`git push origin my-new-feature`)
56
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+
2
+ require 'rake'
3
+ require "bundler/gem_tasks"
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ #t.warning = true
8
+ #t.verbose = true
9
+ t.libs << "spec"
10
+ t.test_files = FileList['spec/**/*_spec.rb']
11
+ end
12
+ task :default => :test
data/TODO.md ADDED
@@ -0,0 +1,19 @@
1
+ TODO
2
+ ====
3
+
4
+ Fixes and ideas for the future
5
+
6
+ ## Per user scotch
7
+
8
+ Different users have a different commit style & frequency.
9
+ We should be able to define a per-user scotch.
10
+
11
+
12
+ ## Automatic scotch : Use median time between consecutive commits, per user
13
+
14
+ def median(array)
15
+ sorted = array.sort
16
+ len = sorted.length
17
+ return (sorted[(len - 1) / 2] + sorted[len / 2]) / 2.0
18
+ end
19
+
data/bin/git-timecost ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ # vim: set syntax=ruby ts=4 sw=4 noet :
3
+
4
+ require 'pp'
5
+ require 'date'
6
+ require 'optparse'
7
+ require 'yaml'
8
+
9
+ require 'timecost'
10
+
11
+ app = TimeCost::CLI.new
12
+ app.parse_cmdline ARGV
13
+ app.analyze
14
+ app.export
15
+ app.report
16
+ #app.report_ranges
17
+ #app.report_users
18
+
19
+ exit 0
20
+
@@ -0,0 +1,38 @@
1
+
2
+ require 'pp'
3
+
4
+ module TimeCost
5
+ class AuthorList
6
+ class UnknownAuthor < RuntimeError ; end
7
+
8
+ # Prepare an empty index (local)
9
+ def initialize
10
+ @count = 0
11
+ @author_to_id = {}
12
+ end
13
+
14
+ def add author
15
+ if @author_to_id.include? author then
16
+ result = @author_to_id[author]
17
+ else
18
+ @author_to_id[author] = @count
19
+ result = @count
20
+ @count += 1
21
+ end
22
+ end
23
+
24
+ def alias author_ref, author_new
25
+ raise UnknownAuthor unless @author_to_id.include? author_ref
26
+ end
27
+
28
+ # Return local user id for git user
29
+ # FIXME: should handle multiple names for same user
30
+ def parse author
31
+ return @author_to_id[author]
32
+ end
33
+
34
+ def size
35
+ return @author_to_id.keys.size
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,192 @@
1
+ module TimeCost
2
+ class CLI
3
+ def initialize
4
+ # FIXME: accept multiple authors
5
+ @config = {
6
+ :author_filter_enable => false,
7
+ :author_filter => ".*?",
8
+
9
+ :date_filter_enable => false,
10
+ :date_filter => ".*?",
11
+
12
+ :input_dump => [],
13
+ :output_dump => nil,
14
+
15
+ :range_granularity => 0.5, # in decimal hours
16
+
17
+ :verbose => false
18
+ }
19
+ @rangelist = {}
20
+ @authorlist = nil
21
+ end
22
+
23
+ def parse_cmdline args
24
+ opts = OptionParser.new do |opts|
25
+ opts.banner = "Usage: #{File.basename $0} [options]"
26
+
27
+ opts.on_tail("-v","--verbose", "Run verbosely") do |v|
28
+ @config[:verbose] = true
29
+ end
30
+
31
+ opts.on_tail("-h","--help", "Show this help") do
32
+ puts opts
33
+ exit 0
34
+ end
35
+
36
+ opts.on("-i","--input FILE", "Set input dump file") do |file|
37
+ @config[:input_dump] << file
38
+ end
39
+
40
+ opts.on("-o","--output FILE", "Set output dump file") do |file|
41
+ @config[:output_dump] = file
42
+ end
43
+
44
+ opts.on("-d","--date DATE", "Keep only commits since DATE") do |date|
45
+ puts "set date filter to #{date}"
46
+ @config[:date_filter] = DateTime.parse(date);
47
+ @config[:date_filter_enable] = true
48
+ end
49
+
50
+ opts.on("-t","--time TIME", "Keep only commits on last TIME datys") do |time|
51
+ puts "set time filter to latest #{time} days"
52
+ @config[:date_filter] = DateTime.now - time.to_f;
53
+ puts "set date filter to date = #{@config[:date_filter]}"
54
+ @config[:date_filter_enable] = true
55
+ end
56
+
57
+ opts.on("-a","--author AUTHOR", "Keep only commits by AUTHOR") do |author|
58
+ puts "set author filter to #{author}"
59
+ @config[:author_filter] = author
60
+ @config[:author_filter_enable] = true
61
+ end
62
+
63
+ # overlap :
64
+ #
65
+ opts.on("-s","--scotch GRANULARITY", "Use GRANULARITY (decimal hours) to merge ranges") do |granularity|
66
+ puts "set scotch to #{granularity}"
67
+ @config[:range_granularity] = granularity.to_f
68
+ end
69
+ end
70
+ opts.parse! args
71
+
72
+ end
73
+
74
+
75
+ def analyze_git
76
+ # git log
77
+ # foreach, create time range (before) + logs
78
+ process = IO.popen ["git", "log",
79
+ "--date=iso",
80
+ "--no-patch",
81
+ "--","."]
82
+
83
+
84
+ @rangelist = {}
85
+ commit = nil
86
+ loop do
87
+ line = process.gets
88
+ break if line.nil?
89
+ # utf-8 fix ?
90
+ # line.encode!( line.encoding, "binary", :invalid => :replace, :undef => :replace)
91
+ line.strip!
92
+
93
+ case line
94
+ when /^commit (.*)$/ then
95
+ id = $1
96
+ # merge ranges & push
97
+ unless commit.nil? then
98
+ range = Range.new commit, granularity: @config[:range_granularity]
99
+
100
+ if not @rangelist.include? commit.author then
101
+ @rangelist[commit.author] = RangeList.new
102
+ end
103
+ @rangelist[commit.author].add range
104
+ end
105
+ commit = Commit.new id
106
+ # puts "commit #{id}"
107
+
108
+ when /^Author:\s*(.*?)\s*$/ then
109
+ unless commit.nil? then
110
+ commit.author = $1
111
+
112
+ if @config[:author_filter_enable] and
113
+ (not commit.author =~ /#{@config[:author_filter]}/) then
114
+ commit = nil
115
+ # reject
116
+ end
117
+
118
+ end
119
+
120
+ when /^Date:\s*(.*?)\s*$/ then
121
+ unless commit.nil? then
122
+ commit.date = $1
123
+
124
+ if @config[:date_filter_enable] and
125
+ (DateTime.parse(commit.date) < @config[:date_filter]) then
126
+ commit = nil
127
+ # reject
128
+ end
129
+ end
130
+
131
+ when /^\s*$/ then
132
+ # skip
133
+
134
+ else
135
+ # add as note
136
+ unless commit.nil? then
137
+ commit.note = if commit.note.nil? then line
138
+ else commit.note + "\n" + line
139
+ end
140
+ end
141
+ end
142
+
143
+ end
144
+
145
+ end
146
+
147
+ def analyze_dumps
148
+ #read ranges
149
+ @rangelist = RangeList.new
150
+
151
+ @config[:input_dump].each do |filename|
152
+ rangelist = YAML::load(File.open(filename,"r"))
153
+ rangelist.each do |range|
154
+ @rangelist.add range
155
+ end
156
+ end
157
+ end
158
+
159
+ def analyze
160
+ if @config[:input_dump].empty? then
161
+ analyze_git
162
+ else
163
+ analyze_dumps
164
+ end
165
+ end
166
+
167
+ def export
168
+ return if @config[:output_dump].nil?
169
+ puts "Exporting to %s" % @config[:output_dump]
170
+ File.open(@config[:output_dump], "w") do |file|
171
+ file.puts YAML::dump(@rangelist)
172
+ end
173
+ end
174
+
175
+ def report
176
+ return if not @config[:output_dump].nil?
177
+
178
+ @rangelist.each do |author,rangelist|
179
+ rangelist.each do |range|
180
+ puts range.to_s(!@config[:author_filter_enable]) + "\n"
181
+ end
182
+ end
183
+ total = 0
184
+ @rangelist.each do |author,rangelist|
185
+ puts "SUB-TOTAL for %s: %.2f hours\n" % [author, rangelist.sum]
186
+ total += rangelist.sum
187
+ end
188
+ puts "TOTAL: %.2f hours" % total
189
+ end
190
+ end
191
+ end
192
+
@@ -0,0 +1,14 @@
1
+
2
+ module TimeCost
3
+
4
+ class Commit
5
+ attr_accessor :author, :commit, :date, :note
6
+ def initialize commit
7
+ @commit = commit
8
+ @note = nil
9
+ @author = nil
10
+ @date = nil
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,117 @@
1
+
2
+ module TimeCost
3
+ class Range
4
+ attr_accessor :time_start, :time_stop, :commits, :author
5
+
6
+ GRANULARITY_DEFAULT = 0.5
7
+
8
+ def initialize commit, options = {}
9
+ @granularity = options[:granularity] || GRANULARITY_DEFAULT
10
+
11
+ # FIXME: First approximation for users
12
+ # later, we'll replace with @user = User.parse(commit.author)
13
+ @author = commit.author
14
+
15
+ @time_stop = DateTime.parse(commit.date)
16
+ @time_start = @time_stop - (@granularity * 3 / 24.0)
17
+ @commits = [commit]
18
+ self
19
+ end
20
+
21
+ def merge range
22
+ # B -----[----]----
23
+ # A --[----]------
24
+ # = ---[------]----
25
+
26
+ # minimum of both
27
+ new_start = if range.time_start < @time_start then range.time_start
28
+ else @time_start
29
+ end
30
+
31
+ new_end = if range.time_stop >= @time_stop then range.time_stop
32
+ else @time_stop
33
+ end
34
+
35
+ @time_start = new_start
36
+ @time_stop = new_end
37
+ @commits.concat range.commits
38
+ end
39
+
40
+ def overlap? range
41
+ result = false
42
+
43
+ # return early result if ranges come from different authors
44
+ return false if (@author != range.author)
45
+
46
+ # Ref ----[----]-----
47
+ # overlapping :
48
+ # A -[----]--------
49
+ # B -------[----]--
50
+ # C -[----------]--
51
+ # D ------[]-------
52
+ # non-overlapping :
53
+ # E -[]------------
54
+ # F -----------[]--
55
+
56
+ start_before_start = (range.time_start < @time_start)
57
+ start_after_start = (range.time_start >= @time_start)
58
+ start_after_stop = (range.time_start >= @time_stop)
59
+ start_before_stop = (range.time_start < @time_stop)
60
+
61
+ stop_before_stop = (range.time_stop < @time_stop)
62
+ stop_after_stop = (range.time_stop >= @time_stop)
63
+ stop_before_start = (range.time_stop < @time_start)
64
+ stop_after_start = (range.time_stop >= @time_start)
65
+
66
+ # A case
67
+ if start_before_start and start_before_stop and
68
+ stop_after_start and stop_before_stop then
69
+ result = true
70
+ end
71
+
72
+ # B case
73
+ if start_after_start and start_before_stop and
74
+ stop_after_start and stop_after_stop then
75
+ result = true
76
+ end
77
+
78
+ # C case
79
+ if start_before_start and start_before_stop and
80
+ stop_after_start and stop_after_stop then
81
+ result = true
82
+ end
83
+
84
+ # D case
85
+ if start_after_start and start_before_stop and
86
+ stop_after_start and stop_before_stop then
87
+ result = true
88
+ end
89
+
90
+ return result
91
+ end
92
+
93
+ def fixed_start
94
+ return @time_start + (@granularity/24.0)
95
+ end
96
+
97
+ def diff
98
+ return ("%.2f" % ((@time_stop - fixed_start).to_f * 24)).to_f
99
+ end
100
+
101
+ def to_s show_authors = true
102
+ val = "(%s)\t%s - %s\n" % [diff, fixed_start, @time_stop]
103
+ if show_authors then
104
+ val += "\tby %s\n" % @commits.first.author
105
+ end
106
+ @commits.each do |commit|
107
+ lines = []
108
+ lines.concat commit.note.split(/\n/)
109
+ r = lines.map{ |s| "\t %s" % s }.join "\n"
110
+ r[1] = '*'
111
+ val += r + "\n"
112
+ end
113
+ return val
114
+ end
115
+ end
116
+ end
117
+
@@ -0,0 +1,46 @@
1
+
2
+ module TimeCost
3
+ class RangeList
4
+ def initialize
5
+ @ranges = []
6
+ end
7
+
8
+ def add range
9
+ merged = false
10
+ merged_range = nil
11
+
12
+ # merge
13
+ @ranges.each do |old|
14
+ #pp old
15
+ if old.overlap? range then
16
+ old.merge range
17
+ merged_range = old
18
+ merged = true
19
+ break
20
+ end
21
+ end
22
+
23
+ # add if needed
24
+ if merged then
25
+ @ranges.delete merged_range
26
+ self.add merged_range
27
+ else
28
+ @ranges.push range
29
+ end
30
+ end
31
+
32
+ def each
33
+ @ranges.each do |r|
34
+ yield r
35
+ end
36
+ end
37
+
38
+ def sum
39
+ result = 0
40
+ @ranges.each do |r|
41
+ result += r.diff
42
+ end
43
+ return result
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Timecost
2
+ VERSION = "0.0.1"
3
+ end
data/lib/timecost.rb ADDED
@@ -0,0 +1,7 @@
1
+
2
+ require 'timecost/commit'
3
+ require 'timecost/range'
4
+ require 'timecost/author_list'
5
+ require 'timecost/range_list'
6
+ require 'timecost/cli'
7
+
@@ -0,0 +1,65 @@
1
+
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ require 'timecost/author_list'
6
+
7
+ describe TimeCost::AuthorList do
8
+ let(:list) { TimeCost::AuthorList.new }
9
+ let(:first) { "Foo <foo@example.com>" }
10
+ let(:second) { "Bar <bar@example.com>" }
11
+
12
+ describe '.new' do
13
+ it "can be created without arguments" do
14
+ assert_instance_of TimeCost::AuthorList, list
15
+ end
16
+ end
17
+
18
+ describe '.add' do
19
+ it "must accept adding authors" do
20
+ assert_respond_to list, :add
21
+
22
+ list.add first
23
+ list.add second
24
+ end
25
+
26
+ it "must assign a different id to different authors" do
27
+ list.add first
28
+ list.add second
29
+ id_foo = list.parse first
30
+ id_bar = list.parse second
31
+ refute_equal id_foo, id_bar
32
+ end
33
+ end
34
+
35
+ describe '.size' do
36
+ it "must be zero in the beginning" do
37
+ assert_equal list.size, 0
38
+ end
39
+
40
+ it "must grow while adding authors" do
41
+ list.add first
42
+ assert_equal list.size, 1
43
+ list.add second
44
+ assert_equal list.size, 2
45
+ end
46
+ end
47
+
48
+ describe '.alias' do
49
+ it "must accept aliases for authors" do
50
+ assert_respond_to list, :alias
51
+
52
+ list.add first
53
+ list.alias first, second
54
+ end
55
+
56
+ it "must assign the same id to aliases authors" do
57
+ list.add first
58
+ list.alias first, second
59
+
60
+ id_foo = list.parse first
61
+ id_bar = list.parse second
62
+ refute_equal id_foo, id_bar
63
+ end
64
+ end
65
+ end
data/spec/cli_spec.rb ADDED
@@ -0,0 +1,16 @@
1
+
2
+
3
+ require_relative 'spec_helper'
4
+
5
+ require 'timecost/cli'
6
+
7
+ describe TimeCost::CLI do
8
+ let(:cli) { TimeCost::CLI.new }
9
+
10
+ describe '.new' do
11
+ it "can be created without arguments" do
12
+ assert_instance_of TimeCost::CLI, cli
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,26 @@
1
+
2
+ require_relative 'spec_helper'
3
+
4
+ require 'timecost/range_list'
5
+
6
+ describe TimeCost::RangeList do
7
+ let(:list) { TimeCost::RangeList.new }
8
+
9
+ describe '.new' do
10
+ it "can be created without arguments" do
11
+ assert_instance_of TimeCost::RangeList, list
12
+ end
13
+ end
14
+
15
+ it "is empty at start" do
16
+ end
17
+
18
+ it "can insert ranges" do
19
+ end
20
+
21
+ it "can merge overlapping ranges" do
22
+ end
23
+
24
+ it "cumulates non-overlapping ranges" do
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+
2
+ require_relative 'spec_helper'
3
+
4
+ require 'timecost/range'
5
+
6
+ describe TimeCost::Range do
7
+ let(:config) do { granularity: 0.5 } end
8
+
9
+ let(:commitA) { nil }
10
+ let(:commitB) { nil }
11
+ let(:commitC) { nil }
12
+ let(:commitD) { nil }
13
+
14
+ let(:rangeA) {
15
+ TimeCost::Range.new commitA, config
16
+ }
17
+
18
+ describe '.new' do
19
+ it "can be created from " do
20
+ assert_instance_of TimeCost::Range, rangeA
21
+ end
22
+ end
23
+
24
+ describe '.overlap?' do
25
+ it "must respond to .overlap?" do
26
+ end
27
+
28
+ it "must return false when ranges are not overlapping" do
29
+ end
30
+
31
+ it "must return true when ranges are overlapping" do
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,16 @@
1
+
2
+ #require 'mark'
3
+ #
4
+ require 'minitest/unit'
5
+ require 'minitest/autorun'
6
+ require 'minitest/spec'
7
+ require 'minitest/pride'
8
+
9
+ $LOAD_PATH.unshift('../lib')
10
+
11
+ #if __FILE__ == $0
12
+ # $LOAD_PATH.unshift('lib', 'spec')
13
+ # Dir.glob('./spec/**/*_spec.rb') { |f| require f }
14
+ #end
15
+
16
+
data/timecost.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'timecost/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "timecost"
8
+ spec.version = Timecost::VERSION
9
+ spec.authors = ["Glenn Y. Rolland"]
10
+ spec.email = ["glenux@glenux.net"]
11
+ spec.summary = %q{Use GIT logs to give an estimation of spent time & costs of your projects.}
12
+ spec.description = %q{Use GIT logs to give an estimation of spent time & costs of your projects.}
13
+ spec.homepage = "https://github.com/glenux/git-timecost"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "minitest", "~> 4.7.5"
24
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: timecost
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Glenn Y. Rolland
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 4.7.5
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 4.7.5
55
+ description: Use GIT logs to give an estimation of spent time & costs of your projects.
56
+ email:
57
+ - glenux@glenux.net
58
+ executables:
59
+ - git-timecost
60
+ extensions: []
61
+ extra_rdoc_files: []
62
+ files:
63
+ - ".gitignore"
64
+ - Gemfile
65
+ - Gemfile.lock
66
+ - LICENSE.txt
67
+ - README.md
68
+ - Rakefile
69
+ - TODO.md
70
+ - bin/git-timecost
71
+ - lib/timecost.rb
72
+ - lib/timecost/author_list.rb
73
+ - lib/timecost/cli.rb
74
+ - lib/timecost/commit.rb
75
+ - lib/timecost/range.rb
76
+ - lib/timecost/range_list.rb
77
+ - lib/timecost/version.rb
78
+ - spec/author_list_spec.rb
79
+ - spec/cli_spec.rb
80
+ - spec/range_list_spec.rb
81
+ - spec/range_spec.rb
82
+ - spec/spec_helper.rb
83
+ - timecost.gemspec
84
+ homepage: https://github.com/glenux/git-timecost
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.2.2
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: Use GIT logs to give an estimation of spent time & costs of your projects.
108
+ test_files:
109
+ - spec/author_list_spec.rb
110
+ - spec/cli_spec.rb
111
+ - spec/range_list_spec.rb
112
+ - spec/range_spec.rb
113
+ - spec/spec_helper.rb