gemirro 0.10.5 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of gemirro might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de7a99ed85512795f32fa3fd05a82216cc056e2d
4
- data.tar.gz: b65ffbd28905ef09f0825f0888d4684ea2534c5d
3
+ metadata.gz: 369070871caf336cca42522e1ecf00a33b8146de
4
+ data.tar.gz: 45b5271ac12aab2d9db654ecf5ac75d61790f173
5
5
  SHA512:
6
- metadata.gz: 65eea62ca9a8ccfa7175371faeacd2909e73c55f665c97479dc0b2d5ba960a1e9e3ea2e0917ac96db96ad939cbec86542cced6c8508e1c0146329e6bd57e3b09
7
- data.tar.gz: f4422435079d1ad2c47bff8217ccbd6e7646386f3717ee66dcccdc653b47e2d25038b9b305bb765fa277a6bea410d3ec99b3e408ee7f04e3377996a21b1f7397
6
+ metadata.gz: 023bb1b397f46bd27afd2d777c2bc0a67f257ee9d32b1031a3bb6f883667d7c44b89ef74d4ce25121ee9a0e7868ff7a71a43985c043288b8a6d756db627d077e
7
+ data.tar.gz: 4aeb7d45c0d41f3ee2b2cbd0d8d47cba52ec659a4357b30e8fac170a48dedce7e755718b007d3997cf91ad8b1eccb4de7d509b436c7e0e18e6f63345edcf1e15
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
- .project
2
- coverage
3
- Gemfile.lock
4
- pkg
5
- .ruby-version
6
- *.gem
1
+ /.project
2
+ /coverage
3
+ /Gemfile.lock
4
+ /pkg
5
+ /.ruby-version
6
+ /*.gem
7
+ /.bundle
data/.rubocop.yml CHANGED
@@ -1,12 +1,16 @@
1
1
  AllCops:
2
2
  Include:
3
3
  - '**/Gemfile'
4
- - lib/**/*
5
- - spec/**/*
4
+ - lib/**/*.rb
5
+ - spec/**/*.rb
6
6
  - gemirro.gemspec
7
7
  Exclude:
8
8
  - files/**/*
9
9
  - templates/**/*
10
+ ModuleLength:
11
+ Exclude:
12
+ - lib/**/*
13
+ - spec/**/*
10
14
  MethodLength:
11
15
  Exclude:
12
16
  - lib/**/*
data/MANIFEST CHANGED
@@ -28,6 +28,8 @@ lib/gemirro/source.rb
28
28
  lib/gemirro/version.rb
29
29
  lib/gemirro/versions_fetcher.rb
30
30
  lib/gemirro/versions_file.rb
31
+ spec/fixtures/gems/gemirro-0.0.1.gem
32
+ spec/fixtures/quick/gemirro-0.0.1.gemspec.rz
31
33
  spec/gemirro/cli_spec.rb
32
34
  spec/gemirro/configuration_spec.rb
33
35
  spec/gemirro/gem_spec.rb
data/README.md CHANGED
@@ -41,6 +41,7 @@ Once all the Gems have been downloaded you'll need to generate an index of all t
41
41
 
42
42
  ```bash
43
43
  $ gemirro index
44
+ $ gemirro index --update # Or only update new files
44
45
  ```
45
46
 
46
47
  Last, launch the server, and all requests will check if gems are detected, and download them if necessary and generate index immediately.
data/gemirro.gemspec CHANGED
@@ -4,13 +4,13 @@ require File.expand_path('../lib/gemirro/version', __FILE__)
4
4
  Gem::Specification.new do |s|
5
5
  s.name = 'gemirro'
6
6
  s.version = Gemirro::VERSION
7
- s.date = '2014-08-19'
7
+ s.date = Date.today.to_s
8
8
  s.authors = ['Pierre Rambaud']
9
9
  s.email = 'pierre.rambaud86@gmail.com'
10
10
  s.license = 'GPL-3.0'
11
- s.summary = 'Gem for easily creating your own RubyGems mirror.'
11
+ s.summary = 'Gem for easily creating your own gems mirror.'
12
12
  s.homepage = 'https://github.com/PierreRambaud/gemirro'
13
- s.description = 'Create your own gem mirror with a simple TCPServer.'
13
+ s.description = 'Create your own gems mirror.'
14
14
  s.executables = ['gemirro']
15
15
 
16
16
  s.files = File.read(File.expand_path('../MANIFEST', __FILE__)).split("\n")
data/lib/gemirro.rb CHANGED
@@ -11,6 +11,7 @@ require 'httpclient'
11
11
  require 'logger'
12
12
  require 'stringio'
13
13
  require 'json'
14
+ require 'tempfile'
14
15
 
15
16
  unless $LOAD_PATH.include?(File.expand_path('../', __FILE__))
16
17
  $LOAD_PATH.unshift(File.expand_path('../', __FILE__))
@@ -5,6 +5,7 @@ Gemirro::CLI.options.command 'index' do
5
5
  separator "\nOptions:\n"
6
6
 
7
7
  on :c=, :config=, 'Path to the configuration file'
8
+ on :u, :update, 'Update only'
8
9
 
9
10
  run do |opts, _args|
10
11
  Gemirro::CLI.load_configuration(opts[:c])
@@ -19,6 +20,7 @@ Gemirro::CLI.options.command 'index' do
19
20
  indexer.ui = Gem::SilentUI.new
20
21
 
21
22
  config.logger.info('Generating indexes')
22
- indexer.generate_index
23
+ indexer.generate_index if opts[:u].nil?
24
+ indexer.update_index unless opts[:u].nil?
23
25
  end
24
26
  end
@@ -9,7 +9,9 @@ module Gemirro
9
9
  server: {
10
10
  access_log: '/tmp/gemirro.access.log',
11
11
  error_log: '/tmp/gemirro.access.log'
12
- }
12
+ },
13
+
14
+ update_on_fetch: true
13
15
  }
14
16
  @configuration ||= Configuration.new(default_config)
15
17
  end
@@ -19,7 +21,7 @@ module Gemirro
19
21
  # destination directory, source, ignored Gems, etc.
20
22
  #
21
23
  class Configuration < Confstruct::Configuration
22
- attr_reader :mirror_directory
24
+ attr_reader :mirror_gems_directory, :mirror_gemspecs_directory
23
25
  attr_accessor :source, :ignored_gems, :logger
24
26
 
25
27
  ##
@@ -77,6 +79,16 @@ module Gemirro
77
79
  "specs.#{marshal_version}.gz"
78
80
  end
79
81
 
