gitalytics 0.0.2 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
-