scrutinize 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []