diff --git a/lib/rubygems/commands/compile_command.rb b/lib/rubygems/commands/compile_command.rb index 87b7fc1..2d948e3 100644 --- a/lib/rubygems/commands/compile_command.rb +++ b/lib/rubygems/commands/compile_command.rb @@ -13,6 +13,14 @@ def initialize options[:include_shared_dir] = value end + add_option "--include GLOB", "Additional artifact to package (relative to the gem dir)" do |value, options| + (options[:artifacts] ||= []) << [true, value] + end + + add_option "--exclude GLOB", "Additional artifact to package (relative to the gem dir)" do |value, options| + (options[:artifacts] ||= []) << [false, value] + end + add_option "--prune", "Clean non-existing files during re-packaging" do |value, options| options[:prune] = true end diff --git a/lib/rubygems/compiler.rb b/lib/rubygems/compiler.rb index 2db9e74..2bdc897 100644 --- a/lib/rubygems/compiler.rb +++ b/lib/rubygems/compiler.rb @@ -3,6 +3,7 @@ require "tmpdir" require "rubygems/installer" require "rubygems/package" +require 'find' class Gem::Compiler include Gem::UserInteraction @@ -25,6 +26,16 @@ def compile artifacts = collect_artifacts + (@options[:artifacts] || []).map do |include, glob| + resolved = Dir.glob("#{target_dir}/#{glob}") + if include + artifacts.concat(resolved) + else + artifacts -= resolved + end + end + + if shared_dir = options[:include_shared_dir] shared_libs = collect_shared(shared_dir) diff --git a/test/rubygems/test_gem_compiler.rb b/test/rubygems/test_gem_compiler.rb index b246f0d..1424407 100644 --- a/test/rubygems/test_gem_compiler.rb +++ b/test/rubygems/test_gem_compiler.rb @@ -173,6 +173,106 @@ def test_compile_bundle_artifacts assert_includes spec.files, "lib/#{artifact}" end + def test_compile_bundle_include + util_reset_arch + + artifact = "foo.some_ext" + + gem_file = util_bake_gem("foo") { |s| + util_fake_extension s, "foo", util_custom_configure(artifact) + } + + compiler = Gem::Compiler.new( + gem_file, :output => @output_dir, + :artifacts => [[true, 'lib/*.some_ext']] + ) + output_gem = nil + + use_ui @ui do + output_gem = compiler.compile + end + + assert_path_exists File.join(@output_dir, output_gem) + spec = util_read_spec File.join(@output_dir, output_gem) + + assert_includes spec.files, "lib/#{artifact}" + end + + def test_compile_bundle_exclude_then_include + util_reset_arch + + script = <<-EO_MKRF + File.open("Rakefile", "w") do |f| + f.puts <<-EOF + task :default do + lib_dir = ENV["RUBYARCHDIR"] || ENV["RUBYLIBDIR"] + FileUtils.mkdir_p File.join(lib_dir, 'baz', 'file1.rb') + FileUtils.mkdir_p File.join(lib_dir, 'baz', 'file2.rb') + FileUtils.mkdir_p File.join(lib_dir, 'foo', 'bar') + touch File.join(lib_dir, 'foo', 'bar', 'somefile.txt') + end + EOF + end + EO_MKRF + + gem_file = util_bake_gem("foo") { |s| + util_fake_extension s, "foo", script + } + + compiler = Gem::Compiler.new( + gem_file, + output: @output_dir, + artifacts: [[false, '**/foo.rb'], [true, 'lib/foo/**/*']] + ) + output_gem = nil + + use_ui @ui do + output_gem = compiler.compile + end + + assert_path_exists File.join(@output_dir, output_gem) + spec = util_read_spec File.join(@output_dir, output_gem) + + assert_includes spec.files, "lib/foo/bar/somefile.txt" + end + + def test_compile_bundle_include_then_exclude + util_reset_arch + + script = <<-EO_MKRF + File.open("Rakefile", "w") do |f| + f.puts <<-EOF + task :default do + lib_dir = ENV["RUBYARCHDIR"] || ENV["RUBYLIBDIR"] + FileUtils.mkdir_p File.join(lib_dir, 'baz', 'somefile.txt') + FileUtils.mkdir_p File.join(lib_dir, 'foo', 'bar') + touch File.join(lib_dir, 'foo', 'bar', 'somefile.txt') + end + EOF + end + EO_MKRF + + gem_file = util_bake_gem("foo") { |s| + util_fake_extension s, "foo", script + } + + compiler = Gem::Compiler.new( + gem_file, :output => @output_dir, + :artifacts => [[true, 'lib/**/*'], [false, 'lib/baz/*']] + ) + output_gem = nil + + use_ui @ui do + output_gem = compiler.compile + end + + assert_path_exists File.join(@output_dir, output_gem) + spec = util_read_spec File.join(@output_dir, output_gem) + + assert_includes spec.files, "lib/foo/bar/somefile.txt" + refute_includes spec.files, "lib/baz/somefile.txt" + end + # We need to check that tempdir paths that contain spaces as are handled # properly on Windows. In some cases, Dir.tmpdir may returned shortened # versions of these components, e.g. "C:/Users/JOHNDO~1/AppData/Local/Temp"