spoom 1.2.2 → 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -0
  3. data/lib/spoom/backtrace_filter/minitest.rb +21 -0
  4. data/lib/spoom/cli/coverage.rb +1 -1
  5. data/lib/spoom/context/git.rb +4 -4
  6. data/lib/spoom/context/sorbet.rb +6 -6
  7. data/lib/spoom/deadcode/erb.rb +4 -4
  8. data/lib/spoom/deadcode/indexer.rb +83 -6
  9. data/lib/spoom/deadcode/location.rb +29 -1
  10. data/lib/spoom/deadcode/plugins/action_mailer.rb +21 -0
  11. data/lib/spoom/deadcode/plugins/actionpack.rb +61 -0
  12. data/lib/spoom/deadcode/plugins/active_job.rb +13 -0
  13. data/lib/spoom/deadcode/plugins/active_model.rb +46 -0
  14. data/lib/spoom/deadcode/plugins/active_record.rb +111 -0
  15. data/lib/spoom/deadcode/plugins/active_support.rb +21 -0
  16. data/lib/spoom/deadcode/plugins/base.rb +354 -0
  17. data/lib/spoom/deadcode/plugins/graphql.rb +47 -0
  18. data/lib/spoom/deadcode/plugins/minitest.rb +28 -0
  19. data/lib/spoom/deadcode/plugins/namespaces.rb +34 -0
  20. data/lib/spoom/deadcode/plugins/rails.rb +31 -0
  21. data/lib/spoom/deadcode/plugins/rake.rb +12 -0
  22. data/lib/spoom/deadcode/plugins/rspec.rb +19 -0
  23. data/lib/spoom/deadcode/plugins/rubocop.rb +41 -0
  24. data/lib/spoom/deadcode/plugins/ruby.rb +65 -0
  25. data/lib/spoom/deadcode/plugins/sorbet.rb +46 -0
  26. data/lib/spoom/deadcode/plugins/thor.rb +21 -0
  27. data/lib/spoom/deadcode/plugins.rb +95 -0
  28. data/lib/spoom/deadcode/remover.rb +616 -0
  29. data/lib/spoom/deadcode/send.rb +22 -0
  30. data/lib/spoom/deadcode.rb +8 -6
  31. data/lib/spoom/sorbet/lsp.rb +2 -2
  32. data/lib/spoom/sorbet/sigils.rb +2 -2
  33. data/lib/spoom/sorbet.rb +1 -0
  34. data/lib/spoom/version.rb +1 -1
  35. metadata +24 -18
@@ -0,0 +1,21 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module Spoom
5
+ module Deadcode
6
+ module Plugins
7
+ class Thor < Base
8
+ extend T::Sig
9
+
10
+ ignore_methods_named("exit_on_failure?")
11
+
12
+ sig { override.params(indexer: Indexer, definition: Definition).void }
13
+ def on_define_method(indexer, definition)
14
+ return if indexer.nesting_block # method defined in `no_commands do ... end`, we don't want to ignore it
15
+
16
+ definition.ignored! if indexer.nesting_class_superclass_name =~ /^(::)?Thor$/
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,95 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "plugins/base"
5
+
6
+ require_relative "plugins/actionpack"
7
+ require_relative "plugins/active_job"
8
+ require_relative "plugins/action_mailer"
9
+ require_relative "plugins/active_model"
10
+ require_relative "plugins/active_record"
11
+ require_relative "plugins/active_support"
12
+ require_relative "plugins/graphql"
13
+ require_relative "plugins/minitest"
14
+ require_relative "plugins/namespaces"
15
+ require_relative "plugins/rails"
16
+ require_relative "plugins/rake"
17
+ require_relative "plugins/rspec"
18
+ require_relative "plugins/rubocop"
19
+ require_relative "plugins/ruby"
20
+ require_relative "plugins/sorbet"
21
+ require_relative "plugins/thor"
22
+
23
+ module Spoom
24
+ module Deadcode
25
+ DEFAULT_CUSTOM_PLUGINS_PATH = ".spoom/deadcode/plugins"
26
+
27
+ DEFAULT_PLUGINS = T.let(
28
+ Set.new([
29
+ Spoom::Deadcode::Plugins::Namespaces,
30
+ Spoom::Deadcode::Plugins::Ruby,
31
+ ]).freeze,
32
+ T::Set[T.class_of(Plugins::Base)],
33
+ )
34
+
35
+ PLUGINS_FOR_GEM = T.let(
36
+ {
37
+ "actionmailer" => Spoom::Deadcode::Plugins::ActionMailer,
38
+ "actionpack" => Spoom::Deadcode::Plugins::ActionPack,
39
+ "activejob" => Spoom::Deadcode::Plugins::ActiveJob,
40
+ "activemodel" => Spoom::Deadcode::Plugins::ActiveModel,
41
+ "activerecord" => Spoom::Deadcode::Plugins::ActiveRecord,
42
+ "activesupport" => Spoom::Deadcode::Plugins::ActiveSupport,
43
+ "graphql" => Spoom::Deadcode::Plugins::GraphQL,
44
+ "minitest" => Spoom::Deadcode::Plugins::Minitest,
45
+ "rails" => Spoom::Deadcode::Plugins::Rails,
46
+ "rake" => Spoom::Deadcode::Plugins::Rake,
47
+ "rspec" => Spoom::Deadcode::Plugins::RSpec,
48
+ "rubocop" => Spoom::Deadcode::Plugins::Rubocop,
49
+ "sorbet-runtime" => Spoom::Deadcode::Plugins::Sorbet,
50
+ "sorbet-static" => Spoom::Deadcode::Plugins::Sorbet,
51
+ "thor" => Spoom::Deadcode::Plugins::Thor,
52
+ }.freeze,
53
+ T::Hash[String, T.class_of(Plugins::Base)],
54
+ )
55
+
56
+ class << self
57
+ extend T::Sig
58
+
59
+ sig { params(context: Context).returns(T::Array[Plugins::Base]) }
60
+ def plugins_from_gemfile_lock(context)
61
+ # These plugins are always loaded
62
+ plugin_classes = DEFAULT_PLUGINS.dup
63
+
64
+ # These plugins depends on the gems used by the project
65
+ context.gemfile_lock_specs.keys.each do |name|
66
+ plugin_class = PLUGINS_FOR_GEM[name]
67
+ plugin_classes << plugin_class if plugin_class
68
+ end
69
+
70
+ plugin_classes.map(&:new)
71
+ end
72
+
73
+ sig { params(context: Context).returns(T::Array[Plugins::Base]) }
74
+ def load_custom_plugins(context)
75
+ context.glob("#{DEFAULT_CUSTOM_PLUGINS_PATH}/*.rb").each do |path|
76
+ require("#{context.absolute_path}/#{path}")
77
+ end
78
+
79
+ ObjectSpace
80
+ .each_object(Class)
81
+ .select do |klass|
82
+ next unless T.unsafe(klass).name # skip anonymous classes, we only use them in tests
83
+ next unless T.unsafe(klass) < Plugins::Base
84
+
85
+ location = Object.const_source_location(T.unsafe(klass).to_s)&.first
86
+ next unless location
87
+ next unless location.start_with?("#{context.absolute_path}/#{DEFAULT_CUSTOM_PLUGINS_PATH}")
88
+
89
+ true
90
+ end
91
+ .map { |klass| T.unsafe(klass).new }
92
+ end
93
+ end
94
+ end
95
+ end