rshade 0.1.9.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.rubocop.yml +31 -0
  4. data/Gemfile +9 -2
  5. data/Gemfile.lock +11 -2
  6. data/README.md +20 -3
  7. data/Rakefile +5 -3
  8. data/bin/console +4 -3
  9. data/lib/rshade/config/registry.rb +40 -0
  10. data/lib/rshade/config/stack_store.rb +63 -0
  11. data/lib/rshade/config/store.rb +12 -7
  12. data/lib/rshade/config.rb +8 -7
  13. data/lib/rshade/core_extensions/object/reveal.rb +37 -5
  14. data/lib/rshade/event.rb +15 -5
  15. data/lib/rshade/event_observer.rb +3 -1
  16. data/lib/rshade/event_processor.rb +12 -11
  17. data/lib/rshade/event_tree.rb +18 -18
  18. data/lib/rshade/filter/abstract_filter.rb +3 -1
  19. data/lib/rshade/filter/default.rb +4 -2
  20. data/lib/rshade/filter/exclude_path_filter.rb +5 -3
  21. data/lib/rshade/filter/filter_builder.rb +14 -3
  22. data/lib/rshade/filter/filter_composition.rb +29 -25
  23. data/lib/rshade/filter/include_path_filter.rb +6 -1
  24. data/lib/rshade/filter/variable_filter.rb +5 -1
  25. data/lib/rshade/formatter/stack/json.rb +51 -0
  26. data/lib/rshade/formatter/stack/stdout.rb +13 -0
  27. data/lib/rshade/formatter/stack/string.rb +53 -0
  28. data/lib/rshade/formatter/trace/file.rb +31 -0
  29. data/lib/rshade/formatter/trace/html.rb +36 -0
  30. data/lib/rshade/formatter/trace/json.rb +60 -0
  31. data/lib/rshade/formatter/trace/stdout.rb +14 -0
  32. data/lib/rshade/formatter/trace/string.rb +48 -0
  33. data/lib/rshade/rspec/rspec.rb +8 -5
  34. data/lib/rshade/serializer/traversal.rb +10 -8
  35. data/lib/rshade/stack.rb +26 -0
  36. data/lib/rshade/stack_frame.rb +61 -0
  37. data/lib/rshade/trace.rb +7 -4
  38. data/lib/rshade/trace_observable.rb +10 -5
  39. data/lib/rshade/version.rb +3 -1
  40. data/lib/rshade.rb +25 -8
  41. data/rshade.gemspec +24 -22
  42. metadata +29 -35
  43. data/lib/rshade/formatter/file.rb +0 -28
  44. data/lib/rshade/formatter/html.rb +0 -33
  45. data/lib/rshade/formatter/json.rb +0 -59
  46. data/lib/rshade/formatter/stdout.rb +0 -10
  47. data/lib/rshade/formatter/string.rb +0 -36
  48. data/lib/rshade/rails/rails.rb +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 91ab4d11c9af8066bff925ab208f10e20c5bf7fd5685418b0c8ef01880c13d2f
4
- data.tar.gz: 7c0e95c99b1707e5290440cf3459e02cd465c653bdbfbfdc3f216d77a3647c66
3
+ metadata.gz: efdbfc08fca88589c49b580abbbeb36687b68986e365291c2c4758633b33943d
4
+ data.tar.gz: 78e8147a5539bb79216281763274c676d916729b62af681b2811caa1772f7031
5
5
  SHA512:
6
- metadata.gz: 21fe1fa50bf9c63261fbed6651ad8999edc22734567c3f33b2ba872ba95640cb70b3cff8fa0c640fd13faa8cf73371bb107ee8d0303e3e1322bba06a87f30d58
7
- data.tar.gz: 2b657588399858bcc1aa9f60cac2baf92ea3427b341542c40f15c7a7a26cbfb17cabfa3b98a2c5465c1905a3c8dfeb9500ed772351d89bdd7c2b6ca3ac223392
6
+ metadata.gz: 39fad4c1cb0663e510aaee89100090a10e689880da9f2fb2422fc404094337bad4bcbd5bb72a96270b284a3709392d4d9879cb1410d8f912d8e55db2962a8e4f
7
+ data.tar.gz: de5d785cfe183f5a7109aeebb128086e0173ce126788165b7dc18b818de066909830e628b5322c84ff6c9655696cb34cc8c7d289aafff036965f6a7caeb7bda0
data/.gitignore CHANGED
@@ -5,6 +5,7 @@
5
5
  /doc/
