diff --git a/lib/rubygems/commands/generate_index_command.rb b/lib/rubygems/commands/generate_index_command.rb index 4cb3985..a11c761 100644 --- a/lib/rubygems/commands/generate_index_command.rb +++ b/lib/rubygems/commands/generate_index_command.rb @@ -22,14 +22,10 @@ def initialize end add_option "--[no-]modern", - "Generate indexes for RubyGems", - "(always true)" do |value, options| + "Generate indexes for RubyGems" do |value, options| options[:build_modern] = value end - deprecate_option("--modern", version: "4.0", extra_msg: "Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.") - deprecate_option("--no-modern", version: "4.0", extra_msg: "The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.") - add_option "--[no-]compact", "Generate compact index files" do |value, options| options[:build_compact] = value @@ -73,8 +69,10 @@ def description # :nodoc: end def execute - # This is always true because it's the only way now. - options[:build_modern] = true + if !options[:build_modern] && !options[:build_compact] + alert_error "At least one of --modern or --compact must be enabled." + terminate_interaction 1 + end if !File.exist?(options[:directory]) || !File.directory?(options[:directory]) diff --git a/lib/rubygems/indexer.rb b/lib/rubygems/indexer.rb index 65fa768..cbcc434 100644 --- a/lib/rubygems/indexer.rb +++ b/lib/rubygems/indexer.rb @@ -108,8 +108,12 @@ def initialize(directory, options = {}) def build_indices specs = map_gems_to_specs gem_file_list Gem::Specification._resort! specs - build_marshal_gemspecs specs - build_modern_indices specs if @build_modern + + if @build_modern + build_marshal_gemspecs specs + build_modern_indices specs + end + build_compact_index specs if @build_compact compress_indices @@ -288,10 +292,10 @@ def map_gems_to_specs(gems) # All future files should be compressed using gzip, not deflate def compress_indices - say "Compressing indices" + if @build_modern + say "Compressing indices" - Gem.time "Compressed indices" do - if @build_modern + Gem.time "Compressed indices" do gzip @specs_index gzip @latest_specs_index gzip @prerelease_specs_index @@ -400,7 +404,7 @@ def install_indices def make_temp_directories FileUtils.rm_rf @directory FileUtils.mkdir_p @directory, :mode => 0o700 - FileUtils.mkdir_p @quick_marshal_dir + FileUtils.mkdir_p @quick_marshal_dir if @build_modern end ## @@ -421,7 +425,13 @@ def paranoid(path, extension) def update_index make_temp_directories - specs_mtime = File.stat(@dest_specs_index).mtime + if @build_modern + reference_file = @dest_specs_index + elsif @build_compact + reference_file = File.join(@dest_directory, "versions") + end + + specs_mtime = File.stat(reference_file).mtime newest_mtime = Time.at 0 updated_gems = gem_file_list.select do |gem| @@ -438,14 +448,18 @@ def update_index specs = map_gems_to_specs updated_gems prerelease, released = specs.partition {|s| s.version.prerelease? } - files = build_marshal_gemspecs specs + files = [] + + if @build_modern + files = build_marshal_gemspecs specs - Gem.time "Updated indexes" do - update_specs_index released, @dest_specs_index, @specs_index - update_specs_index released, @dest_latest_specs_index, @latest_specs_index - update_specs_index(prerelease, - @dest_prerelease_specs_index, - @prerelease_specs_index) + Gem.time "Updated indexes" do + update_specs_index released, @dest_specs_index, @specs_index + update_specs_index released, @dest_latest_specs_index, @latest_specs_index + update_specs_index(prerelease, + @dest_prerelease_specs_index, + @prerelease_specs_index) + end end if @build_compact @@ -460,12 +474,14 @@ def update_index say "Updating production dir #{@dest_directory}" if verbose - files << @specs_index - files << "#{@specs_index}.gz" - files << @latest_specs_index - files << "#{@latest_specs_index}.gz" - files << @prerelease_specs_index - files << "#{@prerelease_specs_index}.gz" + if @build_modern + files << @specs_index + files << "#{@specs_index}.gz" + files << @latest_specs_index + files << "#{@latest_specs_index}.gz" + files << @prerelease_specs_index + files << "#{@prerelease_specs_index}.gz" + end files = files.map do |path| path.sub(%r{^#{Regexp.escape @directory}/?}, "") # HACK? diff --git a/test/rubygems/test_gem_commands_generate_index_command.rb b/test/rubygems/test_gem_commands_generate_index_command.rb index 7e719a5..993bad8 100644 --- a/test/rubygems/test_gem_commands_generate_index_command.rb +++ b/test/rubygems/test_gem_commands_generate_index_command.rb @@ -60,22 +60,45 @@ def test_handle_options_update end def test_handle_options_modern - use_ui @ui do - @cmd.handle_options %w[--modern] - end + @cmd.handle_options %w[--modern] - assert_equal \ - "WARNING: The \"--modern\" option has been deprecated and will be removed in Rubygems 4.0. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated, so this option is not needed.\n", - @ui.error + assert @cmd.options[:build_modern] end def test_handle_options_no_modern + @cmd.handle_options %w[--no-modern] + + refute @cmd.options[:build_modern] + end + + def test_execute_compact_only + @cmd.options[:build_modern] = false + @cmd.options[:build_compact] = true + use_ui @ui do - @cmd.handle_options %w[--no-modern] + @cmd.execute + end + + names = File.join @gemhome, "names" + assert File.exist?(names), names + + versions = File.join @gemhome, "versions" + assert File.exist?(versions), versions + + specs = File.join @gemhome, "specs.4.8.gz" + refute File.exist?(specs), specs + end + + def test_execute_no_modern_no_compact + @cmd.options[:build_modern] = false + @cmd.options[:build_compact] = false + + assert_raise Gem::MockGemUi::TermError do + use_ui @ui do + @cmd.execute + end end - assert_equal \ - "WARNING: The \"--no-modern\" option has been deprecated and will be removed in Rubygems 4.0. The `--no-modern` option is currently ignored. Modern indexes (specs, latest_specs, and prerelease_specs) are always generated.\n", - @ui.error + assert_match(/At least one of --modern or --compact must be enabled/, @ui.error) end end diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb index c86c83e..5975fa4 100644 --- a/test/rubygems/test_gem_indexer.rb +++ b/test/rubygems/test_gem_indexer.rb @@ -504,4 +504,127 @@ def file_md5(file) def file_sha256(file) Digest::SHA256.base64digest(Gem.read_binary(file)) end + + def test_build_indices_compact_only + with_indexer(@indexerdir, build_compact: true, build_modern: false) do |indexer| + indexer.make_temp_directories + + use_ui @ui do + indexer.build_indices + end + + assert File.exist?(File.join(indexer.directory, "names")), "names file should exist" + assert File.exist?(File.join(indexer.directory, "versions")), "versions file should exist" + assert_directory_exists File.join(indexer.directory, "info") + + refute File.exist?(File.join(indexer.directory, "specs.#{@marshal_version}")), + "specs index should not exist" + refute File.exist?(File.join(indexer.directory, "latest_specs.#{@marshal_version}")), + "latest_specs index should not exist" + refute File.exist?(File.join(indexer.directory, "prerelease_specs.#{@marshal_version}")), + "prerelease_specs index should not exist" + refute File.directory?(File.join(indexer.directory, "quick")), + "quick dir should not exist" + end + end + + def test_generate_index_compact_only + with_indexer(@indexerdir, build_compact: true, build_modern: false) do |indexer| + use_ui @ui do + indexer.generate_index + end + + assert_indexed @indexerdir, "names" + assert_indexed @indexerdir, "versions" + assert_directory_exists File.join(@indexerdir, "info") + + refute_indexed @indexerdir, "specs.#{@marshal_version}" + refute_indexed @indexerdir, "specs.#{@marshal_version}.gz" + refute_indexed @indexerdir, "latest_specs.#{@marshal_version}" + refute_indexed @indexerdir, "latest_specs.#{@marshal_version}.gz" + refute_indexed @indexerdir, "prerelease_specs.#{@marshal_version}" + refute_indexed @indexerdir, "prerelease_specs.#{@marshal_version}.gz" + + quickdir = File.join @indexerdir, "quick" + refute File.directory?(quickdir), "quick directory should not exist" + + refute_directory_exists indexer.directory + end + end + + def test_generate_index_compact_only_ui + with_indexer(@indexerdir, build_compact: true, build_modern: false) do |indexer| + use_ui @ui do + indexer.generate_index + end + + refute_match(/Generating Marshal quick index/, @ui.output) + refute_match(/Generating specs index/, @ui.output) + refute_match(/Generating latest specs index/, @ui.output) + refute_match(/Generating prerelease specs index/, @ui.output) + refute_match(/Compressing indices/, @ui.output) + + assert_match(/Generating compact index/, @ui.output) + end + end + + def test_update_index_compact_only + with_indexer(@indexerdir, build_compact: true, build_modern: false) do |indexer| + use_ui @ui do + indexer.generate_index + end + end + + assert_indexed @indexerdir, "names" + assert_indexed @indexerdir, "versions" + infodir = File.join @indexerdir, "info" + assert_directory_exists infodir + + versions_file = File.read File.join @indexerdir, "versions" + info_d_file = File.read File.join @indexerdir, "info", "d" + + @d2_1 = util_spec "d", "2.1" + util_build_gem @d2_1 + + @e1 = util_spec "e", "1" + util_build_gem @e1 + + gems = File.join @indexerdir, "gems" + FileUtils.mv @d2_1.cache_file, gems + FileUtils.mv @e1.cache_file, gems + + with_indexer(@indexerdir, build_compact: true, build_modern: false) do |indexer| + with_system_gems do + use_ui @ui do + indexer.update_index + end + + assert_indexed infodir, "e" + assert_indexed infodir, "d" + + assert_equal <<~INFO_FILE, File.read(File.join(infodir, "e")) + --- + 1 |checksum:#{file_sha256(File.join(gems, "e-1.gem"))} + INFO_FILE + + assert_equal <<~INFO_FILE, File.read(File.join(infodir, "d")) + #{info_d_file.chomp} + 2.1 |checksum:#{file_sha256(File.join(gems, "d-2.1.gem"))} + INFO_FILE + + assert_equal <<~VERSIONS_FILE, File.read(File.join(@indexerdir, "versions")) + #{versions_file.chomp} + d 2.1 #{file_md5(File.join(@indexerdir, "info", "d"))} + e 1 #{file_md5(File.join(@indexerdir, "info", "e"))} + VERSIONS_FILE + + assert_versions_file_info_checksums(@indexerdir) + + refute_indexed @indexerdir, "specs.#{@marshal_version}" + refute_indexed @indexerdir, "specs.#{@marshal_version}.gz" + refute File.directory?(File.join(@indexerdir, "quick")), + "quick directory should not exist" + end + end + end end