contributors 0.1.2 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,3 +1,10 @@
1
+ = Version 0.2
2
+ * Rewritten using Grit.
3
+ * Ignored patterns don't work anymore.
4
+ * Contributors#results takes the criterium for counting
5
+ lines of code as the second argument. It can be either
6
+ :additions, :deletions or :total, which is the default value.
7
+
1
8
  = Version 0.1
2
9
  * The actual library.
3
10
  * Nake tasks for generating CONTRIBUTORS.
data/README.textile CHANGED
@@ -17,13 +17,19 @@ require "contributors"
17
17
 
18
18
  contributors = Contributors.new
19
19
  contributors.results
20
- # => {"stastny@101ideas.cz" => {:name => "Jakub Stastny aka botanicus", :commits = >3, :LOC = >219}}
20
+ # => {#<Grit::Actor "Jakub Stastny aka botanicus <stastny@101ideas.cz>"> => {:commits => 9, :LOC => 255}}
21
21
 
22
- # You can optionally specify project path and list of ignored patterns thusly:
23
- contributors = Contributors.new(Dir.pwd, [/^(vendor|gems)\//, /.+\.gem$/])
22
+ # You can optionally specify project path thusly:
23
+ contributors = Contributors.new(Dir.pwd)
24
24
 
25
- # The Contributors#result method takes an optional argument determining by which field you want to sort the results:
26
- contributors.resuls(:LOC) # or :commits
25
+ # The Contributors#result method takes an optional argument
26
+ # determining by which field you want to sort the results:
27
+ contributors.results(:LOC) # or :commits
28
+
29
+ # By default it takes all the changes (as the second argument
30
+ # defaults to :total), but if you want, you can limit changes
31
+ # on :additions or :deletions only:
32
+ contributors.results(:LOC, :additions)
27
33
  </pre>
28
34
 
29
35
  Use the "Nake":https://github.com/botanicus/nake tasks:
@@ -42,11 +48,11 @@ Task[:contributors].config[:output_path] = Proc.new { File.join(task.config[:pat
42
48
  # OPTIONAL: How to sort results, options are :commits or :LOC, :LOC is default.
43
49
  Task[:contributors].config[:sort_by] = :LOC
44
50
 
45
- # OPTIONAL: An array of regular expressions which should be ignored.
46
- # Defaults to Contributors::IGNORED_PATTERNS, which is [/^vendor\//, /^gems\//, /.+\.gem$/].
47
- Task[:contributors].config[:ignore] = Contributors::IGNORED_PATTERNS
51
+ # OPTIONAL: Criterium for counting lines of code. Can be either
52
+ # :additions, :deletions or :total (which is the default value).
53
+ Task[:contributors].config[:criterium] = :total
48
54
 
49
55
  # OPTIONAL: How to format each line. E-mail is author's e-mail and in data
50
56
  there are keys :name, :commits and :LOC. Commits and LOC are both integers.
51
- Task[:contributors].config[:format] = -> { |email, data| "#{email}: #{data[:LOC]}" }
57
+ Task[:contributors].config[:format] = -> { |author, data| "#{author.email}: #{data[:LOC]}" }
52
58
  </pre>
data/contributors.gemspec CHANGED
@@ -5,9 +5,9 @@ require "base64"
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "contributors"
8
- s.version = "0.1.2"
8
+ s.version = "0.2"
9
9
  s.authors = ["Jakub Stastny aka botanicus"]
10
- s.homepage = "http://github.com/botanicus/contributors"
10
+ s.homepage = "https://github.com/botanicus/contributors"
11
11
  s.summary = "API for getting info about contributors of a project which is in Git."
12
12
  s.description = "The contributors gem is useful for getting informations about project contributors. It assumes that Git is used. In particular it can be used for generating CONTRIBUTORS file."
13
13
  s.cert_chain = nil
@@ -33,6 +33,9 @@ Gem::Specification.new do |s|
33
33
  s.post_install_message = CHANGELOG.new.version_changes
34
34
  end
35
35
 
36
+ # Dependencies
37
+ s.add_dependency "grit"
38
+
36
39
  # RubyForge
37
40
  s.rubyforge_project = "contributors"
38
41
  end
@@ -6,9 +6,9 @@ Task.new(:contributors) do |task|
6
6
  # Settings.
7
7
  task.config[:path] = Dir.pwd
8
8
  task.config[:output_path] = Proc.new { File.join(task.config[:path], "CONTRIBUTORS") }
9
- task.config[:ignore] = nil
10
9
  task.config[:sort_by] = :LOC
11
- task.config[:format] = Proc.new { |email, data| "#{data[:name]}: #{data[:commits]} (#{data[:LOC]} LOC)" }
10
+ task.config[:criterium] = :total
11
+ task.config[:format] = Proc.new { |author, data| "#{author.name}: #{data[:commits]} commits, #{data[:LOC]} LOC" }
12
12
 
13
13
  # Helpers.
14
14
  def task.output_path
@@ -19,21 +19,20 @@ Task.new(:contributors) do |task|
19
19
  end
20
20
  end
21
21
 
22
- def task.ignored_patterns
23
- self.config[:ignore] || Contributors::IGNORED_PATTERNS
24
- end
25
-
26
22
  # Define the actual task.
27
23
  task.define do
28
24
  require "contributors"
29
25
 
30
26
  Dir.chdir(task.config[:path]) do
31
- contributors = Contributors.new(task.config[:path], task.ignored_patterns)
27
+ contributors = Contributors.new(task.config[:path])
32
28
 
33
29
  # Write the actual CONTRIBUTORS file.
34
30
  File.open(task.output_path, "w") do |file|
35
- contributors.results.each do |email, data|
36
- file.puts(task.config[:format].call(email, data))
31
+ sort_by = self.config[:sort_by]
32
+ criterium = self.config[:criterium]
33
+
34
+ contributors.results(sort_by, criterium).each do |author, data|
35
+ file.puts(task.config[:format].call(author, data))
37
36
  end
38
37
  end
39
38
  end
data/lib/contributors.rb CHANGED
@@ -1,65 +1,58 @@
1
1
  # encoding: utf-8
2
2
 
3
- # TODO: Use Grit or something rather than this black magic.
3
+ require "grit"
4
+
4
5
  class Contributors
5
- IGNORED_PATTERNS = [/^vendor\//, /^gems\//, /.+\.gem$/]
6
+ attr_reader :path
7
+ def initialize(path = Dir.pwd)
8
+ @path = path
9
+ end
6
10
 
7
- attr_reader :path, :ignored_patterns
8
- def initialize(path = Dir.pwd, ignored_patterns = IGNORED_PATTERNS)
9
- @path, @ignored_patterns = path, ignored_patterns
11
+ def repo
12
+ @repo ||= Grit::Repo.new(@path)
10
13
  end
11
14
 
12
- def list
13
- repo do
14
- authors = %x{git log | grep ^Author:}.split("\n")
15
- results = authors.reduce(Hash.new) do |results, line|
16
- line.match(/^Author: (.+) <(.+)>$/)
17
- name, email = $1, $2
18
- results[email] ||= Hash.new
19
- results[email][:name] = name
20
- results[email][:commits] ||= 0
21
- results[email][:commits] += 1
22
- results[email][:LOC] = loc[email] || 0
23
- results
24
- end
15
+ def authors_and_commits
16
+ hash = Hash.new { |hash, key| hash[key] = Array.new }
17
+ repo.commits("master", false).reduce(hash) do |buffer, commit|
18
+ key = buffer.keys.find { |author| author.email == commit.author.email }
19
+ key ||= commit.author
20
+
21
+ buffer[key] << commit
22
+ buffer
25
23
  end
26
24
  end
27
25
 
28
- def results(sort_by = :LOC)
29
- unless [:commits, :LOC].include?(sort_by)
30
- raise "Sort_by argument can be only :commits or :LOC!"
26
+ # ["additions", "deletions", "total"]
27
+ def list(criterium = :total)
28
+ unless [:additions, :deletions, :total].include?(criterium)
29
+ raise ArgumentError.new("Criterium can be one of: :additions, :deletions or :total.")
31
30
  end
32
31
 
33
- self.list.sort_by { |_, data| data[sort_by] }.reverse
34
- end
35
-
36
- private
37
- def repo(&block)
38
- Dir.chdir(@path, &block)
39
- end
32
+ authors_and_commits.reduce(Hash.new) do |buffer, pair|
33
+ author, commits = pair
34
+ buffer[author] = {
35
+ commits: commits.length,
36
+ LOC: commits.reduce(0) do |lines, commit|
37
+ lines + commit.stats.to_hash[criterium.to_s]
38
+ end
39
+ }
40
40
 
41
- def files
42
- files = %x{git ls-files}.split("\n")
43
- files.select do |path|
44
- self.ignored_patterns.any? do |pattern|
45
- not path.match(pattern)
46
- end
41
+ buffer
47
42
  end
48
43
  end
49
44
 
50
- # TODO: At the moment this are any lines, not lines of code.
51
- # {email_1 => LOC for email_1, email_2 => LOC for email_2}
52
- def loc
53
- @loc ||= begin
54
- files.reduce(Hash.new) do |buffer, path|
55
- emails = %x{git blame '#{path}' --show-email | awk '{ print $2 }' | ruby -pe '$_.sub!(/^.*<(.+)>.*$/, "\\\\1")'}
56
- emails.split("\n").each do |email|
57
- buffer[email] ||= 0
58
- buffer[email] += 1
59
- end
45
+ def results(sort_by = :LOC, criterium = :total)
46
+ unless [:commits, :LOC].include?(sort_by)
47
+ raise "Sort_by argument can be only :commits or :LOC!"
48
+ end
60
49
 
61
- buffer
62
- end
50
+ # Note: Hash#sort_by(&block) returns an Array, even on 1.9,
51
+ # which isn't really necessary, as hashes on 1.9 are sorted.
52
+ sorted_array = self.list(criterium).sort_by { |_, data| data[sort_by] }
53
+ sorted_array.reverse.reduce(Hash.new) do |buffer, pair|
54
+ author, stats = pair
55
+ buffer.merge(author => stats)
63
56
  end
64
57
  end
65
58
  end
data/tasks.rb CHANGED
@@ -5,4 +5,4 @@ $LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
5
5
 
6
6
  load "contributors.nake"
7
7
 
8
- Task[:contributors].config[:format] = Proc.new { |email, data| "#{email}: #{data.inspect}" }
8
+ Task[:contributors].config[:format] = Proc.new { |author, data| "#{author.inspect}: #{data.inspect}" }
metadata CHANGED
@@ -2,17 +2,27 @@
2
2
  name: contributors
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.2
5
+ version: "0.2"
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jakub Stastny aka botanicus
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain:
12
- date: 2011-03-13 00:00:00 +00:00
12
+ date: 2011-05-02 00:00:00 +02:00
13
13
  default_executable:
14
- dependencies: []
15
-
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: grit
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
16
26
  description: The contributors gem is useful for getting informations about project contributors. It assumes that Git is used. In particular it can be used for generating CONTRIBUTORS file.
17
27
  email: stastny@101ideas.cz
18
28
  executables: []
@@ -31,11 +41,12 @@ files:
31
41
  - lib/contributors.rb
32
42
  - tasks.rb
33
43
  has_rdoc: true
34
- homepage: http://github.com/botanicus/contributors
44
+ homepage: https://github.com/botanicus/contributors
35
45
  licenses: []
36
46
 
37
- post_install_message: "[\e[32mVersion 0.1\e[0m] The actual library.\n\
38
- [\e[32mVersion 0.1\e[0m] Nake tasks for generating CONTRIBUTORS.\n"
47
+ post_install_message: "[\e[32mVersion 0.2\e[0m] Rewritten using Grit.\n\
48
+ [\e[32mVersion 0.2\e[0m] Ignored patterns don't work anymore.\n\
49
+ [\e[32mVersion 0.2\e[0m] Contributors#results takes the criterium for counting lines of code as the second argument. It can be either :additions, :deletions or :total, which is the default value.\n"
39
50
  rdoc_options: []
40
51
 
41
52
  require_paths: