degem 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/degem/cli.rb +5 -9
- data/lib/degem/{decorate_rubygems.rb → decorate_unused_gems.rb} +2 -2
- data/lib/degem/find_unused.rb +24 -150
- data/lib/degem/gemfile.rb +10 -4
- data/lib/degem/parse_gemfile.rb +5 -1
- data/lib/degem/parse_ruby.rb +117 -0
- data/lib/degem/report.rb +11 -15
- data/lib/degem/rubygem.rb +39 -7
- data/lib/degem/{decorated.rb → unused_gem.rb} +1 -1
- data/lib/degem/version.rb +1 -1
- data/lib/degem.rb +11 -4
- metadata +20 -7
- data/lib/degem/grep.rb +0 -42
- data/lib/degem/matcher.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 683ca7f47acea423692062935b4ccd5285e5aa764a12883a4f34237af7be248a
|
4
|
+
data.tar.gz: 1a9a8e898b9f4afcd1668b65a0ebc2b7928a84efa6c31e263c237114fa0a2069
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8e874de8d90b2a2e833b1685938ce9302426c3af5acf8e60bcf26cb0dab994a1520173269a366969018e69fb1abba74f1c4900235a0f7051739073a3962f70d
|
7
|
+
data.tar.gz: 6c19cd8a7e75ef66396e4dc209a14b77765e323804952769cd30a0d9267abb15bf9388ab58ee3f22002320585bb211f80d9d0e86163c7ac0a6b50e992b046cb6
|
data/lib/degem/cli.rb
CHANGED
@@ -9,33 +9,29 @@ module Degem
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def initialize(stderr)
|
12
|
-
|
12
|
+
Degem.stderr = stderr
|
13
13
|
end
|
14
14
|
|
15
15
|
def call
|
16
16
|
unless gemfile_exists?
|
17
|
-
|
17
|
+
Degem.stderr.puts "Gemfile not found in the current directory"
|
18
18
|
return 1
|
19
19
|
end
|
20
20
|
|
21
21
|
unused = find_unused.call
|
22
22
|
decorated = decorate_rubygems.call(unused)
|
23
|
-
Report.new
|
23
|
+
Report.new.call(decorated)
|
24
24
|
0
|
25
25
|
end
|
26
26
|
|
27
27
|
private
|
28
28
|
|
29
29
|
def find_unused
|
30
|
-
FindUnused.new(
|
31
|
-
gemfile_path: GEMFILE,
|
32
|
-
gem_specification: Gem::Specification,
|
33
|
-
grep: Grep.new(@stderr)
|
34
|
-
)
|
30
|
+
FindUnused.new(gemfile_path: GEMFILE)
|
35
31
|
end
|
36
32
|
|
37
33
|
def decorate_rubygems
|
38
|
-
|
34
|
+
DecorateUnusedGems.new(
|
39
35
|
gem_specification: Gem::Specification,
|
40
36
|
git_adapter: GitAdapter.new
|
41
37
|
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Degem
|
4
|
-
class
|
4
|
+
class DecorateUnusedGems
|
5
5
|
def initialize(gem_specification:, git_adapter:)
|
6
6
|
@gem_specification = gem_specification
|
7
7
|
@git_adapter = git_adapter
|
@@ -11,7 +11,7 @@ module Degem
|
|
11
11
|
rubygems.map do |rubygem|
|
12
12
|
gemspec = @gem_specification.find_by_name(rubygem.name)
|
13
13
|
git = @git_adapter.call(rubygem.name)
|
14
|
-
|
14
|
+
UnusedGem.new(rubygem, gemspec, git)
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
data/lib/degem/find_unused.rb
CHANGED
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
module Degem
|
4
4
|
class FindUnused
|
5
|
-
def initialize(gemfile_path:, gem_specification
|
5
|
+
def initialize(gemfile_path:, gem_specification: Gem::Specification, bundle_paths: GitLsFiles.new)
|
6
6
|
@gemfile_path = gemfile_path
|
7
7
|
@gem_specification = gem_specification
|
8
|
-
|
9
|
-
@bundle_paths = bundle_paths.call(
|
8
|
+
fallback = Dir.glob(File.join(File.dirname(gemfile_path), "**/*.rb"))
|
9
|
+
@bundle_paths = bundle_paths.call(fallback)
|
10
10
|
end
|
11
11
|
|
12
12
|
def call
|
13
13
|
rubygems = gemfile.rubygems.reject { _1.name == "degem" }
|
14
|
-
rubygems = reject_railties(rubygems) if rails?
|
14
|
+
rubygems = reject_railties(rubygems) if gemfile.rails?
|
15
15
|
reject_used(rubygems)
|
16
16
|
end
|
17
17
|
|
@@ -20,162 +20,36 @@ module Degem
|
|
20
20
|
attr_reader :gemfile_path
|
21
21
|
|
22
22
|
def reject_railties(rubygems)
|
23
|
-
rubygems
|
24
|
-
.reject { _1.name == "rails" }
|
25
|
-
.reject do |rubygem|
|
26
|
-
gem_path = @gem_specification.find_by_name(rubygem.name).full_gem_path
|
27
|
-
@grep.match?(/(Rails::Railtie|Rails::Engine)/, gem_path)
|
28
|
-
end
|
23
|
+
rubygems.reject(&:rails?).reject(&:railtie?)
|
29
24
|
end
|
30
25
|
|
31
26
|
def reject_used(rubygems)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
def matchers
|
37
|
-
[
|
38
|
-
method(:based_on_top_module),
|
39
|
-
method(:based_on_top_composite_module_dash),
|
40
|
-
method(:based_on_top_composite_module_underscore),
|
41
|
-
method(:based_on_top_call),
|
42
|
-
method(:based_on_top_composite_call_dash),
|
43
|
-
method(:based_on_top_composite_call_underscore),
|
44
|
-
method(:based_on_require),
|
45
|
-
method(:based_on_require_prefix_path),
|
46
|
-
method(:based_on_require_path)
|
47
|
-
].compact
|
48
|
-
end
|
49
|
-
|
50
|
-
def gemfile
|
51
|
-
@gemfile ||= ParseGemfile.new.call(gemfile_path)
|
52
|
-
end
|
53
|
-
|
54
|
-
def rails?
|
55
|
-
@rails ||= gemfile.rails?
|
56
|
-
end
|
57
|
-
|
58
|
-
# gem foo -> Foo:: (but not XFoo:: or X::Foo)
|
59
|
-
def based_on_top_module(rubygem, line)
|
60
|
-
return false if rubygem.name.include?("-")
|
61
|
-
|
62
|
-
regex = %r{
|
63
|
-
(?<!\w::) # Do not match if :: before
|
64
|
-
(?<!\w) # Do not match if \w before
|
65
|
-
#{rubygem.name.capitalize}
|
66
|
-
::
|
67
|
-
}x
|
68
|
-
regex.match?(line)
|
69
|
-
end
|
70
|
-
|
71
|
-
# gem foo_bar -> FooBar (but not XFooBar or X::FooBar)
|
72
|
-
def based_on_top_composite_module_underscore(rubygem, line)
|
73
|
-
return false unless rubygem.name.include?("_")
|
74
|
-
|
75
|
-
regex = %r{
|
76
|
-
(?<!\w::) # Do not match if :: before
|
77
|
-
(?<!\w) # Do not match if \w before
|
78
|
-
#{rubygem.name.split("_").map(&:capitalize).join}
|
79
|
-
::
|
80
|
-
}x
|
81
|
-
regex.match?(line)
|
82
|
-
end
|
83
|
-
|
84
|
-
# gem foo-bar -> Foo::Bar (but not XFoo::Bar or X::Foo::Bar)
|
85
|
-
def based_on_top_composite_module_dash(rubygem, line)
|
86
|
-
return false unless rubygem.name.include?("-")
|
87
|
-
|
88
|
-
regex = %r{
|
89
|
-
(?<!\w::) # Do not match if :: before
|
90
|
-
(?<!\w) # Do not match if \w before
|
91
|
-
#{rubygem.name.split("-").map(&:capitalize).join("::")}
|
92
|
-
}x
|
93
|
-
regex.match?(line)
|
94
|
-
end
|
95
|
-
|
96
|
-
# gem foo -> Foo. (but not X::Foo. or XBar.)
|
97
|
-
def based_on_top_call(rubygem, line)
|
98
|
-
return false if rubygem.name.include?("-")
|
99
|
-
|
100
|
-
regex = %r{
|
101
|
-
(?<!\w::) # Do not match if :: before
|
102
|
-
(?<!\w) # Do not match if \w before
|
103
|
-
#{rubygem.name.capitalize}
|
104
|
-
\.
|
105
|
-
}x
|
106
|
-
regex.match?(line)
|
107
|
-
end
|
108
|
-
|
109
|
-
# gem foo-bar -> FooBar. (but not X::FooBar. or XFooBar.)
|
110
|
-
def based_on_top_composite_call_dash(rubygem, line)
|
111
|
-
return false unless rubygem.name.include?("-")
|
112
|
-
|
113
|
-
regex = %r{
|
114
|
-
(?<!\w::) # Do not match if :: before
|
115
|
-
(?<!\w) # Do not match if \w before
|
116
|
-
#{rubygem.name.split("-").map(&:capitalize).join}
|
117
|
-
\.
|
118
|
-
}x
|
119
|
-
regex.match?(line)
|
27
|
+
bundle = ParseRuby.new.call(@bundle_paths)
|
28
|
+
rubygems = reject_required(rubygems, bundle.requires)
|
29
|
+
reject_consts(rubygems, bundle.consts)
|
120
30
|
end
|
121
31
|
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
(?<!\w) # Do not match if \w before
|
129
|
-
#{rubygem.name.split("_").map(&:capitalize).join}
|
130
|
-
\.
|
131
|
-
}x
|
132
|
-
regex.match?(line)
|
133
|
-
end
|
134
|
-
|
135
|
-
# gem foo-bar -> require 'foo-bar'
|
136
|
-
def based_on_require(rubygem, line)
|
137
|
-
regex = %r{
|
138
|
-
^
|
139
|
-
\s*
|
140
|
-
require
|
141
|
-
\s+
|
142
|
-
['"]
|
143
|
-
#{rubygem.name}
|
144
|
-
['"]
|
145
|
-
}x
|
146
|
-
regex.match?(line)
|
32
|
+
def reject_consts(rubygems, bundle_consts)
|
33
|
+
rubygems.reject do |rubygem|
|
34
|
+
rubygem.own_consts.any? do |own_const|
|
35
|
+
bundle_consts.include?(own_const)
|
36
|
+
end
|
37
|
+
end
|
147
38
|
end
|
148
39
|
|
149
|
-
|
150
|
-
|
151
|
-
|
40
|
+
def reject_required(rubygems, bundle_requires)
|
41
|
+
rubygems.reject do |rubygem|
|
42
|
+
bundle_requires.any? do |bundle_require|
|
43
|
+
next true if bundle_require == rubygem.name
|
44
|
+
next true if bundle_require == rubygem.name.tr("-", "/")
|
152
45
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
require
|
157
|
-
\s+
|
158
|
-
['"]
|
159
|
-
#{rubygem.name.tr("-", "/")} # match foo/bar when rubygem is foo-bar
|
160
|
-
['"]
|
161
|
-
}x
|
162
|
-
regex.match?(line)
|
46
|
+
bundle_require.start_with?("#{rubygem.name}/")
|
47
|
+
end
|
48
|
+
end
|
163
49
|
end
|
164
50
|
|
165
|
-
|
166
|
-
|
167
|
-
return false if rubygem.name.include?("-")
|
168
|
-
|
169
|
-
regex = %r{
|
170
|
-
^
|
171
|
-
\s*
|
172
|
-
require
|
173
|
-
\s+
|
174
|
-
['"]
|
175
|
-
#{rubygem.name}
|
176
|
-
/
|
177
|
-
}x
|
178
|
-
regex.match?(line)
|
51
|
+
def gemfile
|
52
|
+
@gemfile ||= ParseGemfile.new(@gem_specification).call(gemfile_path)
|
179
53
|
end
|
180
54
|
end
|
181
55
|
end
|
data/lib/degem/gemfile.rb
CHANGED
@@ -2,22 +2,28 @@
|
|
2
2
|
|
3
3
|
module Degem
|
4
4
|
class Gemfile
|
5
|
-
def initialize(dsl)
|
5
|
+
def initialize(dsl:, gem_specification:)
|
6
6
|
@dsl = dsl
|
7
|
+
@gem_specification = gem_specification
|
7
8
|
end
|
8
9
|
|
9
10
|
def rubygems
|
10
|
-
@rubygems ||=
|
11
|
+
@rubygems ||=
|
12
|
+
(gemfile_dependencies + gemspec_dependencies)
|
13
|
+
.map { Rubygem.new(rubygem: _1, gem_specification: @gem_specification) }
|
14
|
+
.uniq
|
11
15
|
end
|
12
16
|
|
13
17
|
def rails?
|
14
|
-
|
18
|
+
!!rubygems.find(&:rails?)
|
15
19
|
end
|
16
20
|
|
17
21
|
private
|
18
22
|
|
19
23
|
def gemfile_dependencies
|
20
|
-
@dsl.dependencies.select(&:should_include?)
|
24
|
+
@dsl.dependencies.select(&:should_include?).reject do |dependency|
|
25
|
+
@dsl.gemspecs.flat_map(&:name).include?(dependency.name)
|
26
|
+
end
|
21
27
|
end
|
22
28
|
|
23
29
|
def gemspec_dependencies
|
data/lib/degem/parse_gemfile.rb
CHANGED
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module Degem
|
4
4
|
class ParseGemfile
|
5
|
+
def initialize(gem_specification = Gem::Specification)
|
6
|
+
@gem_specification = gem_specification
|
7
|
+
end
|
8
|
+
|
5
9
|
def call(gemfile_path)
|
6
10
|
dsl = Bundler::Dsl.new
|
7
11
|
dsl.eval_gemfile(gemfile_path)
|
8
|
-
Gemfile.new(dsl)
|
12
|
+
Gemfile.new(dsl: dsl, gem_specification: @gem_specification)
|
9
13
|
end
|
10
14
|
|
11
15
|
private
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class ParseRuby
|
5
|
+
def initialize(visitor = Visitor)
|
6
|
+
@visitor = visitor
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(path)
|
10
|
+
visitor = @visitor.new
|
11
|
+
Array(path).each do |path|
|
12
|
+
visitor.path = path
|
13
|
+
Prism.parse_file(path).value.accept(visitor)
|
14
|
+
Degem.stderr.putc "."
|
15
|
+
end
|
16
|
+
visitor
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
require "prism"
|
21
|
+
|
22
|
+
class Visitor < Prism::Visitor
|
23
|
+
def initialize
|
24
|
+
@requires = Set.new
|
25
|
+
@paths = Set.new
|
26
|
+
@classes = Set.new
|
27
|
+
@modules = Set.new
|
28
|
+
@path = nil
|
29
|
+
@stack = []
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def requires = @requires.to_a
|
34
|
+
def consts = (@paths.union(@classes).union(@modules)).to_a
|
35
|
+
def paths = @paths.to_a
|
36
|
+
def classes = @classes.to_a
|
37
|
+
def modules = @modules.to_a
|
38
|
+
attr_writer :path
|
39
|
+
|
40
|
+
def visit_call_node(node)
|
41
|
+
visit_require_call_node(node)
|
42
|
+
super
|
43
|
+
end
|
44
|
+
|
45
|
+
def visit_module_node(node)
|
46
|
+
@stack.push(node)
|
47
|
+
super
|
48
|
+
@modules.add(@stack.map(&:name).join("::"))
|
49
|
+
@stack.pop
|
50
|
+
end
|
51
|
+
|
52
|
+
def visit_class_node(node)
|
53
|
+
@stack.push(node)
|
54
|
+
super
|
55
|
+
@stack.pop
|
56
|
+
*modules, klass = node.constant_path.full_name_parts rescue [[], node.name]
|
57
|
+
@modules.add((@stack.map(&:name) + modules).join("::")) if modules.any?
|
58
|
+
@classes.add((@stack.map(&:name) + modules + [klass]).join("::"))
|
59
|
+
end
|
60
|
+
|
61
|
+
def visit_constant_path_node(node)
|
62
|
+
paths_from(node).each { @paths.add(_1) }
|
63
|
+
super
|
64
|
+
end
|
65
|
+
|
66
|
+
def visit_constant_read_node(node)
|
67
|
+
@paths.add(node.name.to_s) unless @stack.find { _1.constant_path == node }
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def visit_require_call_node(node)
|
74
|
+
return if node.name.to_s != "require"
|
75
|
+
return if node.receiver
|
76
|
+
return unless node.arguments
|
77
|
+
return unless node.arguments.arguments[0].is_a?(Prism::StringNode)
|
78
|
+
|
79
|
+
required = node.arguments.arguments[0].unescaped
|
80
|
+
@requires.add(required)
|
81
|
+
end
|
82
|
+
|
83
|
+
def from_ancestor_to(node)
|
84
|
+
acc = [node]
|
85
|
+
node = node.respond_to?(:parent) && node.parent
|
86
|
+
while node
|
87
|
+
acc.prepend(node)
|
88
|
+
node = node.respond_to?(:parent) && node.parent
|
89
|
+
end
|
90
|
+
acc
|
91
|
+
end
|
92
|
+
|
93
|
+
def paths_from(node)
|
94
|
+
from_ancestor_to(node)
|
95
|
+
.filter_map { _1.respond_to?(:name) ? _1.name.to_s : nil }
|
96
|
+
.tap { _1.singleton_class.include(Scan) }
|
97
|
+
.scan { |a, b| [a, b].join("::") }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
module Scan
|
102
|
+
def scan(init = nil)
|
103
|
+
if init.nil?
|
104
|
+
init = self[0]
|
105
|
+
xs = self[1..] || []
|
106
|
+
else
|
107
|
+
xs = self
|
108
|
+
end
|
109
|
+
|
110
|
+
return self if xs.empty?
|
111
|
+
|
112
|
+
xs.reduce([init]) do |acc, x|
|
113
|
+
acc + [yield(acc.last, x)]
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
data/lib/degem/report.rb
CHANGED
@@ -2,21 +2,17 @@
|
|
2
2
|
|
3
3
|
module Degem
|
4
4
|
class Report
|
5
|
-
def initialize(stderr)
|
6
|
-
@stderr = stderr
|
7
|
-
end
|
8
|
-
|
9
5
|
def call(rubygems)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
6
|
+
Degem.stderr.puts
|
7
|
+
Degem.stderr.puts
|
8
|
+
Degem.stderr.puts "The following gems may be unused (#{rubygems.size}):"
|
9
|
+
Degem.stderr.puts
|
14
10
|
|
15
11
|
rubygems.each do |rubygem|
|
16
12
|
gem_name(rubygem)
|
17
|
-
|
13
|
+
Degem.stderr.puts
|
18
14
|
commits(rubygem)
|
19
|
-
|
15
|
+
Degem.stderr.puts
|
20
16
|
end
|
21
17
|
end
|
22
18
|
|
@@ -30,15 +26,15 @@ module Degem
|
|
30
26
|
"#{rubygem.name}: #{rubygem.source_code_uri}"
|
31
27
|
end
|
32
28
|
|
33
|
-
|
34
|
-
|
29
|
+
Degem.stderr.puts(heading)
|
30
|
+
Degem.stderr.puts("=" * heading.size)
|
35
31
|
end
|
36
32
|
|
37
33
|
def commits(rubygem)
|
38
34
|
rubygem.commits.each.with_index do |commit, i|
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
Degem.stderr.puts("#{commit.hash[0..6]} (#{commit.date}) #{commit.title}")
|
36
|
+
Degem.stderr.puts(commit.url)
|
37
|
+
Degem.stderr.puts if i + 1 == rubygem.commits.size
|
42
38
|
end
|
43
39
|
end
|
44
40
|
end
|
data/lib/degem/rubygem.rb
CHANGED
@@ -1,16 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "delegate"
|
4
|
+
|
3
5
|
module Degem
|
4
|
-
class Rubygem <
|
5
|
-
|
6
|
+
class Rubygem < SimpleDelegator
|
7
|
+
def initialize(rubygem:, gem_specification:)
|
8
|
+
@gem_specification = gem_specification
|
9
|
+
super(rubygem)
|
10
|
+
end
|
11
|
+
|
12
|
+
def rails?
|
13
|
+
name == "rails"
|
14
|
+
end
|
6
15
|
|
7
|
-
def
|
8
|
-
|
9
|
-
@commits = commits
|
16
|
+
def railtie?
|
17
|
+
parsed.consts.grep(/Rails::Railtie|Rails::Engine/).any?
|
10
18
|
end
|
11
19
|
|
12
|
-
def
|
13
|
-
|
20
|
+
def own_consts
|
21
|
+
variations = [
|
22
|
+
name,
|
23
|
+
name.delete("_-"),
|
24
|
+
name.gsub("_", "::"),
|
25
|
+
name.gsub("-", "::"),
|
26
|
+
*name.split("_").each_cons(2).to_a.map { _1.join("::") },
|
27
|
+
*name.split("_").each_cons(2).to_a.map(&:join),
|
28
|
+
*name.split("-").each_cons(2).to_a.map { _1.join("::") },
|
29
|
+
*name.split("-").each_cons(2).to_a.map(&:join)
|
30
|
+
]
|
31
|
+
|
32
|
+
parsed.classes + (parsed.modules + parsed.paths).filter do |const|
|
33
|
+
variations.any? { |variation| const.downcase == variation.downcase }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def parsed
|
40
|
+
@parsed ||=
|
41
|
+
begin
|
42
|
+
gem_path = @gem_specification.find_by_name(name).full_gem_path
|
43
|
+
paths = Dir.glob(File.join(gem_path, "**", "lib", "**/*.rb"))
|
44
|
+
ParseRuby.new.call(paths)
|
45
|
+
end
|
14
46
|
end
|
15
47
|
end
|
16
48
|
end
|
data/lib/degem/version.rb
CHANGED
data/lib/degem.rb
CHANGED
@@ -2,18 +2,25 @@
|
|
2
2
|
|
3
3
|
require_relative "degem/version"
|
4
4
|
require_relative "degem/gemfile"
|
5
|
+
require_relative "degem/rubygem"
|
5
6
|
require_relative "degem/parse_gemfile"
|
6
|
-
require_relative "degem/grep"
|
7
7
|
require_relative "degem/git_ls_files"
|
8
|
-
require_relative "degem/
|
8
|
+
require_relative "degem/parse_ruby"
|
9
9
|
require_relative "degem/find_unused"
|
10
10
|
require_relative "degem/multi_delegator"
|
11
|
-
require_relative "degem/
|
12
|
-
require_relative "degem/
|
11
|
+
require_relative "degem/unused_gem"
|
12
|
+
require_relative "degem/decorate_unused_gems"
|
13
13
|
require_relative "degem/commit"
|
14
14
|
require_relative "degem/git_adapter"
|
15
15
|
require_relative "degem/report"
|
16
16
|
require_relative "degem/cli"
|
17
17
|
|
18
18
|
module Degem
|
19
|
+
class << self
|
20
|
+
attr_writer :stderr
|
21
|
+
|
22
|
+
def stderr
|
23
|
+
@stderr ||= $stderr
|
24
|
+
end
|
25
|
+
end
|
19
26
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: degem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- 3v0k4
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-12-
|
12
|
-
dependencies:
|
11
|
+
date: 2024-12-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: prism
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.2'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.2'
|
13
27
|
description: Degem finds unused gems in the Ruby bundle (ie, an app with a `Gemfile`
|
14
28
|
or a gem with both a `Gemfile` and a gemspec).
|
15
29
|
email:
|
@@ -23,18 +37,17 @@ files:
|
|
23
37
|
- lib/degem.rb
|
24
38
|
- lib/degem/cli.rb
|
25
39
|
- lib/degem/commit.rb
|
26
|
-
- lib/degem/
|
27
|
-
- lib/degem/decorated.rb
|
40
|
+
- lib/degem/decorate_unused_gems.rb
|
28
41
|
- lib/degem/find_unused.rb
|
29
42
|
- lib/degem/gemfile.rb
|
30
43
|
- lib/degem/git_adapter.rb
|
31
44
|
- lib/degem/git_ls_files.rb
|
32
|
-
- lib/degem/grep.rb
|
33
|
-
- lib/degem/matcher.rb
|
34
45
|
- lib/degem/multi_delegator.rb
|
35
46
|
- lib/degem/parse_gemfile.rb
|
47
|
+
- lib/degem/parse_ruby.rb
|
36
48
|
- lib/degem/report.rb
|
37
49
|
- lib/degem/rubygem.rb
|
50
|
+
- lib/degem/unused_gem.rb
|
38
51
|
- lib/degem/version.rb
|
39
52
|
homepage: https://github.com/3v0k4/degem
|
40
53
|
licenses:
|
data/lib/degem/grep.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "find"
|
4
|
-
|
5
|
-
module Degem
|
6
|
-
class Grep
|
7
|
-
def initialize(stderr = StringIO.new)
|
8
|
-
@stderr = stderr
|
9
|
-
end
|
10
|
-
|
11
|
-
def match?(matcher, dir)
|
12
|
-
Find.find(File.expand_path(dir)) do |path|
|
13
|
-
next unless File.file?(path)
|
14
|
-
next if File.extname(path) != ".rb"
|
15
|
-
|
16
|
-
@stderr.putc "."
|
17
|
-
File.foreach(path) do |line|
|
18
|
-
next unless matcher.match?(line)
|
19
|
-
|
20
|
-
return true
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
false
|
25
|
-
end
|
26
|
-
|
27
|
-
def inverse_many(matchers, paths)
|
28
|
-
Find.find(*paths) do |path|
|
29
|
-
next unless File.file?(path)
|
30
|
-
|
31
|
-
@stderr.putc "."
|
32
|
-
File.foreach(path) do |line|
|
33
|
-
matchers = matchers.reject do |matcher|
|
34
|
-
matcher.match?(line)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
matchers
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
data/lib/degem/matcher.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Degem
|
4
|
-
class Matcher
|
5
|
-
attr_reader :rubygem
|
6
|
-
|
7
|
-
def initialize(rubygem:, matchers:)
|
8
|
-
@rubygem = rubygem
|
9
|
-
@matchers = matchers
|
10
|
-
end
|
11
|
-
|
12
|
-
def match?(string)
|
13
|
-
@matchers.any? { _1.call(@rubygem, string) }
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|