gemirro 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.github/workflows/ruby.yml +29 -0
 - data/.rubocop.yml +6 -3
 - data/Gemfile +9 -0
 - data/Gemfile.lock +126 -0
 - data/MANIFEST +6 -10
 - data/README.md +1 -1
 - data/bin/gemirro +7 -1
 - data/gemirro.gemspec +9 -9
 - data/lib/gemirro/cli/index.rb +12 -3
 - data/lib/gemirro/cli/init.rb +6 -1
 - data/lib/gemirro/cli/server.rb +2 -4
 - data/lib/gemirro/cli/update.rb +6 -0
 - data/lib/gemirro/configuration.rb +1 -1
 - data/lib/gemirro/gems_fetcher.rb +5 -10
 - data/lib/gemirro/http.rb +6 -6
 - data/lib/gemirro/indexer.rb +397 -90
 - data/lib/gemirro/mirror_file.rb +1 -0
 - data/lib/gemirro/server.rb +73 -160
 - data/lib/gemirro/source.rb +2 -2
 - data/lib/gemirro/utils.rb +123 -68
 - data/lib/gemirro/version.rb +1 -1
 - data/lib/gemirro/versions_fetcher.rb +6 -2
 - data/lib/gemirro.rb +1 -1
 - data/spec/gemirro/http_spec.rb +83 -24
 - data/spec/gemirro/indexer_spec.rb +3 -0
 - data/spec/gemirro/server_spec.rb +76 -47
 - data/template/config.rb +6 -0
 - data/template/public/dist/css/gemirro.css +25 -1
 - data/template/public/latest_specs.4.8 +0 -0
 - data/template/public/prerelease_specs.4.8 +0 -0
 - data/template/public/specs.4.8 +0 -0
 - data/views/gem.erb +46 -37
 - data/views/index.erb +41 -33
 - data/views/layout.erb +5 -25
 - data/views/not_found.erb +4 -4
 - metadata +72 -89
 - data/lib/gemirro/cache.rb +0 -115
 - data/spec/gemirro/cache_spec.rb +0 -32
 - data/template/public/dist/css/bootstrap.min.css +0 -7
 - data/template/public/dist/fonts/glyphicons-halflings-regular.eot +0 -0
 - data/template/public/dist/fonts/glyphicons-halflings-regular.svg +0 -288
 - data/template/public/dist/fonts/glyphicons-halflings-regular.ttf +0 -0
 - data/template/public/dist/fonts/glyphicons-halflings-regular.woff +0 -0
 - data/template/public/dist/fonts/glyphicons-halflings-regular.woff2 +0 -0
 - data/template/public/dist/js/bootstrap.min.js +0 -7
 
    
        data/lib/gemirro/indexer.rb
    CHANGED
    
    | 
         @@ -19,12 +19,14 @@ module Gemirro 
     | 
|
| 
       19 
19 
     | 
    
         
             
              #  @return [Array]
         
     | 
| 
       20 
20 
     | 
    
         
             
              #
         
     | 
| 
       21 
21 
     | 
    
         
             
              class Indexer < ::Gem::Indexer
         
     | 