82
+ ##
83
+ # Returns the name of the file that contains an index
84
+ # of all the prerelease versions.
85
+ #
86
+ # @return [String]
87
+ #
88
+ def self.prerelease_versions_file
89
+ "prerelease_specs.#{marshal_version}.gz"
90
+ end
91
+
80
92
  ##
81
93
  # Returns a String containing the Marshal version.
82
94
  #
@@ -91,8 +103,8 @@ module Gemirro
91
103
  #
92
104
  # @return [Gemirro::MirrorDirectory]
93
105
  #
94
- def mirror_directory
95
- @mirror_directory ||= MirrorDirectory.new(gems_directory)
106
+ def mirror_gems_directory
107
+ @mirror_gems_directory ||= MirrorDirectory.new(gems_directory)
96
108
  end
97
109
 
98
110
  ##
@@ -101,7 +113,25 @@ module Gemirro
101
113
  # @return [String]
102
114
  #
103
115
  def gems_directory
104
- File.join(destination, 'gems')
116
+ File.join(destination.to_s, 'gems')
117
+ end
118
+
119
+ ##
120
+ # Return mirror directory
121
+ #
122
+ # @return [Gemirro::MirrorDirectory]
123
+ #
124
+ def mirror_gemspecs_directory
125
+ @mirror_gemspecs_directory ||= MirrorDirectory.new(gemspecs_directory)
126
+ end
127
+
128
+ ##
129
+ # Returns gems directory
130
+ #
131
+ # @return [String]
132
+ #
133
+ def gemspecs_directory
134
+ File.join(destination.to_s, 'quick', self.class.marshal_identifier)
105
135
  end
106
136
 
107
137
  ##
data/lib/gemirro/gem.rb CHANGED
@@ -11,7 +11,8 @@ module Gemirro
11
11
  # @return [Gem::Requirement]
12
12
  #
13
13
  class Gem
14
- attr_reader :name, :requirement
14
+ attr_reader :name, :requirement, :platform
15
+ attr_accessor :gemspec
15
16
 
16
17
  ##
17
18
  # Returns a `Gem::Version` instance based on the specified requirement.
@@ -27,15 +28,16 @@ module Gemirro
27
28
  # @param [String] name
28
29
  # @param [Gem::Requirement|String] requirement
29
30
  #
30
- def initialize(name, requirement = nil)
31
+ def initialize(name, requirement = nil, platform = 'ruby')
31
32
  requirement ||= ::Gem::Requirement.default
32
33
 
33
34
  if requirement.is_a?(String)
34
35
  requirement = ::Gem::Requirement.new(requirement)
35
36
  end
36
37
 
37
- @name = name
38
+ @name = name
38
39
  @requirement = requirement
40
+ @platform = platform
39
41
  end
40
42
 
41
43
  ##
@@ -56,15 +58,34 @@ module Gemirro
56
58
  version && !version.segments.reject { |s| s == 0 }.empty?
57
59
  end
58
60
 
61
+ def gemspec?
62
+ @gemspec == true
63
+ end
64
+
59
65
  ##
60
- # Returns the filename of the Gemfile.
66
+ # Returns the filename of the gem file.
61
67
  #
62
68
  # @param [String] gem_version
63
69
  # @return [String]
64
70
  #
65
71
  def filename(gem_version = nil)
66
72
  gem_version ||= version.to_s
67
- "#{name}-#{gem_version}.gem"
73
+ n = [name, gem_version]
74
+ n.push(@platform) if @platform != 'ruby'
75
+ "#{n.join('-')}.gem"
76
+ end
77
+
78
+ ##
79
+ # Returns the filename of the gemspec file.
80
+ #
81
+ # @param [String] gem_version
82
+ # @return [String]
83
+ #
84
+ def gemspec_filename(gem_version = nil)
85
+ gem_version ||= version.to_s
86
+ n = [name, gem_version]
87
+ n.push(@platform) if @platform != 'ruby'
88
+ "#{n.join('-')}.gemspec.rz"
68
89
  end
69
90
  end
70
91
  end
@@ -72,6 +72,11 @@ module Gemirro
72
72
  @grouped = @gems.group_by(&:name).map do |name, collection|
73
73
  [name, GemVersionCollection.new(collection)]
74
74
  end
75
+
76
+ @grouped.reject! do |name, _collection|
77
+ name.nil?
78
+ end
79
+
75
80
  @grouped.sort_by! do |name, _collection|
76
81
  name.downcase
77
82
  end
@@ -27,19 +27,15 @@ module Gemirro
27
27
  def fetch
28
28
  @source.gems.each do |gem|
29
29
  versions_for(gem).each do |version|
30
- filename = gem.filename(version)
31
- satisfied = gem.requirement.satisfied_by?(version)
32
- name = gem.name
33
-
34
- if gem_exists?(filename) || ignore_gem?(name, version) || !satisfied
35
- logger.debug("Skipping #{filename}")
36
- next
30
+ if gem.gemspec?
31
+ gemfile = fetch_gemspec(gem, version)
32
+ configuration.mirror_gemspecs_directory
33
+ .add_file(gem.gemspec_filename(version), gemfile) if gemfile
34
+ else
35
+ gemfile = fetch_gem(gem, version)
36
+ configuration.mirror_gems_directory
37
+ .add_file(gem.filename(version), gemfile) if gemfile
37
38
  end
38
-
39
- configuration.ignore_gem(gem.name, version)
40
- logger.info("Fetching #{filename}")
41
- gemfile = fetch_gem(gem, version)
42
- configuration.mirror_directory.add_file(filename, gemfile) if gemfile
43
39
  end
44
40
  end
45
41
  end
@@ -69,19 +65,62 @@ module Gemirro
69
65
  end
70
66
 
71
67
  ##
72
- # Tries to download the Gemfile for the specified Gem and version.
68
+ # Tries to download gemspec from a given name and version
69
+ #
70
+ # @param [Gemirro::Gem] gem
71
+ # @param [Gem::Version] version
72
+ # @return [String]
73
+ #
74
+ def fetch_gemspec(gem, version)
75
+ filename = gem.gemspec_filename(version)
76
+ satisfied = gem.requirement.satisfied_by?(version)
77
+
78
+ if gemspec_exists?(filename) || !satisfied
79
+ logger.debug("Skipping #{filename}")
80
+ return
81
+ end
82
+
83
+ logger.info("Fetching #{filename}")
84
+ fetch_from_source(gem, version, true)
85
+ end
86
+
87
+ ##
88
+ # Tries to download the gem file from a given nam and version
73
89
  #
