critique 0.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.
- data/.gemset +1 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/.rvmrc +11 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +55 -0
- data/Rakefile +24 -0
- data/bootstrap.gems +2 -0
- data/critique.gemspec +24 -0
- data/lib/critique/profiling.rb +114 -0
- data/lib/critique/version.rb +3 -0
- data/lib/critique.rb +51 -0
- data/spec/critique_spec.rb +82 -0
- data/spec/process.rb +83 -0
- data/spec/spec_helper.rb +18 -0
- metadata +122 -0
data/.gemset
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
RVM_GEMSET="ruby-1.9.3@critique"
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--colour
|
data/.rvmrc
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Corey Innis
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# Critique
|
2
|
+
|
3
|
+
**WIP**
|
4
|
+
|
5
|
+
critiques your code... simple memory profiling with easy setup (e.g., no need to patch ruby).
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'critique'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install critique
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
given your code:
|
24
|
+
|
25
|
+
class ExampleClass
|
26
|
+
include Critique
|
27
|
+
|
28
|
+
def method
|
29
|
+
critique do
|
30
|
+
# code
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
enable Critique:
|
36
|
+
|
37
|
+
Critique.enable! # e.g., in a Rails initializer
|
38
|
+
Critique.logger = $stdout
|
39
|
+
# or...
|
40
|
+
# Critique.logger = 'path/to/log'
|
41
|
+
# Critique.logger = Rails.logger
|
42
|
+
|
43
|
+
run & view logs:
|
44
|
+
|
45
|
+
X ExampleClass#method --> ... used: 6.60 GB free: 1.59 GB
|
46
|
+
X ExampleClass#method <-- ... used: 6.62 GB free: 1.57 GB delta: +0.32%
|
47
|
+
|
48
|
+
|
49
|
+
## Contributing
|
50
|
+
|
51
|
+
1. Fork it
|
52
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
53
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
54
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
55
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require 'bundler/gem_tasks'
|
3
|
+
|
4
|
+
begin
|
5
|
+
Bundler.setup
|
6
|
+
rescue Bundler::BundlerError => e
|
7
|
+
$stderr.puts e.message
|
8
|
+
$stderr.puts 'run `bundle install` to install missing gems'
|
9
|
+
exit e.status_code
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rake'
|
13
|
+
require 'rspec/core/rake_task'
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
16
|
+
spec.rspec_opts = '-Ispec'
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
20
|
+
spec.rspec_opts = '-Ispec'
|
21
|
+
spec.rcov = true
|
22
|
+
end
|
23
|
+
|
24
|
+
task :default => :spec
|
data/bootstrap.gems
ADDED
data/critique.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/critique/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Corey Innis"]
|
6
|
+
gem.email = ["corey@coolerator.net"]
|
7
|
+
gem.description = %q{critiques your code}
|
8
|
+
gem.summary = %q{critiques your code}
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "critique"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Critique::VERSION
|
17
|
+
|
18
|
+
gem.required_ruby_version = ">= 1.9"
|
19
|
+
gem.add_development_dependency "bundler"
|
20
|
+
gem.add_development_dependency "rake"
|
21
|
+
gem.add_development_dependency "rspec"
|
22
|
+
gem.add_development_dependency "rr"
|
23
|
+
gem.add_development_dependency "simplecov"
|
24
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Critique
|
2
|
+
module Profiling
|
3
|
+
def self.profile(base, caller_offset = 0)
|
4
|
+
method_name = caller[caller_offset] =~ /`([^']*)'/ && $1
|
5
|
+
method_text = label_for(base, method_name)
|
6
|
+
|
7
|
+
Profiler.enter(method_text)
|
8
|
+
result = yield # (Profiler)
|
9
|
+
Profiler.leave(method_text)
|
10
|
+
|
11
|
+
result
|
12
|
+
end
|
13
|
+
|
14
|
+
class Profiler
|
15
|
+
class << self
|
16
|
+
def info(message)
|
17
|
+
Critique.logger.info(['X', padding, message].join)
|
18
|
+
end
|
19
|
+
|
20
|
+
def enter(label)
|
21
|
+
padding(:+)
|
22
|
+
before = stack.push(system_usage.push(label)).last
|
23
|
+
|
24
|
+
info(([label, '-->', filler(label)] + pretty(before)).join(' '))
|
25
|
+
end
|
26
|
+
|
27
|
+
def leave(label)
|
28
|
+
before = stack.pop
|
29
|
+
after = system_usage
|
30
|
+
|
31
|
+
info(([label, '<--', filler(label)] + pretty(after, before)).join(' '))
|
32
|
+
|
33
|
+
padding(:-)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def pretty(pair, diff_with = nil)
|
39
|
+
used = pair[0]
|
40
|
+
free = pair[1]
|
41
|
+
result = [
|
42
|
+
sprintf("used: %.2f GB", used / conversion_gb),
|
43
|
+
sprintf("free: %.2f GB", free / conversion_gb)
|
44
|
+
]
|
45
|
+
|
46
|
+
if diff_with
|
47
|
+
current = used
|
48
|
+
previous = diff_with[0]
|
49
|
+
bytes = (current - previous).to_f
|
50
|
+
percent = (bytes / previous) * 100
|
51
|
+
|
52
|
+
result.push(sprintf("delta: %+.2f%", percent))
|
53
|
+
end
|
54
|
+
|
55
|
+
result
|
56
|
+
end
|
57
|
+
|
58
|
+
def padding(direction = nil)
|
59
|
+
@_padding ||= 0
|
60
|
+
@_padding = @_padding.send(direction, 2) if direction
|
61
|
+
@_padding = 0 if @_padding < 0
|
62
|
+
(' ' * @_padding)
|
63
|
+
end
|
64
|
+
|
65
|
+
def filler(text)
|
66
|
+
'.' * (73 - text.length - @_padding) # data starting at column 80
|
67
|
+
end
|
68
|
+
|
69
|
+
def system_usage
|
70
|
+
# installed = `sysctl -n hw.memsize`.to_i / conversion_gb
|
71
|
+
|
72
|
+
stats = `vm_stat`.split("\n")
|
73
|
+
used = add_stats(stats, 'wired down', 'active', 'inactive')
|
74
|
+
free = add_stats(stats, 'free', 'speculative')
|
75
|
+
|
76
|
+
[used, free]
|
77
|
+
end
|
78
|
+
|
79
|
+
def add_stats(*args)
|
80
|
+
stats = args.shift
|
81
|
+
keys = args
|
82
|
+
matches = stats.select { |s| keys.any? { |k| s =~ /Pages #{k}:/ } }
|
83
|
+
values = matches.map { |m| m.split(/\s+/).last.to_i * conversion_paging }.inject(0, :+)
|
84
|
+
end
|
85
|
+
|
86
|
+
def conversion_paging
|
87
|
+
4096
|
88
|
+
end
|
89
|
+
|
90
|
+
def conversion_gb
|
91
|
+
(1024 * 1024 * 1000.0)
|
92
|
+
end
|
93
|
+
|
94
|
+
def stack
|
95
|
+
@_stack ||= []
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def self.label_for(base, method_name)
|
103
|
+
[label_class(base), label_sep(base), method_name].join
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.label_class(base)
|
107
|
+
base.is_a?(Class) ? base.name : base.class.name
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.label_sep(base)
|
111
|
+
base.is_a?(Class) ? '.' : '#'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
data/lib/critique.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
require "critique/version"
|
2
|
+
require "logger"
|
3
|
+
|
4
|
+
module Critique
|
5
|
+
autoload :Profiling, 'critique/profiling'
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def included(base)
|
9
|
+
base.extend(ClassMethods)
|
10
|
+
end
|
11
|
+
|
12
|
+
def profile(base)
|
13
|
+
yield
|
14
|
+
end
|
15
|
+
|
16
|
+
def disable!
|
17
|
+
module_eval("def self.profile(base) ; yield ; end")
|
18
|
+
end
|
19
|
+
|
20
|
+
def enable!
|
21
|
+
module_eval("def self.profile(base, &block) ; Profiling.profile(base, 2, &block) ; end")
|
22
|
+
@_enabled = true
|
23
|
+
end
|
24
|
+
|
25
|
+
def enabled?
|
26
|
+
@_enabled || false
|
27
|
+
end
|
28
|
+
|
29
|
+
def logger=(logger)
|
30
|
+
if logger.is_a?(IO) || logger.is_a?(String)
|
31
|
+
@_logger = Logger.new(logger)
|
32
|
+
else
|
33
|
+
@_logger = logger
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def logger
|
38
|
+
@_logger ||= Logger.new($stdout)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module ClassMethods
|
43
|
+
def critique(&block)
|
44
|
+
Critique.profile(self, &block)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def critique(&block)
|
49
|
+
Critique.profile(self, &block)
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Critique do
|
4
|
+
class ExampleClass
|
5
|
+
include Critique
|
6
|
+
end
|
7
|
+
|
8
|
+
before do
|
9
|
+
Critique.disable!
|
10
|
+
# Critique.logger = '/dev/null'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is defined" do
|
14
|
+
Critique.should be_a(Module)
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when included" do
|
18
|
+
it "defines .critique on the base class" do
|
19
|
+
ExampleClass.should respond_to(:critique)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "defines #critique on the base class" do
|
23
|
+
ExampleClass.new.should respond_to(:critique)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".enabled?" do
|
28
|
+
context "in the default state" do
|
29
|
+
it "returns false" do
|
30
|
+
Critique.should_not be_enabled
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when enabled" do
|
35
|
+
before do
|
36
|
+
Critique.enable!
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns true" do
|
40
|
+
Critique.should be_enabled
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe ".critique" do
|
46
|
+
let(:code) { 1 + 2 }
|
47
|
+
|
48
|
+
context "when disabled" do
|
49
|
+
it "does not execute profiling" do
|
50
|
+
dont_allow(Critique::Profiling).profile
|
51
|
+
ExampleClass.critique { code }
|
52
|
+
end
|
53
|
+
|
54
|
+
it "executes the code block" do
|
55
|
+
result = ExampleClass.critique { code }
|
56
|
+
result.should == 3
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when enabled" do
|
61
|
+
before do
|
62
|
+
Critique.enable!
|
63
|
+
end
|
64
|
+
|
65
|
+
it "executes profiling" do
|
66
|
+
mock(Critique::Profiling).profile(ExampleClass, 2)
|
67
|
+
ExampleClass.critique { code }
|
68
|
+
end
|
69
|
+
|
70
|
+
it "executes the code block" do
|
71
|
+
ExampleClass.critique { code }.should == 3
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "in the default (disabled) state" do
|
76
|
+
it "does not run profiling" do
|
77
|
+
dont_allow(Critique::Profiling).profile
|
78
|
+
ExampleClass.critique { code }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/spec/process.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'profiling'
|
2
|
+
|
3
|
+
unless ARGV.size == 2
|
4
|
+
puts "usage: ruby process.rb <filename.ext> <config>"
|
5
|
+
puts " e.g.,"
|
6
|
+
puts " ruby process.rb video.mov all"
|
7
|
+
puts " ruby process.rb video.mov 8k"
|
8
|
+
puts " ruby process.rb video.mov 10m"
|
9
|
+
end
|
10
|
+
|
11
|
+
filename = ARGV[0]
|
12
|
+
config = ARGV[1]
|
13
|
+
|
14
|
+
unless filename && File.exists?(filename)
|
15
|
+
puts "\n\nfile does not exist."
|
16
|
+
exit 1
|
17
|
+
end
|
18
|
+
|
19
|
+
class Processor
|
20
|
+
extend Profiling
|
21
|
+
include Profiling
|
22
|
+
|
23
|
+
attr_reader :path, :size
|
24
|
+
|
25
|
+
def initialize(path)
|
26
|
+
@path = path
|
27
|
+
@size = File.size(path)
|
28
|
+
end
|
29
|
+
|
30
|
+
def read_all
|
31
|
+
heading(:all)
|
32
|
+
|
33
|
+
profile do |p|
|
34
|
+
File.read(path) # NOTE: doing nothing with it
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def read_bytes(num)
|
39
|
+
bytes = num.to_i
|
40
|
+
bytes = (bytes * 1024) if num =~ /.*k$/i
|
41
|
+
bytes = (bytes * 1024 * 1024) if num =~ /.*m$/i
|
42
|
+
|
43
|
+
heading(:part, bytes)
|
44
|
+
|
45
|
+
profile do |p|
|
46
|
+
offset = 0
|
47
|
+
length = bytes
|
48
|
+
|
49
|
+
while offset < size
|
50
|
+
remain = size - offset
|
51
|
+
amount = (remain < length) ? remain : length
|
52
|
+
|
53
|
+
$stdout.print '.' # TODO: move to Profiling
|
54
|
+
$stdout.flush
|
55
|
+
|
56
|
+
File.read(path, amount, offset) # NOTE: doing nothing with it
|
57
|
+
offset += amount
|
58
|
+
end
|
59
|
+
|
60
|
+
$stdout.puts
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def heading(mode, length = nil)
|
65
|
+
puts [' ', ('-' * 76)].join
|
66
|
+
puts " process.rb... reading #{size} bytes (#{[mode, length].compact.join(' ')})"
|
67
|
+
puts [' ', ('-' * 76)].join
|
68
|
+
end
|
69
|
+
|
70
|
+
# def self.cls_method
|
71
|
+
# profile do |p|
|
72
|
+
# # p.info("method body")
|
73
|
+
# "return value"
|
74
|
+
# end
|
75
|
+
# end
|
76
|
+
end
|
77
|
+
|
78
|
+
if config == 'all'
|
79
|
+
Processor.new(filename).read_all
|
80
|
+
else
|
81
|
+
Processor.new(filename).read_bytes(config)
|
82
|
+
end
|
83
|
+
# Processor.cls_method
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
|
3
|
+
begin
|
4
|
+
Bundler.setup
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'critique'
|
12
|
+
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each do
|
13
|
+
|f| require f
|
14
|
+
end
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.mock_with :rr
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: critique
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Corey Innis
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-29 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: &70336553333680 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70336553333680
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70336553333200 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70336553333200
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rspec
|
38
|
+
requirement: &70336553332760 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70336553332760
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rr
|
49
|
+
requirement: &70336553332340 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70336553332340
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: simplecov
|
60
|
+
requirement: &70336553317820 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70336553317820
|
69
|
+
description: critiques your code
|
70
|
+
email:
|
71
|
+
- corey@coolerator.net
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gemset
|
77
|
+
- .gitignore
|
78
|
+
- .rspec
|
79
|
+
- .rvmrc
|
80
|
+
- Gemfile
|
81
|
+
- LICENSE
|
82
|
+
- README.md
|
83
|
+
- Rakefile
|
84
|
+
- bootstrap.gems
|
85
|
+
- critique.gemspec
|
86
|
+
- lib/critique.rb
|
87
|
+
- lib/critique/profiling.rb
|
88
|
+
- lib/critique/version.rb
|
89
|
+
- spec/critique_spec.rb
|
90
|
+
- spec/process.rb
|
91
|
+
- spec/spec_helper.rb
|
92
|
+
homepage: ''
|
93
|
+
licenses: []
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
none: false
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '1.9'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
segments:
|
111
|
+
- 0
|
112
|
+
hash: -4008275762118213474
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 1.8.11
|
116
|
+
signing_key:
|
117
|
+
specification_version: 3
|
118
|
+
summary: critiques your code
|
119
|
+
test_files:
|
120
|
+
- spec/critique_spec.rb
|
121
|
+
- spec/process.rb
|
122
|
+
- spec/spec_helper.rb
|