ruby-lint 0.0.5 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.asc +14 -14
- data/.gitignore +1 -0
- data/.yardopts +1 -1
- data/Gemfile +3 -3
- data/MANIFEST +16 -3
- data/benchmark/virtual_machine.rb +17 -0
- data/checksum/ruby-lint-0.0.5.gem.sha512 +1 -0
- data/doc/changelog.md +42 -0
- data/doc/configuration.md +133 -13
- data/lib/ruby-lint/analysis/shadowing_variables.rb +8 -14
- data/lib/ruby-lint/analysis/unused_variables.rb +17 -0
- data/lib/ruby-lint/ast/node.rb +18 -3
- data/lib/ruby-lint/cache.rb +121 -0
- data/lib/ruby-lint/cache_entry.rb +44 -0
- data/lib/ruby-lint/cli/analyze.rb +37 -18
- data/lib/ruby-lint/cli/plot.rb +94 -0
- data/lib/ruby-lint/cli.rb +1 -0
- data/lib/ruby-lint/configuration.rb +48 -3
- data/lib/ruby-lint/definition/ruby_method.rb +28 -1
- data/lib/ruby-lint/definition/ruby_object.rb +37 -3
- data/lib/ruby-lint/definition_builder/ruby_method.rb +4 -1
- data/lib/ruby-lint/definition_builder/ruby_module.rb +4 -1
- data/lib/ruby-lint/definition_generator.rb +3 -2
- data/lib/ruby-lint/definitions/core/arg0.rb +3 -1
- data/lib/ruby-lint/definitions/core/argf.rb +3 -1
- data/lib/ruby-lint/definitions/core/argument_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/argv.rb +3 -1
- data/lib/ruby-lint/definitions/core/array.rb +3 -1
- data/lib/ruby-lint/definitions/core/autoload.rb +3 -1
- data/lib/ruby-lint/definitions/core/basic_object.rb +2 -0
- data/lib/ruby-lint/definitions/core/bignum.rb +3 -1
- data/lib/ruby-lint/definitions/core/binding.rb +3 -1
- data/lib/ruby-lint/definitions/core/class.rb +2 -0
- data/lib/ruby-lint/definitions/core/comparable.rb +3 -1
- data/lib/ruby-lint/definitions/core/complex.rb +3 -1
- data/lib/ruby-lint/definitions/core/condition_variable.rb +3 -1
- data/lib/ruby-lint/definitions/core/continuation.rb +3 -1
- data/lib/ruby-lint/definitions/core/data.rb +3 -1
- data/lib/ruby-lint/definitions/core/date.rb +3 -1
- data/lib/ruby-lint/definitions/core/date_time.rb +3 -1
- data/lib/ruby-lint/definitions/core/default_record_separator.rb +3 -1
- data/lib/ruby-lint/definitions/core/digest.rb +3 -1
- data/lib/ruby-lint/definitions/core/dir.rb +3 -1
- data/lib/ruby-lint/definitions/core/encoding.rb +3 -1
- data/lib/ruby-lint/definitions/core/encoding_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/enumerable.rb +3 -1
- data/lib/ruby-lint/definitions/core/enumerator.rb +3 -1
- data/lib/ruby-lint/definitions/core/env.rb +4 -1
- data/lib/ruby-lint/definitions/core/eoferror.rb +3 -1
- data/lib/ruby-lint/definitions/core/erb.rb +2 -0
- data/lib/ruby-lint/definitions/core/errno.rb +3 -1
- data/lib/ruby-lint/definitions/core/etc.rb +3 -1
- data/lib/ruby-lint/definitions/core/exception.rb +3 -1
- data/lib/ruby-lint/definitions/core/false.rb +3 -1
- data/lib/ruby-lint/definitions/core/false_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/fatal_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/fiber.rb +3 -1
- data/lib/ruby-lint/definitions/core/fiber_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/file.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_list.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_test.rb +3 -1
- data/lib/ruby-lint/definitions/core/file_utils.rb +3 -1
- data/lib/ruby-lint/definitions/core/fixnum.rb +3 -1
- data/lib/ruby-lint/definitions/core/float.rb +3 -1
- data/lib/ruby-lint/definitions/core/float_domain_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/gc.rb +3 -1
- data/lib/ruby-lint/definitions/core/gem.rb +3 -1
- data/lib/ruby-lint/definitions/core/hash.rb +3 -1
- data/lib/ruby-lint/definitions/core/immediate_value.rb +3 -1
- data/lib/ruby-lint/definitions/core/index_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/integer.rb +3 -1
- data/lib/ruby-lint/definitions/core/interrupt.rb +3 -1
- data/lib/ruby-lint/definitions/core/io.rb +3 -1
- data/lib/ruby-lint/definitions/core/ioerror.rb +3 -1
- data/lib/ruby-lint/definitions/core/kernel.rb +2 -0
- data/lib/ruby-lint/definitions/core/key_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/load_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/local_jump_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/marshal.rb +3 -1
- data/lib/ruby-lint/definitions/core/match_data.rb +3 -1
- data/lib/ruby-lint/definitions/core/math.rb +3 -1
- data/lib/ruby-lint/definitions/core/memory_segmention_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/method.rb +3 -1
- data/lib/ruby-lint/definitions/core/module.rb +2 -0
- data/lib/ruby-lint/definitions/core/monitor.rb +3 -1
- data/lib/ruby-lint/definitions/core/monitor_mixin.rb +3 -1
- data/lib/ruby-lint/definitions/core/mutex.rb +3 -1
- data/lib/ruby-lint/definitions/core/name_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/nil.rb +3 -1
- data/lib/ruby-lint/definitions/core/nil_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/no_memory_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/no_method_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/not_implemented_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/numeric.rb +3 -1
- data/lib/ruby-lint/definitions/core/object.rb +3 -1
- data/lib/ruby-lint/definitions/core/object_space.rb +3 -1
- data/lib/ruby-lint/definitions/core/open_struct.rb +3 -1
- data/lib/ruby-lint/definitions/core/option_parser.rb +3 -1
- data/lib/ruby-lint/definitions/core/precision.rb +3 -1
- data/lib/ruby-lint/definitions/core/primitive_failure.rb +3 -1
- data/lib/ruby-lint/definitions/core/proc.rb +3 -1
- data/lib/ruby-lint/definitions/core/process.rb +3 -1
- data/lib/ruby-lint/definitions/core/queue.rb +3 -1
- data/lib/ruby-lint/definitions/core/rake.rb +3 -1
- data/lib/ruby-lint/definitions/core/rake_file_utils.rb +3 -1
- data/lib/ruby-lint/definitions/core/rakeversion.rb +3 -1
- data/lib/ruby-lint/definitions/core/random.rb +3 -1
- data/lib/ruby-lint/definitions/core/range.rb +3 -1
- data/lib/ruby-lint/definitions/core/range_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/rational.rb +3 -1
- data/lib/ruby-lint/definitions/core/rb_config.rb +3 -1
- data/lib/ruby-lint/definitions/core/regexp.rb +3 -1
- data/lib/ruby-lint/definitions/core/regexp_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_copyright.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_description.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_engine.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_patchlevel.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_platform.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_release_date.rb +3 -1
- data/lib/ruby-lint/definitions/core/ruby_version.rb +3 -1
- data/lib/ruby-lint/definitions/core/runtime_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/scan_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/script_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/security_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/shellwords.rb +3 -1
- data/lib/ruby-lint/definitions/core/signal.rb +3 -1
- data/lib/ruby-lint/definitions/core/signal_exception.rb +3 -1
- data/lib/ruby-lint/definitions/core/singleton.rb +3 -1
- data/lib/ruby-lint/definitions/core/sized_queue.rb +3 -1
- data/lib/ruby-lint/definitions/core/standard_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/stderr.rb +2 -0
- data/lib/ruby-lint/definitions/core/stdin.rb +2 -0
- data/lib/ruby-lint/definitions/core/stdout.rb +2 -0
- data/lib/ruby-lint/definitions/core/stop_iteration.rb +3 -1
- data/lib/ruby-lint/definitions/core/string.rb +3 -1
- data/lib/ruby-lint/definitions/core/string_io.rb +3 -1
- data/lib/ruby-lint/definitions/core/string_scanner.rb +3 -1
- data/lib/ruby-lint/definitions/core/struct.rb +3 -1
- data/lib/ruby-lint/definitions/core/syck.rb +3 -1
- data/lib/ruby-lint/definitions/core/symbol.rb +3 -1
- data/lib/ruby-lint/definitions/core/syntax_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_call_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_exit.rb +3 -1
- data/lib/ruby-lint/definitions/core/system_stack_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/thread_group.rb +3 -1
- data/lib/ruby-lint/definitions/core/time.rb +3 -1
- data/lib/ruby-lint/definitions/core/toplevel_binding.rb +3 -1
- data/lib/ruby-lint/definitions/core/true.rb +3 -1
- data/lib/ruby-lint/definitions/core/true_class.rb +3 -1
- data/lib/ruby-lint/definitions/core/type_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/unbound_method.rb +3 -1
- data/lib/ruby-lint/definitions/core/unmarshalable.rb +3 -1
- data/lib/ruby-lint/definitions/core/unsupported_library_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/weak_ref.rb +3 -1
- data/lib/ruby-lint/definitions/core/yaml.rb +1 -0
- data/lib/ruby-lint/definitions/core/zero_division_error.rb +3 -1
- data/lib/ruby-lint/definitions/core/zlib.rb +8840 -0
- data/lib/ruby-lint/definitions/rails/abstract_controller.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_controller.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_dispatch.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_mailer.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_pack.rb +1 -0
- data/lib/ruby-lint/definitions/rails/action_view.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_model.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_record.rb +1 -0
- data/lib/ruby-lint/definitions/rails/active_support.rb +1 -0
- data/lib/ruby-lint/definitions/rails/arel.rb +1 -0
- data/lib/ruby-lint/definitions/rails/rails.rb +1 -0
- data/lib/ruby-lint/definitions/rails/sprockets.rb +1 -0
- data/lib/ruby-lint/file_scanner.rb +2 -0
- data/lib/ruby-lint/iterator.rb +21 -12
- data/lib/ruby-lint/method_call_info.rb +31 -0
- data/lib/ruby-lint/node_hash.rb +105 -0
- data/lib/ruby-lint/parser.rb +4 -2
- data/lib/ruby-lint/runner.rb +62 -6
- data/lib/ruby-lint/template/definition.erb +2 -0
- data/lib/ruby-lint/version.rb +1 -1
- data/lib/ruby-lint/virtual_machine.rb +75 -43
- data/lib/ruby-lint.rb +20 -2
- data/profiling/virtual_machine.rb +20 -0
- data/ruby-lint.gemspec +2 -1
- data/spec/fixtures/complex/rcap.rb +29 -0
- data/spec/fixtures/complex/slop.rb +21 -0
- data/spec/fixtures/file_scanner/lib/ruby-lint/definition/constant_proxy.rb +6 -0
- data/spec/fixtures/file_scanner/lib/ruby-lint/global_scope.rb +6 -0
- data/spec/ruby-lint/analysis/unused_variables_spec.rb +114 -0
- data/spec/ruby-lint/cache_entry_spec.rb +25 -0
- data/spec/ruby-lint/cache_spec.rb +53 -0
- data/spec/ruby-lint/definition/ruby_method_spec.rb +4 -4
- data/spec/ruby-lint/definition/ruby_object_spec.rb +33 -0
- data/spec/ruby-lint/iterator_spec.rb +15 -0
- data/spec/ruby-lint/node_hash_spec.rb +56 -0
- data/spec/ruby-lint/runner_spec.rb +6 -1
- data/spec/ruby-lint/virtual_machine/assignments/variables_spec.rb +2 -2
- data/spec/ruby-lint/virtual_machine/location_spec.rb +64 -0
- data/spec/ruby-lint/virtual_machine/method_call_tracking_spec.rb +64 -0
- data/spec/spec_helper.rb +7 -0
- data/task/generate.rake +1 -1
- data.tar.gz.asc +14 -14
- metadata +34 -7
- metadata.gz.asc +14 -14
- data/debug/memory_usage.rb +0 -14
- data/debug/profile.rb +0 -18
- data/task/profile.rake +0 -27
data/lib/ruby-lint/ast/node.rb
CHANGED
@@ -11,21 +11,21 @@ module RubyLint
|
|
11
11
|
# @return [Numeric]
|
12
12
|
#
|
13
13
|
def line
|
14
|
-
return location.expression.line
|
14
|
+
return location.expression.line if location
|
15
15
|
end
|
16
16
|
|
17
17
|
##
|
18
18
|
# @return [Numeric]
|
19
19
|
#
|
20
20
|
def column
|
21
|
-
return location.expression.column
|
21
|
+
return location.expression.column if location
|
22
22
|
end
|
23
23
|
|
24
24
|
##
|
25
25
|
# @return [String]
|
26
26
|
#
|
27
27
|
def file
|
28
|
-
return location.expression.source_buffer.name
|
28
|
+
return location.expression.source_buffer.name if location
|
29
29
|
end
|
30
30
|
|
31
31
|
##
|
@@ -44,6 +44,21 @@ module RubyLint
|
|
44
44
|
def inspect_oneline
|
45
45
|
return inspect.gsub(/\s*\n\s*/, ' ')
|
46
46
|
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Generates a unique SHA1 digest hash based on the current node.
|
50
|
+
#
|
51
|
+
# @return [String]
|
52
|
+
#
|
53
|
+
def sha1
|
54
|
+
input = inspect
|
55
|
+
|
56
|
+
if location and location.expression
|
57
|
+
input << "#{file}#{line}#{column}"
|
58
|
+
end
|
59
|
+
|
60
|
+
return Digest::SHA1.hexdigest(input)
|
61
|
+
end
|
47
62
|
end # Node
|
48
63
|
end # AST
|
49
64
|
end # RubyLint
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module RubyLint
|
2
|
+
##
|
3
|
+
# The Cache class is used for storing arbitrary Ruby objects in a cache
|
4
|
+
# directory. The primary use case of this class is to store cached ASTs and
|
5
|
+
# their comment associations (as is done by {RubyLint::Runner}).
|
6
|
+
#
|
7
|
+
# @!attribute [r] directory
|
8
|
+
# @return [String]
|
9
|
+
#
|
10
|
+
class Cache
|
11
|
+
attr_reader :directory
|
12
|
+
|
13
|
+
##
|
14
|
+
# The version of the cache format.
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
#
|
18
|
+
FORMAT_VERSION = '1'
|
19
|
+
|
20
|
+
##
|
21
|
+
# @param [String] directory Path to the cache directory.
|
22
|
+
#
|
23
|
+
def initialize(directory)
|
24
|
+
@directory = directory
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Creates the directory specified in {#directory} unless it already exists.
|
29
|
+
#
|
30
|
+
def create_directory!
|
31
|
+
Dir.mkdir(directory) unless File.directory?(directory)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Checks if there's a cache entry for the given name.
|
36
|
+
#
|
37
|
+
# @return [TrueClass|FalseClass]
|
38
|
+
#
|
39
|
+
def exists?(name)
|
40
|
+
return File.file?(entry_filepath(name))
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Returns the cache entry for the given name or `nil` if the entry doesn't
|
45
|
+
# exist.
|
46
|
+
#
|
47
|
+
# @param [String] name
|
48
|
+
# @return [Mixed]
|
49
|
+
#
|
50
|
+
def get(name)
|
51
|
+
return unless exists?(name)
|
52
|
+
|
53
|
+
data = File.read(entry_filepath(name))
|
54
|
+
|
55
|
+
return decode(data)
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Sets the cache entry to the given value. Existing cache entries are
|
60
|
+
# overwritten.
|
61
|
+
#
|
62
|
+
# @param [String] name
|
63
|
+
# @param [Mixed] value
|
64
|
+
#
|
65
|
+
def set(name, value)
|
66
|
+
File.open(entry_filepath(name), 'w') do |handle|
|
67
|
+
handle.write(encode(value))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Removes a cache entry.
|
73
|
+
#
|
74
|
+
# @param [String] name
|
75
|
+
#
|
76
|
+
def delete(name)
|
77
|
+
File.unlink(entry_filepath(name)) if exists?(name)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
##
|
83
|
+
# Returns the filename for the given entry name.
|
84
|
+
#
|
85
|
+
# @param [String] name
|
86
|
+
# @return [String]
|
87
|
+
#
|
88
|
+
def entry_filename(name)
|
89
|
+
return "#{name}.#{FORMAT_VERSION}.cache"
|
90
|
+
end
|
91
|
+
|
92
|
+
##
|
93
|
+
# Returns the full filename of the cache entry's name.
|
94
|
+
#
|
95
|
+
# @param [String] name
|
96
|
+
# @return [String]
|
97
|
+
#
|
98
|
+
def entry_filepath(name)
|
99
|
+
return File.join(directory, entry_filename(name))
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Decodes a cache entry.
|
104
|
+
#
|
105
|
+
# @param [String] input
|
106
|
+
# @return [Mixed]
|
107
|
+
#
|
108
|
+
def decode(input)
|
109
|
+
return Marshal.load(Zlib::Inflate.inflate(input))
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Encodes a cache entry.
|
114
|
+
#
|
115
|
+
# @param [String] input
|
116
|
+
#
|
117
|
+
def encode(input)
|
118
|
+
return Zlib::Deflate.deflate(Marshal.dump(input))
|
119
|
+
end
|
120
|
+
end # Cache
|
121
|
+
end # RubyLint
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module RubyLint
|
2
|
+
##
|
3
|
+
# The CacheEntry class is used to store nodes, comments and file modification
|
4
|
+
# times that belong to a certain root AST. It's primarily used by
|
5
|
+
# {RubyLint::Runner}.
|
6
|
+
#
|
7
|
+
# @!attribute [r] nodes
|
8
|
+
# @return [Array]
|
9
|
+
#
|
10
|
+
# @!attribute [r] comments
|
11
|
+
# @return [Hash]
|
12
|
+
#
|
13
|
+
# @!attribute [r] mtimes
|
14
|
+
# @return [Hash]
|
15
|
+
#
|
16
|
+
class CacheEntry
|
17
|
+
attr_reader :nodes, :comments, :mtimes
|
18
|
+
|
19
|
+
##
|
20
|
+
# @param [Array] nodes
|
21
|
+
# @param [Hash] comments
|
22
|
+
# @param [Hash] mtimes
|
23
|
+
#
|
24
|
+
def initialize(nodes, comments, mtimes)
|
25
|
+
@nodes = nodes
|
26
|
+
@comments = comments
|
27
|
+
@mtimes = mtimes
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Returns `true` if none of the associated files have been modified,
|
32
|
+
# `false` otherwise.
|
33
|
+
#
|
34
|
+
# @return [TrueClass|FalseClass]
|
35
|
+
#
|
36
|
+
def valid?
|
37
|
+
mtimes.each do |file, mtime|
|
38
|
+
return false if File.mtime(file) != mtime
|
39
|
+
end
|
40
|
+
|
41
|
+
return true
|
42
|
+
end
|
43
|
+
end # CacheEntry
|
44
|
+
end # RubyLint
|
@@ -61,6 +61,8 @@ Examples:
|
|
61
61
|
on :b, :benchmark, 'Enables benchmarking mode'
|
62
62
|
on :d, :debug, 'Displays debugging output in STDERR'
|
63
63
|
|
64
|
+
on :'disable-cache', 'Disables caching of external files'
|
65
|
+
|
64
66
|
##
|
65
67
|
# Returns an Array containing the file paths that exist. If a non existing
|
66
68
|
# file is encountered `abort` is called.
|
@@ -110,6 +112,36 @@ Examples:
|
|
110
112
|
@output_destination = destination
|
111
113
|
end
|
112
114
|
|
115
|
+
##
|
116
|
+
# @param [RubyLint::Configuration] configuration
|
117
|
+
# @param [Hash] opts
|
118
|
+
#
|
119
|
+
def configure(configuration, options)
|
120
|
+
option_mapping.each do |key, setter|
|
121
|
+
configuration.send(setter, options[key]) if options[key]
|
122
|
+
end
|
123
|
+
|
124
|
+
if options[:'disable-cache']
|
125
|
+
configuration.enable_cache = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# @param [String] output
|
131
|
+
# @param [Float] exec_time
|
132
|
+
#
|
133
|
+
def show_benchmark_info(output, exec_time)
|
134
|
+
memory_kb = `ps -o rss= #{Process.pid}`.strip.to_f
|
135
|
+
memory_mb = memory_kb / 1024
|
136
|
+
|
137
|
+
output_destination.puts unless output.empty?
|
138
|
+
|
139
|
+
output_destination.puts "Execution time: #{exec_time.round(4)} seconds"
|
140
|
+
|
141
|
+
output_destination.puts "Memory usage: #{memory_mb.round(2)} MB " \
|
142
|
+
"(#{memory_kb.round(2)} KB)"
|
143
|
+
end
|
144
|
+
|
113
145
|
run do |opts, args|
|
114
146
|
abort 'You must specify at least one file to analyze' if args.empty?
|
115
147
|
|
@@ -117,27 +149,14 @@ Examples:
|
|
117
149
|
files = extract_files(args)
|
118
150
|
configuration = RubyLint::Configuration.load_from_file
|
119
151
|
|
120
|
-
|
121
|
-
configuration.send(setter, opts[key]) if opts[key]
|
122
|
-
end
|
123
|
-
|
124
|
-
runner = RubyLint::Runner.new(configuration)
|
125
|
-
output = runner.analyze(files)
|
126
|
-
|
127
|
-
output_destination.puts output unless output.empty?
|
152
|
+
configure(configuration, opts)
|
128
153
|
|
154
|
+
runner = RubyLint::Runner.new(configuration)
|
155
|
+
output = runner.analyze(files)
|
129
156
|
exec_time = Time.now.to_f - start_time
|
130
157
|
|
131
|
-
|
132
|
-
memory_kb = `ps -o rss= #{Process.pid}`.strip.to_f
|
133
|
-
memory_mb = memory_kb / 1024
|
134
|
-
|
135
|
-
output_destination.puts unless output.empty?
|
136
|
-
|
137
|
-
output_destination.puts "Execution time: #{exec_time.round(2)} seconds"
|
158
|
+
output_destination.puts output unless output.empty?
|
138
159
|
|
139
|
-
|
140
|
-
"(#{memory_kb.round(2)} KB)"
|
141
|
-
end
|
160
|
+
show_benchmark_info(output, exec_time) if opts[:benchmark]
|
142
161
|
end # run do |opts, args|
|
143
162
|
end # RubyLint::CLI.options.command
|
@@ -0,0 +1,94 @@
|
|
1
|
+
#:nocov:
|
2
|
+
RubyLint::CLI.options.command :plot do
|
3
|
+
banner 'Usage: ruby-lint plot [FILE] [OPTIONS]'
|
4
|
+
description 'Plots analysis time of a single file'
|
5
|
+
|
6
|
+
separator RubyLint::CLI::OPTIONS_HEADER
|
7
|
+
|
8
|
+
RubyLint::CLI.help_option(self)
|
9
|
+
|
10
|
+
on :i=, :iterations=,
|
11
|
+
'The amount of iterations',
|
12
|
+
:as => Integer,
|
13
|
+
:default => 100
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [String] basename
|
17
|
+
# @param [Array] no_cache
|
18
|
+
# @param [Array] cache
|
19
|
+
# @param [Hash] options
|
20
|
+
#
|
21
|
+
def plot_timings(basename, no_cache, cache, options)
|
22
|
+
x_points = (1..options[:iterations]).to_a
|
23
|
+
|
24
|
+
Gnuplot.open do |gp|
|
25
|
+
Gnuplot::Plot.new(gp) do |plot|
|
26
|
+
plot.title "#{basename} with #{options[:iterations]} iterations"
|
27
|
+
|
28
|
+
plot.xlabel 'Iteration'
|
29
|
+
plot.ylabel 'Time (ms)'
|
30
|
+
|
31
|
+
plot.data << Gnuplot::DataSet.new([x_points, no_cache]) do |ds|
|
32
|
+
ds.with = 'lines'
|
33
|
+
ds.title = 'No caching'
|
34
|
+
end
|
35
|
+
|
36
|
+
plot.data << Gnuplot::DataSet.new([x_points, cache]) do |ds|
|
37
|
+
ds.with = 'lines'
|
38
|
+
ds.title = 'Caching'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Measures the analysis time of a given file.
|
46
|
+
#
|
47
|
+
# @param [String] file
|
48
|
+
# @param [Fixnum] amount
|
49
|
+
# @param [TrueClass|FalseClass] caching
|
50
|
+
#
|
51
|
+
def measure_analysis(file, amount, caching = false)
|
52
|
+
configuration = RubyLint::Configuration.load_from_file
|
53
|
+
configuration.enable_cache = caching
|
54
|
+
|
55
|
+
FileUtils.rm_rf(configuration.cache_directory) if caching
|
56
|
+
|
57
|
+
files = [file]
|
58
|
+
runner = RubyLint::Runner.new(configuration)
|
59
|
+
timings = []
|
60
|
+
|
61
|
+
amount.times do
|
62
|
+
timing = Benchmark.measure { runner.analyze(files) }
|
63
|
+
|
64
|
+
timings << timing.real * 1000
|
65
|
+
end
|
66
|
+
|
67
|
+
return timings
|
68
|
+
end
|
69
|
+
|
70
|
+
run do |opts, args|
|
71
|
+
require 'gnuplot'
|
72
|
+
require 'fileutils'
|
73
|
+
require 'benchmark'
|
74
|
+
|
75
|
+
abort 'No files specified' if args.empty?
|
76
|
+
|
77
|
+
abort "The file #{args[0]} does not exist" unless File.file?(args[0])
|
78
|
+
|
79
|
+
puts 'Measuring, this will take a while...'
|
80
|
+
|
81
|
+
no_cache = measure_analysis(args[0], opts[:iterations])
|
82
|
+
cache = measure_analysis(args[0], opts[:iterations], true)
|
83
|
+
|
84
|
+
plot_timings(File.basename(args[0]), no_cache, cache, opts)
|
85
|
+
|
86
|
+
no_cache_avg = no_cache.inject(:+) / no_cache.length
|
87
|
+
cache_avg = cache.inject(:+) / cache.length
|
88
|
+
|
89
|
+
puts 'Averages:'
|
90
|
+
puts "Cache disabled: #{no_cache_avg} ms"
|
91
|
+
puts "Cache enabled: #{cache_avg} ms"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
#:nocov:
|
data/lib/ruby-lint/cli.rb
CHANGED
@@ -22,9 +22,20 @@ module RubyLint
|
|
22
22
|
# @!attribute [rw] ignore_paths
|
23
23
|
# @return [Array]
|
24
24
|
#
|
25
|
+
# @!attribute [rw] enable_cache
|
26
|
+
# When set to `true` external files and their associated data will be
|
27
|
+
# cached.
|
28
|
+
# @return [TrueClass|FalseClass]
|
29
|
+
#
|
30
|
+
# @!attribute [r] cache_directory
|
31
|
+
# The path to the directory to use for storing cache files.
|
32
|
+
# @return [String]
|
33
|
+
#
|
25
34
|
class Configuration
|
26
|
-
attr_reader :analysis_classes, :report_levels, :presenter, :directories
|
27
|
-
|
35
|
+
attr_reader :analysis_classes, :report_levels, :presenter, :directories,
|
36
|
+
:cache_directory
|
37
|
+
|
38
|
+
attr_accessor :debug, :ignore_paths, :enable_cache
|
28
39
|
|
29
40
|
##
|
30
41
|
# Returns an Array of locations from which to load configuration files.
|
@@ -86,7 +97,8 @@ module RubyLint
|
|
86
97
|
# @param [Hash] options
|
87
98
|
#
|
88
99
|
def initialize(options = {})
|
89
|
-
@debug
|
100
|
+
@debug = false
|
101
|
+
@enable_cache = default_cache_value
|
90
102
|
|
91
103
|
options.each do |key, value|
|
92
104
|
setter = "#{key}="
|
@@ -101,6 +113,16 @@ module RubyLint
|
|
101
113
|
@presenter ||= default_presenter
|
102
114
|
@directories ||= default_directories
|
103
115
|
@ignore_paths ||= []
|
116
|
+
@cache_directory ||= default_cache_directory
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Expands and sets the path as the cache directory.
|
121
|
+
#
|
122
|
+
# @param [String] path
|
123
|
+
#
|
124
|
+
def cache_directory=(path)
|
125
|
+
@cache_directory = File.expand_path(path)
|
104
126
|
end
|
105
127
|
|
106
128
|
##
|
@@ -217,5 +239,28 @@ module RubyLint
|
|
217
239
|
def default_directories
|
218
240
|
return [Dir.pwd]
|
219
241
|
end
|
242
|
+
|
243
|
+
##
|
244
|
+
# @return [TrueClass|FalseClass]
|
245
|
+
#
|
246
|
+
def default_cache_value
|
247
|
+
return ENV['RUBY_LINT_DISABLE_CACHE'] ? false : true
|
248
|
+
end
|
249
|
+
|
250
|
+
##
|
251
|
+
# The default cache directory to use. Per the XDG specification
|
252
|
+
# (http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html)
|
253
|
+
# this is set to `$XDG_CACHE_HOME`/`$HOME/.cache` by default.
|
254
|
+
#
|
255
|
+
# @return [String]
|
256
|
+
#
|
257
|
+
def default_cache_directory
|
258
|
+
root = ENV['XDG_CACHE_HOME'] || File.join(ENV['HOME'], '.cache')
|
259
|
+
|
260
|
+
# ~/.cache might not exist on non Linux systems.
|
261
|
+
Dir.mkdir(root) unless File.directory?(root)
|
262
|
+
|
263
|
+
return File.join(root, 'ruby-lint')
|
264
|
+
end
|
220
265
|
end # Configuration
|
221
266
|
end # RubyLint
|