gem-mirror 0.0.1

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,59 @@
1
+ module GemMirror
2
+ ##
3
+ # The MirrorDirectory is used for dealing with files and directories that are
4
+ # mirrored from an external source.
5
+ #
6
+ # @!attribute [r] path
7
+ # @return [String]
8
+ #
9
+ class MirrorDirectory
10
+ attr_reader :path
11
+
12
+ ##
13
+ # @param [String] path
14
+ #
15
+ def initialize(path)
16
+ @path = path
17
+ end
18
+
19
+ ##
20
+ # Creates a new directory with the given name.
21
+ #
22
+ # @param [String] name
23
+ # @return [GemMirror::MirrorDirectory]
24
+ #
25
+ def add_directory(name)
26
+ full_path = File.join(path, name)
27
+
28
+ Dir.mkdir(full_path) unless File.directory?(full_path)
29
+
30
+ return self.class.new(full_path)
31
+ end
32
+
33
+ ##
34
+ # Creates a new file with the given name and content.
35
+ #
36
+ # @param [String] name
37
+ # @param [String] content
38
+ # @return [Gem::MirrorFile]
39
+ #
40
+ def add_file(name, content)
41
+ full_path = File.join(path, name)
42
+ file = MirrorFile.new(full_path)
43
+
44
+ file.write(content)
45
+
46
+ return file
47
+ end
48
+
49
+ ##
50
+ # Checks if a given file exists in the current directory.
51
+ #
52
+ # @param [String] name
53
+ # @return [TrueClass|FalseClass]
54
+ #
55
+ def file_exists?(name)
56
+ return File.file?(File.join(path, name))
57
+ end
58
+ end # MirrorDirectory
59
+ end # GemMirror
@@ -0,0 +1,63 @@
1
+ module GemMirror
2
+ ##
3
+ # Similar to {GemMirror::MirrorDirectory} the MirrorFile class is used to
4
+ # make it easier to read and write data in a directory that mirrors data from
5
+ # an external source.
6
+ #
7
+ # @!attribute [r] path
8
+ # @return [String]
9
+ #
10
+ class MirrorFile
11
+ attr_reader :path
12
+
13
+ ##
14
+ # @param [String] path
15
+ #
16
+ def initialize(path)
17
+ @path = path
18
+ end
19
+
20
+ ##
21
+ # Writes the specified content to the current file. Existing files are
22
+ # overwritten.
23
+ #
24
+ # @param [String] content
25
+ #
26
+ def write(content)
27
+ handle = File.open(path, 'w')
28
+
29
+ handle.write(content)
30
+ handle.close
31
+ end
32
+
33
+ ##
34
+ # Reads the content of the current file.
35
+ #
36
+ # @return [String]
37
+ #
38
+ def read
39
+ handle = File.open(path, 'r')
40
+ content = handle.read
41
+
42
+ handle.close
43
+
44
+ return content
45
+ end
46
+
47
+ ##
48
+ # Reads the contents of a Gzip encoded file.
49
+ #
50
+ # @return [String]
51
+ #
52
+ def read_gzip
53
+ content = nil
54
+
55
+ Zlib::GzipReader.open(path) do |gz|
56
+ content = gz.read
57
+ gz.close
58
+ end
59
+
60
+ return content
61
+ end
62
+ end # MirrorFile
63
+ end # GemMirror
@@ -0,0 +1,106 @@
1
+ module GemMirror
2
+ ##
3
+ # The Source class is used for storing information about an external source
4
+ # such as the name and the Gems to mirror.
5
+ #
6
+ # @!attribute [r] name
7
+ # @return [String]
8
+ # @!attribute [r] host
9
+ # @return [String]
10
+ # @!attribute [r] gems
11
+ # @return [Array]
12
+ #
13
+ class Source
14
+ attr_reader :name, :host, :gems
15
+
16
+ ##
17
+ # @param [String] name
18
+ # @param [String] host
19
+ # @param [Array] gems
20
+ #
21
+ def initialize(name, host, gems = [])
22
+ @name = name.downcase.gsub(/\s+/, '_')
23
+ @host = host.chomp('/')
24
+ @gems = gems
25
+ end
26
+
27
+ ##
28
+ # Returns a new Source instance based on the current one.
29
+ #
30
+ # @param [Array] new_gems The gems to set, overwrites the current ones.
31
+ # @return [Source]
32
+ #
33
+ def updated(new_gems)
34
+ return self.class.new(name, host, new_gems)
35
+ end
36
+
37
+ ##
38
+ # Fetches a list of all the available Gems and their versions.
39
+ #
40
+ # @return [String]
41
+ #
42
+ def fetch_versions
43
+ return http_get(host + '/' + Configuration.versions_file).body
44
+ end
45
+
46
+ ##
47
+ # Fetches the Gem specification of a Gem.
48
+ #
49
+ # @param [String] name
50
+ # @param [String] version
51
+ # @return [String]
52
+ #
53
+ def fetch_specification(name, version)
54
+ url = host + "/quick/#{Configuration.marshal_identifier}" +
55
+ "/#{name}-#{version}.gemspec.rz"
56
+
57
+ return http_get(url).body
58
+ end
59
+
60
+ ##
61
+ # Fetches the `.gem` file of a given Gem and version.
62
+ #
63
+ # @param [String] name
64
+ # @param [String] version
65
+ # @return [String]
66
+ #
67
+ def fetch_gem(name, version)
68
+ return http_get(host + "/gems/#{name}-#{version}.gem").body
69
+ end
70
+
71
+ ##
72
+ # Adds a new Gem to the source.
73
+ #
74
+ # @param [String] name
75
+ # @param [String] requirement
76
+ #
77
+ def gem(name, requirement = nil)
78
+ gems << Gem.new(name, ::Gem::Requirement.new(requirement))
79
+ end
80
+
81
+ private
82
+
83
+ ##
84
+ # Requests the given HTTP resource.
85
+ #
86
+ # @param [String] url
87
+ # @return [HTTP::Message]
88
+ #
89
+ def http_get(url)
90
+ response = client.get(url, :follow_redirect => true)
91
+
92
+ unless HTTP::Status.successful?(response.status)
93
+ raise HTTPClient::BadResponseError, response.reason
94
+ end
95
+
96
+ return response
97
+ end
98
+
99
+ ##
100
+ # @return [HTTPClient]
101
+ #
102
+ def client
103
+ return @client ||= HTTPClient.new
104
+ end
105
+ end # Source
106
+ end # GemMirror
@@ -0,0 +1,3 @@
1
+ module GemMirror
2
+ VERSION = '0.0.1'
3
+ end # GemMirror
@@ -0,0 +1,30 @@
1
+ module GemMirror
2
+ ##
3
+ # The VersionsFetcher class is used for retrieving the file that contains all
4
+ # registered Gems and their versions.
5
+ #
6
+ # @!attribute [r] source
7
+ # @return [Source]
8
+ #
9
+ class VersionsFetcher
10
+ attr_reader :source
11
+
12
+ ##
13
+ # @param [Source] source
14
+ #
15
+ def initialize(source)
16
+ @source = source
17
+ end
18
+
19
+ ##
20
+ # @return [GemMirror::VersionsFile]
21
+ #
22
+ def fetch
23
+ GemMirror.configuration.logger.info(
24
+ "Updating #{source.name} (#{source.host})"
25
+ )
26
+
27
+ return VersionsFile.load(source.fetch_versions)
28
+ end
29
+ end # VersionsFetcher
30
+ end # GemMirror
@@ -0,0 +1,64 @@
1
+ module GemMirror
2
+ ##
3
+ # The VersionsFile class acts as a small Ruby wrapper around the RubyGems
4
+ # file that contains all Gems and their associated versions.
5
+ #
6
+ # @!attribute [r] versions
7
+ # @return [Array]
8
+ # @!attribute [r] versions_hash
9
+ # @return [Hash]
10
+ #
11
+ class VersionsFile
12
+ attr_reader :versions, :versions_hash
13
+
14
+ ##
15
+ # Reads the versions file from the specified String.
16
+ #
17
+ # @param [String] content
18
+ # @return [GemMirror::VersionsFile]
19
+ #
20
+ def self.load(content)
21
+ buffer = StringIO.new(content)
22
+ reader = Zlib::GzipReader.new(buffer)
23
+ instance = new(Marshal.load(reader.read))
24
+
25
+ reader.close
26
+
27
+ return instance
28
+ end
29
+
30
+ ##
31
+ # @param [Array] versions
32
+ #
33
+ def initialize(versions)
34
+ @versions = versions
35
+ @versions_hash = create_versions_hash
36
+ end
37
+
38
+ ##
39
+ # Creates a Hash based on the Array containing all versions. This Hash is
40
+ # used to more easily (and faster) iterate over all the gems/versions.
41
+ #
42
+ # @return [Hash]
43
+ #
44
+ def create_versions_hash
45
+ hash = Hash.new { |h, k| h[k] = [] }
46
+
47
+ versions.each do |version|
48
+ hash[version[0]] << version
49
+ end
50
+
51
+ return hash
52
+ end
53
+
54
+ ##
55
+ # Returns an Array containing all the available versions for a Gem.
56
+ #
57
+ # @param [String] gem
58
+ # @return [Array]
59
+ #
60
+ def versions_for(gem)
61
+ return versions_hash[gem].map { |version| version[1] }
62
+ end
63
+ end # VersionsFile
64
+ end # GemMirror
@@ -0,0 +1,8 @@
1
+ desc 'Generates the MANIFEST file'
2
+ task :manifest do
3
+ files = `git ls-files`.split("\n").sort
4
+ handle = File.open(File.expand_path('../../MANIFEST', __FILE__), 'w')
5
+
6
+ handle.write(files.join("\n"))
7
+ handle.close
8
+ end
@@ -0,0 +1,25 @@
1
+ # This is the main configuration file for your RubyGems mirror. Here you can
2
+ # change settings such as the location to store Gem files in and what sources
3
+ # and Gems you'd like to mirror.
4
+ GemMirror.configuration.configure do
5
+ # The directory to store indexing information as well as the Gem files in.
6
+ destination File.expand_path('../public', __FILE__)
7
+
8
+ # Directory to use for storing SHA512 checksums of each Gem.
9
+ checksums File.expand_path('../public/checksums', __FILE__)
10
+
11
+ # When set to `true` development dependencies of Gems will also be mirrored.
12
+ development false
13
+
14
+ # If you're mirroring a lot of Gems you'll probably want to switch the
15
+ # logging level to Logger::ERROR or Logger::INFO to reduce the amount of
16
+ # noise.
17
+ logger.level = Logger::DEBUG
18
+
19
+ # A source is a remote location that you want to mirror. The first parameter
20
+ # of this method is the human readable name, the second one the URL. The
21
+ # supplied block is used to determine what Gems (and versions) to mirror.
22
+ source 'rubygems', 'http://rubygems.org' do
23
+ gem 'rack', '>= 1.0.0'
24
+ end
25
+ end
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,174 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gem-mirror
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Yorick Peterse
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: slop
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: httpclient
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: builder
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: yard
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: redcarpet
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Gem for easily creating your own RubyGems mirror.
111
+ email: yorickpeterse@gmail.com
112
+ executables:
113
+ - gem-mirror
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - .yardopts
119
+ - Gemfile
120
+ - LICENSE
121
+ - MANIFEST
122
+ - README.md
123
+ - Rakefile
124
+ - bin/gem-mirror
125
+ - doc/.gitkeep
126
+ - doc/Contributing.md
127
+ - doc/DCO.md
128
+ - doc/css/.gitkeep
129
+ - doc/css/common.css
130
+ - gem-mirror.gemspec
131
+ - lib/gem-mirror.rb
132
+ - lib/gem-mirror/cli.rb
133
+ - lib/gem-mirror/cli/checksum.rb
134
+ - lib/gem-mirror/cli/index.rb
135
+ - lib/gem-mirror/cli/init.rb
136
+ - lib/gem-mirror/cli/update.rb
137
+ - lib/gem-mirror/configuration.rb
138
+ - lib/gem-mirror/gem.rb
139
+ - lib/gem-mirror/gems_fetcher.rb
140
+ - lib/gem-mirror/mirror_directory.rb
141
+ - lib/gem-mirror/mirror_file.rb
142
+ - lib/gem-mirror/source.rb
143
+ - lib/gem-mirror/version.rb
144
+ - lib/gem-mirror/versions_fetcher.rb
145
+ - lib/gem-mirror/versions_file.rb
146
+ - task/manifest.rake
147
+ - template/config.rb
148
+ - template/public/checksums/.gitkeep
149
+ - template/public/gems/.gitkeep
150
+ homepage: https://github.com/yorickpeterse/gem-mirror
151
+ licenses: []
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ none: false
158
+ requirements:
159
+ - - ! '>='
160
+ - !ruby/object:Gem::Version
161
+ version: 1.9.2
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ none: false
164
+ requirements:
165
+ - - ! '>='
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ requirements: []
169
+ rubyforge_project:
170
+ rubygems_version: 1.8.25
171
+ signing_key:
172
+ specification_version: 3
173
+ summary: Gem for easily creating your own RubyGems mirror.
174
+ test_files: []