74
90
  # @param [Gemirro::Gem] gem
75
91
  # @param [Gem::Version] version
76
92
  # @return [String]
77
93
  #
78
94
  def fetch_gem(gem, version)
79
- data = nil
80
95
  filename = gem.filename(version)
96
+ satisfied = gem.requirement.satisfied_by?(version)
97
+ name = gem.name
98
+
99
+ if gem_exists?(filename) || ignore_gem?(name, version) || !satisfied
100
+ logger.debug("Skipping #{filename}")
101
+ return
102
+ end
103
+
104
+ configuration.ignore_gem(gem.name, version)
105
+ logger.info("Fetching #{filename}")
81
106
 
107
+ fetch_from_source(gem, version)
108
+ end
109
+
110
+ ##
111
+ #
112
+ #
113
+ # @param [Gemirro::Gem] gem
114
+ # @param [Gem::Version] version
115
+ # @return [String]
116
+ #
117
+ def fetch_from_source(gem, version, gemspec = false)
118
+ data = nil
82
119
  begin
83
- data = @source.fetch_gem(gem.name, version)
120
+ data = @source.fetch_gem(gem.name, version) unless gemspec
121
+ data = @source.fetch_gemspec(gem.name, version) if gemspec
84
122
  rescue => e
123
+ filename = gem.filename(version)
85
124
  logger.error("Failed to retrieve #{filename}: #{e.message}")
86
125
  logger.debug("Adding #{filename} to the list of ignored Gems")
87
126
 
@@ -113,7 +152,17 @@ module Gemirro
113
152
  # @return [TrueClass|FalseClass]
114
153
  #
115
154
  def gem_exists?(filename)
116
- configuration.mirror_directory.file_exists?(filename)
155
+ configuration.mirror_gems_directory.file_exists?(filename)
156
+ end
157
+
158
+ ##
159
+ # Checks if a given Gemspec has already been downloaded.
160
+ #
161
+ # @param [String] filename
162
+ # @return [TrueClass|FalseClass]
163
+ #
164
+ def gemspec_exists?(filename)
165
+ configuration.mirror_gemspecs_directory.file_exists?(filename)
117
166
  end
118
167
 
119
168
  ##
@@ -82,8 +82,7 @@ module Gemirro
82
82
  # @return [Array]
83
83
  #
84
84
  def install_indicies
85
- verbose = ::Gem.configuration.really_verbose
86
- Gemirro.configuration.logger
85
+ logger
87
86
  .debug("Downloading index into production dir #{@dest_directory}")
88
87
 
89
88
  files = @files
@@ -100,29 +99,14 @@ module Gemirro
100
99
 
101
100
  files.each do |path|
102
101
  file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
103
- dst_name = File.join @dest_directory, file
102
+ src_name = File.join(@directory, file)
103
+ dst_name = File.join(@dest_directory, file)
104
104
 
105
105
  if ["#{@specs_index}.gz",
106
106
  "#{@latest_specs_index}.gz",
107
107
  "#{@prerelease_specs_index}.gz"].include?(path)
108
-
109
- content = Marshal.load(Zlib::GzipReader.open(path).read)
110
- Zlib::GzipWriter.open("#{dst_name}.orig") do |io|
111
- io.write(Marshal.dump(content))
112
- end
113
-
114
- unless @only_origin
115
- source_content = download_from_source(file)
116
- next if source_content.nil?
117
- source_content = Marshal.load(Zlib::GzipReader
118
- .new(StringIO
119
- .new(source_content)).read)
120
- new_content = source_content.concat(content).uniq
121
-
122
- Zlib::GzipWriter.open(dst_name) do |io|
123
- io.write(Marshal.dump(new_content))
124
- end
125
- end
108
+ res = build_zlib_file(file, src_name, dst_name, true)
109
+ next unless res
126
110
  else
127
111
  source_content = download_from_source(file)
128
112
  next if source_content.nil?
@@ -133,21 +117,189 @@ module Gemirro
133
117
  end
134
118
  end
135
119
 
120
+ ##
121
+ # Download file from source
122
+ #
123
+ # @param [String] file File path
124
+ # @return [String]
125
+ #
136
126
  def download_from_source(file)
137
127
  source_host = Gemirro.configuration.source.host
128
+ logger.info("Download from source: #{file}")
138
129
  resp = Http.get("#{source_host}/#{File.basename(file)}")
139
130
  return unless resp.code == 200
140
131
  resp.body
141
132
  end
142
133
 
134
+ ##
135
+ # Build indicies
136
+ #
137
+ # @return [Array]
138
+ #
143
139
  def build_indicies
140
+ specs = *map_gems_to_specs(gem_file_list)
141
+ specs.reject! { |s| s.class != ::Gem::Specification }
144
142
  ::Gem::Specification.dirs = []
145
- ::Gem::Specification.all = *map_gems_to_specs(gem_file_list)
143
+ ::Gem::Specification.all = specs
146
144
 
147
145
  build_marshal_gemspecs
148
146
  build_modern_indicies if @build_modern
149
147
 
150
148
  compress_indicies
151
149
  end
