gitalytics 0.0.2 → 1.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: cce45293feabfcfb6ee420eab9cfac9d300e6c60
4
+ data.tar.gz: 8186c38edf85d533bc7e93be902723556d9f2785
5
+ SHA512:
6
+ metadata.gz: db1c0258b22930f52b8add537e0d140c84b371e408d8bed6b47dc88edcfaff01b43cbc0f46da024bb0e35514e73252151eb5486e55c223ee5224aa4966369ebd
7
+ data.tar.gz: b23d34ab57f25adffdf315edc2d81056287ed9fc79b043c74ed6011f54ae3740da5d37c8655df69bf02e564b952dccea3eaa9a25cc16714ab0361494cf678c98
@@ -0,0 +1,161 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <meta name="description" content="">
8
+ <meta name="author" content="">
9
+
10
+ <title>Gitalytics report</title>
11
+
12
+ <!-- Bootstrap core CSS -->
13
+ <link href="http://netdna.bootstrapcdn.com/bootswatch/3.0.3/cerulean/bootstrap.min.css" rel="stylesheet">
14
+
15
+ <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
16
+ <!--[if lt IE 9]>
17
+ <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
18
+ <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
19
+ <![endif]-->
20
+
21
+ <style>
22
+ /* Sticky footer styles
23
+ -------------------------------------------------- */
24
+
25
+ html,
26
+ body {
27
+ height: 100%;
28
+ /* The html and body elements cannot have any padding or margin. */
29
+ }
30
+
31
+ /* Wrapper for page content to push down footer */
32
+ #wrap {
33
+ min-height: 100%;
34
+ height: auto;
35
+ /* Negative indent footer by its height */
36
+ margin: 0 auto -60px;
37
+ /* Pad bottom by footer height */
38
+ padding: 0 0 60px;
39
+ }
40
+
41
+ /* Set the fixed height of the footer here */
42
+ #footer {
43
+ height: 60px;
44
+ background-color: #f5f5f5;
45
+ }
46
+
47
+
48
+ /* Custom page CSS
49
+ -------------------------------------------------- */
50
+ /* Not required for template or sticky footer method. */
51
+
52
+ #wrap > .container {
53
+ padding: 60px 15px 0;
54
+ }
55
+ .container .text-muted {
56
+ margin: 20px 0;
57
+ }
58
+
59
+ #footer > .container {
60
+ padding-left: 15px;
61
+ padding-right: 15px;
62
+ }
63
+
64
+ .media {
65
+ margin-bottom: 20px;
66
+ }
67
+
68
+ .dp {
69
+ box-sizing: border-box;
70
+ border:10px solid #eee;
71
+ transition: all 0.2s ease-in-out;
72
+ }
73
+
74
+ .dp:hover {
75
+ border:2px solid #eee;
76
+ transform:rotate(360deg);
77
+ -ms-transform:rotate(360deg);
78
+ -webkit-transform:rotate(360deg);
79
+ /*-webkit-font-smoothing:antialiased;*/
80
+ }
81
+
82
+ </style>
83
+ </head>
84
+
85
+ <body>
86
+
87
+ <!-- Wrap all page content here -->
88
+ <div id="wrap">
89
+
90
+ <!-- Fixed navbar -->
91
+ <div class="navbar navbar-default navbar-fixed-top" role="navigation">
92
+ <div class="container">
93
+ <div class="navbar-header">
94
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
95
+ <span class="sr-only">Toggle navigation</span>
96
+ <span class="icon-bar"></span>
97
+ <span class="icon-bar"></span>
98
+ <span class="icon-bar"></span>
99
+ </button>
100
+ <a class="navbar-brand" href="#">Gitalytics</a>
101
+ </div>
102
+ <div class="collapse navbar-collapse">
103
+ <ul class="nav navbar-nav">
104
+ <li class="active"><a href="#">Users</a></li>
105
+ <!-- <li><a href="#about">About</a></li>
106
+ <li><a href="#contact">Contact</a></li> -->
107
+ </ul>
108
+ </div><!--/.nav-collapse -->
109
+ </div>
110
+ </div>
111
+
112
+ <!-- Begin page content -->
113
+ <div class="container">
114
+ <div class="page-header">
115
+ <h1>User stats</h1>
116
+ <p class="lead">Compare the quantity of commits made by each of your repository contributors.<br/> Check who is writing most of the code of your project and maybe give him/her a prize! ;)</p>
117
+ </div>
118
+
119
+ <div class="col-md-5">
120
+ <canvas id="myChart" width="400" height="400"></canvas>
121
+ </div>
122
+ <div class="col-md-7">
123
+ <% @data[:users].each_with_index do |user, i| %>
124
+ <div class="col-md-6">
125
+ <div class="media">
126
+ <a class="pull-left" href="#">
127
+ <img class="media-object dp img-circle" src="<%= "http://www.gravatar.com/avatar/#{user[:gravatar]}" %>" style="width: 100px; height:100px; border-color:<%= "##{user[:color]}" %>">
128
+ </a>
129
+ <div class="media-body">
130
+ <h4 class="media-heading"><%= user[:name] %></h4>
131
+ <hr style="margin:8px auto">
132
+ <%= "#{user[:commits].count} commits between #{(user[:last_date] - user[:first_date]).to_i + 1} days." %>
133
+ <%= "He did something useful on #{user[:working_days]} of those days." %>
134
+ </div>
135
+ </div>
136
+ </div>
137
+ <% end %>
138
+ </div>
139
+ </div>
140
+ </div>
141
+
142
+ <div id="footer">
143
+ <div class="container">
144
+ <p class="text-muted">Gitalytics by <a href="http://gonzalo.robaina.me">Gonzalo Robaina</a></p>
145
+ </div>
146
+ </div>
147
+
148
+
149
+ <!-- Bootstrap core JavaScript
150
+ ================================================== -->
151
+ <!-- Placed at the end of the document so the pages load faster -->
152
+ <script src="https://code.jquery.com/jquery-1.10.2.min.js"></script>
153
+ <script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
154
+ <script src="http://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js"></script>
155
+ <script>
156
+ var data = [<%= @data[:users].map{|d| "{ value: #{d[:commits].count}, color: '##{d[:color]}' }" }.join(',') %>];
157
+ var ctx = document.getElementById("myChart").getContext("2d");
158
+ var myNewChart = new Chart(ctx).Pie(data);
159
+ </script>
160
+ </body>
161
+ </html>
data/bin/gitalytics CHANGED
@@ -1,7 +1,22 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'optparse'
2
3
  require File.expand_path("../../lib/gitalytics.rb", __FILE__)
