scrutinize 0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: cf550ed5c9b1d869f4f069c695689781597ab6a8
4
+ data.tar.gz: ab23c15b94668a85694be5e2cda6b550f3f8f2d4
5
+ SHA512:
6
+ metadata.gz: a34f3266961355ce8020f8013d32722e63e833aed7764068c99cba2432109d7ed87ec9f66a5d373ceb36249db0f8ebfb90127ac7fe49432982540fe04a19b6cb
7
+ data.tar.gz: eb8a279edc898a3188f2430c8c9708e2d5dcb097efc6b89a2e3a9df5af6cc228588f564a4256af080b215b1e7b2882fcdfcf3122d189ee4ce427c21b555e1deb
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # Scrutinize
2
+
3
+ Ruby method call searcher.
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ Usage: scrutinize [options] [method_name ...]
9
+ -t, --targets=MANDATORY A comma separated list of targets to search for the next set of methods on
10
+ -m, --methods=MANDATORY A comma separated list of methods to search for on the last listed set of targets
11
+ -d, --directory=MANDATORY The directory to search
12
+ -c, --config=MANDATORY A YAML config file to load
13
+ -r, --ruby-version=MANDATORY The Ruby version of the files we're searching through
14
+ -h, --help Show this message
15
+ ```
16
+
17
+ ### Examples
18
+
19
+ **Search for calls to `puts` on any target:**
20
+
21
+ ```
22
+ $ scrutinize puts
23
+ ./lib/sinatra/base.rb:1136 @env['rack.errors'].puts
24
+ ./lib/sinatra/base.rb:1416 $stderr.puts
25
+ ./test/integration/app.rb:58 puts
26
+ ...
27
+ ```
28
+
29
+ **Search for calls to `puts` with *no* target:**
30
+
31
+ ```
32
+ $ scrutinize -t SCRUTINIZE_NONE puts
33
+ ./test/integration/app.rb:58 puts
34
+ ```
35
+
36
+ **Search for calls to `read` or `write` on the `IO` or `File` modules:**
37
+
38
+ ```
39
+ $ scrutinize -t IO,File -m read,binread
40
+ ./lib/sinatra/base.rb:1275 IO.binread
41
+ ./lib/sinatra/base.rb:1275 IO.read
42
+ ./test/encoding_test.rb:13 File.read
43
+ ...
44
+ ```
45
+
46
+ **Search for calls to any method on the `IO` or `File` modules:**
47
+
48
+ ```
49
+ $ scrutinize -t IO,File
50
+ ./lib/sinatra/base.rb:44 File.fnmatch
51
+ ./lib/sinatra/base.rb:1275 IO.read
52
+ ./test/integration_helper.rb:26 File.expand_path
53
+ ./test/integration_helper.rb:42 IO.popen
54
+ ./test/yajl_test.rb:9 File.dirname
55
+ ...
56
+ ```
57
+
58
+ ## Installation
59
+
60
+ ```
61
+ bundle install
62
+ rake install
63
+ ```
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/scrutinize ADDED
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path('../../lib', __FILE__)
3
+ require 'scrutinize'
4
+ require 'optparse'
5
+ require 'yaml'
6
+
7
+ options = {'triggers' => [], 'dir' => '.'}
8
+ last_trigger = {}
9
+
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: scrutinize [options] [method_name ...]"
12
+
13
+ opts.on("-t", "--targets", "=MANDATORY", Array, "A comma separated list of targets to search for the next set of methods on") do |t|
14
+ if last_trigger['targets']
15
+ options['triggers'] << last_trigger
16
+ last_trigger = {}
17
+ end
18
+
19
+ last_trigger['targets'] = t
20
+ end
21
+
22
+ opts.on("-m", "--methods", "=MANDATORY", Array, "A comma separated list of methods to search for on the last listed set of targets") do |m|
23
+ if last_trigger['methods']
24
+ options['triggers'] << last_trigger
25
+ last_trigger = {}
26
+ end
27
+
28
+ last_trigger['methods'] = m
29
+ end
30
+
31
+ opts.on("-d", "--directory", "=MANDATORY", String, "The directory to search") do |d|
32
+ options['dir'] = d
33
+ end
34
+
35
+ opts.on("-c", "--config", "=MANDATORY", String, "A YAML config file to load") do |c|
36
+ options.merge! YAML.load File.read c
37
+ end
38
+
39
+ opts.on("-r", "--ruby-version", "=MANDATORY", String, "The Ruby version of the files we're searching through") do |r|
40
+ options['ruby_version'] = r
41
+ end
42
+
43
+ opts.on_tail("-h", "--help", "Show this message") do
44
+ puts opts
45
+ exit
46
+ end
47
+ end.parse!
48
+
49
+ last_trigger['methods'] = ARGV unless ARGV.empty?
50
+ options['triggers'] << last_trigger
51
+
52
+ Scrutinize.scan options
@@ -0,0 +1,110 @@
1
+ require 'scrutinize/trigger'
2
+
3
+ module Scrutinize
4
+ class Config
5
+ KNOWN_VERSIONS = %w(ruby18 ruby19 ruby20 ruby21 ruby22)
6
+
7
+ def initialize(opts = {})
8
+ @options = opts
9
+ end
10
+
11
+ def [](key)
12
+ @options[key]
13
+ end
14
+
15
+ def files
16
+ Dir.glob(File.join(@options['dir'], "**/*.rb"))
17
+ end
18
+
19
+ # Public: A Trigger object based on the configured options.
20
+ #
21
+ # Returns a Trigger.
22
+ def trigger
23
+ @trigger ||= begin
24
+ trigger = Scrutinize::Trigger.new
25
+
26
+ # Trigger configured at top level
27
+ keys = %w(methods method targets target)
28
+ unless (@options.keys & keys).empty?
29
+ trigger.add @options.select { |k,v| keys.include?(k) }
30
+ end
31
+
32
+ # Trigger configured under trigger key
33
+ trigger.add @options['trigger'] if @options['trigger'].is_a?(Hash)
34
+
35
+ # Triggers configured under triggers key
36
+ if @options['triggers'].is_a? Array
37
+ @options['triggers'].each { |t| trigger.add t }
38
+ end
39
+
40
+ trigger
41
+ end
42
+ end
43
+
44
+ # Public: The normalized Ruby version, inferred from RUBY_VERSION and the
45
+ # configured version.
46
+ #
47
+ # Returns a String.
48
+ def ruby_version
49
+ @ruby_version ||= begin
50
+ version = @options['ruby_version'] || RUBY_VERSION
51
+ normalize_version version
52
+ end
53
+ end
54
+
55
+ # Public: Set a new Ruby version.
56
+ #
57
+ # value - A String Ruby version.
58
+ #
59
+ # Returns the normalized value provided.
60
+ def ruby_version=(value)
61
+ normalize_version(value).tap do |version|
62
+ @ruby_version = @options['ruby_version'] = version
63
+ @ruby_parser = parser_for_version version
64
+ end
65
+ end
66
+
67
+ # Public: A Parser instance for the configured Ruby version.
68
+ #
69
+ # Returns a Parser.
70
+ def ruby_parser
71
+ @ruby_parser ||= parser_for_version ruby_version
72
+ end
73
+
74
+ private
75
+
76
+ # Normalize a Ruby version.
77
+ #
78
+ # version - A Ruby version String.
79
+ #
80
+ # Returns a String.
81
+ def normalize_version(version)
82
+ return version if KNOWN_VERSIONS.include?(version)
83
+
84
+ case version
85
+ when /^1\.8\./
86
+ 'ruby18'
87
+ when /^1\.9\./
88
+ 'ruby19'
89
+ when /^2\.0\./
90
+ 'ruby20'
91
+ when /^2\.1\./
92
+ 'ruby21'
93
+ when /^2\.2\./
94
+ 'ruby22'
95
+ else
96
+ raise NotImplementedError
97
+ end
98
+ end
99
+
100
+ # Get the correct Parser class for a given Ruby version.
101
+ #
102
+ # version - A Ruby version String.
103
+ #
104
+ # Returns a Parser class.
105
+ def parser_for_version(version)
106
+ require "parser/#{version}"
107
+ Parser.const_get version.capitalize
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,115 @@
1
+ module Scrutinize
2
+ class Processor
3
+ # Process a file with a Trigger.
4
+ #
5
+ # Returns nothing.
6
+ def self.process(file, trigger, parser)
7
+ new(file, trigger, parser).process
8
+ end
9
+
10
+ # Initialize a Processor instance.
11
+ #
12
+ # file - the file to be processed.
13
+ def initialize(file, trigger, parser)
14
+ @file = file
15
+ @trigger = trigger
16
+ @parser = parser
17
+ end
18
+
19
+ # Process the AST of the file.
20
+ #
21
+ # Returns nothing.
22
+ def process
23
+ process_node ast
24
+ rescue Parser::SyntaxError
25
+ end
26
+
27
+ # Recurse into an Parser::AST::Node, calling appropriate process functions
28
+ # for it and its children nodes.
29
+ #
30
+ # node - a Parser::AST::Node object.
31
+ #
32
+ # Returns nothing.
33
+ def process_node(node)
34
+ if node?(node)
35
+ process_send(node) if node.type == :send
36
+ node.children.each { |c| process_node c }
37
+ end
38
+ end
39
+
40
+ # Process a :send Parser::AST::Node. Call any registered handler for the
41
+ # target/method being invoked.
42
+ #
43
+ # node - a Parser::AST::Node object.
44
+ #
45
+ # Returns nothing.
46
+ def process_send(node)
47
+ target = get_src node.children[0] if node.children[0]
48
+ target = target.slice(2..-1) if node.children[0] && target.start_with?('::')
49
+ method = node.children[1]
50
+
51
+ if @trigger.match? target, method
52
+ puts "#{@file}:#{node.loc.line} #{target}#{'.' if target}#{method}"
53
+ end
54
+ end
55
+
56
+ # Is an object a Parser::AST::Node.
57
+ #
58
+ # node - the object to test.
59
+ #
60
+ # Returns true/false.
61
+ def node?(node)
62
+ node.is_a? Parser::AST::Node
63
+ end
64
+
65
+ # Gets the source code of a given node.
66
+ #
67
+ # node - a Parser::AST::Node object.
68
+ #
69
+ # Returns a String.
70
+ def get_src(node)
71
+ range = node.loc.expression
72
+
73
+ # Line numbers start at 1
74
+ begin_line = range.begin.line - 1
75
+ end_line = range.end.line - 1
76
+ middle_lines = begin_line + 1 ... end_line - 1
77
+
78
+ # Column numbers start at 0
79
+ begin_column = range.begin.column
80
+ end_column = range.end.column
81
+
82
+ # Beginning/ending on same line
83
+ if begin_line == end_line
84
+ return src_lines[begin_line][begin_column...end_column]
85
+ end
86
+
87
+ lines = []
88
+ lines << src_lines[begin_line][begin_column..-1]
89
+ lines += src_lines[middle_lines]
90
+ lines << src_lines[end_line][0...end_line]
91
+ lines.join "\n"
92
+ end
93
+
94
+ # The AST of the source code.
95
+ #
96
+ # Returns a Parser::AST::Node object.
97
+ def ast
98
+ @ast ||= @parser.parse src
99
+ end
100
+
101
+ # The source code, broken up into lines.
102
+ #
103
+ # Returns an Array of Strings.
104
+ def src_lines
105
+ @src_lines = src.lines.to_a
106
+ end
107
+
108
+ # The source code.
109
+ #
110
+ # Returns a String.
111
+ def src
112
+ @src ||= File.read @file
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,108 @@
1
+ require 'set'
2
+
3
+ module Scrutinize
4
+ class Trigger
5
+ ANY = Set.new(['SCRUTINIZE_ANY', true, nil])
6
+ NONE = Set.new(['SCRUTINIZE_NONE', false])
7
+
8
+ # Instantiate a new Trigger.
9
+ #
10
+ # Returns nothing.
11
+ def initialize
12
+ @targets = Set.new
13
+ @methods = Set.new
14
+ @target_methods = Set.new
15
+ @any_target_methods = Set.new
16
+ @any_method_targets = Set.new
17
+ @any_method_any_target = false
18
+ end
19
+
20
+ # Add targets/methods to the trigger.#
21
+ #
22
+ # criteria - A hash of targets/methods
23
+ # :targets - An Array of target names to trigger on. Setting to
24
+ # `true` means all targets match. Setting to nil
25
+ # means that only calls without a target match.
26
+ # :methods - An Array of method names to trigger on. Setting to
27
+ # `true` means all methods match.
28
+ #
29
+ # Returns nothing.
30
+ def add(criteria = {})
31
+ # Stop now if we're searching for everything.
32
+ return if @any_method_any_target
33
+
34
+ # Extract targets/methods from criteria
35
+ targets = Set.new
36
+ targets += Array(criteria['targets']) if criteria.key?('targets')
37
+ targets += Array(criteria['target']) if criteria.key?('target')
38
+ targets += [nil] if targets.empty? # Can't do Array(nil)
39
+
40
+ methods = Set.new
41
+ methods += Array(criteria['methods']) if criteria.key?('methods')
42
+ methods += Array(criteria['method']) if criteria.key?('method')
43
+ methods += [nil] if methods.empty? # Can't do Array(nil)
44
+
45
+ any_method = !(ANY & methods).empty?
46
+ any_target = !(ANY & targets).empty?
47
+
48
+ # Stop now if we're searching for everything.
49
+ if any_target && any_method
50
+ return @any_method_any_target = true
51
+ end
52
+
53
+ # Don't clean up methods if we're looking for all methods.
54
+ if !any_method
55
+ methods.map! &:to_sym
56
+ methods -= @any_target_methods
57
+ end
58
+
59
+ # Stop now if we're looking for any method.
60
+ if any_target
61
+ return @any_target_methods += methods
62
+ end
63
+
64
+ # Clean up targets, preserving no target case.
65
+ if !(targets & NONE).empty?
66
+ targets -= NONE
67
+ targets.map! &:to_sym
68
+ targets.add nil
69
+ else
70
+ targets.map! &:to_str
71
+ end
72
+ targets -= @any_method_targets
73
+
74
+ # Stop now if we're looking for any target.
75
+ if any_method
76
+ return @any_method_targets += targets
77
+ end
78
+
79
+ # Track all the methods/targets we've seen for faster checks.
80
+ @methods += methods
81
+ @targets += targets
82
+
83
+ # Track each target/method combo.
84
+ targets.each do |target|
85
+ methods.each do |method|
86
+ @target_methods.add [target, method]
87
+ end
88
+ end
89
+ end
90
+
91
+ # Checks if a given target/method match the configuration.
92
+ #
93
+ # target - A String target name.
94
+ # method - A Symbol method name.
95
+ #
96
+ # Returns boolean.
97
+ def match?(target, method)
98
+ @any_method_any_target ||
99
+ @any_method_targets.include?(target) ||
100
+ @any_target_methods.include?(method) ||
101
+ (
102
+ @targets.include?(target) &&
103
+ @methods.include?(method) &&
104
+ @target_methods.include?([target, method])
105
+ )
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,3 @@
1
+ module Scrutinize
2
+ VERSION = "0.0.1"
3
+ end
data/lib/scrutinize.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'scrutinize/config'
2
+ require 'scrutinize/processor'
3
+
4
+ module Scrutinize
5
+ extend self
6
+
7
+ def scan(opts)
8
+ config = Config.new opts
9
+ config.files.each do |file|
10
+ Processor.process(file, config.trigger, config.ruby_parser)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ $:.unshift File.expand_path('../lib', __FILE__)
3
+ require 'scrutinize/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "scrutinize"
7
+ spec.version = Scrutinize::VERSION
8
+ spec.authors = ["Ben Toews"]
9
+ spec.email = ["mastahyeti@gmail.com"]
10
+ spec.summary = %q{Ruby method call finder}
11
+
12
+ spec.files = `git ls-files -z`.split("\x0")
13
+ spec.executables = ["scrutinize"]
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_dependency "parser", "~> 2.1.9"
17
+
18
+ spec.add_development_dependency "rspec"
19
+ spec.add_development_dependency "bundler", "~> 1.6"
20
+ spec.add_development_dependency "rake"
21
+ end
@@ -0,0 +1,80 @@
1
+ require 'scrutinize/config'
2
+
3
+ describe Scrutinize::Config do
4
+ describe "with unspecified ruby_version" do
5
+ subject { Scrutinize::Config.new }
6
+
7
+ it "uses RUBY_VERSION" do
8
+ expected = \
9
+ case RUBY_VERSION
10
+ when /^1\.8\./
11
+ 'ruby18'
12
+ when /^1\.9\./
13
+ 'ruby19'
14
+ when /^2\.0\./
15
+ 'ruby20'
16
+ when /^2\.1\./
17
+ 'ruby21'
18
+ when /^2\.2\./
19
+ 'ruby22'
20
+ end
21
+
22
+ expect(subject.ruby_version).to eq(expected)
23
+ end
24
+
25
+ it "can be set to other versions" do
26
+ subject.ruby_version = "1.8.7"
27
+ expect(subject.ruby_version).to eq('ruby18')
28
+ end
29
+
30
+ it "parses crazy versions" do
31
+ subject.ruby_version = "1.8.7.0.0alpha"
32
+ expect(subject.ruby_version).to eq('ruby18')
33
+ end
34
+
35
+ it "selects a parser accordingly" do
36
+ subject.ruby_version = "1.8.7"
37
+ expect(subject.ruby_parser.to_s).to eq("Parser::Ruby18")
38
+ end
39
+
40
+ it "raises for bad ruby versions" do
41
+ expect { subject.ruby_version = "9.9.9" }.to raise_error(NotImplementedError)
42
+ end
43
+ end
44
+
45
+ describe "with specified trigger options" do
46
+ it "allows target/method at top level of options" do
47
+ c = Scrutinize::Config.new 'target' => 'File', 'method' => 'read'
48
+
49
+ expect(c.trigger.match?('File', :read)).to eq(true)
50
+ expect(c.trigger.match?('Foo', :read)).to eq(false)
51
+ expect(c.trigger.match?('File', :foo)).to eq(false)
52
+ end
53
+
54
+ it "allows target/method under trigger key" do
55
+ c = Scrutinize::Config.new(
56
+ 'trigger' => {
57
+ 'target' => 'File',
58
+ 'method' => 'read'
59
+ }
60
+ )
61
+
62
+ expect(c.trigger.match?('File', :read)).to eq(true)
63
+ expect(c.trigger.match?('Foo', :read)).to eq(false)
64
+ expect(c.trigger.match?('File', :foo)).to eq(false)
65
+ end
66
+
67
+ it "allows target/method under triggers key" do
68
+ c = Scrutinize::Config.new(
69
+ 'triggers' => [{
70
+ 'target' => 'File',
71
+ 'method' => 'read'
72
+ }]
73
+ )
74
+
75
+ expect(c.trigger.match?('File', :read)).to eq(true)
76
+ expect(c.trigger.match?('Foo', :read)).to eq(false)
77
+ expect(c.trigger.match?('File', :foo)).to eq(false)
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,96 @@
1
+ require 'scrutinize/trigger'
2
+
3
+ describe Scrutinize::Trigger, "#match?" do
4
+ describe "targets matching any method" do
5
+ subject do
6
+ Scrutinize::Trigger.new.tap do |target|
7
+ target.add 'targets' => %w(File IO)
8
+ end
9
+ end
10
+
11
+ it "matches any method for the targets" do
12
+ expect(subject.match?('File', :write)).to eq(true)
13
+ expect(subject.match?('IO', :read)).to eq(true)
14
+ end
15
+
16
+ it "doesn't match methods for other targets" do
17
+ expect(subject.match?('Foo', :bar)).to eq(false)
18
+ end
19
+ end
20
+
21
+ describe "methods matching any target" do
22
+ subject do
23
+ Scrutinize::Trigger.new.tap do |target|
24
+ target.add 'methods' => %w(read write)
25
+ end
26
+ end
27
+
28
+ it "matches any targets for the methods" do
29
+ expect(subject.match?('Foo', :write)).to eq(true)
30
+ expect(subject.match?('Bar', :read)).to eq(true)
31
+ end
32
+
33
+ it "matches nil targets for the method" do
34
+ expect(subject.match?(nil, :write)).to eq(true)
35
+ end
36
+
37
+ it "doesn't match methods for other targets" do
38
+ expect(subject.match?('Foo', :bar)).to eq(false)
39
+ end
40
+ end
41
+
42
+ describe "any target matching any method" do
43
+ subject do
44
+ Scrutinize::Trigger.new.tap do |target|
45
+ target.add 'target' => nil, 'method' => nil
46
+ end
47
+ end
48
+
49
+ it "matches any method and any target" do
50
+ expect(subject.match?('Foo', :write)).to eq(true)
51
+ expect(subject.match?('Bar', :read)).to eq(true)
52
+ end
53
+ end
54
+
55
+ describe "specific methods and targets" do
56
+ subject do
57
+ Scrutinize::Trigger.new.tap do |target|
58
+ target.add 'target' => 'IO', 'methods' => %w(select read)
59
+ target.add 'target' => 'File', 'methods' => %w(read write)
60
+ end
61
+ end
62
+
63
+ it "matches specified methods/targets" do
64
+ expect(subject.match?('IO', :select)).to eq(true)
65
+ expect(subject.match?('IO', :read)).to eq(true)
66
+ expect(subject.match?('File', :read)).to eq(true)
67
+ expect(subject.match?('File', :write)).to eq(true)
68
+ end
69
+
70
+ it "doesn't match other methods/targets" do
71
+ expect(subject.match?('File', :select)).to eq(false)
72
+ expect(subject.match?('IO', :write)).to eq(false)
73
+ expect(subject.match?('Foo', :bar)).to eq(false)
74
+ end
75
+ end
76
+
77
+ describe "none target with specific methods" do
78
+ subject do
79
+ Scrutinize::Trigger.new.tap do |target|
80
+ target.add 'target' => false, 'methods' => %w(read)
81
+ end
82
+ end
83
+
84
+ it "matches specific methods with none target" do
85
+ expect(subject.match?(nil, :read)).to eq(true)
86
+ end
87
+
88
+ it "doesn't match methods with a target" do
89
+ expect(subject.match?('IO', :read)).to eq(false)
90
+ end
91
+
92
+ it "doesn't match other methods with none target" do
93
+ expect(subject.match?(nil, :foo)).to eq(false)
94
+ end
95
+ end
96
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scrutinize
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ben Toews
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.1.9
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.1.9
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.6'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description:
70
+ email:
71
+ - mastahyeti@gmail.com
72
+ executables:
73
+ - scrutinize
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - README.md
80
+ - Rakefile
81
+ - bin/scrutinize
82
+ - lib/scrutinize.rb
83
+ - lib/scrutinize/config.rb
84
+ - lib/scrutinize/processor.rb
85
+ - lib/scrutinize/trigger.rb
86
+ - lib/scrutinize/version.rb
87
+ - scrutinize.gemspec
88
+ - spec/config_spec.rb
89
+ - spec/trigger_spec.rb
90
+ homepage:
91
+ licenses: []
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.2.2
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: Ruby method call finder
113
+ test_files: []