150
+
151
+ ##
152
+ # Map gems file to specs
153
+ #
154
+ # @param [Array] gems Gems list
155
+ # @return [Array]
156
+ #
157
+ def map_gems_to_specs(gems)
158
+ gems.map.with_index do |gemfile, index|
159
+ # rubocop:disable Metrics/LineLength
160
+ logger.info("[#{index + 1}/#{gems.size}]: Processing #{gemfile.split('/')[-1]}")
161
+ # rubocop:enable Metrics/LineLength
162
+
163
+ if File.size(gemfile) == 0
164
+ logger.warn("Skipping zero-length gem: #{gemfile}")
165
+ next
166
+ end
167
+
168
+ begin
169
+ spec = ::Gem::Package.new(gemfile).spec
170
+ spec.loaded_from = gemfile
171
+
172
+ # HACK: fuck this shit - borks all tests that use pl1
173
+ if File.basename(gemfile, '.gem') != spec.original_name
174
+ exp = spec.full_name
175
+ exp << " (#{spec.original_name})" if
176
+ spec.original_name != spec.full_name
177
+ msg = "Skipping misnamed gem: #{gemfile} should be named #{exp}"
178
+ logger.warn(msg)
179
+ next
180
+ end
181
+
182
+ abbreviate spec
183
+ sanitize spec
184
+
185
+ spec
186
+ rescue SignalException
187
+ msg = 'Received signal, exiting'
188
+ logger.error(msg)
189
+ raise
190
+ rescue StandardError => e
191
+ msg = ["Unable to process #{gemfile}",
192
+ "#{e.message} (#{e.class})",
193
+ "\t#{e.backtrace.join "\n\t"}"].join("\n")
194
+ logger.debug(msg)
195
+ end
196
+ end.compact
197
+ end
198
+
199
+ def update_index
200
+ make_temp_directories
201
+
202
+ specs_mtime = File.stat(@dest_specs_index).mtime
203
+ newest_mtime = Time.at(0)
204
+
205
+ updated_gems = gem_file_list.select do |gem|
206
+ gem_mtime = File.stat(gem).mtime
207
+ newest_mtime = gem_mtime if gem_mtime > newest_mtime
208
+ gem_mtime > specs_mtime
209
+ end
210
+
211
+ if updated_gems.empty?
212
+ logger.info('No new gems')
213
+ terminate_interaction(0)
214
+ end
215
+
216
+ specs = map_gems_to_specs(updated_gems)
217
+ prerelease, released = specs.partition { |s| s.version.prerelease? }
218
+
219
+ ::Gem::Specification.dirs = []
220
+ ::Gem::Specification.all = *specs
221
+ files = build_marshal_gemspecs
222
+
223
+ ::Gem.time('Updated indexes') do
224
+ update_specs_index(released, @dest_specs_index, @specs_index)
225
+ update_specs_index(released,
226
+ @dest_latest_specs_index,
227
+ @latest_specs_index)
228
+ update_specs_index(prerelease,
229
+ @dest_prerelease_specs_index,
230
+ @prerelease_specs_index)
231
+ end
232
+
233
+ compress_indicies
234
+
235
+ logger.info("Updating production dir #{@dest_directory}") if verbose
236
+ files << @specs_index
237
+ files << "#{@specs_index}.gz"
238
+ files << @latest_specs_index
239
+ files << "#{@latest_specs_index}.gz"
240
+ files << @prerelease_specs_index
241
+ files << "#{@prerelease_specs_index}.gz"
242
+
243
+ files.each do |path|
244
+ file = path.sub(%r{^#{Regexp.escape @directory}/?}, '')
245
+ src_name = File.join(@directory, file)
246
+ dst_name = File.join(@dest_directory, file)
247
+
248
+ if ["#{@specs_index}.gz",
249
+ "#{@latest_specs_index}.gz",
250
+ "#{@prerelease_specs_index}.gz"].include?(path)
251
+ res = build_zlib_file(file, src_name, dst_name)
252
+ next unless res
253
+ else
254
+ FileUtils.mv(src_name,
255
+ dst_name,
256
+ verbose: verbose,
257
+ force: true)
258
+ end
259
+
260
+ File.utime(newest_mtime, newest_mtime, dst_name)
261
+ end
262
+ end
263
+
264
+ def build_zlib_file(file, src_name, dst_name, from_source = false)
265
+ content = Marshal.load(Zlib::GzipReader.open(src_name).read)
266
+ create_zlib_file("#{dst_name}.orig", content)
267
+
268
+ return false if @only_origin
269
+
270
+ if from_source
271
+ source_content = download_from_source(file)
272
+ source_content = Marshal.load(Zlib::GzipReader
273
+ .new(StringIO
274
+ .new(source_content)).read)
275
+ else
276
+ source_content = Marshal.load(Zlib::GzipReader.open(dst_name).read)
277
+ end
278
+
279
+ return false if source_content.nil?
280
+ new_content = source_content.concat(content).uniq
281
+ create_zlib_file(dst_name, new_content)
282
+ end
283
+
284
+ def create_zlib_file(dst_name, content)
285
+ temp_file = Tempfile.new('gemirro')
286
+
287
+ Zlib::GzipWriter.open(temp_file.path) do |io|
288
+ io.write(Marshal.dump(content))
289
+ end
290
+
291
+ FileUtils.mv(temp_file.path,
292
+ dst_name,
293
+ verbose: verbose,
294
+ force: true)
295
+ end
296
+
297
+ def verbose
298
+ @verbose ||= ::Gem.configuration.really_verbose
299
+ end
300
+
301
+ def logger
302
+ Gemirro.configuration.logger
303
+ end
152
304
  end
153
305
  end
@@ -25,8 +25,8 @@ module Gemirro
25
25
  error_logger.sync = true
26
26
 
27
27
  before do
28
- Gemirro.configuration.logger = access_logger
29
28
  env['rack.errors'] = error_logger
29
+ Gemirro.configuration.logger = access_logger
30
30
  end
31
31
 
32
32
  ##
@@ -130,26 +130,31 @@ module Gemirro
130
130
  def fetch_gem(resource)
131
131
  name = File.basename(resource)
132
132
  # rubocop:disable Metrics/LineLength
133
- regexp = /^(.*)-(\d+(?:\.\d+){2,4}.*?)(?:-x86-(?:(?:mswin|mingw)(?:32|64)).*?)?\.gem(?:spec\.rz)?$/
133
+ regexp = /^(.*)-(\d+(?:\.\d+){2,4}.*?)(?:-x86-(?:(?:mswin|mingw)(?:32|64)).*?)?\.(gem(?:spec\.rz)?)$/
134
134
  # rubocop:enable Metrics/LineLength
135
135
  result = name.match(regexp)
136
136
  return unless result
137
137
 
138
- gem_name, gem_version = result.captures
138
+ gem_name, gem_version, gem_type = result.captures
139
139
  return unless gem_name && gem_version
140
140
 
141
141
  begin
142
142
  gem = Gemirro::Gem.new(gem_name, gem_version)
143
- return if gems_fetcher.gem_exists?(gem.filename(gem_version))
143
+ gem.gemspec = true if gem_type == 'gemspec.rz'
144
+
145
+ # rubocop:disable Metrics/LineLength
146
+ return if gems_fetcher.gem_exists?(gem.filename(gem_version)) && gem_type == 'gem'
147
+ return if gems_fetcher.gemspec_exists?(gem.gemspec_filename(gem_version)) && gem_type == 'gemspec.rz'
148
+ # rubocop:enable Metrics/LineLength
144
149
 
145
150
  logger.info("Try to download #{gem_name} with version #{gem_version}")
146
151
  gems_fetcher.source.gems.clear
147
152
  gems_fetcher.source.gems.push(gem)
148
153
  gems_fetcher.fetch
149
154
 
150
- update_indexes
155
+ update_indexes if configuration.update_on_fetch
151
156
  rescue StandardError => e
152
- logger.error(e.message)
157
+ logger.error(e)
153
158
  end
154
159
  end
155
160
 
@@ -164,7 +169,7 @@ module Gemirro
164
169
  indexer.ui = ::Gem::SilentUI.new
165
170
 
166
171
  configuration.logger.info('Generating indexes')
167
- indexer.generate_index
172
+ indexer.update_index
168
173
  rescue SystemExit => e
169
174
  configuration.logger.info(e.message)
170
175
  end
@@ -314,11 +319,10 @@ module Gemirro
314
319
  # @return [::Gem::Specification]
315
320
  #
316
321
  def spec_for(gemname, version, platform = 'ruby')
317
- filename = [gemname, version]
318
- filename.push(platform) if platform != 'ruby'
322
+ gem = Gem.new(gemname, version.to_s, platform)
319
323
  gemspec_path = File.join('quick',
320
324
  Gemirro::Configuration.marshal_identifier,
321
- "#{filename.join('-')}.gemspec.rz")
325
+ gem.gemspec_filename)
322
326
  spec_file = File.join(settings.public_folder,
323
327
  gemspec_path)
324
328
 
@@ -34,6 +34,15 @@ module Gemirro
34
34
  Http.get(host + '/' + Configuration.versions_file).body
35
35
  end
36
36
 
37
+ ##
38
+ # Fetches a list of all the available Gems and their versions.
39
+ #
40
+ # @return [String]
41
+ #
42
+ def fetch_prerelease_versions
43
+ Http.get(host + '/' + Configuration.prerelease_versions_file).body
44
+ end
45
+
37
46
  ##
38
47
  # Fetches the `.gem` file of a given Gem and version.
39
48
  #
@@ -45,6 +54,18 @@ module Gemirro
45
54
  Http.get(host + "/gems/#{name}-#{version}.gem").body
46
55
  end
47
56
 
57
+ ##
58
+ # Fetches the `.gemspec.rz` file of a given Gem and version.
59
+ #
60
+ # @param [String] name
61
+ # @param [String] version
62
+ # @return [String]
63
+ #
64
+ def fetch_gemspec(name, version)
65
+ marshal = Gemirro::Configuration.marshal_identifier
66
+ Http.get(host + "/quick/#{marshal}/#{name}-#{version}.gemspec.rz").body
67
+ end
68
+
48
69
  ##
49
70
  # Adds a new Gem to the source.
50
71
  #
@@ -1,5 +1,5 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  # Gemirro Version
3
3
  module Gemirro
4
- VERSION = '0.10.5'
4
+ VERSION = '0.11.0'
5
5
  end
@@ -25,7 +25,7 @@ module Gemirro
25
25
  "Updating #{source.name} (#{source.host})"
26
26
  )
