Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 5 additions & 7 deletions lib/rubygems/commands/generate_index_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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])
Expand Down
56 changes: 36 additions & 20 deletions lib/rubygems/indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

##
Expand All @@ -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|
Expand All @@ -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
Expand All @@ -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?
Expand Down
43 changes: 33 additions & 10 deletions test/rubygems/test_gem_commands_generate_index_command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
123 changes: 123 additions & 0 deletions test/rubygems/test_gem_indexer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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