summaryrefslogtreecommitdiff
path: root/lib/rubygems/commands/generate_index_command.rb
blob: 945d32383cfeddcf8f7fb9ee11b68c98c678e8aa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require 'rubygems/command'
require 'rubygems/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_legacy => true, :build_modern => true

    add_option '-d', '--directory=DIRNAME',
               'repository base dir containing gems subdir' do |dir, options|
      options[:directory] = File.expand_path dir
    end

    add_option '--[no-]legacy',
               'Generate indexes for RubyGems older than',
               '1.2.0' do |value, options|
      unless options[:build_modern] or value then
        raise OptionParser::InvalidOption, 'no indicies will be built'
      end

      options[:build_legacy] = value
    end

    add_option '--[no-]modern',
               'Generate indexes for RubyGems newer',
               'than 1.2.0' do |value, options|
      unless options[:build_legacy] or value then
        raise OptionParser::InvalidOption, 'no indicies will be built'
      end

      options[:build_modern] = value
    end

    add_option '--update',
               'Update modern indexes with gems added',
               'since the last update' do |value, options|
      options[:update] = value
    end

    add_option :RSS, '--rss-gems-host=GEM_HOST',
               'Host name where gems are served from,',
               'used for GUID and enclosure values' do |value, options|
      options[:rss_gems_host] = value
    end

    add_option :RSS, '--rss-host=HOST',
               'Host name for more gems information,',
               'used for RSS feed link' do |value, options|
      options[:rss_host] = value
    end

    add_option :RSS, '--rss-title=TITLE',
               'Set title for RSS feed' do |value, options|
      options[:rss_title] = value
    end
  end

  def defaults_str # :nodoc:
    "--directory . --legacy --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

  # these files support legacy RubyGems
  quick/index
  quick/index.rz                               # quick index manifest
  quick/<gemname>.gemspec.rz                   # legacy YAML quick index
                                               # file
  Marshal.<version>
  Marshal.<version>.Z                          # Marshal full index
  yaml
  yaml.Z                                       # legacy YAML full index

The .Z and .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.
The yaml indexes exist for legacy RubyGems clients and fallback in case of
Marshal version changes.

If --rss-host and --rss-gem-host are given an RSS feed will be generated at
index.rss containing gems released in the last two days.
    EOF
  end

  def execute
    if options[:update] and
       (options[:rss_host] or options[:rss_gems_host]) then
      alert_error '--update not compatible with RSS generation'
      terminate_interaction 1
    end

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

      if options[:update] then
        indexer.update_index
      else
        indexer.generate_index
      end
    end
  end

end