git-age 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/Gemfile.lock +1 -1
- data/README.md +24 -0
- data/bin/git-age +20 -0
- data/graph-cli.png +0 -0
- data/lib/git/age/graph_cli.rb +4 -3
- data/lib/git/age/main.rb +54 -13
- data/lib/git/age/options.rb +4 -1
- data/lib/git/age/stats.rb +44 -0
- data/lib/git/age/version.rb +1 -1
- data/lib/git/age.rb +1 -0
- data.tar.gz.sig +2 -4
- metadata +8 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ec06da504e9bb782269c3fdbad5e0eb887a935c06557f3ec0b0b2e104898e1e
|
4
|
+
data.tar.gz: f606f81e71b79085eb7d6977236311e7f13b50b51118bb9d97dec35e75f15122
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '09a406545ef14ce5a469b949648049cdade634333f2ca49868580dbd058e554dddf48031130800c90b27879f19fcdfb8681d93104d86a8ed9f605487ab6ecfbf'
|
7
|
+
data.tar.gz: 6fdbc40ef845a5368420d6d4608268bc920f74a81c23a2ad0a25ac1acf59b88f7393f54d46d5adf8ded4dba7b23c62697c905a45ac6b055658437c8ca3699ee8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -29,6 +29,10 @@ Usage: git-age [options]
|
|
29
29
|
-t, --title=TITLE Graphic title
|
30
30
|
-x, --xtitle=TITLE X axis title
|
31
31
|
-y, --ytitle=TITLE Y axis title
|
32
|
+
-c, --code=PATTERN Code dir pattern
|
33
|
+
-e, --test=PATTERN Test dir pattern
|
34
|
+
-y, --type=TYPE Graph type, default to bar
|
35
|
+
-v, --version Show version
|
32
36
|
```
|
33
37
|
|
34
38
|
Example:
|
@@ -37,9 +41,29 @@ Example:
|
|
37
41
|
$ git-age -o /tmp/data.csv -t 'Test project' -x 'Dates here' -y 'Lines here' -i /tmp/data.png
|
38
42
|
```
|
39
43
|
|
44
|
+
Sending a dir pattern as your test dir, creating a test column to compare:
|
45
|
+
|
46
|
+
```
|
47
|
+
$ git-age -o /tmp/data.csv -t 'Test project' -x 'Dates here' -y 'Lines here' -i /tmp/data.png -e test
|
48
|
+
```
|
49
|
+
|
50
|
+
If you're sending a test dir, it can be unfair if you don't also send a dir
|
51
|
+
pattern to your code dir, because all other files (configurations, temporary
|
52
|
+
files) will count as code and your code to test ratio will implode. So, sending
|
53
|
+
a code dir pattern:
|
54
|
+
|
55
|
+
```
|
56
|
+
$ git-age -o /tmp/data.csv -t 'Test project' -x 'Dates here' -y 'Lines here' -i /tmp/data.png -e test -c app
|
57
|
+
```
|
58
|
+
|
40
59
|
Supported image processors:
|
41
60
|
|
42
61
|
- [graph-cli](https://github.com/mcastorina/graph-cli)
|
62
|
+
Supports bar graphs (`-y bar`, default) and line graphs (`-y line`).
|
63
|
+
|
64
|
+
Example image:
|
65
|
+
|
66
|
+
![graph-cli graph](https://github.com/taq/git-age/blob/master/graph-cli.png?raw=true)
|
43
67
|
|
44
68
|
Default options are:
|
45
69
|
|
data/bin/git-age
CHANGED
@@ -48,6 +48,26 @@ opts.on('-y', '--ytitle=TITLE', 'Y axis title') do |title|
|
|
48
48
|
options.ytitle = title
|
49
49
|
end
|
50
50
|
|
51
|
+
opts.on('-e', '--test=PATTERN', 'Test dir pattern') do |pattern|
|
52
|
+
STDOUT.puts "Using test dir pattern #{pattern}"
|
53
|
+
options.test = pattern
|
54
|
+
end
|
55
|
+
|
56
|
+
opts.on('-c', '--code=PATTERN', 'Code dir pattern') do |pattern|
|
57
|
+
STDOUT.puts "Using code dir pattern #{pattern}"
|
58
|
+
options.code = pattern
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on('-y', '--type=TYPE', 'Graph type, defaults to bar') do |type|
|
62
|
+
STDOUT.puts "Using graph type #{type}"
|
63
|
+
options.type = type
|
64
|
+
end
|
65
|
+
|
66
|
+
opts.on('-v', '--version', 'Show version') do
|
67
|
+
STDOUT.puts "Version #{Git::Age::VERSION}"
|
68
|
+
return
|
69
|
+
end
|
70
|
+
|
51
71
|
opts.parse!
|
52
72
|
|
53
73
|
Git::Age::Main.new.run
|
data/graph-cli.png
ADDED
Binary file
|
data/lib/git/age/graph_cli.rb
CHANGED
@@ -9,13 +9,14 @@ module Git
|
|
9
9
|
|
10
10
|
def self.create(input)
|
11
11
|
options = Git::Age::Options.instance
|
12
|
+
legend = options.test ? 'code' : ''
|
13
|
+
type = options.type == 'bar' ? '--bar' : ''
|
12
14
|
STDOUT.puts "Creating image #{options.image} ..."
|
13
15
|
|
14
|
-
cmd = "graph #{input}
|
15
|
-
|
16
|
+
cmd = "graph #{input} #{type} -o #{options.image} --title '#{options.title}' --xlabel='#{options.xtitle}' --ylabel='#{options.ytitle}' --xtick-fontsize 5 --time-format-output '%Y-%m-%d' --legend='#{legend}' 2> /dev/null"
|
17
|
+
IO.popen(cmd) do |io|
|
16
18
|
io.read
|
17
19
|
end
|
18
|
-
STDOUT.puts rst
|
19
20
|
end
|
20
21
|
end
|
21
22
|
end
|
data/lib/git/age/main.rb
CHANGED
@@ -1,14 +1,22 @@
|
|
1
|
+
require 'date'
|
1
2
|
require 'io/console'
|
2
3
|
|
3
4
|
module Git
|
4
5
|
module Age
|
5
6
|
class Main
|
7
|
+
attr_reader :dates, :files
|
8
|
+
|
6
9
|
def initialize
|
7
10
|
STDOUT.puts "Waiting, analysing your repository ..."
|
8
11
|
|
9
|
-
@dates = Hash.new
|
10
|
-
@files =
|
12
|
+
@dates = Hash.new { |hash, key| hash[key] = { code: 0, test: 0 } }
|
13
|
+
@files = fill_files
|
11
14
|
@winsize = IO.console.winsize
|
15
|
+
@test = Git::Age::Options.instance.test
|
16
|
+
@code = Git::Age::Options.instance.code
|
17
|
+
|
18
|
+
@test_regexp = @test ? %r{^#{@test}} : nil
|
19
|
+
@code_regexp = @code ? %r{^#{@code}} : nil
|
12
20
|
end
|
13
21
|
|
14
22
|
def run
|
@@ -16,18 +24,27 @@ module Git
|
|
16
24
|
sort_dates
|
17
25
|
create_csv
|
18
26
|
create_image
|
27
|
+
show_stats
|
19
28
|
rescue => e
|
20
29
|
STDERR.puts "Error: #{e}"
|
30
|
+
puts e.backtrace
|
21
31
|
end
|
22
32
|
|
23
33
|
private
|
24
34
|
|
35
|
+
def file_type(file)
|
36
|
+
return :t if @test_regexp && file.match(@test_regexp)
|
37
|
+
|
38
|
+
return :c unless @code_regexp
|
39
|
+
|
40
|
+
@code_regexp && file.match(@code_regexp) ? :c : :u
|
41
|
+
end
|
42
|
+
|
25
43
|
def read_files
|
26
44
|
cnt = 0
|
27
45
|
total = @files.size
|
28
46
|
mapfile = Git::Age::Options.instance.map ? File.open("/tmp/git-age.map", 'w') : nil
|
29
47
|
|
30
|
-
|
31
48
|
@files.each do |file|
|
32
49
|
cnt += 1
|
33
50
|
next unless text?(file)
|
@@ -41,12 +58,14 @@ module Git
|
|
41
58
|
matches = line.match(/[\w^]+\s\([\w\s]+(?<date>\d{4}-\d{2})-\d{2}/)
|
42
59
|
next unless matches
|
43
60
|
|
44
|
-
|
61
|
+
type = file_type(file)
|
62
|
+
mapfile << "#{file}[#{type}]: #{line}\n" if mapfile
|
45
63
|
|
46
|
-
@dates[matches[:date]] += 1
|
64
|
+
@dates[matches[:date]][:test] += 1 if type == :t
|
65
|
+
@dates[matches[:date]][:code] += 1 if type == :c
|
47
66
|
end
|
48
|
-
rescue =>
|
49
|
-
print "Error on file: #{file}\r"
|
67
|
+
rescue => exc
|
68
|
+
print "Error on file: #{file}: #{exc}\r"
|
50
69
|
end
|
51
70
|
end
|
52
71
|
|
@@ -61,13 +80,17 @@ module Git
|
|
61
80
|
|
62
81
|
def create_csv
|
63
82
|
output = Git::Age::Options.instance.output
|
64
|
-
STDOUT.puts "Creating CSV file #{output} ...".ljust(@winsize[1])
|
83
|
+
STDOUT.puts "Creating CSV file #{output} with #{@dates.size} lines ...".ljust(@winsize[1])
|
65
84
|
|
66
85
|
File.open(output, 'w') do |file|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
86
|
+
header = "\"date\",\"code\""
|
87
|
+
header << ",\"test\"" if @test
|
88
|
+
file << "#{header}\n"
|
89
|
+
|
90
|
+
@dates.each do |key, data|
|
91
|
+
line = "\"#{key}\",#{data[:code]}"
|
92
|
+
line << ",#{data[:test]}" if @test
|
93
|
+
file << "#{line}\n"
|
71
94
|
end
|
72
95
|
end
|
73
96
|
rescue => e
|
@@ -93,7 +116,7 @@ module Git
|
|
93
116
|
processor.create(options.output)
|
94
117
|
end
|
95
118
|
|
96
|
-
def
|
119
|
+
def fill_files
|
97
120
|
branch = Git::Age::Options.instance.branch
|
98
121
|
STDOUT.puts "Reading files info from #{branch} branch ..."
|
99
122
|
|
@@ -109,6 +132,24 @@ module Git
|
|
109
132
|
io.read
|
110
133
|
end.match?(/\Atext/)
|
111
134
|
end
|
135
|
+
|
136
|
+
def show_stats
|
137
|
+
stats = Git::Age::Stats.new(self)
|
138
|
+
first = Date.parse(stats.first_commit)
|
139
|
+
last = Date.parse(stats.last_commit)
|
140
|
+
diff = (last - first).to_i + 1
|
141
|
+
ustats = stats.unchanged_stats
|
142
|
+
|
143
|
+
puts "First commit in: #{first}"
|
144
|
+
puts "Last commit in: #{last}"
|
145
|
+
puts "Repository has #{diff} days with commits"
|
146
|
+
puts "Month with more code lines unchanged: #{ustats[:bigger][:date]} (#{ustats[:bigger][:lines]} lines)"
|
147
|
+
|
148
|
+
if @test_regexp && @code_regexp
|
149
|
+
ratio = stats.code_to_test_ratio
|
150
|
+
puts "Code to test ratio: 1:#{ratio[:ratio]} (#{ratio[:code]}/#{ratio[:test]})"
|
151
|
+
end
|
152
|
+
end
|
112
153
|
end
|
113
154
|
end
|
114
155
|
end
|
data/lib/git/age/options.rb
CHANGED
@@ -4,7 +4,7 @@ module Git
|
|
4
4
|
module Age
|
5
5
|
class Options
|
6
6
|
include Singleton
|
7
|
-
attr_accessor :branch, :output, :title, :processor, :image, :xtitle, :ytitle, :map
|
7
|
+
attr_accessor :branch, :output, :title, :processor, :image, :xtitle, :ytitle, :map, :test, :code, :type
|
8
8
|
|
9
9
|
def initialize
|
10
10
|
@branch = 'master'
|
@@ -14,6 +14,9 @@ module Git
|
|
14
14
|
@image = 'git-age.png'
|
15
15
|
@xtitle = 'Dates'
|
16
16
|
@ytitle = 'Lines'
|
17
|
+
@test = nil
|
18
|
+
@code = nil
|
19
|
+
@type = 'bar'
|
17
20
|
@map = false
|
18
21
|
end
|
19
22
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Git
|
2
|
+
module Age
|
3
|
+
class Stats
|
4
|
+
def initialize(data)
|
5
|
+
@data = data
|
6
|
+
end
|
7
|
+
|
8
|
+
def first_commit
|
9
|
+
commit_date('--reverse')
|
10
|
+
end
|
11
|
+
|
12
|
+
def last_commit
|
13
|
+
commit_date
|
14
|
+
end
|
15
|
+
|
16
|
+
def unchanged_stats
|
17
|
+
max = @data.dates.max_by { |key, value| value[:code] }
|
18
|
+
{ bigger: { date: max[0], lines: max[1][:code] } }
|
19
|
+
end
|
20
|
+
|
21
|
+
def code_to_test_ratio
|
22
|
+
stats = @data.dates.reduce({code: 0, test: 0}) do |memo, data|
|
23
|
+
memo[:code] += data[1][:code]
|
24
|
+
memo[:test] += data[1][:test]
|
25
|
+
memo
|
26
|
+
end
|
27
|
+
|
28
|
+
{ code: stats[:code], test: stats[:test], ratio: (stats[:test].to_f / stats[:code].to_f).round(2) }
|
29
|
+
rescue
|
30
|
+
{ code: 0, test: 0, ratio: 0.0 }
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def commit_date(order = nil)
|
36
|
+
cmd = "git log #{order} --pretty=format:%ad --date=short | head -n1"
|
37
|
+
|
38
|
+
IO.popen(cmd) do |io|
|
39
|
+
io.read.chomp.strip
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/git/age/version.rb
CHANGED
data/lib/git/age.rb
CHANGED
data.tar.gz.sig
CHANGED
@@ -1,4 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
v��wG��Y^�CT<_�v�(q����8w9p�ٞ�����1�A�IFF#j�7Qh����(�Ll�&�k��
|
4
|
-
��Im�J��E;s��4%/4������敃�M�˘]��O��+y�b�[p��`�
|
1
|
+
M��Ŏ���;u��r���ࡅ��Tߞ>��$J^���D��!�d?���z"V@@Pd�����z
|
2
|
+
���wڢ�5�"��KONOA1�Q �(,�C ��OF�ߴ�����3i���_������y[ԈrP��1`tH��M#g�|�'8���+�I���!a��,�Wg�Z����F�'���3���\c�n$��
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: git-age
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eustaquio Rangel
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- |
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
7NRJmY9c84Zb3sCf0DV6UH+d2id9Dndp9ewchgDOSwGznt+oJmjDFZ9gYd8IP2Ol
|
37
37
|
1eLrW8x4LHV+EVEIaiVTvmKt
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date: 2022-
|
39
|
+
date: 2022-12-22 00:00:00.000000000 Z
|
40
40
|
dependencies: []
|
41
41
|
description: Check all the repository files lines dates and group it by year and month,
|
42
42
|
allowing check how old code is still in use
|
@@ -58,17 +58,19 @@ files:
|
|
58
58
|
- bin/setup
|
59
59
|
- gem-public_cert.pem
|
60
60
|
- git-age.gemspec
|
61
|
+
- graph-cli.png
|
61
62
|
- lib/git/age.rb
|
62
63
|
- lib/git/age/graph_cli.rb
|
63
64
|
- lib/git/age/main.rb
|
64
65
|
- lib/git/age/options.rb
|
66
|
+
- lib/git/age/stats.rb
|
65
67
|
- lib/git/age/version.rb
|
66
68
|
homepage: https://github.com/taq/git-age
|
67
69
|
licenses: []
|
68
70
|
metadata:
|
69
71
|
homepage_uri: https://github.com/taq/git-age
|
70
72
|
source_code_uri: https://github.com/taq/git-age
|
71
|
-
post_install_message:
|
73
|
+
post_install_message:
|
72
74
|
rdoc_options: []
|
73
75
|
require_paths:
|
74
76
|
- lib
|
@@ -83,8 +85,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
85
|
- !ruby/object:Gem::Version
|
84
86
|
version: '0'
|
85
87
|
requirements: []
|
86
|
-
rubygems_version: 3.3.
|
87
|
-
signing_key:
|
88
|
+
rubygems_version: 3.3.3
|
89
|
+
signing_key:
|
88
90
|
specification_version: 4
|
89
91
|
summary: Create a CSV file with line year and month from your Git repository
|
90
92
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|