Class: Git
- Inherits:
-
Object
- Object
- Git
- Defined in:
- lib/git-stat.rb
Overview
Provides a quick wrapper around git commands in order to analyze and provide interesting statistics around a git repository
Constant Summary collapse
- UNKNOWN_TYPE =
'UNKNOWN'
Class Method Summary collapse
-
.all_stats ⇒ Object
Does Git::files_stat and then formats everything.
-
.blame(file) ⇒ Object
Executes the blame command and returns the String output.
-
.file_stat(file) ⇒ Object
Returns a hash containing some interesting stats about a file including:.
-
.files_stat ⇒ Object
This iterates over files and calls Git::file_stat on each of them.
-
.is_git_project? ⇒ Boolean
Checks if the current directory is a git project.
-
.line_count(file) ⇒ Object
Returns the number of lines in a file.
-
.ls_files ⇒ Object
Returns a list of files in the git project.
-
.merge_hash_value_counts(h1, h2) ⇒ Object
Merges two hashes containing counts together.
-
.project_name ⇒ Object
Returns the project name, which is assumed to be the current directory’s name.
-
.remote_branches ⇒ Object
Returns a list of all remote branches.
-
.sort_hash(hash) ⇒ Object
Creates a “sorted” hash by the value counts.
-
.tags ⇒ Object
Returns a list of tags.
Class Method Details
.all_stats ⇒ Object
Does Git::files_stat and then formats everything. Output will look like this:
{
'project_name' => Git::project_name(),
'total_files' => stats[:number_of_files],
'total_lines' => stats[:total_line_counts],
'file_types' => stats[:file_types],
'authors_line_count' => stats[:authors_influence],
'line_counts_by_type' => stats[:line_counts_by_type],
'branches' => Git::remote_branches(),
'tags' => Git::()
}
194 195 196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/git-stat.rb', line 194 def self.all_stats stats = files_stat() { 'project_name' => Git::project_name(), 'total_files' => stats[:number_of_files], 'total_lines' => stats[:total_line_counts], 'file_types' => stats[:file_types], 'authors_line_count' => stats[:authors_influence], 'line_counts_by_type' => stats[:line_counts_by_type], 'branches' => Git::remote_branches(), 'tags' => Git::() } end |
.blame(file) ⇒ Object
Executes the blame command and returns the String output
54 55 56 |
# File 'lib/git-stat.rb', line 54 def self.blame(file) `git blame "#{file}"` end |
.file_stat(file) ⇒ Object
Returns a hash containing some interesting stats about a file including:
-
The file
-
The file type
-
line count
-
and all the authors and the number of lines they were responsible for
It will look something like this:
{
:file => file,
:type => type,
:line_count => line_count,
:authors_influence =>
}
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/git-stat.rb', line 82 def self.file_stat(file) = {} line_count = 0 type = File.extname(file).empty? ? UNKNOWN_TYPE : File.extname(file) begin lines = blame(file).split(/\n/) line_count = lines.length lines.each do |line| if (line.match(/\((.*?)\s+[0-9]{4}-[0-9]{2}-[0-9]{2}\s+[0-9]{2}:[0-9]{2}:[0-9]{2}\s.[0-9]*\s+[0-9]*\)/)) [$1] += 1 if .has_key?($1) [$1] = 1 unless .has_key?($1) else $stderr.puts "[WARN] Did not find whom to blame on this line in file: #{file}" $stderr.flush end end rescue Exception line_count = Git::line_count(file) end { :file => file, :type => type, :line_count => line_count, :authors_influence => } end |
.files_stat ⇒ Object
This iterates over files and calls Git::file_stat on each of them. Output will look like this:
{
:number_of_files => number_of_files,
:total_line_counts => total_line_counts,
:file_types => sort_hash(types_count),
:line_counts_by_type => sort_hash(line_counts_by_type),
:authors_influence => sort_hash()
}
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/git-stat.rb', line 144 def self.files_stat files = Git::ls_files() number_of_files = files.length types_count = {} line_counts = {} line_counts_by_type = {} = {} total_line_counts = 0 file_index = 0 files.each do |file| file_index += 1 file_stat = file_stat(file) = merge_hash_value_counts(, file_stat[:authors_influence]) total_line_counts += file_stat[:line_count] if types_count.has_key?(file_stat[:type]) types_count[file_stat[:type]] += 1 line_counts_by_type[file_stat[:type]] += file_stat[:line_count] else types_count[file_stat[:type]] = 1 line_counts_by_type[file_stat[:type]] = file_stat[:line_count] end line_counts[file] = Git::line_count(file) end { :number_of_files => number_of_files, :total_line_counts => total_line_counts, :file_types => sort_hash(types_count), :line_counts_by_type => sort_hash(line_counts_by_type), :authors_influence => sort_hash() } end |
.is_git_project? ⇒ Boolean
Checks if the current directory is a git project
18 19 20 21 |
# File 'lib/git-stat.rb', line 18 def self.is_git_project? `git status` $?.success? end |
.line_count(file) ⇒ Object
Returns the number of lines in a file
61 62 63 |
# File 'lib/git-stat.rb', line 61 def self.line_count(file) `git blame "#{file}" | wc -l`.to_i end |
.ls_files ⇒ Object
Returns a list of files in the git project
33 34 35 |
# File 'lib/git-stat.rb', line 33 def self.ls_files `git ls-files`.split(/\n/) end |
.merge_hash_value_counts(h1, h2) ⇒ Object
Merges two hashes containing counts together
112 113 114 115 116 117 118 |
# File 'lib/git-stat.rb', line 112 def self.merge_hash_value_counts(h1, h2) h2.each_key.inject(h1) do |result,key| result[key] += h2[key] if result.has_key?(key) result[key] = h2[key] unless result.has_key?(key) result end end |
.project_name ⇒ Object
Returns the project name, which is assumed to be the current directory’s name
26 27 28 |
# File 'lib/git-stat.rb', line 26 def self.project_name `printf '%s\n' "${PWD##*/}"`.chomp end |
.remote_branches ⇒ Object
Returns a list of all remote branches
40 41 42 |
# File 'lib/git-stat.rb', line 40 def self.remote_branches `git branch -a | grep remotes | awk '{print $1}'`.split(/\n/) end |
.sort_hash(hash) ⇒ Object
Creates a “sorted” hash by the value counts. This is simply for easier visual output when serialized to yaml
124 125 126 127 128 129 130 |
# File 'lib/git-stat.rb', line 124 def self.sort_hash(hash) sorted_array = hash.sort_by {|k,v| v}.reverse sorted_array.inject({}) do |result,element| result[element[0]] = element[1] result end end |
.tags ⇒ Object
Returns a list of tags
47 48 49 |
# File 'lib/git-stat.rb', line 47 def self. `git tag -l`.split(/\n/) end |