3
4
 
5
+ options = {
6
+ format: 'cli'
7
+ }
8
+ OptionParser.new do |opts|
9
+ opts.banner = "Usage: gitalytics [options]"
10
+
11
+ opts.on("-v", "--version", "Display gem version") do |v|
12
+ p "Gitalytics #{Gitalytics::VERSION}"
13
+ exit
14
+ end
15
+
16
+ opts.on("-h", "--html", "Outputs html report") do |v|
17
+ options[:format] = 'html'
18
+ end
19
+ end.parse!
20
+
4
21
  Dir.chdir($1 || '.')
5
- g = Gitalytics.new
6
- res = g.log_to_hash
7
- g.output_summary_report(res)
22
+ Gitalytics.new.analyze(options)
data/lib/gitalytics.rb CHANGED
@@ -1,40 +1,69 @@
1
1
  require 'date'
2
+ require 'erb'
3
+ require 'digest/md5'
2
4
 
3
5
  class Gitalytics
6
+
7
+ VERSION = '1.0.1'
8
+
9
+ attr_accessor :data
10
+
11
+ def initialize
12
+ @data = {}
13
+ end
14
+
15
+ def analyze(options)
16
+ log_to_hash
17
+ case options[:format]
18
+ when 'html'
19
+ output_html_report
20
+ else
21
+ output_cli_report
22
+ end
23
+ end
24
+
25
+ private
4
26
  def log_to_hash
5
27
  lines = []
6
- command = "git log --pretty='%cn|%cd|%s'"
28
+ command = "git log --pretty='%cn|%ce|%cd|%s'"
7
29
  result = `#{command}`
8
30
 
9
31
  result.each_line do |line|
10
32
  parts = line.split('|')
11
- lines << {:username => parts[0], :date => Date.parse(parts[1]), :subject => parts[2]}
33
+ lines << { name: parts[0], email: parts[1], date: Date.parse(parts[2]), subject: parts[3]}
12
34
  end
