degem 0.1.0 → 0.3.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 +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
|