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 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
+ [![Code Climate](https://codeclimate.com/github/MrJoy/code_statistics.png)](https://codeclimate.com/github/MrJoy/code_statistics)
4
+ [![Coverage](https://codeclimate.com/github/MrJoy/code_statistics/coverage.png)](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
+
@@ -0,0 +1,3 @@
1
+ require File.join(File.dirname(__FILE__), 'code_counter', 'version')
2
+ require File.join(File.dirname(__FILE__), 'code_counter', 'engine')
3
+ require File.join(File.dirname(__FILE__), 'code_counter', 'rake')
@@ -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
@@ -0,0 +1,3 @@
1
+ module CodeCounter
2
+ VERSION='0.3.1'
3
+ 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: []