6
6
  /pkg/
7
7
  /spec/reports/
8
+ /spec/store/
8
9
  /tmp/
9
10
  .idea
10
11
 
@@ -12,4 +13,4 @@
12
13
  .rspec_status
13
14
  .ruby-version
14
15
  .DS_Store
15
- test.rb
16
+ test.rb
data/.rubocop.yml ADDED
@@ -0,0 +1,31 @@
1
+ # The behavior of RuboCop can be controlled via the .rubocop.yml
2
+ # configuration file. It makes it possible to enable/disable
3
+ # certain cops (checks) and to alter their behavior if they accept
4
+ # any parameters. The file can be placed either in your home
5
+ # directory or in some project directory.
6
+ #
7
+ # RuboCop will start looking for the configuration file in the directory
8
+ # where the inspected file is and continue its way up to the root directory.
9
+ #
10
+ # See https://docs.rubocop.org/rubocop/configuration
11
+ AllCops:
12
+ NewCops: enable
13
+ Exclude:
14
+ - 'spec/fixture/**/*'
15
+ Style/HashSyntax:
16
+ EnforcedShorthandSyntax: never
17
+
18
+ Naming/MethodParameterName:
19
+ Exclude:
20
+ - spec/**/*
21
+ - test.rb
22
+ Style/Documentation:
23
+ Enabled: false
24
+ Metrics/BlockLength:
25
+ Max: 75
26
+ Metrics/MethodLength:
27
+ Max: 30
28
+ Metrics/PerceivedComplexity:
29
+ Max: 10
30
+ Metrics/AbcSize:
31
+ Max: 30
data/Gemfile CHANGED
@@ -1,10 +1,17 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
6
 
5
7
  # Specify your gem's dependencies in rshade.gemspec
6
8
  gemspec
7
9
 
8
10
  group :development, :test do
11
+ gem 'binding_of_caller'
12
+ gem 'bundler', '~> 2.2.33'
13
+ gem 'prism'
9
14
  gem 'pry'
15
+ gem 'rake', '>= 12.3.3'
16
+ gem 'rspec', '~> 3.0'
10
17
  end
data/Gemfile.lock CHANGED
@@ -1,16 +1,22 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rshade (0.1.9.1)
4
+ rshade (0.2.1)
5
+ binding_of_caller
5
6
  colorize
7
+ prism
6
8
 
7
9
  GEM
8
10
  remote: https://rubygems.org/
9
11
  specs:
12
+ binding_of_caller (1.0.1)
13
+ debug_inspector (>= 1.2.0)
10
14
  coderay (1.1.3)
11
- colorize (0.8.1)
15
+ colorize (1.1.0)
16
+ debug_inspector (1.2.0)
12
17
  diff-lcs (1.5.0)
13
18
  method_source (1.0.0)
19
+ prism (1.3.0)
14
20
  pry (0.14.1)
15
21
  coderay (~> 1.1)
16
22
  method_source (~> 1.0)
@@ -32,9 +38,12 @@ GEM
32
38
  PLATFORMS
33
39
  x86_64-darwin-19
34
40
  x86_64-darwin-20
41
+ x86_64-darwin-22
35
42
 
36
43
  DEPENDENCIES
44
+ binding_of_caller
37
45
  bundler (~> 2.2.33)
46
+ prism
38
47
  pry
39
48
  rake (>= 12.3.3)