13
35
 
14
- return {
15
- :users => lines.map{|r| r[:username]}.uniq,
16
- :dates => lines.map{|r| r[:date]}.uniq,
17
- :records => lines
18
- }
36
+ @data[:users] = get_user_data(lines)
19
37
  end
20
38
 
21
- def output_summary_report(res)
22
- # Report how many commits over time
23
- res[:users].each do |user|
24
- dates_for_user = res[:records].select{|r| r[:username] == user}.map{|r| r[:date]}
25
- commit_count = dates_for_user.count
26
- date_count = dates_for_user.uniq.count
27
- first_date = dates_for_user.min
28
- last_date = dates_for_user.max
29
- puts "#{user} has made #{commit_count} commits over the last #{last_date-first_date} days. He did something useful on #{date_count} of those days."
39
+ def output_cli_report
40
+ @data[:users].each do |user|
41
+ puts "#{user[:name]} has made #{user[:commits].count} commits between #{(user[:last_date] - user[:first_date]).to_i + 1} days. He did something useful on #{user[:working_days]} of those days."
30
42
  end
31
43
  end
32
- end
33
44
 
34
- # class Commit
35
- # attr_accesor :author, :message, :date
36
- # end
45
+ def output_html_report
46
+ template_file = File.read(File.join(File.dirname(__FILE__), "..", "assets", "gitalytics.html.erb"))
47
+ erb = ERB.new(template_file)
48
+ File.open("gitalytics_result.html", 'w+') { |file| file.write(erb.result(binding)) }
49
+ end
37
50
 
38
- # class Author
39
- # attr_accesor :name, :email
40
- # end
51
+ def get_user_data(lines)
52
+ users = lines.map{ |r| [r[:name], r[:email]] }.uniq
53
+ users.map{ |u|
54
+ commits = lines.select{ |r| r[:name] == u[0] }
55
+ dates = commits.map{ |c| c[:date] }
56
+ {
57
+ name: u[0],
58
+ email: u[1],
59
+ gravatar: Digest::MD5.hexdigest(u[1]),
60
+ color: "%06x" % (rand * 0xffffff),
61
+ commits: commits,
62
+ first_date: dates.min,
63
+ last_date: dates.max,
64
+ working_days: dates.uniq.count
65
+ }
66
+ }
67
+ end
68
+
69
+ end
metadata CHANGED
@@ -1,66 +1,47 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: gitalytics
3
- version: !ruby/object:Gem::Version
4
- hash: 27
5
- prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
11
5
  platform: ruby
12
- authors:
6
+ authors:
13
7
  - Gonzalo Robaina
14
8
  autorequire:
15
9
  bindir: bin
16
10
  cert_chain: []
17
-
18
- date: 2013-12-27 00:00:00 Z
11
+ date: 2013-12-27 00:00:00.000000000 Z
19
12
  dependencies: []
20
-
21
13
  description: Get usefull analytics from your git log
22
14
  email: gonzalor@gmail.com
23
- executables:
15
+ executables:
24
16
  - gitalytics
25
17
  extensions: []
26
-
27
18
  extra_rdoc_files: []
28
-
29
- files:
19
+ files:
30
20
  - lib/gitalytics.rb
21
+ - assets/gitalytics.html.erb
31
22
  - bin/gitalytics
32
23
  homepage: http://rubygems.org/gems/gitalytics
33
- licenses:
24
+ licenses:
34
25
  - MIT
26
+ metadata: {}
35
27
  post_install_message:
36
28
  rdoc_options: []
37
-
38
- require_paths:
29
+ require_paths:
39
30
  - lib
40
- required_ruby_version: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ">="
44
- - !ruby/object:Gem::Version
45
- hash: 3
46
- segments:
47
- - 0
48
- version: "0"
49
- required_rubygems_version: !ruby/object:Gem::Requirement
50
- none: false
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- hash: 3
55
- segments:
56
- - 0
57
- version: "0"
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
58
41
  requirements: []
59
-
60
42
  rubyforge_project:
61
- rubygems_version: 1.8.24
43
+ rubygems_version: 2.1.10
62
44
  signing_key:
63
- specification_version: 3
45
+ specification_version: 4
64
46
  summary: Git Analytics
65
47
  test_files: []
66
-