gem_mirror 0.1.0.pre

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.
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemMirror
4
+ ##
5
+ # The Source class is used for storing information about an external source
6
+ # such as the name and the Gems to mirror.
7
+ #
8
+ # @!attribute [r] name
9
+ # @return [String]
10
+ # @!attribute [r] host
11
+ # @return [String]
12
+ # @!attribute [r] gems
13
+ # @return [Array]
14
+ #
15
+ class Source
16
+ attr_reader :name, :host, :gems
17
+
18
+ ##
19
+ # @param [String] name
20
+ # @param [String] host
21
+ # @param [Array] gems
22
+ #
23
+ def initialize(name, host, gems = [])
24
+ @name = name.downcase.gsub(/\s+/, "_")
25
+ @host = host.chomp("/")
26
+ @gems = gems
27
+ end
28
+
29
+ ##
30
+ # Returns a new Source instance based on the current one.
31
+ #
32
+ # @param [Array] new_gems The gems to set, overwrites the current ones.
33
+ # @return [Source]
34
+ #
35
+ def updated(new_gems)
36
+ self.class.new(name, host, new_gems)
37
+ end
38
+
39
+ ##
40
+ # Fetches a list of all the available Gems and their versions.
41
+ #
42
+ # @return [String]
43
+ #
44
+ def fetch_versions
45
+ http_get("#{host}/#{Configuration.versions_file}").body
46
+ end
47
+
48
+ ##
49
+ # Fetches the Gem specification of a Gem.
50
+ #
51
+ # @param [String] name
52
+ # @param [String] version
53
+ # @return [String]
54
+ #
55
+ def fetch_specification(name, version)
56
+ url = host + "/quick/#{Configuration.marshal_identifier}" \
57
+ "/#{name}-#{version}.gemspec.rz"
58
+
59
+ http_get(url).body
60
+ end
61
+
62
+ ##
63
+ # Fetches the `.gem` file of a given Gem and version.
64
+ #
65
+ # @param [String] name
66
+ # @param [String] version
67
+ # @return [String]
68
+ #
69
+ def fetch_gem(name, version)
70
+ http_get(host + "/gems/#{name}-#{version}.gem").body
71
+ end
72
+
73
+ ##
74
+ # Adds a new Gem to the source.
75
+ #
76
+ # @param [String] name
77
+ # @param [String] requirement
78
+ #
79
+ def gem(name, requirement = nil)
80
+ gems << Gem.new(name, requirement)
81
+ end
82
+
83
+ private
84
+
85
+ ##
86
+ # Requests the given HTTP resource.
87
+ #
88
+ # @param [String] url
89
+ # @return [HTTP::Message]
90
+ #
91
+ def http_get(url)
92
+ response = client.get(url, follow_redirect: true)
93
+
94
+ raise HTTPClient::BadResponseError, response.reason unless HTTP::Status.successful?(response.status)
95
+
96
+ response
97
+ end
98
+
99
+ ##
100
+ # @return [HTTPClient]
101
+ #
102
+ def client
103
+ @client ||= HTTPClient.new
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemMirror
4
+ # The current gem version as a string
5
+ VERSION = "0.1.0.pre"
6
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemMirror
4
+ ##
5
+ # The VersionsFetcher class is used for retrieving the file that contains all
6
+ # registered Gems and their versions.
7
+ #
8
+ # @!attribute [r] source
9
+ # @return [Source]
10
+ #
11
+ class VersionsFetcher
12
+ attr_reader :source
13
+
14
+ ##
15
+ # @param [Source] source
16
+ #
17
+ def initialize(source)
18
+ @source = source
19
+ end
20
+
21
+ ##
22
+ # @return [GemMirror::VersionsFile]
23
+ #
24
+ def fetch
25
+ GemMirror.configuration.logger.info(
26
+ "Updating #{source.name} (#{source.host})"
27
+ )
28
+
29
+ VersionsFile.load(source.fetch_versions)
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GemMirror
4
+ ##
5
+ # The VersionsFile class acts as a small Ruby wrapper around the RubyGems
6
+ # file that contains all Gems and their associated versions.
7
+ #
8
+ # @!attribute [r] versions
9
+ # @return [Array]
10
+ # @!attribute [r] versions_hash
11
+ # @return [Hash]
12
+ #
13
+ class VersionsFile
14
+ attr_reader :versions, :versions_hash
15
+
16
+ ##
17
+ # Reads the versions file from the specified String.
18
+ #
19
+ # @param [String] content
20
+ # @return [GemMirror::VersionsFile]
21
+ #
22
+ def self.load(content)
23
+ buffer = StringIO.new(content)
24
+ reader = Zlib::GzipReader.new(buffer)
25
+ instance = new(Marshal.load(reader.read))
26
+
27
+ reader.close
28
+
29
+ instance
30
+ end
31
+
32
+ ##
33
+ # @param [Array] versions
34
+ #
35
+ def initialize(versions)
36
+ @versions = versions
37
+ @versions_hash = create_versions_hash
38
+ end
39
+
40
+ ##
41
+ # Creates a Hash based on the Array containing all versions. This Hash is
42
+ # used to more easily (and faster) iterate over all the gems/versions.
43
+ #
44
+ # @return [Hash]
45
+ #
46
+ def create_versions_hash
47
+ hash = Hash.new { |h, k| h[k] = [] }
48
+
49
+ versions.each do |version|
50
+ hash[version[0]] << version
51
+ end
52
+
53
+ hash
54
+ end
55
+
56
+ ##
57
+ # Returns an Array containing all the available versions for a Gem.
58
+ #
59
+ # @param [String] gem
60
+ # @return [Array]
61
+ #
62
+ def versions_for(gem)
63
+ versions_hash[gem].map { |version| version[1] }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This is the main configuration file for your RubyGems mirror. Here you can
4
+ # change settings such as the location to store Gem files in and what sources
5
+ # and Gems you'd like to mirror.
6
+ GemMirror.configuration.configure do
7
+ # The directory to store indexing information as well as the Gem files in.
8
+ destination File.expand_path("public", __dir__)
9
+
10
+ # Directory to use for storing SHA512 checksums of each Gem.
11
+ checksums File.expand_path("public/checksums", __dir__)
12
+
13
+ # When set to `true` development dependencies of Gems will also be mirrored.
14
+ development false
15
+
16
+ # If you're mirroring a lot of Gems you'll probably want to switch the
17
+ # logging level to Logger::ERROR or Logger::INFO to reduce the amount of
18
+ # noise.
19
+ logger.level = Logger::DEBUG
20
+
21
+ # A source is a remote location that you want to mirror. The first parameter
22
+ # of this method is the human readable name, the second one the URL. The
23
+ # supplied block is used to determine what Gems (and versions) to mirror.
24
+ source "rubygems", "https://rubygems.org" do
25
+ gem "rack", ">= 1.0.0"
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,290 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem_mirror
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre
5
+ platform: ruby
6
+ authors:
7
+ - Yorick Peterse
8
+ - Patrick Callahan
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2021-06-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: confstruct
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.0'
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '2'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '1.0'
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '2'
34
+ - !ruby/object:Gem::Dependency
35
+ name: httpclient
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.8'
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '3'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: '2.8'
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '3'
54
+ - !ruby/object:Gem::Dependency
55
+ name: slop
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '='
59
+ - !ruby/object:Gem::Version
60
+ version: '3.6'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '='
66
+ - !ruby/object:Gem::Version
67
+ version: '3.6'
68
+ - !ruby/object:Gem::Dependency
69
+ name: bundler
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: 1.17.3
75
+ - - "<"
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: 1.17.3
85
+ - - "<"
86
+ - !ruby/object:Gem::Version
87
+ version: '3.0'
88
+ - !ruby/object:Gem::Dependency
89
+ name: rake
90
+ requirement: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: 13.0.0
95
+ - - "<"
96
+ - !ruby/object:Gem::Version
97
+ version: '14'
98
+ type: :development
99
+ prerelease: false
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 13.0.0
105
+ - - "<"
106
+ - !ruby/object:Gem::Version
107
+ version: '14'
108
+ - !ruby/object:Gem::Dependency
109
+ name: rake-manifest
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: 0.2.0
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - "~>"
120
+ - !ruby/object:Gem::Version
121
+ version: 0.2.0
122
+ - !ruby/object:Gem::Dependency
123
+ name: redcarpet
124
+ requirement: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - "~>"
127
+ - !ruby/object:Gem::Version
128
+ version: 3.5.0
129
+ type: :development
130
+ prerelease: false
131
+ version_requirements: !ruby/object:Gem::Requirement
132
+ requirements:
133
+ - - "~>"
134
+ - !ruby/object:Gem::Version
135
+ version: 3.5.0
136
+ - !ruby/object:Gem::Dependency
137
+ name: rspec
138
+ requirement: !ruby/object:Gem::Requirement
139
+ requirements:
140
+ - - "~>"
141
+ - !ruby/object:Gem::Version
142
+ version: '3.2'
143
+ type: :development
144
+ prerelease: false
145
+ version_requirements: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - "~>"
148
+ - !ruby/object:Gem::Version
149
+ version: '3.2'
150
+ - !ruby/object:Gem::Dependency
151
+ name: rubocop
152
+ requirement: !ruby/object:Gem::Requirement
153
+ requirements:
154
+ - - '='
155
+ - !ruby/object:Gem::Version
156
+ version: 1.16.0
157
+ type: :development
158
+ prerelease: false
159
+ version_requirements: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '='
162
+ - !ruby/object:Gem::Version
163
+ version: 1.16.0
164
+ - !ruby/object:Gem::Dependency
165
+ name: rubocop-performance
166
+ requirement: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - '='
169
+ - !ruby/object:Gem::Version
170
+ version: 1.11.3
171
+ type: :development
172
+ prerelease: false
173
+ version_requirements: !ruby/object:Gem::Requirement
174
+ requirements:
175
+ - - '='
176
+ - !ruby/object:Gem::Version
177
+ version: 1.11.3
178
+ - !ruby/object:Gem::Dependency
179
+ name: rubocop-rake
180
+ requirement: !ruby/object:Gem::Requirement
181
+ requirements:
182
+ - - '='
183
+ - !ruby/object:Gem::Version
184
+ version: 0.5.1
185
+ type: :development
186
+ prerelease: false
187
+ version_requirements: !ruby/object:Gem::Requirement
188
+ requirements:
189
+ - - '='
190
+ - !ruby/object:Gem::Version
191
+ version: 0.5.1
192
+ - !ruby/object:Gem::Dependency
193
+ name: rubocop-rspec
194
+ requirement: !ruby/object:Gem::Requirement
195
+ requirements:
196
+ - - '='
197
+ - !ruby/object:Gem::Version
198
+ version: 2.3.0
199
+ type: :development
200
+ prerelease: false
201
+ version_requirements: !ruby/object:Gem::Requirement
202
+ requirements:
203
+ - - '='
204
+ - !ruby/object:Gem::Version
205
+ version: 2.3.0
206
+ - !ruby/object:Gem::Dependency
207
+ name: yard
208
+ requirement: !ruby/object:Gem::Requirement
209
+ requirements:
210
+ - - "~>"
211
+ - !ruby/object:Gem::Version
212
+ version: 0.9.0
213
+ type: :development
214
+ prerelease: false
215
+ version_requirements: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - "~>"
218
+ - !ruby/object:Gem::Version
219
+ version: 0.9.0
220
+ description: |
221
+ gem-mirror is a tool for creating and managing a private
222
+ mirror of RubyGems. It is also suitable for hosting private
223
+ gems.
224
+ email:
225
+ - pmc@patrickcallahan.com
226
+ executables:
227
+ - gem_mirror
228
+ extensions: []
229
+ extra_rdoc_files:
230
+ - CHANGELOG.md
231
+ - LICENSE.txt
232
+ - README.md
233
+ files:
234
+ - CHANGELOG.md
235
+ - LICENSE.txt
236
+ - README.md
237
+ - exe/gem_mirror
238
+ - gem_mirror.gemspec
239
+ - lib/gem_mirror.rb
240
+ - lib/gem_mirror/cli.rb
241
+ - lib/gem_mirror/cli/checksum.rb
242
+ - lib/gem_mirror/cli/index.rb
243
+ - lib/gem_mirror/cli/init.rb
244
+ - lib/gem_mirror/cli/update.rb
245
+ - lib/gem_mirror/configuration.rb
246
+ - lib/gem_mirror/gem.rb
247
+ - lib/gem_mirror/gems_fetcher.rb
248
+ - lib/gem_mirror/mirror_directory.rb
249
+ - lib/gem_mirror/mirror_file.rb
250
+ - lib/gem_mirror/source.rb
251
+ - lib/gem_mirror/version.rb
252
+ - lib/gem_mirror/versions_fetcher.rb
253
+ - lib/gem_mirror/versions_file.rb
254
+ - template/config.rb
255
+ homepage: https://github.com/dirtyharrycallahan/gem_mirror
256
+ licenses:
257
+ - MIT
258
+ metadata:
259
+ allowed_push_host: https://rubygems.org
260
+ changelog_uri: https://github.com/dirtyharrycallahan/gem_mirror/blob/master/CHANGELOG.md
261
+ homepage_uri: https://github.com/dirtyharrycallahan/gem_mirror
262
+ source_code_uri: https://github.com/dirtyharrycallahan/gem_mirror
263
+ bug_tracker_uri: https://github.com/dirtyharrycallahan/gem_mirror/issues
264
+ post_install_message:
265
+ rdoc_options:
266
+ - "--title"
267
+ - gem_mirror - A Tool for Managing a Private Gem Repository
268
+ - "--main"
269
+ - README.md
270
+ - "--line-numbers"
271
+ - "--inline-source"
272
+ - "--quiet"
273
+ require_paths:
274
+ - lib
275
+ required_ruby_version: !ruby/object:Gem::Requirement
276
+ requirements:
277
+ - - ">="
278
+ - !ruby/object:Gem::Version
279
+ version: 2.5.0
280
+ required_rubygems_version: !ruby/object:Gem::Requirement
281
+ requirements:
282
+ - - ">"
283
+ - !ruby/object:Gem::Version
284
+ version: 1.3.1
285
+ requirements: []
286
+ rubygems_version: 3.2.19
287
+ signing_key:
288
+ specification_version: 4
289
+ summary: A tool for creating and managing a private rubygems mirror.
290
+ test_files: []