Skip to content

Commit

Permalink
[rubygems/rubygems] Extract generate_index command to rubygems-genera…
Browse files Browse the repository at this point in the history
…te_index gem

So generate_index can be implemented with dependencies, such as the compact index

Took this approach from feedback in rubygems/rubygems#6853

Running `gem generate_index` by default will use an installed rubygems-generate_index, or install and then use the command from the gem

Apply suggestions from code review

rubygems/rubygems@fc1cb9bc9e

Co-authored-by: Hiroshi SHIBATA <hsbt@ruby-lang.org>
  • Loading branch information
2 people authored and matzbot committed Dec 8, 2023
1 parent 0166d56 commit 4817166
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 979 deletions.
1 change: 1 addition & 0 deletions lib/rubygems/command_manager.rb
Expand Up @@ -249,6 +249,7 @@ def load_and_instantiate(command_name)
def invoke_command(args, build_args)
cmd_name = args.shift.downcase
cmd = find_command cmd_name
terminate_interaction 1 unless cmd
cmd.deprecation_warning if cmd.deprecated?
cmd.invoke_with_build_args args, build_args
end
Expand Down
113 changes: 39 additions & 74 deletions lib/rubygems/commands/generate_index_command.rb
@@ -1,86 +1,51 @@
# frozen_string_literal: true

require_relative "../command"
require_relative "../indexer"

##
# Generates a index files for use as a gem server.
#
# See `gem help generate_index`

class Gem::Commands::GenerateIndexCommand < Gem::Command
def initialize
super "generate_index",
"Generates the index files for a gem server directory",
directory: ".", build_modern: true
unless defined? Gem::Commands::GenerateIndexCommand
class Gem::Commands::GenerateIndexCommand < Gem::Command
module RubygemsTrampoline
def description # :nodoc:
<<~EOF
The generate_index command has been moved to the rubygems-generate_index gem.
EOF
end

add_option "-d", "--directory=DIRNAME",
"repository base dir containing gems subdir" do |dir, options|
options[:directory] = File.expand_path dir
end
def execute
alert_error "Install the rubygems-generate_index gem for the generate_index command"
end

add_option "--[no-]modern",
"Generate indexes for RubyGems",
"(always true)" do |value, options|
options[:build_modern] = value
def invoke_with_build_args(args, build_args)
name = "rubygems-generate_index"
spec = begin
Gem::Specification.find_by_name(name)
rescue Gem::LoadError
require "rubygems/dependency_installer"
Gem.install(name, Gem::Requirement.default, Gem::DependencyInstaller::DEFAULT_OPTIONS).find {|s| s.name == name }
end

# remove the methods defined in this file so that the methods defined in the gem are used instead,
# and without a method redefinition warning
%w[description execute invoke_with_build_args].each do |method|
RubygemsTrampoline.remove_method(method)
end
self.class.singleton_class.remove_method(:new)

spec.activate
Gem.load_plugin_files spec.matches_for_glob("rubygems_plugin#{Gem.suffix_pattern}")

self.class.new.invoke_with_build_args(args, build_args)
end
end
private_constant :RubygemsTrampoline

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 "--update",
"Update modern indexes with gems added",
"since the last update" do |value, options|
options[:update] = value
# remove_method(:initialize) warns, but removing new does not warn
def self.new
command = allocate
command.send(:initialize, "generate_index", "Generates the index files for a gem server directory (requires rubygems-generate_index)")
command
end
end

def defaults_str # :nodoc:
"--directory . --modern"
end

def description # :nodoc:
<<-EOF
The generate_index command creates a set of indexes for serving gems
statically. The command expects a 'gems' directory under the path given to
the --directory option. The given directory will be the directory you serve
as the gem repository.

For `gem generate_index --directory /path/to/repo`, expose /path/to/repo via
your HTTP server configuration (not /path/to/repo/gems).
When done, it will generate a set of files like this:
gems/*.gem # .gem files you want to
# index
specs.<version>.gz # specs index
latest_specs.<version>.gz # latest specs index
prerelease_specs.<version>.gz # prerelease specs index
quick/Marshal.<version>/<gemname>.gemspec.rz # Marshal quick index file
The .rz extension files are compressed with the inflate algorithm.
The Marshal version number comes from ruby's Marshal::MAJOR_VERSION and
Marshal::MINOR_VERSION constants. It is used to ensure compatibility.
EOF
end

def execute
# This is always true because it's the only way now.
options[:build_modern] = true

if !File.exist?(options[:directory]) ||
!File.directory?(options[:directory])
alert_error "unknown directory name #{options[:directory]}."
terminate_interaction 1
else
indexer = Gem::Indexer.new options.delete(:directory), options

if options[:update]
indexer.update_index
else
indexer.generate_index
end
end
prepend(RubygemsTrampoline)
end
end
2 changes: 1 addition & 1 deletion lib/rubygems/commands/help_command.rb
Expand Up @@ -333,7 +333,7 @@ def show_commands # :nodoc:
@command_manager.command_names.each do |cmd_name|
command = @command_manager[cmd_name]

next if command.deprecated?
next if command&.deprecated?

summary =
if command
Expand Down

0 comments on commit 4817166

Please sign in to comment.