code-stats 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +16 -0
- data/bin/code_stats +31 -0
- data/lib/code_stats.rb +28 -0
- data/lib/code_stats/code_stats.rb +51 -0
- data/lib/code_stats/file_set.rb +43 -0
- data/lib/code_stats/gems.rb +6 -0
- data/lib/code_stats/languages.rb +134 -0
- data/lib/code_stats/project.rb +55 -0
- data/lib/code_stats/report.html.haml +59 -0
- data/lib/code_stats/report.rb +42 -0
- data/lib/code_stats/report/highchart.js +11103 -0
- data/lib/code_stats/report/jquery.js +8936 -0
- data/lib/code_stats/report/report.js +75 -0
- data/lib/code_stats/report/style.css +14 -0
- data/lib/code_stats/support.rb +13 -0
- data/readme.md +40 -0
- data/spec/code_stats_spec.rb +15 -0
- data/spec/languages_spec.rb +221 -0
- data/spec/project_spec.rb +35 -0
- data/spec/sample_project/docs/sample.rb +1 -0
- data/spec/sample_project/specs/a_spec.rb +2 -0
- data/spec/sample_project/src/a.js +10 -0
- data/spec/sample_project/src/b.rb +8 -0
- data/spec/sample_project/src/c.unknown +0 -0
- data/spec/spec_helper.rb +8 -0
- metadata +123 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
var Report = {};
|
2
|
+
Report.plot = function(selector, projects){
|
3
|
+
var sources = [], specs = [], labels = [];
|
4
|
+
for(var i = 0; i < projects.length; i++){
|
5
|
+
var project = projects[i];
|
6
|
+
labels.push(project[0]);
|
7
|
+
sources.push(project[1]);
|
8
|
+
specs.push(project[2]);
|
9
|
+
}
|
10
|
+
|
11
|
+
var chart = new Highcharts.Chart({
|
12
|
+
chart: {
|
13
|
+
renderTo: 'plot',
|
14
|
+
defaultSeriesType: 'column'
|
15
|
+
},
|
16
|
+
title: {
|
17
|
+
text: null // 'Stacked column chart'
|
18
|
+
},
|
19
|
+
xAxis: {
|
20
|
+
categories: labels,
|
21
|
+
labels: {
|
22
|
+
rotation: -45,
|
23
|
+
align: 'right'
|
24
|
+
}
|
25
|
+
},
|
26
|
+
yAxis: {
|
27
|
+
min: 0,
|
28
|
+
title: {
|
29
|
+
text: 'Characters Count'
|
30
|
+
},
|
31
|
+
stackLabels: {
|
32
|
+
enabled: true,
|
33
|
+
style: {
|
34
|
+
fontWeight: 'bold',
|
35
|
+
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
|
36
|
+
}
|
37
|
+
}
|
38
|
+
},
|
39
|
+
legend: {
|
40
|
+
align: 'right',
|
41
|
+
x: -100,
|
42
|
+
verticalAlign: 'top',
|
43
|
+
y: 20,
|
44
|
+
floating: true,
|
45
|
+
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColorSolid) || 'white',
|
46
|
+
borderColor: '#CCC',
|
47
|
+
borderWidth: 1,
|
48
|
+
shadow: false
|
49
|
+
},
|
50
|
+
tooltip: {
|
51
|
+
formatter: function() {
|
52
|
+
return '<b>'+ this.x +'</b><br/>'+
|
53
|
+
this.series.name +': '+ this.y +'<br/>'+
|
54
|
+
'Total: '+ this.point.stackTotal;
|
55
|
+
}
|
56
|
+
},
|
57
|
+
plotOptions: {
|
58
|
+
column: {
|
59
|
+
stacking: 'normal',
|
60
|
+
dataLabels: {
|
61
|
+
enabled: true,
|
62
|
+
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
|
63
|
+
}
|
64
|
+
}
|
65
|
+
},
|
66
|
+
series: [{
|
67
|
+
name: 'Specs',
|
68
|
+
data: specs
|
69
|
+
}, {
|
70
|
+
name: 'Sources',
|
71
|
+
data: sources
|
72
|
+
}]
|
73
|
+
});
|
74
|
+
|
75
|
+
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
body {font-size: 14px; font-family: Arial, sans-serif;}
|
2
|
+
h1 {margin: 20px; font-size: 20px;}
|
3
|
+
p {margin: 20px;}
|
4
|
+
|
5
|
+
.nowrap {white-space:nowrap;}
|
6
|
+
.bold {font-weight: bold;}
|
7
|
+
.report {font-size: 12px; border-collapse: collapse; text-align:left; margin: 20px;}
|
8
|
+
.report th{font-size: 14px; font-weight:normal; border-bottom: 2px solid; padding: 10px 8px;}
|
9
|
+
.report td{border-bottom: 1px solid; padding: 6px 8px;}
|
10
|
+
|
11
|
+
.plot {margin: 20px; margin-bottom: 50px; width: 800px; height: 600px;}
|
12
|
+
|
13
|
+
p.powered {font-size: 10px; margin: 25px; color: gray; text-align: right; position: absolute; top: 0; right: 0; border: 0;}
|
14
|
+
p.powered a {text-decoration: none;}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
String.class_eval do
|
2
|
+
# Ruby just crashes on some files, don't know why and don't want to
|
3
|
+
# spend time on this shit, just found this hack somewhere in the internet.
|
4
|
+
def force_utf8_encoding
|
5
|
+
force_encoding('binary').gsub(156.chr,"Oe")
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
Numeric.class_eval do
|
10
|
+
def to_s_with_delimiter delimiter = ' '
|
11
|
+
to_s.gsub(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
12
|
+
end
|
13
|
+
end
|
data/readme.md
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Code Stats
|
2
|
+
|
3
|
+
[![rails-thumb]][rails-img] [![some-os-projects-thumb]][some-os-projects-img] [![mongoid-vs-mongomapper-thumb]][mongoid-vs-mongomapper-img]
|
4
|
+
|
5
|
+
Complexity of [Rails libraries][rails], Comparing [some Open Source projects][some-os-projects], [MongoMapper vs Mongoid][mongoid-vs-mongomapper] (to see the report save the html file from link on Your computer and open it).
|
6
|
+
|
7
|
+
I deliberately choose the Red color for the sources (and the Blue for specs / tests) because the less code - the better (in general, with other things been equal).
|
8
|
+
|
9
|
+
It's simple as an egg - and it means that You can easilly understood all it's code in about 20-30 minutes and be able to easilly hack and customize it with Your needs.
|
10
|
+
|
11
|
+
# What's the point of these graphs and numbers?
|
12
|
+
|
13
|
+
# Installation & Usage
|
14
|
+
|
15
|
+
This tool is language-agnostic, but it itself is made with Ruby, so You need Ruby installed to use it. Next, just install it as a gem:
|
16
|
+
|
17
|
+
``` bash
|
18
|
+
gem install code_stats
|
19
|
+
```
|
20
|
+
|
21
|
+
Now run it on some of Your projects, You can also specify some options (type code_stats without arguments to see full help):
|
22
|
+
|
23
|
+
``` bash
|
24
|
+
code_stat /projects/wordpress
|
25
|
+
code_stat /projects/* except: JavaScript
|
26
|
+
```
|
27
|
+
|
28
|
+
Copyright (c) Alexey Petrushin http://petrush.in, released under the MIT license.
|
29
|
+
|
30
|
+
[rails-thumb]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/rails.thumb.png
|
31
|
+
[some-os-projects-thumb]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/some-os-projects.thumb.png
|
32
|
+
[mongoid-vs-mongomapper-thumb]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/mongoid-vs-mongomapper.thumb.png
|
33
|
+
|
34
|
+
[rails-img]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/rails.png
|
35
|
+
[some-os-projects-img]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/some-os-projects.png
|
36
|
+
[mongoid-vs-mongomapper-img]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/mongoid-vs-mongomapper.png
|
37
|
+
|
38
|
+
[rails]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/rails.html
|
39
|
+
[some-os-projects]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/some-os-projects.html
|
40
|
+
[mongoid-vs-mongomapper]: https://github.com/alexeypetrushin/code_stats/raw/master/docs/mongoid-vs-mongomapper.html
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Project" do
|
4
|
+
it "analyze" do
|
5
|
+
projects = CodeStats.analyze sample_project_path
|
6
|
+
report = CodeStats::Report.new(*projects).render
|
7
|
+
report.should =~ /sample_project.+32/m
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should also accept options (from error)" do
|
11
|
+
projects = CodeStats.analyze sample_project_path
|
12
|
+
report = CodeStats::Report.new(*(projects << {except: :JavaScript})).render
|
13
|
+
report.should =~ /sample_project.+13/m
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,221 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
shared_examples_for 'language' do
|
4
|
+
it "should strip comments" do
|
5
|
+
lang = CodeStats.parse @script, @extension
|
6
|
+
lang.code.should == <<-CODE
|
7
|
+
code_a
|
8
|
+
code_b
|
9
|
+
CODE
|
10
|
+
# lang.code.should_not include 'comment_a'
|
11
|
+
# lang.code.should_not include 'comment_a2'
|
12
|
+
# lang.code.should_not include 'comment_b'
|
13
|
+
# lang.code.should_not include 'comment_b2'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Java" do
|
18
|
+
it_should_behave_like "language"
|
19
|
+
|
20
|
+
before do
|
21
|
+
@extension = :java
|
22
|
+
@script = <<-JAVA
|
23
|
+
code_a
|
24
|
+
/*
|
25
|
+
comment_a
|
26
|
+
*/
|
27
|
+
/*
|
28
|
+
* comment_a2
|
29
|
+
*/
|
30
|
+
// comment_b
|
31
|
+
// comment_b2
|
32
|
+
code_b
|
33
|
+
JAVA
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "JavaScript" do
|
38
|
+
it_should_behave_like "language"
|
39
|
+
|
40
|
+
before do
|
41
|
+
@extension = :js
|
42
|
+
@script = <<-JAVA_SCRIPT
|
43
|
+
code_a
|
44
|
+
/*
|
45
|
+
comment_a
|
46
|
+
*/
|
47
|
+
/*
|
48
|
+
* comment_a2
|
49
|
+
*/
|
50
|
+
// comment_b
|
51
|
+
// comment_b2
|
52
|
+
code_b
|
53
|
+
JAVA_SCRIPT
|
54
|
+
end
|
55
|
+
|
56
|
+
it "removing comments should correctly change lines count" do
|
57
|
+
script = <<-JAVA_SCRIPT
|
58
|
+
// a variable
|
59
|
+
a = 1;
|
60
|
+
|
61
|
+
/*
|
62
|
+
* b variable
|
63
|
+
*/
|
64
|
+
b = 2;
|
65
|
+
|
66
|
+
// sum
|
67
|
+
alert(a + b);
|
68
|
+
JAVA_SCRIPT
|
69
|
+
|
70
|
+
code = <<-JAVA_SCRIPT
|
71
|
+
a = 1;
|
72
|
+
|
73
|
+
b = 2;
|
74
|
+
|
75
|
+
alert(a + b);
|
76
|
+
JAVA_SCRIPT
|
77
|
+
|
78
|
+
lang = CodeStats.parse script, :js
|
79
|
+
lang.code.should == code
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "Ruby" do
|
84
|
+
it_should_behave_like "language"
|
85
|
+
|
86
|
+
before do
|
87
|
+
@extension = :rb
|
88
|
+
@script = <<-RUBY
|
89
|
+
code_a
|
90
|
+
# comment_a
|
91
|
+
# comment_a2
|
92
|
+
code_b
|
93
|
+
RUBY
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "Cpp" do
|
98
|
+
it_should_behave_like "language"
|
99
|
+
|
100
|
+
before do
|
101
|
+
@extension = :cpp
|
102
|
+
@script = <<-CPP
|
103
|
+
code_a
|
104
|
+
/*
|
105
|
+
comment_a
|
106
|
+
*/
|
107
|
+
/*
|
108
|
+
* comment_a2
|
109
|
+
*/
|
110
|
+
// comment_b
|
111
|
+
// comment_b2
|
112
|
+
code_b
|
113
|
+
CPP
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "CoffeeScript" do
|
118
|
+
it_should_behave_like "language"
|
119
|
+
|
120
|
+
before do
|
121
|
+
@extension = :coffee
|
122
|
+
@script = <<-COFFEE_SCRIPT
|
123
|
+
code_a
|
124
|
+
###
|
125
|
+
comment_a
|
126
|
+
###
|
127
|
+
###
|
128
|
+
comment_a2
|
129
|
+
###
|
130
|
+
# comment_b
|
131
|
+
# comment_b2
|
132
|
+
code_b
|
133
|
+
COFFEE_SCRIPT
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "Yaml" do
|
138
|
+
it_should_behave_like "language"
|
139
|
+
|
140
|
+
before do
|
141
|
+
@extension = :yml
|
142
|
+
@script = <<-YAML
|
143
|
+
code_a
|
144
|
+
# comment_a
|
145
|
+
# comment_a2
|
146
|
+
code_b
|
147
|
+
YAML
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "Haml" do
|
152
|
+
it_should_behave_like "language"
|
153
|
+
|
154
|
+
before do
|
155
|
+
@extension = :haml
|
156
|
+
@script = <<-HAML
|
157
|
+
code_a
|
158
|
+
/ comment_a
|
159
|
+
/ comment_a2
|
160
|
+
code_b
|
161
|
+
HAML
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "Erb" do
|
166
|
+
it_should_behave_like "language"
|
167
|
+
|
168
|
+
before do
|
169
|
+
@extension = :erb
|
170
|
+
@script = <<-ERB
|
171
|
+
code_a
|
172
|
+
code_b
|
173
|
+
ERB
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "Rjs" do
|
178
|
+
it_should_behave_like "language"
|
179
|
+
|
180
|
+
before do
|
181
|
+
@extension = :rjs
|
182
|
+
@script = <<-RJS
|
183
|
+
code_a
|
184
|
+
code_b
|
185
|
+
RJS
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "Php" do
|
190
|
+
it_should_behave_like "language"
|
191
|
+
|
192
|
+
before do
|
193
|
+
@extension = :php
|
194
|
+
@script = <<-PHP
|
195
|
+
code_a
|
196
|
+
/*
|
197
|
+
comment_a
|
198
|
+
*/
|
199
|
+
/*
|
200
|
+
* comment_a2
|
201
|
+
*/
|
202
|
+
// comment_b
|
203
|
+
// comment_b2
|
204
|
+
code_b
|
205
|
+
PHP
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "Python" do
|
210
|
+
it_should_behave_like "language"
|
211
|
+
|
212
|
+
before do
|
213
|
+
@extension = :py
|
214
|
+
@script = <<-PYTHON
|
215
|
+
code_a
|
216
|
+
# comment_a
|
217
|
+
# comment_a2
|
218
|
+
code_b
|
219
|
+
PYTHON
|
220
|
+
end
|
221
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Project" do
|
4
|
+
it "general" do
|
5
|
+
prj = CodeStats::Project.new sample_project_path
|
6
|
+
prj.name.should == 'sample_project'
|
7
|
+
prj.files.size.should == 4
|
8
|
+
|
9
|
+
prj.analyze!
|
10
|
+
|
11
|
+
prj.unknown_extensions.should == [:unknown]
|
12
|
+
|
13
|
+
# sources
|
14
|
+
prj.lines_count.should == 10
|
15
|
+
prj.characters_count.should == 32
|
16
|
+
|
17
|
+
prj.lines_count_by_language.should == {JavaScript: 5, Ruby: 5}
|
18
|
+
prj.characters_count_by_language.should == {JavaScript: 19, Ruby: 13}
|
19
|
+
|
20
|
+
# specs
|
21
|
+
prj.specs.lines_count.should == 2
|
22
|
+
prj.specs.characters_count.should == 16
|
23
|
+
|
24
|
+
prj.specs.lines_count_by_language.should == {Ruby: 2}
|
25
|
+
prj.specs.characters_count_by_language.should == {Ruby: 16}
|
26
|
+
end
|
27
|
+
|
28
|
+
it "language filters" do
|
29
|
+
prj = CodeStats::Project.new sample_project_path
|
30
|
+
prj.analyze!
|
31
|
+
|
32
|
+
prj.lines_count(except: :JavaScript).should == 5
|
33
|
+
prj.characters_count(except: :JavaScript).should == 13
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
puts "Hello World"
|