degem 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/exe/degem +5 -0
- data/lib/degem/cli.rb +48 -0
- data/lib/degem/commit.rb +3 -0
- data/lib/degem/decorate_rubygems.rb +18 -0
- data/lib/degem/decorated.rb +16 -0
- data/lib/degem/find_unused.rb +181 -0
- data/lib/degem/gemfile.rb +27 -0
- data/lib/degem/git_adapter.rb +78 -0
- data/lib/degem/git_ls_files.rb +21 -0
- data/lib/degem/grep.rb +42 -0
- data/lib/degem/matcher.rb +16 -0
- data/lib/degem/multi_delegator.rb +20 -0
- data/lib/degem/parse_gemfile.rb +17 -0
- data/lib/degem/report.rb +45 -0
- data/lib/degem/rubygem.rb +16 -0
- data/lib/degem/version.rb +5 -0
- data/lib/degem.rb +19 -0
- metadata +66 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 99c4e8766d6d3f8e6f710e2e13c0e0007190617fff3f83d198b469f0aec2ffb9
|
4
|
+
data.tar.gz: 4df2c08f44fc1eb1c694a85ae55d36421f4610bb717f3789eb8b5feb93c726e3
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 26145f7a46f9b9a3152092ba4fa7065261630b66c5edf443d7e90d1eff1c88264814edefc3048d73c39b24cb7a7e9709114baf5959133de351b841967f17fba0
|
7
|
+
data.tar.gz: 5f3d721a7bf24c8541f93d5a67672ca71f8bfa7550a11822af4e214d6e338d905b9a4f8a3324457593de276c88cbb18eaf10af910faa8470a9abca9096787eca
|
data/exe/degem
ADDED
data/lib/degem/cli.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class Cli
|
5
|
+
GEMFILE = "Gemfile"
|
6
|
+
|
7
|
+
def self.call
|
8
|
+
exit new($stderr).call
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(stderr)
|
12
|
+
@stderr = stderr
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
unless gemfile_exists?
|
17
|
+
@stderr.puts "Gemfile not found in the current directory"
|
18
|
+
return 1
|
19
|
+
end
|
20
|
+
|
21
|
+
unused = find_unused.call
|
22
|
+
decorated = decorate_rubygems.call(unused)
|
23
|
+
Report.new(@stderr).call(decorated)
|
24
|
+
0
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def find_unused
|
30
|
+
FindUnused.new(
|
31
|
+
gemfile_path: GEMFILE,
|
32
|
+
gem_specification: Gem::Specification,
|
33
|
+
grep: Grep.new(@stderr)
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def decorate_rubygems
|
38
|
+
DecorateRubygems.new(
|
39
|
+
gem_specification: Gem::Specification,
|
40
|
+
git_adapter: GitAdapter.new
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
def gemfile_exists?
|
45
|
+
File.file?(GEMFILE)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/degem/commit.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class DecorateRubygems
|
5
|
+
def initialize(gem_specification:, git_adapter:)
|
6
|
+
@gem_specification = gem_specification
|
7
|
+
@git_adapter = git_adapter
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(rubygems)
|
11
|
+
rubygems.map do |rubygem|
|
12
|
+
gemspec = @gem_specification.find_by_name(rubygem.name)
|
13
|
+
git = @git_adapter.call(rubygem.name)
|
14
|
+
Rubygem.new(rubygem, gemspec, git)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class Rubygem < MultiDelegator
|
5
|
+
attr_reader :commits
|
6
|
+
|
7
|
+
def initialize(_, _, commits)
|
8
|
+
super
|
9
|
+
@commits = commits
|
10
|
+
end
|
11
|
+
|
12
|
+
def source_code_uri
|
13
|
+
metadata["source_code_uri"] || homepage
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class FindUnused
|
5
|
+
def initialize(gemfile_path:, gem_specification:, grep: Grep.new, bundle_paths: GitLsFiles.new)
|
6
|
+
@gemfile_path = gemfile_path
|
7
|
+
@gem_specification = gem_specification
|
8
|
+
@grep = grep
|
9
|
+
@bundle_paths = bundle_paths.call(File.dirname(gemfile_path))
|
10
|
+
end
|
11
|
+
|
12
|
+
def call
|
13
|
+
rubygems = gemfile.rubygems.reject { _1.name == "degem" }
|
14
|
+
rubygems = reject_railties(rubygems) if rails?
|
15
|
+
reject_used(rubygems)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :gemfile_path
|
21
|
+
|
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
|
29
|
+
end
|
30
|
+
|
31
|
+
def reject_used(rubygems)
|
32
|
+
candidates = rubygems.map { Matcher.new(rubygem: _1, matchers: matchers) }
|
33
|
+
@grep.inverse_many(candidates, @bundle_paths).map(&:rubygem)
|
34
|
+
end
|
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)
|
120
|
+
end
|
121
|
+
|
122
|
+
# gem foo_bar -> FooBar. (but not X::FooBar. or XFooBar.)
|
123
|
+
def based_on_top_composite_call_underscore(rubygem, line)
|
124
|
+
return false unless rubygem.name.include?("_")
|
125
|
+
|
126
|
+
regex = %r{
|
127
|
+
(?<!\w::) # Do not match if :: before
|
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)
|
147
|
+
end
|
148
|
+
|
149
|
+
# gem foo-bar -> require 'foo/bar'
|
150
|
+
def based_on_require_path(rubygem, line)
|
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)
|
163
|
+
end
|
164
|
+
|
165
|
+
# gem foo -> require 'foo/'
|
166
|
+
def based_on_require_prefix_path(rubygem, line)
|
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)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class Gemfile
|
5
|
+
def initialize(dsl)
|
6
|
+
@dsl = dsl
|
7
|
+
end
|
8
|
+
|
9
|
+
def rubygems
|
10
|
+
@rubygems ||= (gemfile_dependencies + gemspec_dependencies).uniq
|
11
|
+
end
|
12
|
+
|
13
|
+
def rails?
|
14
|
+
@rails ||= rubygems.map(&:name).include?("rails")
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def gemfile_dependencies
|
20
|
+
@dsl.dependencies.select(&:should_include?)
|
21
|
+
end
|
22
|
+
|
23
|
+
def gemspec_dependencies
|
24
|
+
@dsl.gemspecs.flat_map(&:dependencies)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "ostruct"
|
4
|
+
require "open3"
|
5
|
+
|
6
|
+
module Degem
|
7
|
+
class GitAdapter
|
8
|
+
def call(gem_name)
|
9
|
+
out, _err, status = git_log(gem_name)
|
10
|
+
return [] unless status.zero?
|
11
|
+
|
12
|
+
out.split("\n").map do |commit|
|
13
|
+
hash, date, title = commit.split("\t")
|
14
|
+
Commit.new(hash:, date:, title:, url: to_commit_url(hash))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def git_remote_origin_url
|
21
|
+
out, err, status = Open3.capture3("git remote get-url origin")
|
22
|
+
[out, err, status.exitstatus]
|
23
|
+
end
|
24
|
+
|
25
|
+
def git_log(gem_name)
|
26
|
+
out1, err1, status1 = git_log_gemfile(gem_name)
|
27
|
+
out2, err2, status2 = git_log_gemspec(gem_name)
|
28
|
+
|
29
|
+
[
|
30
|
+
[out1.to_s, out2.to_s].join,
|
31
|
+
[err1.to_s, err2.to_s].join,
|
32
|
+
(status1 + status2) < 2 ? 0 : 1
|
33
|
+
]
|
34
|
+
end
|
35
|
+
|
36
|
+
def git_log_gemfile(gem_name)
|
37
|
+
out, err, status = Open3.capture3([
|
38
|
+
"git log",
|
39
|
+
"--pretty=format:'%H%x09%cs%x09%s'",
|
40
|
+
"--pickaxe-regex",
|
41
|
+
"--follow",
|
42
|
+
"-S \"gem\\s*['\\\"]#{gem_name}['\\\"]\"",
|
43
|
+
"--",
|
44
|
+
"Gemfile",
|
45
|
+
"|",
|
46
|
+
"cat"
|
47
|
+
].join(" "))
|
48
|
+
|
49
|
+
[out, err, status.exitstatus]
|
50
|
+
end
|
51
|
+
|
52
|
+
def git_log_gemspec(gem_name)
|
53
|
+
out, err, status = Open3.capture3([
|
54
|
+
"git log",
|
55
|
+
"--pretty=format:'%H%x09%cs%x09%s'",
|
56
|
+
"--pickaxe-regex",
|
57
|
+
"--follow",
|
58
|
+
"-S \"spec\\.add_(development_)?dependency\\s*['\\\"]#{gem_name}['\\\"]\"",
|
59
|
+
"--",
|
60
|
+
"*.gemspec",
|
61
|
+
"|",
|
62
|
+
"cat"
|
63
|
+
].join(" "))
|
64
|
+
|
65
|
+
[out, err, status.exitstatus]
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_commit_url(commit_hash)
|
69
|
+
remote, _, status = git_remote_origin_url
|
70
|
+
return "" unless status.zero?
|
71
|
+
|
72
|
+
repository = (remote.match(%r{github\.com[:/](.+?)(\.git)}) || [])[1]
|
73
|
+
return "" if repository.nil?
|
74
|
+
|
75
|
+
"https://github.com/#{repository}/commit/#{commit_hash}"
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "open3"
|
4
|
+
|
5
|
+
module Degem
|
6
|
+
class GitLsFiles
|
7
|
+
def call(fallback)
|
8
|
+
out, _err, status = git_ls
|
9
|
+
return fallback unless status.zero?
|
10
|
+
|
11
|
+
out.split("\x0").select { _1.end_with?(".rb") }.map { File.expand_path(_1) }
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def git_ls
|
17
|
+
out, err, status = Open3.capture3("git ls-files -z")
|
18
|
+
[out, err, status.exitstatus]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/degem/grep.rb
ADDED
@@ -0,0 +1,42 @@
|
|
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
|
@@ -0,0 +1,16 @@
|
|
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
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class MultiDelegator
|
5
|
+
def initialize(*delegates)
|
6
|
+
@delegates = delegates
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing(method, *args)
|
10
|
+
delegate = @delegates.find { _1.respond_to?(method) }
|
11
|
+
return delegate.public_send(method, *args) if delegate
|
12
|
+
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def respond_to_missing?(method, include_private = false)
|
17
|
+
@delegates.any? { _1.respond_to?(method, include_private) } || super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class ParseGemfile
|
5
|
+
def call(gemfile_path)
|
6
|
+
dsl = Bundler::Dsl.new
|
7
|
+
dsl.eval_gemfile(gemfile_path)
|
8
|
+
Gemfile.new(dsl)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def definition(gemfile_path)
|
14
|
+
Bundler::Dsl.evaluate(gemfile_path, nil, {})
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/degem/report.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class Report
|
5
|
+
def initialize(stderr)
|
6
|
+
@stderr = stderr
|
7
|
+
end
|
8
|
+
|
9
|
+
def call(rubygems)
|
10
|
+
@stderr.puts
|
11
|
+
@stderr.puts
|
12
|
+
@stderr.puts "The following gems may be unused:"
|
13
|
+
@stderr.puts
|
14
|
+
|
15
|
+
rubygems.each do |rubygem|
|
16
|
+
gem_name(rubygem)
|
17
|
+
@stderr.puts
|
18
|
+
commits(rubygem)
|
19
|
+
@stderr.puts
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def gem_name(rubygem)
|
26
|
+
heading =
|
27
|
+
if rubygem.source_code_uri.nil?
|
28
|
+
rubygem.name
|
29
|
+
else
|
30
|
+
"#{rubygem.name}: #{rubygem.source_code_uri}"
|
31
|
+
end
|
32
|
+
|
33
|
+
@stderr.puts(heading)
|
34
|
+
@stderr.puts("=" * heading.size)
|
35
|
+
end
|
36
|
+
|
37
|
+
def commits(rubygem)
|
38
|
+
rubygem.commits.each.with_index do |commit, i|
|
39
|
+
@stderr.puts("#{commit.hash[0..6]} (#{commit.date}) #{commit.title}")
|
40
|
+
@stderr.puts(commit.url)
|
41
|
+
@stderr.puts if i + 1 == rubygem.commits.size
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Degem
|
4
|
+
class Rubygem < MultiDelegator
|
5
|
+
attr_reader :commits
|
6
|
+
|
7
|
+
def initialize(_, _, commits)
|
8
|
+
super
|
9
|
+
@commits = commits
|
10
|
+
end
|
11
|
+
|
12
|
+
def source_code_uri
|
13
|
+
metadata["source_code_uri"] || homepage
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/degem.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "degem/version"
|
4
|
+
require_relative "degem/gemfile"
|
5
|
+
require_relative "degem/parse_gemfile"
|
6
|
+
require_relative "degem/grep"
|
7
|
+
require_relative "degem/git_ls_files"
|
8
|
+
require_relative "degem/matcher"
|
9
|
+
require_relative "degem/find_unused"
|
10
|
+
require_relative "degem/multi_delegator"
|
11
|
+
require_relative "degem/rubygem"
|
12
|
+
require_relative "degem/decorate_rubygems"
|
13
|
+
require_relative "degem/commit"
|
14
|
+
require_relative "degem/git_adapter"
|
15
|
+
require_relative "degem/report"
|
16
|
+
require_relative "degem/cli"
|
17
|
+
|
18
|
+
module Degem
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: degem
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- 3v0k4
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-05 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: Degem finds unused gems in the Ruby bundle (ie, an app with a `Gemfile`
|
14
|
+
or a gem with both a `Gemfile` and a gemspec).
|
15
|
+
email:
|
16
|
+
- riccardo.odone@gmail.com
|
17
|
+
executables:
|
18
|
+
- degem
|
19
|
+
extensions: []
|
20
|
+
extra_rdoc_files: []
|
21
|
+
files:
|
22
|
+
- exe/degem
|
23
|
+
- lib/degem.rb
|
24
|
+
- lib/degem/cli.rb
|
25
|
+
- lib/degem/commit.rb
|
26
|
+
- lib/degem/decorate_rubygems.rb
|
27
|
+
- lib/degem/decorated.rb
|
28
|
+
- lib/degem/find_unused.rb
|
29
|
+
- lib/degem/gemfile.rb
|
30
|
+
- lib/degem/git_adapter.rb
|
31
|
+
- lib/degem/git_ls_files.rb
|
32
|
+
- lib/degem/grep.rb
|
33
|
+
- lib/degem/matcher.rb
|
34
|
+
- lib/degem/multi_delegator.rb
|
35
|
+
- lib/degem/parse_gemfile.rb
|
36
|
+
- lib/degem/report.rb
|
37
|
+
- lib/degem/rubygem.rb
|
38
|
+
- lib/degem/version.rb
|
39
|
+
homepage: https://github.com/3v0k4/degem
|
40
|
+
licenses:
|
41
|
+
- MIT
|
42
|
+
metadata:
|
43
|
+
homepage_uri: https://github.com/3v0k4/degem
|
44
|
+
source_code_uri: https://github.com/3v0k4/degem
|
45
|
+
changelog_uri: https://github.com/3v0k4/degem/blob/main/CHANGELOG.md
|
46
|
+
rubygems_mfa_required: 'true'
|
47
|
+
post_install_message:
|
48
|
+
rdoc_options: []
|
49
|
+
require_paths:
|
50
|
+
- lib
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: 3.1.0
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubygems_version: 3.5.23
|
63
|
+
signing_key:
|
64
|
+
specification_version: 4
|
65
|
+
summary: Find unused gems in the Ruby bundle
|
66
|
+
test_files: []
|