27
27
 
28
- VersionsFile.load(source.fetch_versions)
28
+ VersionsFile.load(source.fetch_versions, source.fetch_prerelease_versions)
29
29
  end
30
30
  end
31
31
  end
@@ -15,13 +15,20 @@ module Gemirro
15
15
  ##
16
16
  # Reads the versions file from the specified String.
17
17
  #
18
- # @param [String] content
18
+ # @param [String] spec_content
19
+ # @param [String] prerelease_content
19
20
  # @return [Gemirro::VersionsFile]
20
21
  #
21
- def self.load(content)
22
- buffer = StringIO.new(content)
23
- reader = Zlib::GzipReader.new(buffer)
24
- instance = new(Marshal.load(reader.read))
22
+ def self.load(spec_content, prerelease_content)
23
+ buffer = StringIO.new(spec_content)
24
+ reader = Zlib::GzipReader.new(buffer)
25
+ versions = Marshal.load(reader.read)
26
+
27
+ buffer = StringIO.new(prerelease_content)
28
+ reader = Zlib::GzipReader.new(buffer)
29
+ versions.concat(Marshal.load(reader.read))
30
+
31
+ instance = new(versions)
25
32
 
26
33
  reader.close
27
34
 
@@ -58,8 +58,8 @@ module Gemirro
58
58
 
59
59
  it 'return mirror directory' do
60
60
  allow(@config).to receive(:gems_directory).once.and_return('/tmp')
61
- expect(@config.mirror_directory).to be_a(MirrorDirectory)
62
- expect(@config.mirror_directory.path).to eq('/tmp')
61
+ expect(@config.mirror_gems_directory).to be_a(MirrorDirectory)
62
+ expect(@config.mirror_gems_directory.path).to eq('/tmp')
63
63
  end
64
64
 
65
65
  it 'should return gems directory' do
@@ -13,8 +13,9 @@ module Gemirro
13
13
 
14
14
  before(:each) do
15
15
  @source = Source.new('RubyGems', 'https://rubygems.org')
16
- @versions_file = VersionsFile.new(['0.0.1'])
16
+ @versions_file = VersionsFile.new(['0.0.1', '0.0.2'])
17
17
  @fetcher = GemsFetcher.new(@source, @versions_file)
18
+ Gemirro.configuration.ignored_gems.clear
18
19
  end
19
20
 
20
21
  it 'should be initialized' do
@@ -34,19 +35,25 @@ module Gemirro
34
35
  @fetcher.configuration.destination = './'
35
36
  expect(@fetcher.gem_exists?('test')).to be_falsy
36
37
  MirrorDirectory.new('./').add_directory('gems')
38
+ MirrorDirectory.new('./').add_directory('quick/Marshal.4.8')
37
39
  MirrorFile.new('gems/test').write('content')
38
40
  expect(@fetcher.gem_exists?('test')).to be_truthy
39
41
  end
40
42
 
41
43
  it 'should ignore gem' do
44
+ allow(@fetcher.logger).to receive(:info)
45
+ .once.with('Fetching gemirro-0.0.1.gem')
42
46
  expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_falsy
43
47
  @fetcher.configuration.ignore_gem('gemirro', '0.0.1')
44
48
  expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_truthy
45
49
  end
46
50
 
47
51
  it 'should log error when fetch gem failed' do
52
+ allow(@fetcher.logger).to receive(:info)
53
+ .once.with('Fetching gemirro-0.0.1.gem')
48
54
  gem = Gem.new('gemirro')
49
55
  version = ::Gem::Version.new('0.0.1')
56
+ @fetcher.configuration.ignore_gem('gemirro', '0.0.1')
50
57
  allow(@source).to receive(:fetch_gem)
51
58
  .once.with('gemirro', version).and_raise(ArgumentError)
52
59
  allow(@fetcher.logger).to receive(:error)
@@ -59,6 +66,9 @@ module Gemirro
59
66
  end
60
67
 
61
68
  it 'should fetch gem' do