| 
       22 
     | 
    
         
            -
                attr_accessor( 
     | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
       24 
     | 
    
         
            -
             
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
                attr_accessor(
         
     | 
| 
      
 23 
     | 
    
         
            +
                  :files,
         
     | 
| 
      
 24 
     | 
    
         
            +
                  :quick_marshal_dir,
         
     | 
| 
      
 25 
     | 
    
         
            +
                  :directory,
         
     | 
| 
      
 26 
     | 
    
         
            +
                  :dest_directory,
         
     | 
| 
      
 27 
     | 
    
         
            +
                  :only_origin,
         
     | 
| 
      
 28 
     | 
    
         
            +
                  :updated_gems
         
     | 
| 
      
 29 
     | 
    
         
            +
                )
         
     | 
| 
       28 
30 
     | 
    
         | 
| 
       29 
31 
     | 
    
         
             
                ##
         
     | 
| 
       30 
32 
     | 
    
         
             
                # Create an indexer that will index the gems in +directory+.
         
     | 
| 
         @@ -37,34 +39,38 @@ module Gemirro 
     | 
|
| 
       37 
39 
     | 
    
         
             
                  require 'fileutils'
         
     | 
| 
       38 
40 
     | 
    
         
             
                  require 'tmpdir'
         
     | 
| 
       39 
41 
     | 
    
         
             
                  require 'zlib'
         
     | 
| 
      
 42 
     | 
    
         
            +
                  require 'builder/xchar'
         
     | 
| 
      
 43 
     | 
    
         
            +
                  require 'compact_index'
         
     | 
| 
       40 
44 
     | 
    
         | 
| 
       41 
     | 
    
         
            -
                   
     | 
| 
       42 
     | 
    
         
            -
                    raise 'Gem::Indexer requires that the XML Builder ' \
         
     | 
| 
       43 
     | 
    
         
            -
                          'library be installed:' \
         
     | 
| 
       44 
     | 
    
         
            -
                          "\n\tgem install builder"
         
     | 
| 
       45 
     | 
    
         
            -
                  end
         
     | 
| 
       46 
     | 
    
         
            -
             
     | 
| 
       47 
     | 
    
         
            -
                  options = { build_modern: true }.merge options
         
     | 
| 
      
 45 
     | 
    
         
            +
                  options.merge!({ build_modern: true, build_compact: true })
         
     | 
| 
       48 
46 
     | 
    
         | 
| 
       49 
47 
     | 
    
         
             
                  @build_modern = options[:build_modern]
         
     | 
| 
      
 48 
     | 
    
         
            +
                  @build_compact = options[:build_compact]
         
     | 
| 
       50 
49 
     | 
    
         | 
| 
       51 
50 
     | 
    
         
             
                  @dest_directory = directory
         
     | 
| 
       52 
     | 
    
         
            -
                  @directory = 
     | 
| 
       53 
     | 
    
         
            -
             
     | 
| 
      
 51 
     | 
    
         
            +
                  @directory =
         
     | 
| 
      
 52 
     | 
    
         
            +
                    File.join(Dir.tmpdir, "gem_generate_index_#{rand(1_000_000_000)}")
         
     | 
| 
       54 
53 
     | 
    
         | 
| 
       55 
54 
     | 
    
         
             
                  marshal_name = "Marshal.#{::Gem.marshal_version}"
         
     | 
| 
       56 
55 
     | 
    
         | 
| 
       57 
     | 
    
         
            -
                  @master_index = 
     | 
| 
       58 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
                  @master_index =
         
     | 
| 
      
 57 
     | 
    
         
            +
                    File.join(@directory, 'yaml')
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @marshal_index =
         
     | 
| 
      
 59 
     | 
    
         
            +
                    File.join(@directory, marshal_name)
         
     | 
| 
       59 
60 
     | 
    
         | 
| 
       60 
     | 
    
         
            -
                  @quick_dir = File.join 
     | 
| 
       61 
     | 
    
         
            -
                  @quick_marshal_dir = 
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 61 
     | 
    
         
            +
                  @quick_dir = File.join(@directory, 'quick')
         
     | 
| 
      
 62 
     | 
    
         
            +
                  @quick_marshal_dir =
         
     | 
| 
      
 63 
     | 
    
         
            +
                    File.join(@quick_dir, marshal_name)
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @quick_marshal_dir_base =
         
     | 
| 
      
 65 
     | 
    
         
            +
                    File.join(@dest_directory, 'quick', marshal_name) # FIX: UGH
         
     | 
| 
       63 
66 
     | 
    
         | 
| 
       64 
     | 
    
         
            -
                  @quick_index = 
     | 
| 
       65 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
                  @quick_index =
         
     | 
| 
      
 68 
     | 
    
         
            +
                    File.join(@quick_dir, 'index')
         
     | 
| 
      
 69 
     | 
    
         
            +
                  @latest_index =
         
     | 
| 
      
 70 
     | 
    
         
            +
                    File.join(@quick_dir, 'latest_index')
         
     | 
| 
       66 
71 
     | 
    
         | 
| 
       67 
     | 
    
         
            -
                  @specs_index = 
     | 
| 
      
 72 
     | 
    
         
            +
                  @specs_index =
         
     | 
| 
      
 73 
     | 
    
         
            +
                    File.join(@directory, "specs.#{::Gem.marshal_version}")
         
     | 
| 
       68 
74 
     | 
    
         
             
                  @latest_specs_index =
         
     | 
| 
       69 
75 
     | 
    
         
             
                    File.join(@directory, "latest_specs.#{::Gem.marshal_version}")
         
     | 
| 
       70 
76 
     | 
    
         
             
                  @prerelease_specs_index =
         
     | 
| 
         @@ -75,6 +81,10 @@ module Gemirro 
     | 
|
| 
       75 
81 
     | 
    
         
             
                    File.join(@dest_directory, "latest_specs.#{::Gem.marshal_version}")
         
     | 
| 
       76 
82 
     | 
    
         
             
                  @dest_prerelease_specs_index =
         
     | 
| 
       77 
83 
     | 
    
         
             
                    File.join(@dest_directory, "prerelease_specs.#{::Gem.marshal_version}")
         
     | 
| 
      
 84 
     | 
    
         
            +
                  @infos_dir =
         
     | 
| 
      
 85 
     | 
    
         
            +
                    File.join(@dest_directory, 'info')
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @api_v1_dependencies_dir =
         
     | 
| 
      
 87 
     | 
    
         
            +
                    File.join(@dest_directory, 'api', 'v1', 'dependencies')
         
     | 
| 
       78 
88 
     | 
    
         | 
| 
       79 
89 
     | 
    
         
             
                  @files = []
         
     | 
| 
       80 
90 
     | 
    
         
             
                end
         
     | 
| 
         @@ -100,28 +110,24 @@ module Gemirro 
     | 
|
| 
       100 
110 
     | 
    
         | 
| 
       101 
111 
     | 
    
         
             
                  if files.include?(@quick_marshal_dir) && !files.include?(@quick_dir)
         
     | 
| 
       102 
112 
     | 
    
         
             
                    files.delete @quick_marshal_dir
         
     | 
| 
       103 
     | 
    
         
            -
                     
     | 
| 
       104 
     | 
    
         
            -
                    FileUtils. 
     | 
| 
       105 
     | 
    
         
            -
                    FileUtils. 
     | 
| 
       106 
     | 
    
         
            -
                    FileUtils.mv(@quick_marshal_dir, dst_name,
         
     | 
| 
       107 
     | 
    
         
            -
                                 verbose: verbose, force: true)
         
     | 
| 
      
 113 
     | 
    
         
            +
                    FileUtils.mkdir_p(File.dirname(@quick_marshal_dir_base), verbose: verbose)
         
     | 
| 
      
 114 
     | 
    
         
            +
                    FileUtils.rm_rf(@quick_marshal_dir_base, verbose: verbose)
         
     | 
| 
      
 115 
     | 
    
         
            +
                    FileUtils.mv(@quick_marshal_dir, @quick_marshal_dir_base, verbose: verbose, force: true)
         
     | 
| 
       108 
116 
     | 
    
         
             
                  end
         
     | 
| 
       109 
117 
     | 
    
         | 
| 
       110 
118 
     | 
    
         
             
                  files.each do |path|
         
     | 
| 
       111 
119 
     | 
    
         
             
                    file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
         
     | 
| 
       112 
     | 
    
         
            -
                    src_name = File.join(@directory, file)
         
     | 
| 
       113 
     | 
    
         
            -
                    dst_name = File.join(@dest_directory, file)
         
     | 
| 
       114 
120 
     | 
    
         | 
| 
       115 
121 
     | 
    
         
             
                    if ["#{@specs_index}.gz",
         
     | 
| 
       116 
122 
     | 
    
         
             
                        "#{@latest_specs_index}.gz",
         
     | 
| 
       117 
123 
     | 
    
         
             
                        "#{@prerelease_specs_index}.gz"].include?(path)
         
     | 
| 
       118 
     | 
    
         
            -
                      res = build_zlib_file(file,  
     | 
| 
      
 124 
     | 
    
         
            +
                      res = build_zlib_file(file, File.join(@directory, file), File.join(@dest_directory, file), true)
         
     | 
| 
       119 
125 
     | 
    
         
             
                      next unless res
         
     | 
| 
       120 
126 
     | 
    
         
             
                    else
         
     | 
| 
       121 
127 
     | 
    
         
             
                      source_content = download_from_source(file)
         
     | 
| 
       122 
128 
     | 
    
         
             
                      next if source_content.nil?
         
     | 
| 
       123 
129 
     | 
    
         | 
| 
       124 
     | 
    
         
            -
                      MirrorFile.new( 
     | 
| 
      
 130 
     | 
    
         
            +
                      MirrorFile.new(File.join(@dest_directory, file)).write(source_content)
         
     | 
| 
       125 
131 
     | 
    
         
             
                    end
         
     | 
| 
       126 
132 
     | 
    
         | 
| 
       127 
133 
     | 
    
         
             
                    FileUtils.rm_rf(path)
         
     | 
| 
         @@ -129,7 +135,7 @@ module Gemirro 
     | 
|
| 
       129 
135 
     | 
    
         
             
                end
         
     | 
| 
       130 
136 
     | 
    
         | 
| 
       131 
137 
     | 
    
         
             
                ##
         
     | 
| 
       132 
     | 
    
         
            -
                # Download file from source
         
     | 
| 
      
 138 
     | 
    
         
            +
                # Download file from source (example: rubygems.org)
         
     | 
| 
       133 
139 
     | 
    
         
             
                #
         
     | 
| 
       134 
140 
     | 
    
         
             
                # @param [String] file File path
         
     | 
| 
       135 
141 
     | 
    
         
             
                # @return [String]
         
     | 
| 
         @@ -164,14 +170,255 @@ module Gemirro 
     | 
|
| 
       164 
170 
     | 
    
         
             
                  ::Gem::Specification.all = specs
         
     | 
| 
       165 
171 
     | 
    
         | 
| 
       166 
172 
     | 
    
         
             
                  if ::Gem::VERSION >= '2.5.0'
         
     | 
| 
       167 
     | 
    
         
            -
                    build_marshal_gemspecs 
     | 
| 
       168 
     | 
    
         
            -
                    build_modern_indices 
     | 
| 
      
 173 
     | 
    
         
            +
                    build_marshal_gemspecs(specs)
         
     | 
| 
      
 174 
     | 
    
         
            +
                    build_modern_indices(specs) if @build_modern
         
     | 
| 
       169 
175 
     | 
    
         
             
                    compress_indices
         
     | 
| 
       170 
176 
     | 
    
         
             
                  else
         
     | 
| 
       171 
177 
     | 
    
         
             
                    build_marshal_gemspecs
         
     | 
| 
       172 
178 
     | 
    
         
             
                    build_modern_indicies if @build_modern
         
     | 
| 
       173 
179 
     | 
    
         
             
                    compress_indicies
         
     | 
| 
       174 
180 
     | 
    
         
             
                  end
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                  build_api_v1_dependencies(specs)
         
     | 
| 
      
 183 
     | 
    
         
            +
             
     | 
| 
      
 184 
     | 
    
         
            +
                  return unless @build_compact
         
     | 
| 
      
 185 
     | 
    
         
            +
             
     | 
| 
      
 186 
     | 
    
         
            +
                  build_compact_index_names
         
     | 
| 
      
 187 
     | 
    
         
            +
                  build_compact_index_infos(specs)
         
     | 
| 
      
 188 
     | 
    
         
            +
                  build_compact_index_versions(specs)
         
     | 
| 
      
 189 
     | 
    
         
            +
                end
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                ##
         
     | 
| 
      
 192 
     | 
    
         
            +
                # Cache Modern Index endpoints /api/v1/dependencies?gems= and /api/v1/dependencies.json?gems=
         
     | 
| 
      
 193 
     | 
    
         
            +
                # This single request may include many fragments. server.rb determines which are required per request.
         
     | 
| 
      
 194 
     | 
    
         
            +
                #
         
     | 
| 
      
 195 
     | 
    
         
            +
                # @return nil
         
     | 
| 
      
 196 
     | 
    
         
            +
                #
         
     | 
| 
      
 197 
     | 
    
         
            +
                def build_api_v1_dependencies(specs, partial = false)
         
     | 
| 
      
 198 
     | 
    
         
            +
                  FileUtils.mkdir_p(@api_v1_dependencies_dir)
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                  if partial
         
     | 
| 
      
 201 
     | 
    
         
            +
                    specs.collect(&:name).uniq do |name|
         
     | 
| 
      
 202 
     | 
    
         
            +
                      FileUtils.rm_rf(Dir.glob(File.join(@api_v1_dependencies_dir, "#{name}.*.*.list")))
         
     | 
| 
      
 203 
     | 
    
         
            +
                    end
         
     | 
| 
      
 204 
     | 
    
         
            +
                  else
         
     | 
| 
      
 205 
     | 
    
         
            +
                    FileUtils.rm_rf(Dir.glob(File.join(@api_v1_dependencies_dir, '*.list')))
         
     | 
| 
      
 206 
     | 
    
         
            +
                  end
         
     | 
| 
      
 207 
     | 
    
         
            +
             
     | 
| 
      
 208 
     | 
    
         
            +
                  grouped_specs = specs.sort_by(&:name).group_by(&:name)
         
     | 
| 
      
 209 
     | 
    
         
            +
                  grouped_specs.each_with_index do |(name, gem_versions), index|
         
     | 
| 
      
 210 
     | 
    
         
            +
                    Utils.logger.info("[#{index + 1}/#{grouped_specs.size}]: Caching /api/v1/dependencies/#{name}")
         
     | 
| 
      
 211 
     | 
    
         
            +
             
     | 
| 
      
 212 
     | 
    
         
            +
                    gem_versions =
         
     | 
| 
      
 213 
     | 
    
         
            +
                      gem_versions.sort do |a, b|
         
     | 
| 
      
 214 
     | 
    
         
            +
                        a.version <=> b.version
         
     | 
| 
      
 215 
     | 
    
         
            +
                      end
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                    cg = []
         
     | 
| 
      
 218 
     | 
    
         
            +
                    Parallel.each_with_index(
         
     | 
| 
      
 219 
     | 
    
         
            +
                      gem_versions,
         
     | 
| 
      
 220 
     | 
    
         
            +
                      in_threads: Utils.configuration.update_thread_count
         
     | 
| 
      
 221 
     | 
    
         
            +
                    ) do |spec, index2|
         
     | 
| 
      
 222 
     | 
    
         
            +
                      next if spec.nil?
         
     | 
| 
      
 223 
     | 
    
         
            +
             
     | 
| 
      
 224 
     | 
    
         
            +
                      dependencies = spec.dependencies.select do |d|
         
     | 
| 
      
 225 
     | 
    
         
            +
                        d.type == :runtime
         
     | 
| 
      
 226 
     | 
    
         
            +
                      end
         
     | 
| 
      
 227 
     | 
    
         
            +
             
     | 
| 
      
 228 
     | 
    
         
            +
                      dependencies = dependencies.collect do |d|
         
     | 
| 
      
 229 
     | 
    
         
            +
                        [d.name.is_a?(Array) ? d.name.first : d.name, d.requirement.to_s]
         
     | 
| 
      
 230 
     | 
    
         
            +
                      end
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                      cg[index2] =
         
     | 
| 
      
 233 
     | 
    
         
            +
                        {
         
     | 
| 
      
 234 
     | 
    
         
            +
                          name: spec.name,
         
     | 
| 
      
 235 
     | 
    
         
            +
                          number: spec.version.to_s,
         
     | 
| 
      
 236 
     | 
    
         
            +
                          platform: spec.platform,
         
     | 
| 
      
 237 
     | 
    
         
            +
                          dependencies: dependencies
         
     | 
| 
      
 238 
     | 
    
         
            +
                        }
         
     | 
| 
      
 239 
     | 
    
         
            +
                    end
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
                    Tempfile.create("api_v1_dependencies_#{name}.list") do |f|
         
     | 
| 
      
 242 
     | 
    
         
            +
                      f.write Marshal.dump(cg)
         
     | 
| 
      
 243 
     | 
    
         
            +
                      f.rewind
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                      FileUtils.cp(
         
     | 
| 
      
 246 
     | 
    
         
            +
                        f.path,
         
     | 
| 
      
 247 
     | 
    
         
            +
                        File.join(
         
     | 
| 
      
 248 
     | 
    
         
            +
                          @api_v1_dependencies_dir,
         
     | 
| 
      
 249 
     | 
    
         
            +
                          "#{name}.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
         
     | 
| 
      
 250 
     | 
    
         
            +
                        )
         
     | 
| 
      
 251 
     | 
    
         
            +
                      )
         
     | 
| 
      
 252 
     | 
    
         
            +
                    end
         
     | 
| 
      
 253 
     | 
    
         
            +
                  end
         
     | 
| 
      
 254 
     | 
    
         
            +
                end
         
     | 
| 
      
 255 
     | 
    
         
            +
             
     | 
| 
      
 256 
     | 
    
         
            +
                ##
         
     | 
| 
      
 257 
     | 
    
         
            +
                # Cache compact_index endpoint /names
         
     | 
| 
      
 258 
     | 
    
         
            +
                # Report all gems with versions available. Does not require opening spec files.
         
     | 
| 
      
 259 
     | 
    
         
            +
                #
         
     | 
| 
      
 260 
     | 
    
         
            +
                # @return nil
         
     | 
| 
      
 261 
     | 
    
         
            +
                #
         
     | 
| 
      
 262 
     | 
    
         
            +
                def build_compact_index_names
         
     | 
| 
      
 263 
     | 
    
         
            +
                  Utils.logger.info('[1/1]: Caching /names')
         
     | 
| 
      
 264 
     | 
    
         
            +
                  FileUtils.rm_rf(Dir.glob(File.join(@dest_directory, 'names*.list')))
         
     | 
| 
      
 265 
     | 
    
         
            +
             
     | 
| 
      
 266 
     | 
    
         
            +
                  gem_name_list = Dir.glob('*.gem', base: File.join(@dest_directory, 'gems')).collect do |x|
         
     | 
| 
      
 267 
     | 
    
         
            +
                    x.sub(/-\d+(\.\d+)*(\.[a-zA-Z\d]+)*([-_a-zA-Z\d]+)?\.gem/, '')
         
     | 
| 
      
 268 
     | 
    
         
            +
                  end.uniq.sort!
         
     | 
| 
      
 269 
     | 
    
         
            +
             
     | 
| 
      
 270 
     | 
    
         
            +
                  Tempfile.create('names.list') do |f|
         
     | 
| 
      
 271 
     | 
    
         
            +
                    f.write CompactIndex.names(gem_name_list).to_s
         
     | 
| 
      
 272 
     | 
    
         
            +
                    f.rewind
         
     | 
| 
      
 273 
     | 
    
         
            +
                    FileUtils.cp(
         
     | 
| 
      
 274 
     | 
    
         
            +
                      f.path,
         
     | 
| 
      
 275 
     | 
    
         
            +
                      File.join(
         
     | 
| 
      
 276 
     | 
    
         
            +
                        @dest_directory,
         
     | 
| 
      
 277 
     | 
    
         
            +
                        "names.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
         
     | 
| 
      
 278 
     | 
    
         
            +
                      ),
         
     | 
| 
      
 279 
     | 
    
         
            +
                      verbose: verbose
         
     | 
| 
      
 280 
     | 
    
         
            +
                    )
         
     | 
| 
      
 281 
     | 
    
         
            +
                  end
         
     | 
| 
      
 282 
     | 
    
         
            +
             
     | 
| 
      
 283 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 284 
     | 
    
         
            +
                end
         
     | 
| 
      
 285 
     | 
    
         
            +
             
     | 
| 
      
 286 
     | 
    
         
            +
                ##
         
     | 
| 
      
 287 
     | 
    
         
            +
                # Cache compact_index endpoint /versions
         
     | 
| 
      
 288 
     | 
    
         
            +
                #
         
     | 
| 
      
 289 
     | 
    
         
            +
                # @param [Array] specs Gems list
         
     | 
| 
      
 290 
     | 
    
         
            +
                # @param [Boolean] partial Is gem list an update or a full index
         
     | 
| 
      
 291 
     | 
    
         
            +
                # @return nil
         
     | 
| 
      
 292 
     | 
    
         
            +
                #
         
     | 
| 
      
 293 
     | 
    
         
            +
                def build_compact_index_versions(specs, partial = false)
         
     | 
| 
      
 294 
     | 
    
         
            +
                  Utils.logger.info('[1/1]: Caching /versions')
         
     | 
| 
      
 295 
     | 
    
         
            +
             
     | 
| 
      
 296 
     | 
    
         
            +
                  cg =
         
     | 
| 
      
 297 
     | 
    
         
            +
                    specs
         
     | 
| 
      
 298 
     | 
    
         
            +
                    .sort_by(&:name)
         
     | 
| 
      
 299 
     | 
    
         
            +
                    .group_by(&:name)
         
     | 
| 
      
 300 
     | 
    
         
            +
                    .collect do |name, gem_versions|
         
     | 
| 
      
 301 
     | 
    
         
            +
                      gem_versions =
         
     | 
| 
      
 302 
     | 
    
         
            +
                        gem_versions.sort do |a, b|
         
     | 
| 
      
 303 
     | 
    
         
            +
                          a.version <=> b.version
         
     | 
| 
      
 304 
     | 
    
         
            +
                        end
         
     | 
| 
      
 305 
     | 
    
         
            +
             
     | 
| 
      
 306 
     | 
    
         
            +
                      info_file = Dir.glob(File.join(@infos_dir, "#{name}.*.*.list")).last
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                      throw "Info file for #{name} not found" unless info_file
         
     | 
| 
      
 309 
     | 
    
         
            +
             
     | 
| 
      
 310 
     | 
    
         
            +
                      info_file_checksum = info_file.split('.', -4)[-3]
         
     | 
| 
      
 311 
     | 
    
         
            +
             
     | 
| 
      
 312 
     | 
    
         
            +
                      CompactIndex::Gem.new(
         
     | 
| 
      
 313 
     | 
    
         
            +
                        name,
         
     | 
| 
      
 314 
     | 
    
         
            +
                        gem_versions.collect do |y|
         
     | 
| 
      
 315 
     | 
    
         
            +
                          CompactIndex::GemVersion.new(
         
     | 
| 
      
 316 
     | 
    
         
            +
                            y.version.to_s,
         
     | 
| 
      
 317 
     | 
    
         
            +
                            y.platform,
         
     | 
| 
      
 318 
     | 
    
         
            +
                            nil,
         
     | 
| 
      
 319 
     | 
    
         
            +
                            info_file_checksum
         
     | 
| 
      
 320 
     | 
    
         
            +
                          )
         
     | 
| 
      
 321 
     | 
    
         
            +
                        end
         
     | 
| 
      
 322 
     | 
    
         
            +
                      )
         
     | 
| 
      
 323 
     | 
    
         
            +
                    end
         
     | 
| 
      
 324 
     | 
    
         
            +
             
     | 
| 
      
 325 
     | 
    
         
            +
                  Tempfile.create('versions.list') do |f|
         
     | 
| 
      
 326 
     | 
    
         
            +
                    previous_versions_file = Dir.glob(File.join(@dest_directory, 'versions*.list')).last
         
     | 
| 
      
 327 
     | 
    
         
            +
             
     | 
| 
      
 328 
     | 
    
         
            +
                    if partial && previous_versions_file
         
     | 
| 
      
 329 
     | 
    
         
            +
                      versions_file = CompactIndex::VersionsFile.new(previous_versions_file)
         
     | 
| 
      
 330 
     | 
    
         
            +
                    else
         
     | 
| 
      
 331 
     | 
    
         
            +
                      versions_file = CompactIndex::VersionsFile.new(f.path)
         
     | 
| 
      
 332 
     | 
    
         
            +
                      f.write format('created_at: %s', Time.now.utc.iso8601)
         
     | 
| 
      
 333 
     | 
    
         
            +
                      f.write "\n---\n"
         
     | 
| 
      
 334 
     | 
    
         
            +
                    end
         
     | 
| 
      
 335 
     | 
    
         
            +
             
     | 
| 
      
 336 
     | 
    
         
            +
                    f.write CompactIndex.versions(versions_file, cg)
         
     | 
| 
      
 337 
     | 
    
         
            +
                    f.rewind
         
     | 
| 
      
 338 
     | 
    
         
            +
             
     | 
| 
      
 339 
     | 
    
         
            +
                    FileUtils.rm_rf(Dir.glob(File.join(@dest_directory, 'versions*.list')))
         
     | 
| 
      
 340 
     | 
    
         
            +
             
     | 
| 
      
 341 
     | 
    
         
            +
                    FileUtils.cp(
         
     | 
| 
      
 342 
     | 
    
         
            +
                      f.path,
         
     | 
| 
      
 343 
     | 
    
         
            +
                      File.join(
         
     | 
| 
      
 344 
     | 
    
         
            +
                        @dest_directory,
         
     | 
| 
      
 345 
     | 
    
         
            +
                        "versions.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
         
     | 
| 
      
 346 
     | 
    
         
            +
                      ),
         
     | 
| 
      
 347 
     | 
    
         
            +
                      verbose: verbose
         
     | 
| 
      
 348 
     | 
    
         
            +
                    )
         
     | 
| 
      
 349 
     | 
    
         
            +
                  end
         
     | 
| 
      
 350 
     | 
    
         
            +
             
     | 
| 
      
 351 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 352 
     | 
    
         
            +
                end
         
     | 
| 
      
 353 
     | 
    
         
            +
             
     | 
| 
      
 354 
     | 
    
         
            +
                ##
         
     | 
| 
      
 355 
     | 
    
         
            +
                # Cache compact_index endpoint /info/[gemname]
         
     | 
| 
      
 356 
     | 
    
         
            +
                #
         
     | 
| 
      
 357 
     | 
    
         
            +
                # @param [Array] specs Gems list
         
     | 
| 
      
 358 
     | 
    
         
            +
                # @param [Boolean] partial Is gem list an update or a full index
         
     | 
| 
      
 359 
     | 
    
         
            +
                # @return nil
         
     | 
| 
      
 360 
     | 
    
         
            +
                #
         
     | 
| 
      
 361 
     | 
    
         
            +
                def build_compact_index_infos(specs, partial = false)
         
     | 
| 
      
 362 
     | 
    
         
            +
                  FileUtils.mkdir_p(@infos_dir)
         
     | 
| 
      
 363 
     | 
    
         
            +
             
     | 
| 
      
 364 
     | 
    
         
            +
                  if partial
         
     | 
| 
      
 365 
     | 
    
         
            +
                    specs.collect(&:name).uniq do |name|
         
     | 
| 
      
 366 
     | 
    
         
            +
                      FileUtils.rm_rf(Dir.glob(File.join(@infos_dir, "#{name}.*.*.list")))
         
     | 
| 
      
 367 
     | 
    
         
            +
                    end
         
     | 
| 
      
 368 
     | 
    
         
            +
                  else
         
     | 
| 
      
 369 
     | 
    
         
            +
                    FileUtils.rm_rf(Dir.glob(File.join(@infos_dir, '*.list')))
         
     | 
| 
      
 370 
     | 
    
         
            +
                  end
         
     | 
| 
      
 371 
     | 
    
         
            +
             
     | 
| 
      
 372 
     | 
    
         
            +
                  grouped_specs = specs.sort_by(&:name).group_by(&:name)
         
     | 
| 
      
 373 
     | 
    
         
            +
                  grouped_specs.each_with_index do |(name, gem_versions), index|
         
     | 
| 
      
 374 
     | 
    
         
            +
                    Utils.logger.info("[#{index + 1}/#{grouped_specs.size}]: Caching /info/#{name}")
         
     | 
| 
      
 375 
     | 
    
         
            +
             
     | 
| 
      
 376 
     | 
    
         
            +
                    gem_versions =
         
     | 
| 
      
 377 
     | 
    
         
            +
                      gem_versions.sort do |a, b|
         
     | 
| 
      
 378 
     | 
    
         
            +
                        a.version <=> b.version
         
     | 
| 
      
 379 
     | 
    
         
            +
                      end
         
     | 
| 
      
 380 
     | 
    
         
            +
             
     | 
| 
      
 381 
     | 
    
         
            +
                    versions =
         
     | 
| 
      
 382 
     | 
    
         
            +
                      Parallel.map(gem_versions, in_threads: Utils.configuration.update_thread_count) do |spec|
         
     | 
| 
      
 383 
     | 
    
         
            +
                        deps =
         
     | 
| 
      
 384 
     | 
    
         
            +
                          spec
         
     | 
| 
      
 385 
     | 
    
         
            +
                          .dependencies
         
     | 
| 
      
 386 
     | 
    
         
            +
                          .select { |d| d.type == :runtime }
         
     | 
| 
      
 387 
     | 
    
         
            +
                          .sort_by(&:name)
         
     | 
| 
      
 388 
     | 
    
         
            +
                          .collect do |dependency|
         
     | 
| 
      
 389 
     | 
    
         
            +
                            CompactIndex::Dependency.new(
         
     | 
| 
      
 390 
     | 
    
         
            +
                              dependency.name,
         
     | 
| 
      
 391 
     | 
    
         
            +
                              dependency.requirement.to_s
         
     | 
| 
      
 392 
     | 
    
         
            +
                            )
         
     | 
| 
      
 393 
     | 
    
         
            +
                          end
         
     | 
| 
      
 394 
     | 
    
         
            +
             
     | 
| 
      
 395 
     | 
    
         
            +
                        CompactIndex::GemVersion.new(
         
     | 
| 
      
 396 
     | 
    
         
            +
                          spec.version,
         
     | 
| 
      
 397 
     | 
    
         
            +
                          spec.platform,
         
     | 
| 
      
 398 
     | 
    
         
            +
                          Digest::SHA256.file(spec.loaded_from).hexdigest,
         
     | 
| 
      
 399 
     | 
    
         
            +
                          nil,
         
     | 
| 
      
 400 
     | 
    
         
            +
                          deps,
         
     | 
| 
      
 401 
     | 
    
         
            +
                          spec.required_ruby_version.to_s,
         
     | 
| 
      
 402 
     | 
    
         
            +
                          spec.required_rubygems_version.to_s
         
     | 
| 
      
 403 
     | 
    
         
            +
                        )
         
     | 
| 
      
 404 
     | 
    
         
            +
                      end
         
     | 
| 
      
 405 
     | 
    
         
            +
             
     | 
| 
      
 406 
     | 
    
         
            +
                    Tempfile.create("info_#{name}.list") do |f|
         
     | 
| 
      
 407 
     | 
    
         
            +
                      f.write CompactIndex.info(versions).to_s
         
     | 
| 
      
 408 
     | 
    
         
            +
                      f.rewind
         
     | 
| 
      
 409 
     | 
    
         
            +
             
     | 
| 
      
 410 
     | 
    
         
            +
                      FileUtils.cp(
         
     | 
| 
      
 411 
     | 
    
         
            +
                        f.path,
         
     | 
| 
      
 412 
     | 
    
         
            +
                        File.join(
         
     | 
| 
      
 413 
     | 
    
         
            +
                          @infos_dir,
         
     | 
| 
      
 414 
     | 
    
         
            +
                          "#{name}.#{Digest::MD5.file(f.path).hexdigest}.#{Digest::SHA256.file(f.path).hexdigest}.list"
         
     | 
| 
      
 415 
     | 
    
         
            +
                        ),
         
     | 
| 
      
 416 
     | 
    
         
            +
                        verbose: verbose
         
     | 
| 
      
 417 
     | 
    
         
            +
                      )
         
     | 
| 
      
 418 
     | 
    
         
            +
                    end
         
     | 
| 
      
 419 
     | 
    
         
            +
                  end
         
     | 
| 
      
 420 
     | 
    
         
            +
             
     | 
| 
      
 421 
     | 
    
         
            +
                  nil
         
     | 
| 
       175 
422 
     | 
    
         
             
                end
         
     | 
| 
       176 
423 
     | 
    
         | 
| 
       177 
424 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -181,21 +428,23 @@ module Gemirro 
     | 
|
| 
       181 
428 
     | 
    
         
             
                # @return [Array]
         
     | 
| 
       182 
429 
     | 
    
         
             
                #
         
     | 
| 
       183 
430 
     | 
    
         
             
                def map_gems_to_specs(gems)
         
     | 
| 
       184 
     | 
    
         
            -
                   
     | 
| 
      
 431 
     | 
    
         
            +
                  results = []
         
     | 
| 
      
 432 
     | 
    
         
            +
             
     | 
| 
      
 433 
     | 
    
         
            +
                  Parallel.each_with_index(gems, in_threads: Utils.configuration.update_thread_count) do |gemfile, index|
         
     | 
| 
       185 
434 
     | 
    
         
             
                    Utils.logger.info("[#{index + 1}/#{gems.size}]: Processing #{gemfile.split('/')[-1]}")
         
     | 
| 
       186 
     | 
    
         
            -
                    if File. 
     | 
| 
      
 435 
     | 
    
         
            +
                    if File.empty?(gemfile)
         
     | 
| 
       187 
436 
     | 
    
         
             
                      Utils.logger.warn("Skipping zero-length gem: #{gemfile}")
         
     | 
| 
       188 
437 
     | 
    
         
             
                      next
         
     | 
| 
       189 
438 
     | 
    
         
             
                    end
         
     | 
| 
       190 
439 
     | 
    
         | 
| 
       191 
440 
     | 
    
         
             
                    begin
         
     | 
| 
       192 
441 
     | 
    
         
             
                      begin
         
     | 
| 
       193 
     | 
    
         
            -
                        spec = 
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
             
     | 
| 
       196 
     | 
    
         
            -
             
     | 
| 
       197 
     | 
    
         
            -
             
     | 
| 
       198 
     | 
    
         
            -
             
     | 
| 
      
 442 
     | 
    
         
            +
                        spec =
         
     | 
| 
      
 443 
     | 
    
         
            +
                          if ::Gem::Package.respond_to? :open
         
     | 
| 
      
 444 
     | 
    
         
            +
                            ::Gem::Package.open(File.open(gemfile, 'rb'), 'r', &:metadata)
         
     | 
| 
      
 445 
     | 
    
         
            +
                          else
         
     | 
| 
      
 446 
     | 
    
         
            +
                            ::Gem::Package.new(gemfile).spec
         
     | 
| 
      
 447 
     | 
    
         
            +
                          end
         
     | 
| 
       199 
448 
     | 
    
         
             
                      rescue NotImplementedError
         
     | 
| 
       200 
449 
     | 
    
         
             
                        next
         
     | 
| 
       201 
450 
     | 
    
         
             
                      end
         
     | 
| 
         @@ -213,7 +462,7 @@ module Gemirro 
     | 
|
| 
       213 
462 
     | 
    
         
             
                      end
         
     | 
| 
       214 
463 
     | 
    
         | 
| 
       215 
464 
     | 
    
         
             
                      version = spec.version.version
         
     | 
| 
       216 
     | 
    
         
            -
                      unless version =~ /^\d 
     | 
| 
      
 465 
     | 
    
         
            +
                      unless version =~ /^\d+(\.\d+)?(\.\d+)?.*/
         
     | 
| 
       217 
466 
     | 
    
         
             
                        msg = "Skipping gem #{spec.full_name} - invalid version #{version}"
         
     | 
| 
       218 
467 
     | 
    
         
             
                        Utils.logger.warn(msg)
         
     | 
| 
       219 
468 
     | 
    
         
             
                        next
         
     | 
| 
         @@ -223,8 +472,8 @@ module Gemirro 
     | 
|
| 
       223 
472 
     | 
    
         
             
                        spec.abbreviate
         
     | 
| 
       224 
473 
     | 
    
         
             
                        spec.sanitize
         
     | 
| 
       225 
474 
     | 
    
         
             
                      else
         
     | 
| 
       226 
     | 
    
         
            -
                        abbreviate 
     | 
| 
       227 
     | 
    
         
            -
                        sanitize 
     | 
| 
      
 475 
     | 
    
         
            +
                        abbreviate(spec)
         
     | 
| 
      
 476 
     | 
    
         
            +
                        sanitize(spec)
         
     | 
| 
       228 
477 
     | 
    
         
             
                      end
         
     | 
| 
       229 
478 
     | 
    
         | 
| 
       230 
479 
     | 
    
         
             
                      spec
         
     | 
| 
         @@ -238,20 +487,48 @@ module Gemirro 
     | 
|
| 
       238 
487 
     | 
    
         
             
                             "\t#{e.backtrace.join "\n\t"}"].join("\n")
         
     | 
| 
       239 
488 
     | 
    
         
             
                      Utils.logger.debug(msg)
         
     | 
| 
       240 
489 
     | 
    
         
             
                    end
         
     | 
| 
       241 
     | 
    
         
            -
             
     | 
| 
      
 490 
     | 
    
         
            +
             
     | 
| 
      
 491 
     | 
    
         
            +
                    results[index] = spec
         
     | 
| 
      
 492 
     | 
    
         
            +
                  end
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
                  # nils can result from insert by index
         
     | 
| 
      
 495 
     | 
    
         
            +
                  results.compact
         
     | 
| 
       242 
496 
     | 
    
         
             
                end
         
     | 
| 
       243 
497 
     | 
    
         | 
| 
      
 498 
     | 
    
         
            +
                ##
         
     | 
| 
      
 499 
     | 
    
         
            +
                # Handle `index --update`, detecting changed files and file lists.
         
     | 
| 
      
 500 
     | 
    
         
            +
                #
         
     | 
| 
      
 501 
     | 
    
         
            +
                # @return nil
         
     | 
| 
      
 502 
     | 
    
         
            +
                #
         
     | 
| 
       244 
503 
     | 
    
         
             
                def update_index
         
     | 
| 
       245 
504 
     | 
    
         
             
                  make_temp_directories
         
     | 
| 
       246 
505 
     | 
    
         | 
| 
       247 
     | 
    
         
            -
                   
     | 
| 
      
 506 
     | 
    
         
            +
                  present_gemfiles = Dir.glob('*.gem', base: File.join(@dest_directory, 'gems'))
         
     | 
| 
      
 507 
     | 
    
         
            +
                  indexed_gemfiles = Dir.glob('*.gemspec.rz', base: @quick_marshal_dir_base).collect { |x| x.gsub(/spec.rz$/, '') }
         
     | 
| 
      
 508 
     | 
    
         
            +
             
     | 
| 
      
 509 
     | 
    
         
            +
                  @updated_gems = []
         
     | 
| 
      
 510 
     | 
    
         
            +
                  # detect files manually added to public/gems
         
     | 
| 
      
 511 
     | 
    
         
            +
                  @updated_gems += (present_gemfiles - indexed_gemfiles).collect { |x| File.join(@dest_directory, 'gems', x) }
         
     | 
| 
      
 512 
     | 
    
         
            +
                  # detect files manually deleted from public/gems
         
     | 
| 
      
 513 
     | 
    
         
            +
                  @updated_gems += (indexed_gemfiles - present_gemfiles).collect { |x| File.join(@dest_directory, 'gems', x) }
         
     | 
| 
      
 514 
     | 
    
         
            +
             
     | 
| 
      
 515 
     | 
    
         
            +
                  specs_mtime =
         
     | 
| 
      
 516 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 517 
     | 
    
         
            +
                      File.stat(@dest_specs_index).mtime
         
     | 
| 
      
 518 
     | 
    
         
            +
                    rescue StandardError
         
     | 
| 
      
 519 
     | 
    
         
            +
                      Time.at(0)
         
     | 
| 
      
 520 
     | 
    
         
            +
                    end
         
     | 
| 
       248 
521 
     | 
    
         
             
                  newest_mtime = Time.at(0)
         
     | 
| 
       249 
522 
     | 
    
         | 
| 
       250 
     | 
    
         
            -
                   
     | 
| 
       251 
     | 
    
         
            -
             
     | 
| 
       252 
     | 
    
         
            -
                     
     | 
| 
       253 
     | 
    
         
            -
             
     | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
      
 523 
     | 
    
         
            +
                  # files that have been replaced
         
     | 
| 
      
 524 
     | 
    
         
            +
                  @updated_gems +=
         
     | 
| 
      
 525 
     | 
    
         
            +
                    gem_file_list.select do |gem|
         
     | 
| 
      
 526 
     | 
    
         
            +
                      gem_mtime = File.stat(gem).mtime
         
     | 
| 
      
 527 
     | 
    
         
            +
                      newest_mtime = gem_mtime if gem_mtime > newest_mtime
         
     | 
| 
      
 528 
     | 
    
         
            +
                      gem_mtime > specs_mtime
         
     | 
| 
      
 529 
     | 
    
         
            +
                    end
         
     | 
| 
      
 530 
     | 
    
         
            +
             
     | 
| 
      
 531 
     | 
    
         
            +
                  @updated_gems.uniq!
         
     | 
| 
       255 
532 
     | 
    
         | 
| 
       256 
533 
     | 
    
         
             
                  if @updated_gems.empty?
         
     | 
| 
       257 
534 
     | 
    
         
             
                    Utils.logger.info('No new gems')
         
     | 
| 
         @@ -259,24 +536,46 @@ module Gemirro 
     | 
|
| 
       259 
536 
     | 
    
         
             
                  end
         
     | 
| 
       260 
537 
     | 
    
         | 
| 
       261 
538 
     | 
    
         
             
                  specs = map_gems_to_specs(@updated_gems)
         
     | 
| 
      
 539 
     | 
    
         
            +
             
     | 
| 
      
 540 
     | 
    
         
            +
                  # specs only includes latest discovered files.
         
     | 
| 
      
 541 
     | 
    
         
            +
                  # /info/[gemname] and /api/v1/dependencies can not be rebuilt
         
     | 
| 
      
 542 
     | 
    
         
            +
                  # incrementally, so retrive specs for all versions of these gems.
         
     | 
| 
      
 543 
     | 
    
         
            +
                  gem_name_updates = specs.collect(&:name).uniq
         
     | 
| 
      
 544 
     | 
    
         
            +
                  u2 =
         
     | 
| 
      
 545 
     | 
    
         
            +
                    Dir.glob(File.join(File.join(@dest_directory, 'gems'), '*.gem')).select do |possibility|
         
     | 
| 
      
 546 
     | 
    
         
            +
                      gem_name_updates.any? { |updated| File.basename(possibility) =~ /^#{updated}-\d/ }
         
     | 
| 
      
 547 
     | 
    
         
            +
                    end
         
     | 
| 
      
 548 
     | 
    
         
            +
             
     | 
| 
      
 549 
     | 
    
         
            +
                  Utils.logger.info('Reloading for /info/[gemname]')
         
     | 
| 
      
 550 
     | 
    
         
            +
                  version_specs = map_gems_to_specs(u2)
         
     | 
| 
      
 551 
     | 
    
         
            +
             
     | 
| 
       262 
552 
     | 
    
         
             
                  prerelease, released = specs.partition { |s| s.version.prerelease? }
         
     | 
| 
       263 
553 
     | 
    
         | 
| 
       264 
554 
     | 
    
         
             
                  ::Gem::Specification.dirs = []
         
     | 
| 
       265 
555 
     | 
    
         
             
                  ::Gem::Specification.all = *specs
         
     | 
| 
       266 
     | 
    
         
            -
                  files = 
     | 
| 
       267 
     | 
    
         
            -
             
     | 
| 
       268 
     | 
    
         
            -
             
     | 
| 
       269 
     | 
    
         
            -
             
     | 
| 
       270 
     | 
    
         
            -
             
     | 
| 
      
 556 
     | 
    
         
            +
                  files =
         
     | 
| 
      
 557 
     | 
    
         
            +
                    if ::Gem::VERSION >= '2.5.0'
         
     | 
| 
      
 558 
     | 
    
         
            +
                      build_marshal_gemspecs specs
         
     | 
| 
      
 559 
     | 
    
         
            +
                    else
         
     | 
| 
      
 560 
     | 
    
         
            +
                      build_marshal_gemspecs
         
     | 
| 
      
 561 
     | 
    
         
            +
                    end
         
     | 
| 
       271 
562 
     | 
    
         | 
| 
       272 
563 
     | 
    
         
             
                  ::Gem.time('Updated indexes') do
         
     | 
| 
       273 
     | 
    
         
            -
                    update_specs_index( 
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
     | 
    
         
            -
             
     | 
| 
       276 
     | 
    
         
            -
             
     | 
| 
       277 
     | 
    
         
            -
                     
     | 
| 
       278 
     | 
    
         
            -
             
     | 
| 
       279 
     | 
    
         
            -
             
     | 
| 
      
 564 
     | 
    
         
            +
                    update_specs_index(
         
     | 
| 
      
 565 
     | 
    
         
            +
                      released,
         
     | 
| 
      
 566 
     | 
    
         
            +
                      @dest_specs_index,
         
     | 
| 
      
 567 
     | 
    
         
            +
                      @specs_index
         
     | 
| 
      
 568 
     | 
    
         
            +
                    )
         
     | 
| 
      
 569 
     | 
    
         
            +
                    update_specs_index(
         
     | 
| 
      
 570 
     | 
    
         
            +
                      released,
         
     | 
| 
      
 571 
     | 
    
         
            +
                      @dest_latest_specs_index,
         
     | 
| 
      
 572 
     | 
    
         
            +
                      @latest_specs_index
         
     | 
| 
      
 573 
     | 
    
         
            +
                    )
         
     | 
| 
      
 574 
     | 
    
         
            +
                    update_specs_index(
         
     | 
| 
      
 575 
     | 
    
         
            +
                      prerelease,
         
     | 
| 
      
 576 
     | 
    
         
            +
                      @dest_prerelease_specs_index,
         
     | 
| 
      
 577 
     | 
    
         
            +
                      @prerelease_specs_index
         
     | 
| 
      
 578 
     | 
    
         
            +
                    )
         
     | 
| 
       280 
579 
     | 
    
         
             
                  end
         
     | 
| 
       281 
580 
     | 
    
         | 
| 
       282 
581 
     | 
    
         
             
                  if ::Gem::VERSION >= '2.5.0'
         
     | 
| 
         @@ -285,6 +584,14 @@ module Gemirro 
     | 
|
| 
       285 
584 
     | 
    
         
             
                    compress_indicies
         
     | 
| 
       286 
585 
     | 
    
         
             
                  end
         
     | 
| 
       287 
586 
     | 
    
         | 
| 
      
 587 
     | 
    
         
            +
                  build_api_v1_dependencies(version_specs, true)
         
     | 
| 
      
 588 
     | 
    
         
            +
             
     | 
| 
      
 589 
     | 
    
         
            +
                  if @build_compact
         
     | 
| 
      
 590 
     | 
    
         
            +
                    build_compact_index_names
         
     | 
| 
      
 591 
     | 
    
         
            +
                    build_compact_index_infos(version_specs, true)
         
     | 
| 
      
 592 
     | 
    
         
            +
                    build_compact_index_versions(specs, true)
         
     | 
| 
      
 593 
     | 
    
         
            +
                  end
         
     | 
| 
      
 594 
     | 
    
         
            +
             
     | 
| 
       288 
595 
     | 
    
         
             
                  Utils.logger.info("Updating production dir #{@dest_directory}") if verbose
         
     | 
| 
       289 
596 
     | 
    
         
             
                  files << @specs_index
         
     | 
| 
       290 
597 
     | 
    
         
             
                  files << "#{@specs_index}.gz"
         
     | 
| 
         @@ -295,36 +602,36 @@ module Gemirro 
     | 
|
| 
       295 
602 
     | 
    
         | 
| 
       296 
603 
     | 
    
         
             
                  files.each do |path|
         
     | 
| 
       297 
604 
     | 
    
         
             
                    file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
         
     | 
| 
       298 
     | 
    
         
            -
                    src_name = File.join(@directory, file)
         
     | 
| 
       299 
     | 
    
         
            -
                    dst_name = File.join(@dest_directory, file)
         
     | 
| 
       300 
605 
     | 
    
         | 
| 
       301 
     | 
    
         
            -
                    if ["#{@specs_index}.gz",
         
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
                        "#{@prerelease_specs_index}.gz"].include?(path)
         
     | 
| 
       304 
     | 
    
         
            -
                      res = build_zlib_file(file, src_name, dst_name)
         
     | 
| 
      
 606 
     | 
    
         
            +
                    if ["#{@specs_index}.gz", "#{@latest_specs_index}.gz", "#{@prerelease_specs_index}.gz"].include?(path)
         
     | 
| 
      
 607 
     | 
    
         
            +
                      res = build_zlib_file(file, File.join(@directory, file), File.join(@dest_directory, file))
         
     | 
| 
       305 
608 
     | 
    
         
             
                      next unless res
         
     | 
| 
       306 
609 
     | 
    
         
             
                    else
         
     | 
| 
       307 
     | 
    
         
            -
                      FileUtils.mv( 
     | 
| 
       308 
     | 
    
         
            -
             
     | 
| 
       309 
     | 
    
         
            -
             
     | 
| 
       310 
     | 
    
         
            -
             
     | 
| 
      
 610 
     | 
    
         
            +
                      FileUtils.mv(
         
     | 
| 
      
 611 
     | 
    
         
            +
                        File.join(@directory, file),
         
     | 
| 
      
 612 
     | 
    
         
            +
                        File.join(@dest_directory, file),
         
     | 
| 
      
 613 
     | 
    
         
            +
                        verbose: verbose,
         
     | 
| 
      
 614 
     | 
    
         
            +
                        force: true
         
     | 
| 
      
 615 
     | 
    
         
            +
                      )
         
     | 
| 
       311 
616 
     | 
    
         
             
                    end
         
     | 
| 
       312 
617 
     | 
    
         | 
| 
       313 
     | 
    
         
            -
                    File.utime(newest_mtime, newest_mtime,  
     | 
| 
      
 618 
     | 
    
         
            +
                    File.utime(newest_mtime, newest_mtime, File.join(@dest_directory, file))
         
     | 
| 
       314 
619 
     | 
    
         
             
                  end
         
     | 
| 
       315 
620 
     | 
    
         
             
                end
         
     | 
| 
       316 
621 
     | 
    
         | 
| 
       317 
622 
     | 
    
         
             
                def build_zlib_file(file, src_name, dst_name, from_source = false)
         
     | 
| 
       318 
623 
     | 
    
         
             
                  content = Marshal.load(Zlib::GzipReader.open(src_name).read)
         
     | 
| 
       319 
     | 
    
         
            -
                  create_zlib_file("#{dst_name}. 
     | 
| 
      
 624 
     | 
    
         
            +
                  create_zlib_file("#{dst_name}.local", content)
         
     | 
| 
       320 
625 
     | 
    
         | 
| 
       321 
626 
     | 
    
         
             
                  return false if @only_origin
         
     | 
| 
       322 
627 
     | 
    
         | 
| 
       323 
628 
     | 
    
         
             
                  if from_source
         
     | 
| 
       324 
629 
     | 
    
         
             
                    source_content = download_from_source(file)
         
     | 
| 
       325 
     | 
    
         
            -
                    source_content = Marshal.load( 
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
      
 630 
     | 
    
         
            +
                    source_content = Marshal.load(
         
     | 
| 
      
 631 
     | 
    
         
            +
                      Zlib::GzipReader.new(
         
     | 
| 
      
 632 
     | 
    
         
            +
                        StringIO.new(source_content)
         
     | 
| 
      
 633 
     | 
    
         
            +
                      ).read
         
     | 
| 
      
 634 
     | 
    
         
            +
                    )
         
     | 
| 
       328 
635 
     | 
    
         
             
                  else
         
     | 
| 
       329 
636 
     | 
    
         
             
                    source_content = Marshal.load(Zlib::GzipReader.open(dst_name).read)
         
     | 
| 
       330 
637 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -336,17 +643,17 @@ module Gemirro 
     | 
|
| 
       336 
643 
     | 
    
         
             
                end
         
     | 
| 
       337 
644 
     | 
    
         | 
| 
       338 
645 
     | 
    
         
             
                def create_zlib_file(dst_name, content)
         
     | 
| 
       339 
     | 
    
         
            -
                   
     | 
| 
       340 
     | 
    
         
            -
             
     | 
| 
       341 
     | 
    
         
            -
             
     | 
| 
       342 
     | 
    
         
            -
                     
     | 
| 
      
 646 
     | 
    
         
            +
                  Tempfile.create(File.basename(dst_name)) do |f|
         
     | 
| 
      
 647 
     | 
    
         
            +
                    gzf = Zlib::GzipWriter.new(f)
         
     | 
| 
      
 648 
     | 
    
         
            +
                    gzf.write(Marshal.dump(content))
         
     | 
| 
      
 649 
     | 
    
         
            +
                    gzf.close
         
     | 
| 
      
 650 
     | 
    
         
            +
             
     | 
| 
      
 651 
     | 
    
         
            +
                    FileUtils.cp(
         
     | 
| 
      
 652 
     | 
    
         
            +
                      f.path,
         
     | 
| 
      
 653 
     | 
    
         
            +
                      dst_name,
         
     | 
| 
      
 654 
     | 
    
         
            +
                      verbose: verbose
         
     | 
| 
      
 655 
     | 
    
         
            +
                    )
         
     | 
| 
       343 
656 
     | 
    
         
             
                  end
         
     | 
| 
       344 
     | 
    
         
            -
             
     | 
| 
       345 
     | 
    
         
            -
                  FileUtils.mv(temp_file.path,
         
     | 
| 
       346 
     | 
    
         
            -
                               dst_name,
         
     | 
| 
       347 
     | 
    
         
            -
                               verbose: verbose,
         
     | 
| 
       348 
     | 
    
         
            -
                               force: true)
         
     | 
| 
       349 
     | 
    
         
            -
                  Utils.cache.flush_key(File.basename(dst_name))
         
     | 
| 
       350 
657 
     | 
    
         
             
                end
         
     | 
| 
       351 
658 
     | 
    
         | 
| 
       352 
659 
     | 
    
         
             
                def verbose
         
     |