ruby-lint 0.0.5 → 0.9.0
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 +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
|