69
+ allow(@fetcher.logger).to receive(:info)
70
+ .once.with('Fetching gemirro-0.0.1.gem')
71
+ MirrorDirectory.new('./').add_directory('gems')
62
72
  gem = Gem.new('gemirro')
63
73
  version = ::Gem::Version.new('0.0.1')
64
74
  allow(@source).to receive(:fetch_gem)
@@ -67,6 +77,35 @@ module Gemirro
67
77
  expect(@fetcher.fetch_gem(gem, version)).to eq('gemirro')
68
78
  end
69
79
 
80
+ it 'should fetch gemspec' do
81
+ allow(@fetcher.logger).to receive(:info)
82
+ .once.with('Fetching gemirro-0.0.1.gemspec.rz')
83
+ MirrorDirectory.new('./').add_directory('quick/Marshal.4.8')
84
+ gem = Gem.new('gemirro')
85
+ gem.gemspec = true
86
+ version = ::Gem::Version.new('0.0.1')
87
+ allow(@source).to receive(:fetch_gemspec)
88
+ .once.with('gemirro', version).and_return('gemirro')
89
+
90
+ expect(@fetcher.fetch_gemspec(gem, version)).to eq('gemirro')
91
+ end
92
+
93
+ it 'should not fetch gemspec if file exists' do
94
+ allow(@fetcher.logger).to receive(:info)
95
+ .once.with('Fetching gemirro-0.0.1.gemspec.rz')
96
+ allow(@fetcher).to receive(:gemspec_exists?)
97
+ .once.with('gemirro-0.0.1.gemspec.rz')
98
+ .and_return(true)
99
+ allow(@fetcher.logger).to receive(:debug)
100
+ .once.with('Skipping gemirro-0.0.1.gemspec.rz')
101
+
102
+ gem = Gem.new('gemirro')
103
+ gem.gemspec = true
104
+ version = ::Gem::Version.new('0.0.1')
105
+
106
+ expect(@fetcher.fetch_gemspec(gem, version)).to be_nil
107
+ end
108
+
70
109
  it 'should retrieve versions for specific gem' do
71
110
  gem = Gem.new('gemirro', '0.0.2')
72
111
  allow(@versions_file).to receive(:versions_for)
@@ -75,6 +114,7 @@ module Gemirro
75
114
  end
76
115
 
77
116
  it 'should fetch all gems and log debug if gem is not satisfied' do
117
+ MirrorDirectory.new('./').add_directory('gems')
78
118
  gem = Gem.new('gemirro', '0.0.1')
79
119
  allow(gem.requirement).to receive(:satisfied_by?)
80
120
  .once.with(nil).and_return(false)
@@ -87,18 +127,21 @@ module Gemirro
87
127
  it 'should fetch all gems' do
88
128
  gem = Gem.new('gemirro', '0.0.2')
89
129
  @fetcher.source.gems << gem
90
- allow(@fetcher).to receive(:versions_for).once.and_return(['0.0.2'])
91
- allow(gem.requirement).to receive(:satisfied_by?)
92
- .once.with('0.0.2').and_return(true)
130
+ gemspec = Gem.new('gemirro', '0.0.1')
131
+ gemspec.gemspec = true
132
+ @fetcher.source.gems << gemspec
133
+
134
+ allow(@fetcher).to receive(:fetch_gemspec)
135
+ .once.with(gemspec, nil).and_return('gemfile')
93
136
  allow(@fetcher).to receive(:fetch_gem)
94
- .once.with(gem, '0.0.2').and_return('gemfile')
95
- allow(@fetcher.configuration).to receive(:ignore_gem)
96
- .once.with('gemirro', '0.0.2')
97
- allow(@fetcher.logger).to receive(:info)
98
- .once.with('Fetching gemirro-0.0.2.gem')
99
- allow(@fetcher.configuration.mirror_directory).to receive(:add_file)
137
+ .once.with(gem, nil).and_return('gemfile')
138
+
139
+ allow(@fetcher.configuration.mirror_gems_directory).to receive(:add_file)
100
140
  .once.with('gemirro-0.0.2.gem', 'gemfile')
101
- expect(@fetcher.fetch).to eq([gem])
141
+ allow(@fetcher.configuration.mirror_gemspecs_directory)
142
+ .to receive(:add_file)
143
+ .once.with('gemirro-0.0.1.gemspec.rz', 'gemfile')
144
+ expect(@fetcher.fetch).to eq([gem, gemspec])
102
145
  end
103
146
  end
104
147
  end
@@ -1,6 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'spec_helper'
3
3
  require 'rubygems/indexer'
4
+ require 'tempfile'
4
5
  require 'gemirro/source'
5
6
  require 'gemirro/indexer'
6
7
  require 'gemirro/mirror_file'
@@ -11,6 +12,28 @@ module Gemirro
11
12
  describe 'Indexer' do
12
13
  include FakeFS::SpecHelpers
13
14
 
15
+ before(:each) do
16
+ allow_any_instance_of(Logger).to receive(:info)
17
+ allow_any_instance_of(Logger).to receive(:debug)
18
+ allow_any_instance_of(Logger).to receive(:warn)
19
+ end
20
+
21
+ it 'should download from source' do
22
+ source = Source.new('Rubygems', 'https://rubygems.org')
23
+ allow(Gemirro.configuration).to receive(:source).and_return(source)
24
+
25
+ dir = MirrorDirectory.new('/tmp')
26
+ dir.add_directory('test')
27
+ indexer = Indexer.new('/tmp/test')
28
+
29
+ Struct.new('HttpGet', :code, :body)
30
+ http_get = Struct::HttpGet.new(200, 'bad')
31
+ allow(Http).to receive(:get).once.and_return(http_get)
32
+
33
+ expect(indexer.download_from_source('something'))
34
+ .to eq('bad')
35
+ end
36
+
14
37
  it 'should install indicies' do
15
38
  dir = MirrorDirectory.new('/tmp')
16
39
  dir.add_directory('test')
@@ -44,25 +67,19 @@ module Gemirro
44
67
  '/tmp/test/quick/Marshal.4.8',
45
68
  verbose: true, force: true)
46
69
 
70
+ allow(FileUtils).to receive(:mv)
71
+
47
72
  source = Source.new('Rubygems', 'https://rubygems.org')
48
73
  allow(Gemirro.configuration).to receive(:source).and_return(source)
49
74
 
50
- Struct.new('HttpGet', :code, :body)
51
75
  wio = StringIO.new('w')
52
76
  w_gz = Zlib::GzipWriter.new(wio)
53
77
  w_gz.write(['content'])
54
78
  w_gz.close
