Skip to content

Commit 6efb420

Browse files
committed
Remove duplicate gems when producting logstash artifacts
Bundler is used to manage a gem environment that is shipped with logstash artifacts. By default, bundler will install newer/duplicate gems than shipped with ruby distributions (in logstash's case jruby). Duplicate gems in the shipped environment can cause issues with code loading with ambiguous gem specs or gem activation issues. This commit adds a step to compute the duplicate gems managed with bundler (and therefore direct/transitive dependencies of logstash/plugins) and *removes* copies shipped with jruby. Note that there are two locations to do the deduplication at. Both the stdlib gems as well as what jruby refers to as "bundled" gems. The existing pattern for excluding files from artifacts is used to implement the deduplication.
1 parent a83b7a4 commit 6efb420

File tree

1 file changed

+53
-12
lines changed

1 file changed

+53
-12
lines changed

rakelib/artifacts.rake

Lines changed: 53 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,56 @@ namespace "artifact" do
8282
res
8383
end
8484

85+
def duplicated_gems_exclude_paths
86+
shared_gems_path = 'vendor/jruby/lib/ruby/gems/shared/gems'
87+
default_gemspecs_path = 'vendor/jruby/lib/ruby/gems/shared/specifications/default'
88+
bundle_gems_path = 'vendor/bundle/jruby/*/gems'
89+
90+
exclusions = []
91+
92+
# "bundled" gems in jruby
93+
# https://github.com/jruby/jruby/blob/024123c29d73b672d50730117494f3e4336a0edb/lib/pom.rb#L108-L152
94+
shared_gem_names = Dir.glob(File.join(shared_gems_path, '*')).map do |path|
95+
match = File.basename(path).match(/^(.+?)-\d+/)
96+
match ? match[1] : nil
97+
end.compact
98+
99+
# "default" gems in jruby/ruby
100+
# https://github.com/jruby/jruby/blob/024123c29d73b672d50730117494f3e4336a0edb/lib/pom.rb#L21-L106
101+
default_gem_names = Dir.glob(File.join(default_gemspecs_path, '*.gemspec')).map do |path|
102+
match = File.basename(path).match(/^(.+?)-\d+/)
103+
match ? match[1] : nil
104+
end.compact
105+
106+
# gems we explicitly manage with bundler (we always want these to take precedence)
107+
bundle_gem_names = Dir.glob(File.join(bundle_gems_path, '*')).map do |path|
108+
match = File.basename(path).match(/^(.+?)-\d+/)
109+
match ? match[1] : nil
110+
end.compact
111+
112+
shared_duplicates = shared_gem_names & bundle_gem_names
113+
default_duplicates = default_gem_names & bundle_gem_names
114+
all_duplicates = (shared_duplicates + default_duplicates).uniq
115+
puts "Adding duplicate gems to exclude path: #{all_duplicates.sort.join(', ')}"
116+
117+
# Exclude shared/bundled gems duplicates
118+
shared_duplicates.each do |gem_name|
119+
exclusions << "vendor/jruby/lib/ruby/gems/shared/gems/#{gem_name}-*/**/*"
120+
exclusions << "vendor/jruby/lib/ruby/gems/shared/gems/#{gem_name}-*"
121+
exclusions << "vendor/jruby/lib/ruby/gems/shared/specifications/#{gem_name}-*.gemspec"
122+
end
123+
124+
# Exclude default gems duplicates
125+
default_duplicates.each do |gem_name|
126+
exclusions << "vendor/jruby/lib/ruby/gems/shared/specifications/default/#{gem_name}-*.gemspec"
127+
exclusions << "vendor/jruby/lib/ruby/stdlib/#{gem_name}.rb"
128+
exclusions << "vendor/jruby/lib/ruby/stdlib/#{gem_name}/**/*"
129+
exclusions << "vendor/jruby/lib/ruby/stdlib/#{gem_name}"
130+
end
131+
132+
exclusions
133+
end
134+
85135
def default_exclude_paths
86136
return @exclude_paths if @exclude_paths
87137

@@ -101,18 +151,9 @@ namespace "artifact" do
101151
@exclude_paths << 'vendor/**/gems/**/Gemfile.lock'
102152
@exclude_paths << 'vendor/**/gems/**/Gemfile'
103153

104-
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rake-*'
105-
# exclude ruby-maven-libs 3.3.9 jars until JRuby ships with >= 3.8.9
106-
@exclude_paths << 'vendor/bundle/jruby/**/gems/ruby-maven-libs-3.3.9/**/*'
107-
108-
# remove this after JRuby includes rexml 3.3.x
109-
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/rexml-3.2.5/**/*'
110-
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/specifications/rexml-3.2.5.gemspec'
111-
112-
# remove this after JRuby includes net-imap-0.2.4+
113-
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/specifications/net-imap-0.2.3.gemspec'
114-
@exclude_paths << 'vendor/jruby/lib/ruby/gems/shared/gems/net-imap-0.2.3/**/*'
115-
154+
@exclude_paths.concat(duplicated_gems_exclude_paths)
155+
puts "Full exclude_paths list:"
156+
@exclude_paths.each { |path| puts " - #{path}" }
116157
@exclude_paths.freeze
117158
end
118159

0 commit comments

Comments
 (0)