gitalytics 1.3.0 → 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,63 @@
1
+ - require 'haml_helper'
2
+ !!!
3
+ %html{lang: "en"}
4
+ %head
5
+ %meta{content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/
6
+ %meta{charset: "utf-8"}/
7
+ %meta{content: "IE=edge", "http-equiv" => "X-UA-Compatible"}/
8
+ %meta{content: "width=device-width, initial-scale=1.0", name: "viewport"}/
9
+ %meta{content: "Gitalytics Report", name: "description"}/
10
+ %meta{content: "Gonzalo Robaina", name: "author"}/
11
+ %title Gitalytics report
12
+ / Bootstrap core CSS
13
+ %link{crossorigin: "anonymous", href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css", integrity: "sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7", rel: "stylesheet"}/
14
+ %link{crossorigin: "anonymous", href: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css", integrity: "sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r", rel: "stylesheet"}/
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
+ = render :css
20
+ %body
21
+ / Wrap all page content here
22
+ #wrap
23
+ / Fixed navbar
24
+ .navbar.navbar-default.navbar-fixed-top{role: "navigation"}
25
+ .container
26
+ .navbar-header
27
+ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
28
+ %span.sr-only Toggle navigation
29
+ %span.icon-bar
30
+ %span.icon-bar
31
+ %span.icon-bar
32
+ %a.navbar-brand{href: "https://rubygems.org/gems/gitalytics"} Gitalytics
33
+ .collapse.navbar-collapse
34
+ %ul.nav.navbar-nav
35
+ %li.active
36
+ %a{data: {toggle: :tab}, href: "#dashboard"} Dashboard
37
+ %li
38
+ %a{data: {toggle: :tab}, href: "#authors"} Authors
39
+ %li
40
+ %a{data: {toggle: :tab}, href: "#commits"} Commits
41
+ %li
42
+ %a{data: {toggle: :tab}, href: "#dates"} Dates
43
+ / <li><a href="#contact">Contact</a></li>
44
+ / /.nav-collapse
45
+ / Begin page content
46
+ .container
47
+ .tab-content
48
+ = render :dashboard, users: @users, commits: @commits
49
+ = render :authors, users: @users
50
+ = render :commits, commits: @commits
51
+ = render :dates, commits: @commits
52
+ #footer
53
+ .container
54
+ %p.text-muted
55
+ Gitalytics v#{Gitalytics::VERSION} by
56
+ %a{href: "http://gonzalo.robaina.me"} Gonzalo Robaina
57
+ /
58
+ External JavaScript Files
59
+ \==================================================
60
+ %script{src: "https://code.jquery.com/jquery-2.2.4.min.js"}
61
+ %script{crossorigin: "anonymous", integrity: "sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS", src: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"}
62
+ %script{src: "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.min.js"}
63
+ = render :javascript, { users: @users, weekday_commits: @weekday_commits }
@@ -4,37 +4,46 @@
4
4
  Encoding.default_external = Encoding::UTF_8
5
5
  $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
6
6
 
7
+ require 'benchmark'
7
8
  require 'optparse'
8
9
  require 'gitalytics'
9
10
 
10
11
  options = {
12
+ benchmark: false,
11
13
  browser: false,
12
14
  format: 'cli',
13
15
  group_by: 'name'
14
16
  }
15
17
 
16
18
  OptionParser.new do |opts|
17
- opts.banner = "Usage: gitalytics [options]"
19
+ opts.banner = 'Usage: gitalytics [options]'
18
20
 
19
- opts.on("-v", "--version", "Display gem version") do |v|
21
+ opts.on('-v', '--version', 'Display gem version') do
20
22
  p "Gitalytics #{Gitalytics::VERSION}"
21
23
  exit
22
24
  end
23
25
 
24
- opts.on("-h", "--html", "Outputs html report and displays it in default web browser") do |v|
26
+ opts.on('-h', '--html', 'Outputs html report and displays it in default web browser') do
25
27
  options[:format] = 'html'
26
28
  options[:browser] = true
27
29
  end
28
30
 
29
- opts.on("-n", "--no-browser", "Do not open html report in browser") do |v|
31
+ opts.on('-n', '--no-browser', 'Do not open html report in browser') do
30
32
  options[:format] = 'html'
31
33
  options[:browser] = false
32
34
  end
33
35
 
34
- opts.on("-e", "--group-email", "Group commits by author's email address") do |v|
36
+ opts.on('-e', '--group-email', "Group commits by author's email address") do
35
37
  options[:group_by] = 'email'
36
38
  end
39
+
40
+ opts.on('-b', '--benchmark', 'Benchmark gitalytics') do
41
+ options[:benchmark] = true
42
+ end
37
43
  end.parse!
38
44
 
39
- Dir.chdir($1 || '.')
40
- Gitalytics.analyze(options)
45
+ if options[:benchmark]
46
+ puts Benchmark.measure { Gitalytics.analyze(options) }
47
+ else
48
+ Gitalytics.analyze(options)
49
+ end
@@ -4,25 +4,27 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'gitalytics/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "gitalytics"
7
+ spec.name = 'gitalytics'
8
8
  spec.version = Gitalytics::VERSION
9
9
 
10
- spec.authors = ["Gonzalo Robaina"]
11
- spec.email = "gonzalor@gmail.com"
10
+ spec.authors = ['Gonzalo Robaina']
11
+ spec.email = 'gonzalo@robaina.me'
12
12
 
13
- spec.summary = "Git Analytics"
14
- spec.description = "Get usefull analytics from your git log"
15
- spec.homepage = "http://gonza.uy/gitalytics"
16
- spec.license = "MIT"
13
+ spec.summary = 'Git Analytics'
14
+ spec.description = 'Get usefull analytics from your git log'
15
+ spec.homepage = 'http://gonza.uy/gitalytics'
16
+ spec.license = 'MIT'
17
17
 
18
18
  spec.files = `git ls-files -z`.split("\x0")
19
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
22
22
 
23
- spec.required_ruby_version = '>= 1.9.3'
23
+ spec.required_ruby_version = '>= 2.0.0'
24
24
 
25
- spec.add_development_dependency "bundler", "~> 1.7"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_dependency "color-generator"
25
+ spec.add_development_dependency 'bundler', '~> 1.7'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'byebug'
28
+ spec.add_dependency 'color-generator'
29
+ spec.add_dependency 'haml'
28
30
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'erb'
3
+ require 'haml'
4
4
  require 'matrix'
5
5
  require 'gitalytics/commit'
6
6
  require 'gitalytics/gitlog'
@@ -8,6 +8,7 @@ require 'gitalytics/user'
8
8
  require 'gitalytics/version'
9
9
 
10
10
  module Gitalytics
11
+ OUTPUT_FILE = 'gitalytics_result.html'.freeze
11
12
 
12
13
  module_function
13
14
 
@@ -32,31 +33,35 @@ module Gitalytics
32
33
  end
33
34
  end
34
35
 
36
+ def prepare_data(data)
37
+ @users = data[:users].sort { |x, y| y.commits.length <=> x.commits.length }
38
+ @commits = data[:commits]
39
+ weekday_commits = @users.map(&:weekday_commits)
40
+ @weekday_commits = weekday_commits.map { |a| Vector[*a] }.inject(:+).to_a
41
+ end
42
+
43
+ def template_file
44
+ dir = File.dirname(__FILE__)
45
+ filepath = File.join(dir, '..', 'assets', 'gitalytics.html.haml')
46
+ File.read(filepath)
47
+ end
48
+
35
49
  def output_html_report(data, open_in_browser)
36
- template_file = File.read(File.join(File.dirname(__FILE__), "..", "assets", "gitalytics.html.erb"))
37
- erb = ERB.new(template_file)
38
- output_file = "gitalytics_result.html"
39
- File.open(output_file, 'w+') do |file|
40
- @users = data[:users].sort do |x, y|
41
- y.commits.length <=> x.commits.length
42
- end
43
- @commits = data[:commits]
44
- weekday_commits = @users.map(&:weekday_commits)
45
- @weekday_commits = weekday_commits.map { |a| Vector[*a] }.inject(:+).to_a
46
-
47
- file.write(erb.result(binding))
50
+ File.open(OUTPUT_FILE, 'w+') do |file|
51
+ prepare_data(data)
52
+ file.write(Haml::Engine.new(template_file).render(self))
48
53
  end
49
- open_report_in_browser(output_file) if open_in_browser
54
+ open_report_in_browser if open_in_browser
50
55
  end
51
56
 
52
- def open_report_in_browser(filename)
53
- host = RbConfig::CONFIG['host_os']
54
- if host =~ /mswin|mingw|cygwin/
55
- system "start #{filename}"
56
- elsif host =~ /darwin/
57
- system "open #{filename}"
58
- elsif host =~ /linux|bsd/
59
- system "xdg-open #{filename}"
57
+ def open_report_in_browser
58
+ case RbConfig::CONFIG['host_os']
59
+ when /mswin|mingw|cygwin/
60
+ system "start #{OUTPUT_FILE}"
61
+ when /darwin/
62
+ system "open #{OUTPUT_FILE}"
63
+ when /linux|bsd/
64
+ system "xdg-open #{OUTPUT_FILE}"
60
65
  end
61
66
  end
62
67
  end
@@ -1,5 +1,4 @@
1
1
  class Commit
2
-
3
2
  attr_accessor :hash, :author, :date, :subject, :summary
4
3
 
5
4
  def initialize(hash)
@@ -8,15 +7,14 @@ class Commit
8
7
  end
9
8
 
10
9
  def insertions
11
- summary.inject(0) { |total, current| total + current[:insertions] }
10
+ summary.inject(0) { |a, e| a + e[:insertions] }
12
11
  end
13
12
 
14
13
  def deletions
15
- summary.inject(0) { |total, current| total + current[:deletions] }
14
+ summary.inject(0) { |a, e| a + e[:deletions] }
16
15
  end
17
16
 
18
17
  def files_committed
19
- summary.map{ |s| s[:filename] }
18
+ summary.map { |s| s[:filename] }
20
19
  end
21
-
22
20
  end
@@ -3,20 +3,19 @@ require 'gitalytics/user'
3
3
  require 'date'
4
4
 
5
5
  module GitLog
6
-
7
6
  module_function
8
7
 
9
- def parse_git_log(group_by)
10
- users, commits = [], []
8
+ @users = []
9
+ @commits = []
11
10
 
12
- log = get_log
13
- blocks = get_blocks(log)
11
+ def parse_git_log(group_by)
12
+ blocks = get_blocks(get_log)
14
13
 
15
14
  blocks.each do |(hash, block_string)|
16
- commits << parse_block(hash, block_string, users, group_by)
15
+ @commits << parse_block(hash, block_string, group_by)
17
16
  end
18
17
 
19
- {users: users, commits: commits}
18
+ { users: @users, commits: @commits }
20
19
  end
21
20
 
22
21
  def get_log
@@ -25,13 +24,13 @@ module GitLog
25
24
 
26
25
  def get_blocks(log_string)
27
26
  commits = log_string.scan(/^([a-f0-9]{40})/).map(&:first)
28
- blocks = log_string.split(/^[a-f0-9]{40}/).map(&:strip)
27
+ blocks = log_string.split(/^[a-f0-9]{40}/).map(&:strip)
29
28
  blocks.shift # get rid of first empty string
30
29
 
31
30
  commits.zip(blocks)
32
31
  end
33
32
 
34
- def parse_block(hash, block_string, users, group_by)
33
+ def parse_block(hash, block_string, group_by)
35
34
  commit = Commit.new(hash)
36
35
 
37
36
  block_string.encode!('UTF-8', 'UTF8-MAC') if defined?(Encoding::UTF8_MAC)
@@ -41,41 +40,39 @@ module GitLog
41
40
  commit.subject = data[:subject]
42
41
  commit.date = Date.parse(data[:date])
43
42
 
44
- get_commit_author(data, commit, users, group_by)
43
+ get_commit_author(data, commit, group_by)
45
44
  get_commit_summary(block_string, commit)
46
45
 
47
46
  commit
48
47
  end
49
48
 
50
49
  def get_commit_summary(block_string, commit)
51
- block_string.scan(/^(?<insertions>\d+)\s+(?<deletions>\d+)\s+(?<filename>.*)$/).each do |summary|
50
+ regex = /^(?<insertions>\d+)\s+(?<deletions>\d+)\s+(?<filename>.*)$/
51
+ block_string.scan(regex).each do |summary|
52
52
  commit.summary << {
53
53
  insertions: summary[0].to_i,
54
54
  deletions: summary[1].to_i,
55
- filename: summary[2],
55
+ filename: summary[2]
56
56
  }
57
57
  end
58
58
  end
59
59
 
60
- def get_commit_author(data, commit, users, group_by)
61
- user = get_user(data[:name], data[:email], users, group_by)
60
+ def get_commit_author(data, commit, group_by)
61
+ user = get_user(data[:name], data[:email], group_by)
62
62
 
63
63
  commit.author = user
64
64
  user.commits << commit
65
65
  end
66
66
 
67
- def get_user(name, email, users, group_by)
68
- if group_by == 'name'
69
- users.each do |user|
70
- return user if user.name == name
71
- end
72
- elsif group_by == 'email'
73
- users.each do |user|
74
- return user if user.email == email
75
- end
67
+ def get_user(name, email, group_by)
68
+ case group_by
69
+ when 'name'
70
+ u = @users.index { |user| user.name == name }
71
+ when 'email'
72
+ u = @users.index { |user| user.email == email }
76
73
  end
77
- users << new_user = User.new(name, email)
74
+ return @users[u] if u
75
+ @users << new_user = User.new(name, email)
78
76
  new_user
79
77
  end
80
-
81
78
  end
@@ -2,14 +2,15 @@ require 'color-generator'
2
2
  require 'digest/md5'
3
3
 
4
4
  class User
5
-
6
5
  attr_accessor :name, :email, :commits, :colors
7
6
 
8
7
  def initialize(name, email)
9
- self.name = name
10
- self.email = email
8
+ self.name = name
9
+ self.email = email
11
10
  self.commits = []
12
- self.colors = ColorGenerator.new(saturation: 0.3, lightness: 0.75).create_rgb.join(', ')
11
+ self.colors = ColorGenerator.new(saturation: 0.3, lightness: 0.75)
12
+ .create_rgb
13
+ .join(', ')
13
14
  end
14
15
 
15
16
  def gravatar
@@ -33,11 +34,11 @@ class User
33
34
  end
34
35
 
35
36
  def total_insertions
36
- commits.map(&:insertions).inject(0) { |total, current| total + current }
37
+ commits.map(&:insertions).inject(0) { |a, e| a + e }
37
38
  end
38
39
 
39
40
  def total_deletions
40
- commits.map(&:deletions).inject(0) { |total, current| total + current }
41
+ commits.map(&:deletions).inject(0) { |a, e| a + e }
41
42
  end
42
43
 
43
44
  def total_changes
@@ -45,7 +46,8 @@ class User
45
46
  end
46
47
 
47
48
  def summary
48
- "#{name} has made #{commits.count} commits on #{working_days} separate days during a span of #{commits_period} days."
49
+ "#{name} has made #{commits.count} commits on #{working_days} "\
50
+ "separate days during a span of #{commits_period} days."
49
51
  end
50
52
 
51
53
  def rgba(opacity = 1)
@@ -53,10 +55,8 @@ class User
53
55
  end
54
56
 
55
57
  def weekday_commits
56
- days = Array.new(7) {0}
57
- commits.each do |c|
58
- days[c.date.wday] += 1
59
- end
58
+ days = Array.new(7) { 0 }
59
+ commits.each { |c| days[c.date.wday] += 1 }
60
60
  days
61
61
  end
62
62
  end
@@ -1,3 +1,3 @@
1
1
  module Gitalytics
2
- VERSION = "1.3.0"
2
+ VERSION = "1.3.1"
3
3
  end
@@ -0,0 +1,8 @@
1
+ module Haml::Helpers
2
+ def render(partial, locals = {})
3
+ dir = File.dirname(__FILE__)
4
+ filepath = File.join(dir, '..', 'assets', "_#{partial}.html.haml")
5
+ file = File.read(filepath)
6
+ Haml::Engine.new(file).render(Object.new, locals)
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ 2013-02-13 23:11:16 -0200 Gonzalo Robaina <gonzalor@gmail.com> Print basic commit report on the console
2
+
3
+ 6 1 bin/gitalytics
4
+ 33 6 lib/gitalytics.rb
@@ -0,0 +1,4 @@
1
+ 2012-12-19 06:04:59 -0800 Gonzalo Robaina <gonzalor@gmail.com> Initial commit
2
+
3
+ 16 0 .gitignore
4
+ 4 0 README.md
@@ -0,0 +1,7 @@
1
+ 2012-12-06 10:29:49 -0200 Gonzalo Robaina <gonzalor@gmail.com> initial commit
2
+
3
+ 1 0 README.md
4
+ 3 0 bin/gitalytics
5
+ 13 0 gitalytics.gemspec
6
+ 49 0 lib/gist.rb
7
+ 11 0 lib/gitalytics.rb
@@ -0,0 +1,15 @@
1
+ bea63e76c7c6d5afd42ac5b24a911b36e5c261f9 2013-02-13 23:11:16 -0200 Gonzalo Robaina <gonzalor@gmail.com> Print basic commit report on the console
2
+
3
+ 6 1 bin/gitalytics
4
+ 33 6 lib/gitalytics.rb
5
+ d392710a9e657c72e73ca87df3ed2c8c802441e4 2012-12-19 06:04:59 -0800 Gonzalo Robaina <gonzalor@gmail.com> Initial commit
6
+
7
+ 16 0 .gitignore
8
+ 4 0 README.md
9
+ 9a99ae5dbc1eaadf268ca925cce9b68d10216151 2012-12-06 10:29:49 -0200 Gonzalo Robaina <gonzalor@gmail.com> initial commit
10
+
11
+ 1 0 README.md
12
+ 3 0 bin/gitalytics
13
+ 13 0 gitalytics.gemspec
14
+ 49 0 lib/gist.rb
15
+ 11 0 lib/gitalytics.rb