55
- http_get = Struct::HttpGet.new(200, wio.string)
79
+ allow(indexer).to receive(:download_from_source).and_return(wio.string)
80
+
56
81
  allow(Marshal).to receive(:load).and_return(['content'])
57
82
  allow(Marshal).to receive(:dump).and_return(['content'])
58
- allow(Zlib::GzipWriter).to receive(:open)
59
- .once.with('/tmp/test/specs.4.8.gz.orig')
60
- allow(Zlib::GzipWriter).to receive(:open)
61
- .once.with('/tmp/test/specs.4.8.gz')
62
- allow(Http).to receive(:get)
63
- .with('https://rubygems.org/specs.4.8.gz').and_return(http_get)
64
- allow(Http).to receive(:get)
65
- .with('https://rubygems.org/something.4.8.gz').and_return(http_get)
66
83
 
67
84
  Struct.new('GzipReader', :read)
68
85
  gzip_reader = Struct::GzipReader.new(wio.string)
@@ -76,15 +93,6 @@ module Gemirro
76
93
  '/tmp/gem_generate_index/something.4.8.gz'])
77
94
  end
78
95
 
79
- it 'should exit if there is no new gems' do
80
- dir = MirrorDirectory.new('./')
81
- dir.add_directory('gem_generate_index/gems')
82
- MirrorFile.new('./specs.4.8').write('')
83
-
84
- indexer = Indexer.new('./')
85
- allow(indexer).to receive(:make_temp_directories).and_return(true)
86
- end
87
-
88
96
  it 'should build indicies' do
89
97
  indexer = Indexer.new('/')
90
98
  dir = MirrorDirectory.new('/')
@@ -94,19 +102,82 @@ module Gemirro
94
102
  dir.add_directory("#{indexer.directory.gsub(%r{^/}, '')}/gems")
95
103
  dir.add_directory("#{indexer.directory.gsub(%r{^/}, '')}/quick")
96
104
 
105
+ fixtures_dir = File.dirname(__FILE__) + '/../fixtures'
106
+ FakeFS::FileSystem
107
+ .clone("#{fixtures_dir}/gems/gemirro-0.0.1.gem",
108
+ "#{indexer.directory}/gems/gemirro-0.0.1.gem")
109
+ FakeFS::FileSystem
110
+ .clone("#{fixtures_dir}/gems/gemirro-0.0.1.gem",
111
+ '/gems/gemirro-0.0.1.gem')
112
+ FakeFS::FileSystem
113
+ .clone("#{fixtures_dir}/gems/gemirro-0.0.1.gem",
114
+ '/gems/gemirral-0.0.1.gem') # Skipping misnamed
115
+ FakeFS::FileSystem
116
+ .clone("#{fixtures_dir}/quick/gemirro-0.0.1.gemspec.rz",
117
+ "#{indexer.directory}/quick/gemirro-0.0.1.gemspec.rz")
118
+
119
+ MirrorFile.new('gems/gemirro-0.0.2.gem').write('') # Empty file
120
+ MirrorFile.new('gems/gemirro-0.0.3.gem').write('Error') # Empty file
97
121
  MirrorFile.new('/specs.4.8').write('')
98
- MirrorFile.new("#{indexer.directory}/gems/gemirro-0.1.0.gem").write('')
99
- MirrorFile.new('gems/gemirro-0.1.0.gem').write('')
100
- MirrorFile.new("#{indexer.directory}/quick/gemirro-0.1.0.gemspec.rz")
101
- .write('test')
102
122
 
103
123
  allow(indexer).to receive(:gem_file_list)
104
- .and_return(['gems/gemirro-0.1.0.gem'])
124
+ .and_return(['gems/gemirro-0.0.1.gem',
125
+ 'gems/gemirro-0.0.2.gem',
126
+ 'gems/gemirro-0.0.3.gem',
127
+ 'gems/gemirral-0.0.1.gem'])
105
128
  allow(indexer).to receive(:build_marshal_gemspecs).once.and_return([
106
- "#{indexer.directory}/quick/gemirro-0.1.0.gemspec.rz"])
129
+ "#{indexer.directory}/quick/gemirro-0.0.1.gemspec.rz"])
107
130
  allow(indexer).to receive(:compress_indicies).once.and_return(true)
108
131
 
109
132
  indexer.build_indicies
110
133
  end
134
+
135
+ it 'should update index and exit ruby gems' do
136
+ indexer = Indexer.new('/')
137
+ MirrorDirectory.new('/')
138
+ MirrorFile.new('/specs.4.8').write('')
139
+ expect { indexer.update_index }.to raise_error(::Gem::SystemExitException)
140
+ end
141
+
142
+ it 'should update index' do
143
+ dir = MirrorDirectory.new('/tmp')
144
+ dir.add_directory('gem_generate_index/quick/Marshal.4.8')
145
+ dir.add_directory('test/gems')
146
+ dir.add_directory('test/quick')
147
+
148
+ indexer = Indexer.new('/tmp/test')
149
+ indexer.quick_marshal_dir = '/tmp/gem_generate_index/quick/Marshal.4.8'
150
+ indexer.dest_directory = '/tmp/test'
151
+ indexer.directory = '/tmp/gem_generate_index'
152
+ indexer.instance_variable_set('@specs_index',
153
+ '/tmp/gem_generate_index/specs.4.8')
154
+
155
+ MirrorFile.new("#{indexer.directory}/specs.4.8.gz").write('')
156
+ MirrorFile.new("#{indexer.directory}/specs.4.8").write('')
157
+ MirrorFile.new("#{indexer.dest_directory}/specs.4.8").write('')
158
+ File.utime(Time.at(0), Time.at(0), "#{indexer.dest_directory}/specs.4.8")
159
+
160
+ fixtures_dir = File.dirname(__FILE__) + '/../fixtures'
161
+ FakeFS::FileSystem
162
+ .clone("#{fixtures_dir}/gems/gemirro-0.0.1.gem",
163
+ "#{indexer.dest_directory}/gems/gemirro-0.0.1.gem")
164
+ FakeFS::FileSystem
165
+ .clone("#{fixtures_dir}/quick/gemirro-0.0.1.gemspec.rz",
166
+ "#{indexer.directory}/quick/gemirro-0.0.1.gemspec.rz")
167
+
168
+ allow(indexer).to receive(:make_temp_directories)
169
+ allow(indexer).to receive(:update_specs_index)
170
+ allow(indexer).to receive(:compress_indicies)
171
+ allow(indexer).to receive(:build_zlib_file)
172
+ allow(indexer).to receive(:build_marshal_gemspecs).once.and_return([
173
+ "#{indexer.directory}/quick/gemirro-0.0.1.gemspec.rz"])
174
+
175
+ allow(Marshal).to receive(:load).and_return(['content'])
176
+ allow(Marshal).to receive(:dump).and_return(['content'])
177
+ allow(FileUtils).to receive(:mv)
178
+ allow(File).to receive(:utime)
179
+
180
+ indexer.update_index
181
+ end
111
182
  end
