code_counter 0.3.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +44 -0
- data/LICENSE.md +28 -0
- data/README.md +116 -0
- data/bin/code_counter +17 -0
- data/code_counter.gemspec +41 -0
- data/lib/code_counter.rb +3 -0
- data/lib/code_counter/cli.rb +14 -0
- data/lib/code_counter/engine.rb +237 -0
- data/lib/code_counter/rake.rb +17 -0
- data/lib/code_counter/version.rb +3 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9bbdf015cdbbaabfcf13e4d1f92f3908faaa5f7d
|
4
|
+
data.tar.gz: d0c93d2c78986a80eb3334581c2695e9beaabe3c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 29fe7cbaae18b03c6e5b3f9dc7cb6737fb2d4d7c99843fd660485344a34a8d38b72d8eb8406018adf05f0e2b1b42fe4a3484e6c6949ffe5027324ac18e2ed233
|
7
|
+
data.tar.gz: 1bbeca19a84e7dab0dc55540d3d1a3cdadfacad602447e11ec3ef13a1a4d783a9554ff597a05e5c20f23b9d7096ec4c0565c5614117e47612e92beda45cecaea
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Changes
|
2
|
+
|
3
|
+
## v0.3.1
|
4
|
+
|
5
|
+
* Add CodeClimate badge to `README.md`.
|
6
|
+
* Correct email address in `README.md` and `code_statistics.gemspec`.
|
7
|
+
* Switch to secure RubyGems URL.
|
8
|
+
* Rename gem to `code_counter` so it can be published to RubyGems.
|
9
|
+
* Improve documentation generation.
|
10
|
+
* Remove use of `test-construct` in favor of simpler fixture directories.
|
11
|
+
* Switch to `rspec`.
|
12
|
+
* Begin adding tests for CLI.
|
13
|
+
* Fix an uninitialized variable bug.
|
14
|
+
* Paths listed in `ADDITIONAL_SOURCE_DIRECTORIES` don't need to be relative to
|
15
|
+
the current directory anymore.
|
16
|
+
* Add support for `.rake` files.
|
17
|
+
* Add support for files with arbitrary extensions in binary directories.
|
18
|
+
* Make `bin`, `script`, and `scripts` be binary directories by default.
|
19
|
+
* Add `ADDITIONAL_BINARY_DIRECTORIES` var for adding binary directory mappings
|
20
|
+
to the CLI.
|
21
|
+
|
22
|
+
|
23
|
+
## v0.3.0
|
24
|
+
|
25
|
+
* Modernize project to work well with newer Rake, and in the world of Bundler.
|
26
|
+
* Formalize development environment, and fix broken tasks.
|
27
|
+
* Don't leave file handles open needlessly.
|
28
|
+
* Make all path additions recursive. (Incl. allowing more-specific
|
29
|
+
definitions earlier on to override definitions later on...)
|
30
|
+
* Allow specifying multiple paths to be grouped into one line item.
|
31
|
+
* Normalized mechanism for configuring things.
|
32
|
+
* Substantially simplify code.
|
33
|
+
* Add a proper changelog.
|
34
|
+
* Don't add development-dependencies to gem; let people use `git clone` for
|
35
|
+
that.
|
36
|
+
* Improve Cucumber support by treating `Given`/`When`/`Then` matcher blocks as
|
37
|
+
methods. (Analogous to how `should`/`it` methods were already treated.)
|
38
|
+
* Reduce namespace pollution in both `rake` task namespace, and Ruby global
|
39
|
+
namespace.
|
40
|
+
|
41
|
+
|
42
|
+
## v0.2.13
|
43
|
+
|
44
|
+
* Initial fork from devver's repo.
|
data/LICENSE.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# License
|
2
|
+
|
3
|
+
## Ownership
|
4
|
+
|
5
|
+
* Copyright (c) 2009, 2010 Devver
|
6
|
+
* Copyright (c) 2012 Cloudability Inc
|
7
|
+
* Copyright (c) 2014 Jon Frisby
|
8
|
+
|
9
|
+
## The MIT License
|
10
|
+
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
12
|
+
a copy of this software and associated documentation files (the
|
13
|
+
"Software"), to deal in the Software without restriction, including
|
14
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
15
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
16
|
+
permit persons to whom the Software is furnished to do so, subject to
|
17
|
+
the following conditions:
|
18
|
+
|
19
|
+
The above copyright notice and this permission notice shall be
|
20
|
+
included in all copies or substantial portions of the Software.
|
21
|
+
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
23
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
24
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
25
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
26
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
27
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
28
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# code_counter
|
2
|
+
|
3
|
+
[](https://codeclimate.com/github/MrJoy/code_statistics)
|
4
|
+
[](https://codeclimate.com/github/MrJoy/code_statistics)
|
5
|
+
|
6
|
+
This started as an extraction of the Rails `rake stat` task, so it could be
|
7
|
+
used on non-Rails projects and have it's features slowly expanded.
|
8
|
+
|
9
|
+
Improvements include:
|
10
|
+
|
11
|
+
* Support for RSpec and Cucumber out of the box.
|
12
|
+
* Includes `.rake` files.
|
13
|
+
* Includes scripts (by default, in `bin/`, `script/`, and `scripts/`) with no
|
14
|
+
extension, provided they have a shebang line.
|
15
|
+
|
16
|
+
|
17
|
+
## Requirements
|
18
|
+
|
19
|
+
This project requires Ruby 1.9.x or higher.
|
20
|
+
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
### Rake
|
25
|
+
|
26
|
+
Add this to the bottom of your `Rakefile`:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
require 'code_counter'
|
30
|
+
```
|
31
|
+
|
32
|
+
Then, when you run `rake -T` you'll see a stats task, unless you already had
|
33
|
+
one defined. If you have an existing task named `stats`, and want to use this
|
34
|
+
one, simply make a task of a new name that depends on the `code_counter`
|
35
|
+
task, like so:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
task :new_stats => :code_counter
|
39
|
+
```
|
40
|
+
|
41
|
+
To configure the task:
|
42
|
+
|
43
|
+
```ruby
|
44
|
+
task :stats_configuration do
|
45
|
+
CodeCounter::Engine.clear!
|
46
|
+
CodeCounter::Engine.init!
|
47
|
+
|
48
|
+
# By default, this will recursively add the specified path, and only look for
|
49
|
+
# files ending in `.rb`, `.rake`, or `.feature`.
|
50
|
+
CodeCounter::Engine.add_path("Some Group", "some/path")
|
51
|
+
|
52
|
+
# Don't add recursively:
|
53
|
+
CodeCounter::Engine.add_path("Some Group", "other/path", false)
|
54
|
+
|
55
|
+
# Add recursively, and don't filter by file extension:
|
56
|
+
CodeCounter::Engine.add_path("Some Group", "my/script/dir", true, true)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Add a dependency on our config task here so that our config gets loaded when
|
60
|
+
# we run `rake stats`.
|
61
|
+
task :code_counter => :stats_configuration
|
62
|
+
```
|
63
|
+
|
64
|
+
|
65
|
+
### CLI
|
66
|
+
|
67
|
+
```bash
|
68
|
+
code_counter
|
69
|
+
```
|
70
|
+
|
71
|
+
Additionally, you can configure things using some environment variables:
|
72
|
+
|
73
|
+
* `ADDITIONAL_SOURCE_DIRECTORIES`: A comma-separated list of directories to
|
74
|
+
scan for source files. You may assign a directory to a named group by
|
75
|
+
prefixing the path with a group name and colon. E.G. `ADDITIONAL_SOURCE_DIRECTORIES='Libraries:my_awesome_code'`
|
76
|
+
* `ADDITIONAL_BINARY_DIRECTORIES`: A comma-separated list of directories to
|
77
|
+
scan for binaries. You may assign a directory to a named group by prefixing
|
78
|
+
the path with a group name and colon. E.G. `ADDITIONAL_BINARY_DIRECTORIES='Binaries:my_awesome_scripts'`
|
79
|
+
* `IGNORE_FILE_GLOBS`: A comma-separated list of file globs to ignore.
|
80
|
+
|
81
|
+
|
82
|
+
## TODOs
|
83
|
+
|
84
|
+
* make bin accept passed cmd line arguments to run
|
85
|
+
* stop relying on ENV vars
|
86
|
+
* count number of total files
|
87
|
+
* count number of of .rb or passed in filter files
|
88
|
+
* find todo, perf, bug, hack, etc comments and display them with info about
|
89
|
+
them (line number etc)
|
90
|
+
* reduce duplication between bin and task
|
91
|
+
* comments:code ratio
|
92
|
+
* support for more languages
|
93
|
+
* JS
|
94
|
+
* CoffeeScript
|
95
|
+
* don't accidentally count __actual__ binaries
|
96
|
+
* Include `Rakefile*` in analysis
|
97
|
+
|
98
|
+
[jfrisby@mrjoy.com](mailto:jfrisby@mrjoy.com)
|
99
|
+
|
100
|
+
|
101
|
+
## Note on Patches/Pull Requests
|
102
|
+
|
103
|
+
* Fork the project.
|
104
|
+
* Make your feature addition or bug fix.
|
105
|
+
* Add tests for it. This is important so I don't break it in a future version
|
106
|
+
unintentionally.
|
107
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have
|
108
|
+
your own version, that is fine but bump version in a commit by itself I can
|
109
|
+
ignore when I pull)
|
110
|
+
* Send me a pull request. Bonus points for topic branches.
|
111
|
+
|
112
|
+
|
113
|
+
## Copyright
|
114
|
+
|
115
|
+
Distributed under the MIT license. See LICENSE.md for details, including
|
116
|
+
authorship/ownership.
|
data/bin/code_counter
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#! /usr/bin/env ruby
|
2
|
+
require File.expand_path('../../lib/code_counter/engine', __FILE__)
|
3
|
+
require File.expand_path('../../lib/code_counter/cli', __FILE__)
|
4
|
+
|
5
|
+
(ENV['ADDITIONAL_SOURCE_DIRECTORIES'] || '').split(',').each do |dir|
|
6
|
+
(path, label) = CodeCounter::CLI.expand_labeled_path(dir)
|
7
|
+
CodeCounter::Engine.add_path(label, path, true, false)
|
8
|
+
end
|
9
|
+
|
10
|
+
(ENV['ADDITIONAL_BINARY_DIRECTORIES'] || '').split(',').each do |dir|
|
11
|
+
(path, label) = CodeCounter::CLI.expand_labeled_path(dir)
|
12
|
+
CodeCounter::Engine.add_path(label, path, true, true)
|
13
|
+
end
|
14
|
+
|
15
|
+
user_ignored_globs = (ENV['IGNORE_FILE_GLOBS'] || '').split(',')
|
16
|
+
|
17
|
+
puts CodeCounter::Engine.new(user_ignored_globs).to_s
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: code_counter 0.3.1 ruby lib
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "code_counter"
|
9
|
+
s.version = "0.3.1"
|
10
|
+
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
13
|
+
s.authors = ["Jon Frisby", "Dan Mayer"]
|
14
|
+
s.date = "2014-06-06"
|
15
|
+
s.description = "This is a port of the rails 'rake stats' method so it can be made more robust and work for non rails projects. New features may eventually be added as well."
|
16
|
+
s.email = "jfrisby@mrjoy.com"
|
17
|
+
s.executables = ["code_counter"]
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"CHANGELOG.md",
|
20
|
+
"LICENSE.md",
|
21
|
+
"README.md"
|
22
|
+
]
|
23
|
+
s.files = [
|
24
|
+
"CHANGELOG.md",
|
25
|
+
"LICENSE.md",
|
26
|
+
"README.md",
|
27
|
+
"bin/code_counter",
|
28
|
+
"code_counter.gemspec",
|
29
|
+
"lib/code_counter.rb",
|
30
|
+
"lib/code_counter/cli.rb",
|
31
|
+
"lib/code_counter/engine.rb",
|
32
|
+
"lib/code_counter/rake.rb",
|
33
|
+
"lib/code_counter/version.rb"
|
34
|
+
]
|
35
|
+
s.homepage = "http://github.com/MrJoy/code_counter"
|
36
|
+
s.licenses = ["MIT"]
|
37
|
+
s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
|
38
|
+
s.rubygems_version = "2.2.2"
|
39
|
+
s.summary = "Making a gem of the normal rails rake stats method, to make it more robust and work on non rails projects"
|
40
|
+
end
|
41
|
+
|
data/lib/code_counter.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module CodeCounter
|
2
|
+
class CLI
|
3
|
+
def self.expand_labeled_path(dir_with_label)
|
4
|
+
components = dir_with_label.split(/\s*:\s*/)
|
5
|
+
if components.length > 1
|
6
|
+
(label, path) = *components
|
7
|
+
else
|
8
|
+
label = path = components.first
|
9
|
+
end
|
10
|
+
|
11
|
+
return [Pathname.new(path).expand_path.to_s, label]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,237 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module CodeCounter
|
4
|
+
class Engine
|
5
|
+
BIN_DIRECTORIES = Set.new
|
6
|
+
STATS_DIRECTORIES = []
|
7
|
+
TEST_TYPES = Set.new
|
8
|
+
|
9
|
+
###########################################################################
|
10
|
+
# Mechanisms for configuring the behavior of this tool
|
11
|
+
###########################################################################
|
12
|
+
def self.clear!
|
13
|
+
BIN_DIRECTORIES.clear
|
14
|
+
STATS_DIRECTORIES.clear
|
15
|
+
TEST_TYPES.clear
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.add_path(key, directory, recursive=true, is_bin_dir=false)
|
19
|
+
directory = File.expand_path(directory)
|
20
|
+
if File.directory?(directory)
|
21
|
+
STATS_DIRECTORIES << [key, directory]
|
22
|
+
BIN_DIRECTORIES << directory if is_bin_dir
|
23
|
+
if(recursive)
|
24
|
+
Dir.entries(directory).
|
25
|
+
reject { |dirent| dirent =~ /^\.\.?$/ }.
|
26
|
+
map { |dirent| File.join(directory, dirent) }.
|
27
|
+
reject { |dirent| !File.directory?(dirent) }.
|
28
|
+
each { |dirent| add_path(key, dirent, recursive, is_bin_dir) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.add_test_group(key)
|
34
|
+
TEST_TYPES << key
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
###########################################################################
|
39
|
+
# Default configuration
|
40
|
+
###########################################################################
|
41
|
+
def self.init!
|
42
|
+
add_path("Controllers", "app/controllers")
|
43
|
+
add_path("Mailers", "app/mailers")
|
44
|
+
add_path("Models", "app/models")
|
45
|
+
add_path("Views", "app/views")
|
46
|
+
add_path("Helpers", "app/helpers")
|
47
|
+
add_path("Binaries", "bin", true, true)
|
48
|
+
add_path("Binaries", "script", true, true)
|
49
|
+
add_path("Binaries", "scripts", true, true)
|
50
|
+
add_path("Libraries", "lib")
|
51
|
+
add_path("Source", "source")
|
52
|
+
add_path("Source", "src")
|
53
|
+
add_path("Unit tests", "test")
|
54
|
+
add_path("RSpec specs", "spec")
|
55
|
+
add_path("Features", "features")
|
56
|
+
|
57
|
+
add_test_group("Unit tests")
|
58
|
+
add_test_group("RSpec specs")
|
59
|
+
add_test_group("Features")
|
60
|
+
end
|
61
|
+
init!
|
62
|
+
|
63
|
+
|
64
|
+
###########################################################################
|
65
|
+
# Internals
|
66
|
+
###########################################################################
|
67
|
+
FILTER = /.*\.(rb|feature|rake)$/
|
68
|
+
attr_reader :print_buffer
|
69
|
+
|
70
|
+
def initialize(ignore_file_globs = [])
|
71
|
+
@bin_dirs = BIN_DIRECTORIES.dup
|
72
|
+
@pairs = STATS_DIRECTORIES.select { |pair| File.directory?(pair[1]) }
|
73
|
+
@print_buffer = ""
|
74
|
+
@ignore_files = collect_files_to_ignore(ignore_file_globs)
|
75
|
+
|
76
|
+
@pairs = coalesce_pairs(@pairs)
|
77
|
+
|
78
|
+
@statistics = calculate_statistics
|
79
|
+
@total = (@pairs.length > 1) ? calculate_total : nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def coalesce_pairs(pairs)
|
83
|
+
groups = {}
|
84
|
+
paths_seen = {}
|
85
|
+
pairs.each do |pair|
|
86
|
+
next if(paths_seen[pair.last])
|
87
|
+
paths_seen[pair.last] = true
|
88
|
+
(groups[pair.first] ||= Set.new) << pair.last
|
89
|
+
end
|
90
|
+
return groups
|
91
|
+
end
|
92
|
+
|
93
|
+
def collect_files_to_ignore(ignore_file_globs)
|
94
|
+
files_to_remove = []
|
95
|
+
ignore_file_globs.each do |glob|
|
96
|
+
files_to_remove.concat(Dir[glob])
|
97
|
+
end
|
98
|
+
files_to_remove.map { |filepath| File.expand_path(filepath) }
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
@print_buffer = ''
|
103
|
+
print_header
|
104
|
+
@pairs.each { |pair| print_line(pair.first, @statistics[pair.first]) }
|
105
|
+
print_splitter
|
106
|
+
|
107
|
+
if @total
|
108
|
+
print_line("Total", @total)
|
109
|
+
print_splitter
|
110
|
+
end
|
111
|
+
|
112
|
+
print_code_test_stats
|
113
|
+
@print_buffer
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def calculate_statistics
|
119
|
+
@pairs.inject({}) { |stats, pair| stats[pair.first] = calculate_group_statistics(pair.last); stats }
|
120
|
+
end
|
121
|
+
|
122
|
+
def ignore_file?(file_path)
|
123
|
+
@ignore_files.include?(file_path)
|
124
|
+
end
|
125
|
+
|
126
|
+
def calculate_group_statistics(directories, pattern = FILTER)
|
127
|
+
stats = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
|
128
|
+
|
129
|
+
directories.each do |directory|
|
130
|
+
Dir.foreach(directory) do |file_name|
|
131
|
+
next if file_name =~ /\A\.\.?\Z/
|
132
|
+
is_expected_ext = file_name =~ pattern
|
133
|
+
next unless @bin_dirs.include?(directory) || is_expected_ext
|
134
|
+
file_path = File.expand_path(File.join(directory, file_name))
|
135
|
+
next if ignore_file?(file_path)
|
136
|
+
|
137
|
+
# First, check if a file with an unknown extension is binary...
|
138
|
+
next unless is_expected_ext || is_shell_program?(file_path)
|
139
|
+
|
140
|
+
# Now, go ahead and analyze the file.
|
141
|
+
File.open(file_path) do |fh|
|
142
|
+
while line = fh.gets
|
143
|
+
stats["lines"] += 1
|
144
|
+
stats["classes"] += 1 if line =~ /class [A-Z]/
|
145
|
+
stats["methods"] += 1 if line =~ /(def [a-z]|should .* do|test .* do|it .* do|(Given|When|Then) .* do)/
|
146
|
+
stats["codelines"] += 1 unless line =~ /^\s*$/ || line =~ /^\s*#/
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
return stats
|
153
|
+
end
|
154
|
+
|
155
|
+
def is_shell_program?(path)
|
156
|
+
magic_word = File.open(path, "r", { :encoding => "ASCII-8BIT" }) do |fh|
|
157
|
+
fh.read(2)
|
158
|
+
end
|
159
|
+
return magic_word == '#!'
|
160
|
+
end
|
161
|
+
|
162
|
+
def calculate_total
|
163
|
+
total = { "lines" => 0, "codelines" => 0, "classes" => 0, "methods" => 0 }
|
164
|
+
@statistics.each_value { |pair| pair.each { |k, v| total[k] += v } }
|
165
|
+
total
|
166
|
+
end
|
167
|
+
|
168
|
+
def calculate_code
|
169
|
+
calculate_type(false)
|
170
|
+
end
|
171
|
+
|
172
|
+
def calculate_tests
|
173
|
+
calculate_type(true)
|
174
|
+
end
|
175
|
+
|
176
|
+
def calculate_type(test_match)
|
177
|
+
type_loc = 0
|
178
|
+
@statistics.each { |k, v| type_loc += v['codelines'] if TEST_TYPES.include?(k)==test_match }
|
179
|
+
type_loc
|
180
|
+
end
|
181
|
+
|
182
|
+
COL_WIDTHS = [[22,-1], [7,1], [7,1], [9,1], [9,1], [5,1], [7,1]]
|
183
|
+
HEADER_PATTERN = '|' + COL_WIDTHS.map { |(w,_)| "%-#{w}s" }.join('|') + "|\n"
|
184
|
+
ROW_PATTERN = '|' + COL_WIDTHS.map { |(w,d)| "%#{w*d}s" }.join('|') + "|\n"
|
185
|
+
HEADERS = ['Name', 'Lines', 'LOC', 'Classes', 'Methods', 'M/C', 'LOC/M']
|
186
|
+
SPLITTER = HEADER_PATTERN % COL_WIDTHS.map { |(w,_)| '-' * w }
|
187
|
+
|
188
|
+
def pad_elements(list)
|
189
|
+
return list.map { |e| " #{e} " }
|
190
|
+
end
|
191
|
+
|
192
|
+
def print_header
|
193
|
+
print_splitter
|
194
|
+
@print_buffer << HEADER_PATTERN % pad_elements(HEADERS)
|
195
|
+
print_splitter
|
196
|
+
end
|
197
|
+
|
198
|
+
def print_splitter
|
199
|
+
@print_buffer << SPLITTER
|
200
|
+
end
|
201
|
+
|
202
|
+
def x_over_y(top, bottom)
|
203
|
+
return (bottom > 0) ? (top / bottom) : 0
|
204
|
+
end
|
205
|
+
|
206
|
+
def print_line(name, stats)
|
207
|
+
return if stats['lines'] == 0
|
208
|
+
|
209
|
+
# Ugly hack for subtracting out class/end. >.<
|
210
|
+
loc_over_m = x_over_y(stats["codelines"], stats["methods"])
|
211
|
+
loc_over_m -= 2 if loc_over_m >= 2
|
212
|
+
|
213
|
+
@print_buffer << ROW_PATTERN % pad_elements([
|
214
|
+
name,
|
215
|
+
stats['lines'],
|
216
|
+
stats['codelines'],
|
217
|
+
stats['classes'],
|
218
|
+
stats['methods'],
|
219
|
+
x_over_y(stats["methods"], stats["classes"]),
|
220
|
+
loc_over_m,
|
221
|
+
])
|
222
|
+
end
|
223
|
+
|
224
|
+
def print_code_test_stats
|
225
|
+
code = calculate_code
|
226
|
+
tests = calculate_tests
|
227
|
+
|
228
|
+
ratio = if code!=0
|
229
|
+
"#{sprintf("%.1f", tests.to_f/code)}"
|
230
|
+
else
|
231
|
+
"0.0"
|
232
|
+
end
|
233
|
+
@print_buffer << " Code LOC: #{code} Test LOC: #{tests} Code to Test Ratio: 1:#{ratio}\n"
|
234
|
+
@print_buffer << "\n"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# This is for apps that already had a stats task, but want to use the newer
|
2
|
+
# features of this gem.
|
3
|
+
if(defined?(Rake::Task))
|
4
|
+
task :code_counter do
|
5
|
+
if ENV['IGNORE_FILE_GLOBS']
|
6
|
+
user_ignored_dirs = ENV['IGNORE_FILE_GLOBS'].split(',')
|
7
|
+
else
|
8
|
+
user_ignored_dirs = []
|
9
|
+
end
|
10
|
+
puts CodeCounter::Engine(user_ignored_dirs).to_s
|
11
|
+
end
|
12
|
+
|
13
|
+
unless(Rake::Task.task_defined?(:stats))
|
14
|
+
desc "Report code statistics (KLOCs, etc) from the application."
|
15
|
+
task :stats => :code_counter
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: code_counter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Frisby
|
8
|
+
- Dan Mayer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-06-06 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: This is a port of the rails 'rake stats' method so it can be made more
|
15
|
+
robust and work for non rails projects. New features may eventually be added as
|
16
|
+
well.
|
17
|
+
email: jfrisby@mrjoy.com
|
18
|
+
executables:
|
19
|
+
- code_counter
|
20
|
+
extensions: []
|
21
|
+
extra_rdoc_files:
|
22
|
+
- CHANGELOG.md
|
23
|
+
- LICENSE.md
|
24
|
+
- README.md
|
25
|
+
files:
|
26
|
+
- CHANGELOG.md
|
27
|
+
- LICENSE.md
|
28
|
+
- README.md
|
29
|
+
- bin/code_counter
|
30
|
+
- code_counter.gemspec
|
31
|
+
- lib/code_counter.rb
|
32
|
+
- lib/code_counter/cli.rb
|
33
|
+
- lib/code_counter/engine.rb
|
34
|
+
- lib/code_counter/rake.rb
|
35
|
+
- lib/code_counter/version.rb
|
36
|
+
homepage: http://github.com/MrJoy/code_counter
|
37
|
+
licenses:
|
38
|
+
- MIT
|
39
|
+
metadata: {}
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 1.9.2
|
49
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
requirements: []
|
55
|
+
rubyforge_project:
|
56
|
+
rubygems_version: 2.2.2
|
57
|
+
signing_key:
|
58
|
+
specification_version: 4
|
59
|
+
summary: Making a gem of the normal rails rake stats method, to make it more robust
|
60
|
+
and work on non rails projects
|
61
|
+
test_files: []
|