40
49
  rshade!
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # RShade
2
-
3
- ![warcraft shade](https://github.com/gingray/rshade/raw/master/shade.jpg)
2
+ <p align="center">
3
+ <img src="https://github.com/gingray/rshade/raw/master/shade.jpg">
4
+ </p>
4
5
 
5
6
  RShade is a debugging/code exploration tool based on `TracePoint` functionality.
6
7
  Recent years I've working with relatively huge legacy code and I need a tool which can help me to figure out what is going on due execution.
@@ -85,7 +86,7 @@ On such huge codebase as spree it's helpful to know what callbacks are triggered
85
86
  context 'when cost currency is nil' do
86
87
  before { variant.cost_currency = nil }
87
88
 
88
- it 'populates cost currency with the default value on save', focus: true do
89
+ it 'populates cost currency with the default value on save' do
89
90
  RShade::Trace.reveal do
90
91
  variant.save!
91
92
  end
@@ -99,6 +100,22 @@ Below is example how output will look like.
99
100
  As you can see all code that have been in use is printed.
100
101
  [![asciicast](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373.svg)](https://asciinema.org/a/MR5KL7TmHmYRUhwBUWQjBI373)
101
102
 
103
+ ## Stack reveal
104
+ Config
105
+
106
+ ```ruby
107
+ ::RShade::Config::Registry.instance.stack_config do |config|
108
+ config.exclude_gems!
109
+ filepath = File.join(Rails.root, 'log', 'rshade-stack.json.log')
110
+ config.formatter!(:json, { filepath: filepath, pretty: false })
111
+ end
112
+ ```
113
+
114
+ Execute (put in any place where you want reveal stack)
115
+ ```ruby
116
+ ::RShade::Stack.trace
117
+ ```
118
+
102
119
  ## TODO
103
120
  Use stack to keep connections between current method and caller
104
121
  take a look on https://github.com/matugm/visual-call-graph
data/Rakefile CHANGED
@@ -1,6 +1,8 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
3
5
 
4
6
  RSpec::Core::RakeTask.new(:spec)
5
7
 
6
- task :default => :spec
8
+ task default: :spec
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "rshade"
4
+ require 'bundler/setup'
5
+ require 'rshade'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +11,5 @@ require "rshade"
10
11
  # require "pry"
11
12
  # Pry.start
12
13
 
13
- require "irb"
14
+ require 'irb'
14
15
  IRB.start(__FILE__)
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RShade
4
+ class Config
5
+ class Registry
6
+ include Singleton
7
+ attr_reader :map, :mutex
8
+
9
+ def initialize
10
+ @map = {}
11
+ @mutex = Mutex.new
12
+ defaults
13
+ end
14
+
15
+ def default_stack_config
16
+ val = nil
17
+ mutex.synchronize do
18
+ val = map[:store_default]
19
+ end
20
+ val
21
+ end
22
+
23
+ def stack_config(&block)
24
+ val = nil
25
+ mutex.synchronize do
26
+ val = ::RShade::Config::StackStore.new
27
+ block.call(val)
28
+ map[:store_default] = val
29
+ end
30
+ val
31
+ end
32
+
33
+ def defaults
34
+ mutex.synchronize do
35
+ map[:store_default] = ::RShade::Config::StackStore.new
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RShade
4
+ class Config
5
+ class StackStore
6
+ attr_reader :filter, :formatter, :custom_serializers
7
+
8
+ DEFAULT_FORMATTER = {
9
+ json: ::RShade::Formatter::Stack::Json,
10
+ stdout: ::RShade::Formatter::Stack::Stdout
11
+ }.freeze
12
+
13
+ # @param [Hash] options
14
+ # @option options [::RShade::Filter::FilterComposition] :filter_composition
15
+ # @option options [#call(event_store)] :formatter
16
+ def initialize(options = {})
17
+ @filter = options.fetch(:filter, default_filter_composition)
18
+ @formatter = options.fetch(:formatter, ::RShade::Formatter::Stack::Stdout.new)
19
+ @custom_serializers = options.fetch(:custom_serializers, {})
20
+ end
21
+
22
+ def add_custom_serializers(hash)
23
+ custom_serializers.merge!(hash)
24
+ self
25
+ end
26
+
27
+ def config_filter(filter_type, &block)
28
+ filter.config_filter(filter_type, &block)
29
+ self
30
+ end
31
+
32
+ def formatter!(formatter, opts = {})
33
+ @formatter = formatter.is_a?(Symbol) ? set_symbol_formatter(formatter, opts) : formatter
34
+ self
35
+ end
36
+
37
+ def exclude_gems!
38
+ config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
39
+ paths.concat(RShade::Config.default_excluded_path)
40
+ end
41
+ self
42
+ end
43
+
44
+ private
45
+
46
+ def set_symbol_formatter(type, opts)
47
+ formatter_class = DEFAULT_FORMATTER[type]
48
+ return formatter_class unless formatter_class
49
+
50
+ @formatter = formatter_class.new(**opts)
51
+ end
52
+
53
+ def default_filter_composition
54
+ variable_filter = RShade::Filter::VariableFilter.new
55
+ include_filter = RShade::Filter::IncludePathFilter.new
56
+ exclude_filter = RShade::Filter::ExcludePathFilter.new
57
+
58
+ RShade::Filter::FilterBuilder.build([:or,
59
+ [:or, variable_filter, include_filter], exclude_filter])
60
+ end
61
+ end
62
+ end
63
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
 
2
3
  module RShade
3
4
  class Config
@@ -8,14 +9,14 @@ module RShade
8
9
  # @option options [RShade::Filter::FilterComposition] :filter_composition
9
10
  # @option options [#call(event_store)] :formatter
10
11
  # @option options [Array<Symbol>] :tp_events
11
- def initialize(options={})
12
+ def initialize(options = {})
12
13
  @filter_composition = options.fetch(:filter_composition, default_filter_composition)
13
- @formatter = options.fetch(:formatter, ::RShade::Formatter::Stdout)
14
- @tp_events = options.fetch(:tp_events, [:call, :return])
14
+ @formatter = options.fetch(:formatter, ::RShade::Formatter::Trace::Stdout)
15
+ @tp_events = options.fetch(:tp_events, %i[call return])
15
16
  @custom_serializers = options.fetch(:custom_serializers, {})
16
17
  end
17
18
 
18
- def set_tp_events(tp_events)
19
+ def tp_events!(tp_events)
19
20
  @tp_events = tp_events
20
21
  self
21
22
  end
@@ -25,13 +26,12 @@ module RShade
25
26
  self
26
27
  end
27
28
 
28
-
29
29
  def config_filter(filter_type, &block)
30
30
  filter_composition.config_filter(filter_type, &block)
31
31
  self
32
32
  end
33
33
 
34
- def set_formatter(formatter)
34
+ def formatter!(formatter)
35
35
  @formatter = formatter
36
36
  self
37
37
  end
@@ -39,7 +39,12 @@ module RShade
39
39
  private
40
40
 
41
41
  def default_filter_composition
42
- RShade::Filter::FilterBuilder.build([:or,[:or, RShade::Filter::VariableFilter.new, RShade::Filter::IncludePathFilter.new] , RShade::Filter::ExcludePathFilter.new])
42
+ variable_filter = RShade::Filter::VariableFilter.new
43
+ include_filter = RShade::Filter::IncludePathFilter.new
44
+ exclude_filter = RShade::Filter::ExcludePathFilter.new
45
+
46
+ RShade::Filter::FilterBuilder.build([:or,
47
+ [:or, variable_filter, include_filter], exclude_filter])
43
48
  end
44
49
  end
45
50
  end
data/lib/rshade/config.rb CHANGED
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class Config
3
- RUBY_VERSION_PATTERN = /ruby-[0-9.]*/
5
+ RUBY_VERSION_PATTERN = /ruby-[0-9.]*/.freeze
4
6
 
5
7
  def self.default
6
- ::RShade::Config::Store.new.set_formatter(::RShade::Formatter::Stdout.new)
8
+ ::RShade::Config::Store.new.formatter!(::RShade::Formatter::Trace::Stdout.new)
7
9
  .config_filter(::RShade::Filter::ExcludePathFilter) do |paths|
8
10
  default_excluded_path.each do |path|
9
11
  paths << path
@@ -20,13 +22,13 @@ module RShade
20
22
  # @option options [RShade::Filter::FilterComposition] :filter_composition
21
23
  # @option options [#call(event_store)] :formatter
22
24
  # @option options [Array<Symbol>] :tp_events
23
- def self.create(options={})
25
+ def self.create(options = {})
24
26
  new(Config::Store.new(options))
25
27
  end
26
28
 
27
29
  def tp_events(&block)
28
30
  events = block.call
29
- @config_store.set_tp_events(events)
31
+ @config_store.tp_events!(events)
30
32
  self
31
33
  end
32
34
 
@@ -47,7 +49,7 @@ module RShade
47
49
 
48
50
  def formatter(&block)
49
51
  formatter = block.call
50
- @config_store.set_formatter(formatter)
52
+ @config_store.formatter!(formatter)
51
53
  self
52
54
  end
53
55
 
@@ -68,9 +70,8 @@ module RShade
68
70
  @root_dir ||= File.expand_path('../../', __dir__)
69
71
  end
70
72
 
71
- private
72
73
  def self.default_excluded_path
73
- [ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/].flatten.compact
74
+ [ENV['GEM_PATH'].split(':'), RUBY_VERSION_PATTERN, /internal/, %r{/gems/}].flatten.compact
74
75
  end
75
76
  end
76
77
  end
@@ -1,8 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
- def reveal(&block)
3
- trace = ::RShade::Trace.reveal do
4
- block.call
4
+ # rubocop:disable Metrics/MethodLength
5
+ def reveal(method_name = nil, **opts, &block)
6
+ if method_name
7
+ @__cache_rshade_reveal ||= {}
8
+ config = opts.fetch(:config, ::RShade::Config.default)
9
+ @__cache_rshade_reveal[method_name] = config
10
+ instance_eval do
11
+ def method_added(name)
12
+ super
13
+ return unless @__cache_rshade_reveal[name]
14
+
15
+ if @__reveal_rewrite
16
+ @__reveal_rewrite = false
17
+ return
18
+ end
19
+ @__reveal_rewrite = true
20
+ config = @__cache_rshade_reveal[name]
21
+ origin_method = instance_method(name)
22
+ define_method(name) do |*args, &fn|
23
+ val = nil
24
+ trace = ::RShade::Trace.reveal(config) do
25
+ val = origin_method.bind(self).call(*args, &fn)
26
+ end
27
+ trace.show
28
+ val
29
+ end
30
+ end
31
+ end
32
+ else
33
+ trace = ::RShade::Trace.reveal do
34
+ block.call if block_given?
35
+ end
36
+ trace.show
5
37
  end
6
- trace.show
7
38
  end
8
- end
39
+ # rubocop:enable Metrics/MethodLength
40
+ end
data/lib/rshade/event.rb CHANGED
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  # nodoc
3
5
  class Event
4
6
  attr_reader :hash, :skipped
5
- RETURN_EVENTS = [:return, :b_return, :c_return]
6
7
 
8
+ RETURN_EVENTS = %i[return b_return c_return].freeze
7
9
 
8
10
  def initialize(hash)
9
11
  @hash = hash
10
12
  end
11
13
 
12
- [:klass, :path, :lineno, :method_name, :vars, :level, :return_value].each do |method_name|
14
+ %i[klass path lineno method_name vars level return_value].each do |method_name|
13
15
  define_method method_name do
14
16
  fetch method_name
15
17
  end
@@ -20,7 +22,7 @@ module RShade
20
22
  self
21
23
  end
22
24
 
23
- def set_return_value!(return_value)
25
+ def return_value!(return_value)
24
26
  @hash[:return_value] = return_value
25
27
  self
26
28
  end
@@ -38,12 +40,20 @@ module RShade
38
40
  def self.from_trace_point(evt)
39
41
  vars = {}
40
42
  evt.binding.local_variables.each do |var_name|
41
- vars[var_name] = evt.binding.local_variable_get var_name
43
+ local_val = evt.binding.local_variable_get(var_name)
44
+ local_val_type = local_val.is_a?(Class) ? local_val : local_val.class
45
+ hash = { name: var_name, value: local_val, type: local_val_type }
46
+ vars[var_name] = hash
42
47
  end
43
48
 
44
49
  hash = { path: evt.path, lineno: evt.lineno, klass: evt.defined_class, method_name: evt.method_id, vars: vars,
45
50
  event_type: evt.event }
46
- hash.merge!({return_value: evt.return_value}) if RETURN_EVENTS.include?(evt.event)
51
+
52
+ if RETURN_EVENTS.include?(evt.event)
53
+ ret_val = evt.return_value
54
+ ret_val_type = evt.return_value.is_a?(Class) ? evt.return_value : evt.return_value.class
55
+ hash.merge!({ return_value: { value: ret_val, type: ret_val_type } })
56
+ end
47
57
  new(hash)
48
58
  end
49
59
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class EventObserver
3
5
  attr_reader :event_processor, :config
@@ -42,4 +44,4 @@ module RShade
42
44
  config.filter_composition.call(event)
43
45
  end
44
46
  end
45
- end
47
+ end
@@ -1,36 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  # nodoc
3
5
  class EventProcessor
4
- attr_reader :store
6
+ attr_reader :store, :serializer
5
7
 
6
8
  def initialize(store, config)
7
9
  @store = store
8
10
  custom_serializers = config.custom_serializers
9
- @var_serializer = ::RShade::Serializer::Traversal.new(custom_serializers)
11
+ @serializer = ::RShade::Serializer::Traversal.new(custom_serializers)
10
12
  end
11
13
 
12
14
  # @param [RShade::Event] event
13
15
  # @param [Integer] level
14
16
  def enter(event, level)
15
- event.with_serialized_vars!(@var_serializer).with_level!(level)
17
+ event.with_serialized_vars!(serializer).with_level!(level)
16
18
  store.add(event, level)
17
19
  end
18
20
 
19
21
  # @param [RShade::Event] event
20
22
  # @param [Integer] level
21
- def leave(event, level)
23
+ def leave(event, _level)
22
24
  store.current! do |node|
23
- node.value.set_return_value!(event.return_value)
24
- .with_serialized_return!(->(value) { value.inspect })
25
+ node.value.return_value!(event.return_value)
26
+ .with_serialized_return!(serializer)
25
27
  end
26
- rescue => e
28
+ rescue StandardError
27
29
  # this rescue here due this issue which reproduce in ruby-2.6.6 at least
28
30
  # https://bugs.ruby-lang.org/issues/18060
29
31
  end
32
+
30
33
  # @param [RShade::Event] event
31
34
  # @param [Integer] level
32
- def other(event, level)
33
-
34
- end
35
+ def other(event, level); end
35
36
  end
36
- end
37
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  class EventTree
3
5
  include Enumerable
@@ -8,6 +10,7 @@ module RShade
8
10
  @current = @head = EventTreeNode.new(nil, 0, nil)
9
11
  end
10
12
 
13
+ # rubocop:disable Metrics/AbcSize
11
14
  def add(value, level)
12
15
  if current.level + 1 == level
13
16
  current.children << EventTreeNode.new(value, level, current)
@@ -16,22 +19,19 @@ module RShade
16
19
  if current.level + 1 < level
17
20
 
18
21
  last = current.children.last
19
- unless last
20
- current.children << EventTreeNode.new(nil, current.level + 1 , current)
21
- end
22
+ current.children << EventTreeNode.new(nil, current.level + 1, current) unless last
22
23
  @current = current.children.last
23
24
  add(value, level)
24
25
  return
25
26
  end
26
27
 
27
- if current.level + 1 > level
28
- unless current.parent
29
- return
30
- end
31
- @current = current.parent
32
- add(value, level)
33
- end
28
+ return unless current.level + 1 > level
29
+ return unless current.parent
30
+
31
+ @current = current.parent
32
+ add(value, level)
34
33
  end
34
+ # rubocop:enable Metrics/AbcSize
35
35
 
36
36
  def current!(&block)
37
37
  block.call(current.children.last) if current.children.last
@@ -47,29 +47,29 @@ module RShade
47
47
  attr_reader :children, :level, :vlevel, :value
48
48
  attr_accessor :parent
49
49
 
50
- def initialize(value, level, parent=nil)
50
+ def initialize(value, level, parent = nil)
51
51
  @children = []
52
52
  @level = level
53
53
  @parent = parent
54
54
  @value = value
55
- @vlevel = set_vlevel(parent)
55
+ @vlevel = vlevel!(parent)
56
56
  end
57
57
 
58
58
  def each(&block)
59
- block.call(self) if parent != nil || value != nil
59
+ block.call(self) if !parent.nil? || !value.nil?
60
60
  children.each { |item| item.each(&block) }
61
61
  end
62
62
 
63
63
  private
64
64
 
65
- def set_vlevel(node)
66
- return 0 if node == nil
65
+ def vlevel!(node)
66
+ return 0 if node.nil?
67
67
 
68
- if node.value || node.level == 0
68
+ if node.value || node.level.zero?
69
69
  node.vlevel + 1
70
70
  else
71
- set_vlevel(node.parent)
71
+ vlevel!(node.parent)
72
72
  end
73
73
  end
74
74
  end
75
- end
75
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class AbstractFilter
@@ -23,4 +25,4 @@ module RShade
23
25
  end
24
26
  end
25
27
  end
26
- end
28
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RShade
2
4
  module Filter
3
5
  class Default
4
- RUBY_VERSION_PATTERN = /ruby-[0-9.]*/
6
+ RUBY_VERSION_PATTERN = /ruby-[0-9.]*/.freeze
5
7
 
6
8
  def self.create
7
9
  new.create
@@ -25,4 +27,4 @@ module RShade
25
27
  end
26
28
  end
27
29
  end
28
- end
30
+ end