112
183
  end
@@ -21,7 +21,6 @@ RSpec.configure do |c|
21
21
  end
22
22
 
23
23
  # Server tests
24
- # rubocop:disable Metrics/ModuleLength
25
24
  module Gemirro
26
25
  describe 'Gemirro::Server' do
27
26
  include FakeFS::SpecHelpers
@@ -131,7 +130,7 @@ module Gemirro
131
130
  gem_indexer = Struct::GemIndexer.new
132
131
  allow(gem_indexer).to receive(:only_origin=).once.and_return(true)
133
132
  allow(gem_indexer).to receive(:ui=).once.and_return(true)
134
- allow(gem_indexer).to receive(:generate_index).once.and_return(true)
133
+ allow(gem_indexer).to receive(:update_index).once.and_return(true)
135
134
 
136
135
  allow(Gemirro.configuration).to receive(:source)
137
136
  .twice.and_return(source)
@@ -171,7 +170,7 @@ module Gemirro
171
170
  gem_indexer = Struct::GemIndexer.new
172
171
  allow(gem_indexer).to receive(:only_origin=).once.and_return(true)
173
172
  allow(gem_indexer).to receive(:ui=).once.and_return(true)
174
- allow(gem_indexer).to receive(:generate_index)
173
+ allow(gem_indexer).to receive(:update_index)
175
174
  .once.and_raise(SystemExit)
176
175
 
177
176
  allow(Gemirro.configuration).to receive(:source)
@@ -33,6 +33,14 @@ module Gemirro
33
33
  expect(@source.fetch_gem('gemirro', '0.0.1')).to be_truthy
34
34
  end
35
35
 
36
+ it 'should fetch gemspec' do
37
+ Struct.new('FetchGemspec', :body)
38
+ result = Struct::FetchGemspec.new(true)
39
+ allow(Http).to receive(:get).once.with(
40
+ 'https://rubygems.org/quick/Marshal.4.8/gemirro-0.0.1.gemspec.rz').and_return(result)
41
+ expect(@source.fetch_gemspec('gemirro', '0.0.1')).to be_truthy
42
+ end
43
+
36
44
  it 'should add gems' do
37
45
  expect(@source.gems).to eq([])
38
46
  @source.gem('gemirro')
@@ -18,7 +18,8 @@ module Gemirro
18
18
  allow(Gemirro.configuration.logger).to receive(:info)
19
19
  .once.with("Updating #{@source.name} (#{@source.host})")
20
20
  allow(@source).to receive(:fetch_versions).once.and_return([])
21
- allow(VersionsFile).to receive(:load).with([])
21
+ allow(@source).to receive(:fetch_prerelease_versions).once.and_return([])
22
+ allow(VersionsFile).to receive(:load).with([], [])
22
23
  expect(@fetcher.fetch).to be_nil
23
24
  end
24
25
  end
@@ -26,25 +26,36 @@ module Gemirro
26
26
  end
27
27
 
28
28
  it 'should load versions file' do
29
- wio = StringIO.new('w')
30
- w_gz = Zlib::GzipWriter.new(wio)
29
+ spec = StringIO.new('w')
30
+ w_gz = Zlib::GzipWriter.new(spec)
31
31
  w_gz.write(Marshal.dump([
32
32
  ['gemirro', '0.0.1'],
33
33
  ['gemirro', '0.0.2']
34
34
  ]))
35
35
  w_gz.close
36
+ prerelease = StringIO.new('w')
37
+ w_gz = Zlib::GzipWriter.new(prerelease)
38
+ w_gz.write(Marshal.dump([
39
+ ['gemirro', '0.0.1.alpha1'],
40
+ ['gemirro', '0.0.2.alpha2']
41
+ ]))
42
+ w_gz.close
36
43
 
37
- result = VersionsFile.load(wio.string)
44
+ result = VersionsFile.load(spec.string, prerelease.string)
38
45
  expect(result).to be_a(VersionsFile)
39
46
 
40
47
  expect(result.versions).to eq([
41
48
  ['gemirro', '0.0.1'],
42
- ['gemirro', '0.0.2']
49
+ ['gemirro', '0.0.2'],
50
+ ['gemirro', '0.0.1.alpha1'],
51
+ ['gemirro', '0.0.2.alpha2']
43
52
  ])
44
53
  expect(result.versions_hash).to eq(
45
54
  'gemirro' => [
46
55
  ['gemirro', '0.0.1'],
47
- ['gemirro', '0.0.2']
56
+ ['gemirro', '0.0.2'],
57
+ ['gemirro', '0.0.1.alpha1'],
58
+ ['gemirro', '0.0.2.alpha2']
48
59
  ]
49
60
  )
50
61
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gemirro
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.5
4
+ version: 0.11.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pierre Rambaud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-19 00:00:00.000000000 Z
11
+ date: 2015-07-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: slop
@@ -178,7 +178,7 @@ dependencies:
178
178
  - - "~>"
179
179
  - !ruby/object:Gem::Version
180
180
  version: 0.6.7
181
- description: Create your own gem mirror with a simple TCPServer.
181
+ description: Create your own gems mirror.
182
182
  email: pierre.rambaud86@gmail.com
183
183
  executables:
184
184
  - gemirro
@@ -215,6 +215,8 @@ files:
215
215
  - lib/gemirro/version.rb
216
216
  - lib/gemirro/versions_fetcher.rb
217
217
  - lib/gemirro/versions_file.rb
218
+ - spec/fixtures/gems/gemirro-0.0.1.gem
219
+ - spec/fixtures/quick/gemirro-0.0.1.gemspec.rz
218
220
  - spec/gemirro/cli_spec.rb
219
221
  - spec/gemirro/configuration_spec.rb
220
222
  - spec/gemirro/gem_spec.rb
@@ -272,6 +274,6 @@ rubyforge_project:
272
274
  rubygems_version: 2.4.8
273
275
  signing_key:
274
276
  specification_version: 4
275
- summary: Gem for easily creating your own RubyGems mirror.
277
+ summary: Gem for easily creating your own gems mirror.
276
278
  test_files: []
277
279
  has_rdoc: