degem 0.1.0 → 0.2.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
- 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 +25 -145
- data/lib/degem/gemfile.rb +9 -3
- data/lib/degem/parse_gemfile.rb +5 -1
- data/lib/degem/parse_ruby.rb +110 -0
- data/lib/degem/report.rb +11 -15
- data/lib/degem/rubygem.rb +33 -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: 4ca5d0f8ec44263d688f664f508c95477f5740aba98449817d1aee6728516c6c
|
4
|
+
data.tar.gz: 7dd84507228188120a8ee904e648fedc0116c639f83ba6c57f445a2d5267c69a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bee7cac14068642532355b2b88e205b1ebadc35ee8e8f6f31fea257079295e0cae4733d0f59cba95ddea9bc0404bf62cfc641790a98d0ae203630633cfdbeb2b
|
7
|
+
data.tar.gz: de01fdf89638fcb8bbbbc267a731e55197442fdaeb26d3b80567811b9f79accfac9a78fe07056b7ea0b993afe025acbbb2a8a80948ee0b78cc51dd89cdd3ed4c
|
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,11 +2,11 @@
|
|
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
|
@@ -22,160 +22,40 @@ module Degem
|
|
22
22
|
def reject_railties(rubygems)
|
23
23
|
rubygems
|
24
24
|
.reject { _1.name == "rails" }
|
25
|
-
.reject
|
26
|
-
gem_path = @gem_specification.find_by_name(rubygem.name).full_gem_path
|
27
|
-
@grep.match?(/(Rails::Railtie|Rails::Engine)/, gem_path)
|
28
|
-
end
|
25
|
+
.reject { _1.consts.grep(/Rails::Railtie|Rails::Engine/).any? }
|
29
26
|
end
|
30
27
|
|
31
28
|
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)
|
29
|
+
bundle = ParseRuby.new.call(@bundle_paths)
|
30
|
+
rubygems = reject_required(rubygems, bundle.requires)
|
31
|
+
reject_consts(rubygems, bundle.consts)
|
82
32
|
end
|
83
33
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
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)
|
34
|
+
def reject_consts(rubygems, bundle_consts)
|
35
|
+
rubygems.reject do |rubygem|
|
36
|
+
rubygem.own_consts.any? do |own_const|
|
37
|
+
bundle_consts.include?(own_const)
|
38
|
+
end
|
39
|
+
end
|
120
40
|
end
|
121
41
|
|
122
|
-
|
123
|
-
|
124
|
-
|
42
|
+
def reject_required(rubygems, bundle_requires)
|
43
|
+
rubygems.reject do |rubygem|
|
44
|
+
bundle_requires.any? do |bundle_require|
|
45
|
+
next true if bundle_require == rubygem.name
|
46
|
+
next true if bundle_require == rubygem.name.tr("-", "/")
|
125
47
|
|
126
|
-
|
127
|
-
|
128
|
-
|
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)
|
48
|
+
bundle_require.start_with?("#{rubygem.name}/")
|
49
|
+
end
|
50
|
+
end
|
147
51
|
end
|
148
52
|
|
149
|
-
|
150
|
-
|
151
|
-
return false unless rubygem.name.include?("-")
|
152
|
-
|
153
|
-
regex = %r{
|
154
|
-
^
|
155
|
-
\s*
|
156
|
-
require
|
157
|
-
\s+
|
158
|
-
['"]
|
159
|
-
#{rubygem.name.tr("-", "/")} # match foo/bar when rubygem is foo-bar
|
160
|
-
['"]
|
161
|
-
}x
|
162
|
-
regex.match?(line)
|
53
|
+
def gemfile
|
54
|
+
@gemfile ||= ParseGemfile.new(@gem_specification).call(gemfile_path)
|
163
55
|
end
|
164
56
|
|
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)
|
57
|
+
def rails?
|
58
|
+
@rails ||= gemfile.rails?
|
179
59
|
end
|
180
60
|
end
|
181
61
|
end
|
data/lib/degem/gemfile.rb
CHANGED
@@ -2,12 +2,16 @@
|
|
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?
|
@@ -17,7 +21,9 @@ module Degem
|
|
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,110 @@
|
|
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
|
+
@consts = Set.new
|
26
|
+
@path = nil
|
27
|
+
@stack = []
|
28
|
+
super
|
29
|
+
end
|
30
|
+
|
31
|
+
def requires = @requires.to_a
|
32
|
+
def consts = @consts.to_a
|
33
|
+
attr_writer :path
|
34
|
+
|
35
|
+
def visit_call_node(node)
|
36
|
+
visit_require_call_node(node)
|
37
|
+
super
|
38
|
+
end
|
39
|
+
|
40
|
+
def visit_module_node(node)
|
41
|
+
@stack.push(node)
|
42
|
+
super
|
43
|
+
@consts.add(@stack.map(&:name).join("::"))
|
44
|
+
@stack.pop
|
45
|
+
end
|
46
|
+
|
47
|
+
def visit_class_node(node)
|
48
|
+
@stack.push(node)
|
49
|
+
super
|
50
|
+
@consts.add(@stack.map(&:name).join("::"))
|
51
|
+
@stack.pop
|
52
|
+
end
|
53
|
+
|
54
|
+
def visit_constant_path_node(node)
|
55
|
+
consts_from(node).each { @consts.add(_1) }
|
56
|
+
super
|
57
|
+
end
|
58
|
+
|
59
|
+
def visit_constant_read_node(node)
|
60
|
+
@consts.add(node.name.to_s) unless @stack.find { _1.constant_path == node }
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def visit_require_call_node(node)
|
67
|
+
return if node.name.to_s != "require"
|
68
|
+
return if node.receiver
|
69
|
+
return unless node.arguments
|
70
|
+
return unless node.arguments.arguments[0].is_a?(Prism::StringNode)
|
71
|
+
|
72
|
+
required = node.arguments.arguments[0].unescaped
|
73
|
+
@requires.add(required)
|
74
|
+
end
|
75
|
+
|
76
|
+
def from_ancestor_to(node)
|
77
|
+
acc = [node]
|
78
|
+
node = node.respond_to?(:parent) && node.parent
|
79
|
+
while node
|
80
|
+
acc.prepend(node)
|
81
|
+
node = node.respond_to?(:parent) && node.parent
|
82
|
+
end
|
83
|
+
acc
|
84
|
+
end
|
85
|
+
|
86
|
+
def consts_from(node)
|
87
|
+
from_ancestor_to(node)
|
88
|
+
.filter_map { _1.respond_to?(:name) ? _1.name.to_s : nil }
|
89
|
+
.tap { _1.singleton_class.include(Scan) }
|
90
|
+
.scan { |a, b| [a, b].join("::") }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
module Scan
|
95
|
+
def scan(init = nil)
|
96
|
+
if init.nil?
|
97
|
+
init = self[0]
|
98
|
+
xs = self[1..] || []
|
99
|
+
else
|
100
|
+
xs = self
|
101
|
+
end
|
102
|
+
|
103
|
+
return self if xs.empty?
|
104
|
+
|
105
|
+
xs.reduce([init]) do |acc, x|
|
106
|
+
acc + [yield(acc.last, x)]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
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,42 @@
|
|
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 consts
|
13
|
+
parsed.consts
|
14
|
+
end
|
15
|
+
|
16
|
+
def own_consts
|
17
|
+
variations = [
|
18
|
+
name,
|
19
|
+
name.delete("_-"),
|
20
|
+
name.gsub("_", "::"),
|
21
|
+
name.gsub("-", "::"),
|
22
|
+
*name.split("_").each_cons(2).to_a.map { _1.join("::") },
|
23
|
+
*name.split("_").each_cons(2).to_a.map(&:join),
|
24
|
+
*name.split("-").each_cons(2).to_a.map { _1.join("::") },
|
25
|
+
*name.split("-").each_cons(2).to_a.map(&:join)
|
26
|
+
]
|
6
27
|
|
7
|
-
|
8
|
-
super
|
9
|
-
@commits = commits
|
28
|
+
consts.filter { |const| variations.any? { |variation| const.downcase == variation.downcase } }
|
10
29
|
end
|
11
30
|
|
12
|
-
|
13
|
-
|
31
|
+
private
|
32
|
+
|
33
|
+
def parsed
|
34
|
+
@parsed ||=
|
35
|
+
begin
|
36
|
+
gem_path = @gem_specification.find_by_name(name).full_gem_path
|
37
|
+
paths = Dir.glob(File.join(gem_path, "**/*.rb"))
|
38
|
+
ParseRuby.new.call(paths)
|
39
|
+
end
|
14
40
|
end
|
15
41
|
end
|
16
42
|
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.2.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-18 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
|