git-swear-stats 0.1.0
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.
- data/LICENSE +14 -0
- data/README.md +44 -0
- data/Rakefile +3 -0
- data/bin/git-swear-stats +155 -0
- metadata +93 -0
data/LICENSE
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
2
|
+
Version 2, December 2004
|
3
|
+
|
4
|
+
Copyright (C) 2013 James Pearson
|
5
|
+
|
6
|
+
Everyone is permitted to copy and distribute verbatim or modified
|
7
|
+
copies of this license document, and changing it is allowed as long
|
8
|
+
as the name is changed.
|
9
|
+
|
10
|
+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
11
|
+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
12
|
+
|
13
|
+
0. You just DO WHAT THE FUCK YOU WANT TO.
|
14
|
+
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Inspired by [the Linux Kernel Fuck Count] and [its descendent],
|
2
|
+
`git-swear-stats` will give you some interesting statistics on swearing in a
|
3
|
+
git repository's commit messages.
|
4
|
+
|
5
|
+
[the Linux Kernel Fuck Count]: http://durak.org/sean/pubs/kfc/
|
6
|
+
[its descendent]: http://www.vidarholen.net/contents/wordcount/
|
7
|
+
|
8
|
+
# Installation
|
9
|
+
|
10
|
+
[$]> gem install git-swear-stats
|
11
|
+
|
12
|
+
# Usage
|
13
|
+
|
14
|
+
[$]> git-swear-stats --help
|
15
|
+
git-swear-stats
|
16
|
+
|
17
|
+
Usage:
|
18
|
+
git-swear-stats [options] [messages|diffs]
|
19
|
+
|
20
|
+
Options:
|
21
|
+
-h, --help Show this screen.
|
22
|
+
--debug Print out debug messages.
|
23
|
+
--include-merges Look at merge commits.
|
24
|
+
--no-progress Don't print out progress information.
|
25
|
+
|
26
|
+
# Example Output
|
27
|
+
|
28
|
+
[$]> git swear-stats
|
29
|
+
Reading in git log... done!
|
30
|
+
Parsing git log.
|
31
|
+
Overall:
|
32
|
+
+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
33
|
+
| clusterfuck | fuck | fsck | eff | shit | cunt | cock | ass | arse | bitch | wtf | fag | damn | bastard | hell |
|
34
|
+
+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
35
|
+
| 1 | 3 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 3 | 1 | 1 | 1 | 1 |
|
36
|
+
+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
37
|
+
Authors:
|
38
|
+
+---------------+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
39
|
+
| | clusterfuck | fuck | fsck | eff | shit | cunt | cock | ass | arse | bitch | wtf | fag | damn | bastard | hell |
|
40
|
+
+---------------+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
41
|
+
| xiongchiamiov | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 |
|
42
|
+
| James Pearson | 1 | 2 | 2 | 2 | 2 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
|
43
|
+
+---------------+-------------+------+------+-----+------+------+------+-----+------+-------+-----+-----+------+---------+------+
|
44
|
+
|
data/Rakefile
ADDED
data/bin/git-swear-stats
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
# May you recognize your weaknesses and share your strengths.
|
5
|
+
# May you share freely, never taking more than you give.
|
6
|
+
# May you find love and love everyone you find.
|
7
|
+
|
8
|
+
require 'docopt'
|
9
|
+
require 'git'
|
10
|
+
require 'pp'
|
11
|
+
require 'terminal-table'
|
12
|
+
|
13
|
+
# Git intercepts `git swear-stats --help`, so unfortunately most people won't
|
14
|
+
# see this usage message. Docopt is still a great way to do parsing, though.
|
15
|
+
doc = <<DOCOPT
|
16
|
+
git-swear-stats
|
17
|
+
|
18
|
+
Usage:
|
19
|
+
git-swear-stats [options] [messages|diffs]
|
20
|
+
|
21
|
+
Options:
|
22
|
+
-h, --help Show this screen.
|
23
|
+
--debug Print out debug messages.
|
24
|
+
--include-merges Look at merge commits.
|
25
|
+
--no-progress Don't print out progress information.
|
26
|
+
|
27
|
+
DOCOPT
|
28
|
+
begin
|
29
|
+
options = Docopt::docopt doc
|
30
|
+
rescue Docopt::Exit => e
|
31
|
+
puts e.message
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
pp options if options['--debug']
|
35
|
+
|
36
|
+
swears = [
|
37
|
+
%r{^(dip)?shit(ty)?$},
|
38
|
+
%r{^(cluster|mother)?(fuck|fsck|eff)(ing|er|ed|head)?$},
|
39
|
+
%r{^cunt$},
|
40
|
+
%r{^cock(suck|sucker)?$},
|
41
|
+
%r{^(ass|arse)(hole)?$},
|
42
|
+
%r{^bitch(y)?$},
|
43
|
+
%r{^wtf$},
|
44
|
+
%r{^fag(got)?$},
|
45
|
+
%r{^(god)?damn(ed|able)?$},
|
46
|
+
%r{^bastard$},
|
47
|
+
%r{^hell(ish)?$},
|
48
|
+
]
|
49
|
+
wordDelimiters = %r{[ \-_.,!?;:*"'|{}()\n]}
|
50
|
+
|
51
|
+
wordStats = {}
|
52
|
+
wordStats.default = 0
|
53
|
+
authorStats = {}
|
54
|
+
|
55
|
+
repo = Git.open '.'
|
56
|
+
# By default, we only get up to 30 commits in the log. By digging through the
|
57
|
+
# source, I found that passing nil to repo.log() ends up setting the limit to
|
58
|
+
# nil, and thus giving us all commits.
|
59
|
+
print 'Reading in git log... ' if not options['--no-progress']
|
60
|
+
log = repo.log nil
|
61
|
+
puts 'done!' if not options['--no-progress']
|
62
|
+
|
63
|
+
print 'Parsing git log' if not options['--no-progress']
|
64
|
+
log.each_with_index do |commit, i|
|
65
|
+
# Merges often have data in them from other commits, pull request
|
66
|
+
# descriptions, etc., so it's not really fair to count them.
|
67
|
+
# Git::Log unfortunately appears to have no way of passing --no-merges
|
68
|
+
# through to the underlying binary, so we have to check merges on a
|
69
|
+
# commit-by-commit basis instead.
|
70
|
+
next if not options['--include-merges'] and commit.parents.count > 1
|
71
|
+
|
72
|
+
author = commit.author.name
|
73
|
+
if not authorStats.key? author
|
74
|
+
authorStats[author] = {}
|
75
|
+
authorStats[author].default = 0
|
76
|
+
end
|
77
|
+
|
78
|
+
if !options['diffs']
|
79
|
+
# Splitting on words makes our regexes a little simpler.
|
80
|
+
commit.message.split(wordDelimiters).each do |word|
|
81
|
+
word.downcase! # A little bit of normalization.
|
82
|
+
swears.each do |swear|
|
83
|
+
if word =~ swear
|
84
|
+
wordStats[word] += 1
|
85
|
+
authorStats[author][word] += 1
|
86
|
+
if options['--debug']
|
87
|
+
puts '-'*80
|
88
|
+
puts author
|
89
|
+
puts commit.message
|
90
|
+
puts '-'*80
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
if !options['messages']
|
98
|
+
# The git module doesn't handle a diff on the initial commit very well - by
|
99
|
+
# which I mean it throws an exception.
|
100
|
+
# TODO: Monkeypatch the shit out of Git::Commit.
|
101
|
+
next if commit.parents.count == 0
|
102
|
+
|
103
|
+
diff = commit.diff_parent.to_s.force_encoding 'iso-8859-1'
|
104
|
+
# We only want to look at stuff they did, not surrounding things. We'll
|
105
|
+
# approximate this by grepping through lines "added".
|
106
|
+
lines = diff.split("\n")
|
107
|
+
# Drop the first four lines to get rid of the diff header.
|
108
|
+
lines.drop(4).keep_if {|line| line =~ /^\+/}.each do |line|
|
109
|
+
line[1..-1].split(wordDelimiters).each do |word|
|
110
|
+
word.downcase! # A little bit of normalization.
|
111
|
+
swears.each do |swear|
|
112
|
+
if word =~ swear
|
113
|
+
wordStats[word] += 1
|
114
|
+
authorStats[author][word] += 1
|
115
|
+
if options['--debug']
|
116
|
+
puts '-'*80
|
117
|
+
puts author
|
118
|
+
puts line
|
119
|
+
puts '-'*80
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# For large repos, parsing can take a while; let users know something is
|
128
|
+
# happening.
|
129
|
+
print '.' if i % 100 == 0 and not options['--no-progress']
|
130
|
+
end
|
131
|
+
puts if not options['--no-progress']
|
132
|
+
|
133
|
+
# People who haven't sworn at all aren't very interesting.
|
134
|
+
authorStats.delete_if {|author, swears| swears.empty?}
|
135
|
+
|
136
|
+
pp wordStats if options['--debug']
|
137
|
+
pp authorStats if options['--debug']
|
138
|
+
|
139
|
+
puts 'Overall:'
|
140
|
+
table = Terminal::Table.new
|
141
|
+
table.headings = wordStats.keys
|
142
|
+
table.add_row wordStats.values
|
143
|
+
puts table
|
144
|
+
|
145
|
+
puts 'Authors:'
|
146
|
+
table = Terminal::Table.new
|
147
|
+
table.headings = header = [''] + wordStats.keys
|
148
|
+
authorStats.each do |author, stats|
|
149
|
+
row = []
|
150
|
+
stats[''] = author # Cheat a little for the first column.
|
151
|
+
header.each {|swear| row << stats[swear]}
|
152
|
+
table.add_row row
|
153
|
+
end
|
154
|
+
puts table
|
155
|
+
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: git-swear-stats
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- James Pearson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2013-03-24 00:00:00 -07:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: docopt
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: git
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :runtime
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: terminal-table
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: *id003
|
49
|
+
description: Gather statistics on swearing in a repo.
|
50
|
+
email:
|
51
|
+
- xiong.chiamiov@gmail.com
|
52
|
+
executables:
|
53
|
+
- git-swear-stats
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
extra_rdoc_files:
|
57
|
+
- LICENSE
|
58
|
+
- README.md
|
59
|
+
files:
|
60
|
+
- LICENSE
|
61
|
+
- Rakefile
|
62
|
+
- README.md
|
63
|
+
- bin/git-swear-stats
|
64
|
+
has_rdoc: true
|
65
|
+
homepage: https://github.com/xiongchiamiov/git-swear-stats
|
66
|
+
licenses: []
|
67
|
+
|
68
|
+
post_install_message:
|
69
|
+
rdoc_options: []
|
70
|
+
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: "0"
|
79
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
requirements: []
|
86
|
+
|
87
|
+
rubyforge_project:
|
88
|
+
rubygems_version: 1.5.3
|
89
|
+
signing_key:
|
90
|
+
specification_version: 3
|
91
|
+
summary: Gather statistics on swearing in a repo.
|
92
|
+
test_files: []
|
93
|
+
|