gem_mirror 0.1.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG.md +7 -0
- data/LICENSE.txt +19 -0
- data/README.md +85 -0
- data/exe/gem_mirror +7 -0
- data/gem_mirror.gemspec +55 -0
- data/lib/gem_mirror.rb +31 -0
- data/lib/gem_mirror/cli.rb +67 -0
- data/lib/gem_mirror/cli/checksum.rb +43 -0
- data/lib/gem_mirror/cli/index.rb +31 -0
- data/lib/gem_mirror/cli/init.rb +23 -0
- data/lib/gem_mirror/cli/update.rb +25 -0
- data/lib/gem_mirror/configuration.rb +140 -0
- data/lib/gem_mirror/gem.rb +66 -0
- data/lib/gem_mirror/gems_fetcher.rb +254 -0
- data/lib/gem_mirror/mirror_directory.rb +61 -0
- data/lib/gem_mirror/mirror_file.rb +65 -0
- data/lib/gem_mirror/source.rb +106 -0
- data/lib/gem_mirror/version.rb +6 -0
- data/lib/gem_mirror/versions_fetcher.rb +32 -0
- data/lib/gem_mirror/versions_file.rb +66 -0
- data/template/config.rb +27 -0
- metadata +290 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9dc1e0fb7c8d5bee7140b693cb630b95b69f5e9ffb23fe31478759a311748c11
|
4
|
+
data.tar.gz: 909b09e6a4dab1184d83dde3004376491c5066ef54d9c8f55b036a90a7148c4c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 359b87727794e927bb4c9332dbae112bfe01e7bd578a99f574d4a0ad58d7a5749897d8975c7f8fff0637b8084806acd3390266191b0392d95c589bb12c4486a2
|
7
|
+
data.tar.gz: 376d68180e4fa30da16ae889952c43254be87e7d34ddefca526cad22085c6bdd5d72c8490072f528c23c5a85d8ec439068a0d5a97ea6d43f4ed2e19ad625916b
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2013, Yorick Peterse
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
of this software and associated documentation files (the "Software"), to deal
|
5
|
+
in the Software without restriction, including without limitation the rights
|
6
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
copies of the Software, and to permit persons to whom the Software is
|
8
|
+
furnished to do so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in
|
11
|
+
all copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Gem Mirror
|
2
|
+
|
3
|
+
gem_mirror is a Ruby application that makes it easy to create your own RubyGems
|
4
|
+
mirror without having to stitch together ugly Bash scripts or deal with more
|
5
|
+
complex tools such as [Geminabox][geminabox]. Unlike tools such as Geminabox
|
6
|
+
and others gem_mirror does mirroring only, it has no authentication and you
|
7
|
+
can't upload gems to it. I created this project to improve my knowledge of Ruby
|
8
|
+
and Ruby infrastructure.
|
9
|
+
|
10
|
+
It was forked from the now archived github project which has also moved
|
11
|
+
to gitlab [gem-mirror].
|
12
|
+
|
13
|
+
## Differences with Geminabox
|
14
|
+
|
15
|
+
Geminabox is basically a tiny DIY RubyGems that focuses more on uploading your
|
16
|
+
own gems (e.g. company specific ones) instead of mirroring an external source.
|
17
|
+
gem_mirror however purely focuses on generating a mirror that can be used by
|
18
|
+
the RubyGems CLI utility.
|
19
|
+
|
20
|
+
## Differences with gem-server
|
21
|
+
|
22
|
+
RubyGems comes with the command `gem-server` which can be used to serve the
|
23
|
+
Gems you have installed on that machine and user. Similar to Geminabox it does
|
24
|
+
not provide the means to actually mirror an external source. It's also Rack
|
25
|
+
based and uses WEBRick, which isn't exactly the best server around.
|
26
|
+
|
27
|
+
## How do I use it?
|
28
|
+
|
29
|
+
The process of setting up a mirror is fairly easy and can be done in a matter
|
30
|
+
of minutes depending on the number of gems you are mirroring and your internet
|
31
|
+
speed.
|
32
|
+
|
33
|
+
The first step is to set up a new, empty mirror. This is done by running the
|
34
|
+
`gem_mirror init` command similar to how you initialize a new Git repository:
|
35
|
+
|
36
|
+
$ gem_mirror init /srv/http/mirror.com/
|
37
|
+
|
38
|
+
Once created, you should edit the main configuration file named `config.rb`.
|
39
|
+
This configuration file specifies what sources to mirror (you can mirror
|
40
|
+
multiple ones!), which gems, etc.
|
41
|
+
|
42
|
+
Once configured you can pull all the gems by running the following command:
|
43
|
+
|
44
|
+
$ gem_mirror update
|
45
|
+
|
46
|
+
If your configuration file is not located in the current directory you can
|
47
|
+
specify the path to it using the `-c` or `--config` option. The process of
|
48
|
+
downloading all the Gems takes a while and can use quite a bit of memory so
|
49
|
+
make sure you have plenty of time and RAM available.
|
50
|
+
|
51
|
+
Once all the Gems have been downloaded you'll need to generate an index of all
|
52
|
+
the installed files. This can be done as following:
|
53
|
+
|
54
|
+
$ gem_mirror index
|
55
|
+
|
56
|
+
Last but not least you may want to generate a list of SHA512 checksums. Although
|
57
|
+
RubyGems doesn't use these they might come in handy when verifying Gems (e.g.
|
58
|
+
when RubyGems gets hacked again). This can be done using the following command:
|
59
|
+
|
60
|
+
$ gem_mirror checksum
|
61
|
+
|
62
|
+
If you want to do all this automatically (which is recommended) you can use a
|
63
|
+
simple Cronjob like the following one:
|
64
|
+
|
65
|
+
@hourly cd /srv/http/mirror.com && gem_mirror update && gem_mirror index
|
66
|
+
|
67
|
+
## Requirements
|
68
|
+
|
69
|
+
* Ruby 2.5.0 or newer
|
70
|
+
* Enough space to store Gems
|
71
|
+
|
72
|
+
## Installation
|
73
|
+
|
74
|
+
Assuming RubyGems isn't down you can install the Gem as following:
|
75
|
+
|
76
|
+
$ gem install gem_mirror
|
77
|
+
|
78
|
+
## License
|
79
|
+
|
80
|
+
All source code in this repository is licensed under the MIT license unless
|
81
|
+
specified otherwise. A copy of this license can be found in the file "LICENSE"
|
82
|
+
in the root directory of this repository.
|
83
|
+
|
84
|
+
[geminabox]: https://github.com/geminabox/geminabox
|
85
|
+
[gem-mirror]: https://gitlab.com/yorickpeterse/gem-mirror
|
data/exe/gem_mirror
ADDED
data/gem_mirror.gemspec
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/gem_mirror/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "gem_mirror"
|
7
|
+
s.version = GemMirror::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
10
|
+
s.authors = ["Yorick Peterse", "Patrick Callahan"]
|
11
|
+
s.description = <<~DESCRIPTION
|
12
|
+
gem-mirror is a tool for creating and managing a private
|
13
|
+
mirror of RubyGems. It is also suitable for hosting private
|
14
|
+
gems.
|
15
|
+
DESCRIPTION
|
16
|
+
|
17
|
+
s.email = ["pmc@patrickcallahan.com"]
|
18
|
+
s.files = Dir["{assets,config,lib,template}/**/*"] + ["gem_mirror.gemspec"]
|
19
|
+
s.files += %w[CHANGELOG.md LICENSE.txt README.md]
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.bindir = "exe"
|
22
|
+
s.executables = %w[gem_mirror]
|
23
|
+
s.extra_rdoc_files = %w[CHANGELOG.md LICENSE.txt README.md]
|
24
|
+
s.homepage = "https://github.com/dirtyharrycallahan/gem_mirror"
|
25
|
+
s.licenses = ["MIT"]
|
26
|
+
s.summary = %q{A tool for creating and managing a private rubygems mirror.}
|
27
|
+
|
28
|
+
s.rdoc_options += [
|
29
|
+
"--title", "gem_mirror - A Tool for Managing a Private Gem Repository",
|
30
|
+
"--main", "README.md",
|
31
|
+
"--line-numbers",
|
32
|
+
"--inline-source",
|
33
|
+
"--quiet"
|
34
|
+
]
|
35
|
+
s.metadata["allowed_push_host"] = "https://rubygems.org"
|
36
|
+
s.metadata["changelog_uri"] = "https://github.com/dirtyharrycallahan/gem_mirror/blob/master/CHANGELOG.md"
|
37
|
+
s.metadata["homepage_uri"] = s.homepage
|
38
|
+
s.metadata["source_code_uri"] = s.homepage
|
39
|
+
s.metadata["bug_tracker_uri"] = "https://github.com/dirtyharrycallahan/gem_mirror/issues"
|
40
|
+
|
41
|
+
s.add_runtime_dependency("confstruct", "~> 1.0", "< 2")
|
42
|
+
s.add_runtime_dependency("httpclient", "~> 2.8", "< 3")
|
43
|
+
s.add_runtime_dependency("slop", "= 3.6")
|
44
|
+
|
45
|
+
s.add_development_dependency("bundler", ">= 1.17.3", "< 3.0")
|
46
|
+
s.add_development_dependency("rake", ">= 13.0.0", "< 14")
|
47
|
+
s.add_development_dependency("rake-manifest", "~> 0.2.0")
|
48
|
+
s.add_development_dependency("redcarpet", "~> 3.5.0")
|
49
|
+
s.add_development_dependency("rspec", "~> 3.2")
|
50
|
+
s.add_development_dependency("rubocop", "= 1.16.0")
|
51
|
+
s.add_development_dependency("rubocop-performance", "= 1.11.3")
|
52
|
+
s.add_development_dependency("rubocop-rake", "= 0.5.1")
|
53
|
+
s.add_development_dependency("rubocop-rspec", "= 2.3.0")
|
54
|
+
s.add_development_dependency("yard", "~> 0.9.0")
|
55
|
+
end
|
data/lib/gem_mirror.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "rubygems/user_interaction"
|
5
|
+
require "rubygems/indexer"
|
6
|
+
require "fileutils"
|
7
|
+
require "digest/sha2"
|
8
|
+
require "confstruct"
|
9
|
+
require "slop"
|
10
|
+
require "zlib"
|
11
|
+
require "httpclient"
|
12
|
+
require "logger"
|
13
|
+
require "stringio"
|
14
|
+
|
15
|
+
$LOAD_PATH.unshift(File.expand_path(__dir__)) unless $LOAD_PATH.include?(File.expand_path(__dir__))
|
16
|
+
|
17
|
+
require_relative "gem_mirror/version"
|
18
|
+
require_relative "gem_mirror/configuration"
|
19
|
+
require_relative "gem_mirror/gem"
|
20
|
+
require_relative "gem_mirror/source"
|
21
|
+
require_relative "gem_mirror/mirror_directory"
|
22
|
+
require_relative "gem_mirror/mirror_file"
|
23
|
+
require_relative "gem_mirror/versions_file"
|
24
|
+
require_relative "gem_mirror/versions_fetcher"
|
25
|
+
require_relative "gem_mirror/gems_fetcher"
|
26
|
+
|
27
|
+
require_relative "gem_mirror/cli"
|
28
|
+
require_relative "gem_mirror/cli/checksum"
|
29
|
+
require_relative "gem_mirror/cli/index"
|
30
|
+
require_relative "gem_mirror/cli/init"
|
31
|
+
require_relative "gem_mirror/cli/update"
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Namespace for GemMirror
|
4
|
+
module GemMirror
|
5
|
+
# Namespace for classes and modules that handle the command line interface
|
6
|
+
module CLI
|
7
|
+
##
|
8
|
+
# Hash containing the default Slop options.
|
9
|
+
#
|
10
|
+
# @return [Hash]
|
11
|
+
#
|
12
|
+
SLOP_OPTIONS = {
|
13
|
+
strict: true,
|
14
|
+
banner: "Usage: gem_mirror [COMMAND] [OPTIONS]"
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
##
|
18
|
+
# @return [Slop]
|
19
|
+
#
|
20
|
+
def self.options
|
21
|
+
@options ||= default_options
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Loads the specified configuration file or displays an error if it doesn't
|
26
|
+
# exist.
|
27
|
+
#
|
28
|
+
# @param [String] config_file
|
29
|
+
# @return [GemMirror::Configuration]
|
30
|
+
#
|
31
|
+
def self.load_configuration(config_file)
|
32
|
+
config_file ||= Configuration.default_configuration_file
|
33
|
+
config_file = File.expand_path(config_file, Dir.pwd)
|
34
|
+
|
35
|
+
abort "The configuration file #{config_file} does not exist" unless File.file?(config_file)
|
36
|
+
|
37
|
+
require(config_file)
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# @return [Slop]
|
42
|
+
#
|
43
|
+
def self.default_options
|
44
|
+
Slop.new(SLOP_OPTIONS.dup) do
|
45
|
+
separator "\nOptions:\n"
|
46
|
+
|
47
|
+
on :h, :help, "Shows this help message" do
|
48
|
+
puts self
|
49
|
+
exit
|
50
|
+
end
|
51
|
+
|
52
|
+
on :v, :version, "Shows the current version" do
|
53
|
+
puts CLI.version_information
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
##
|
59
|
+
# Returns a String containing some platform/version related information.
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
#
|
63
|
+
def self.version_information
|
64
|
+
"gem_mirror v#{GemMirror::VERSION} on #{RUBY_DESCRIPTION}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
GemMirror::CLI.options.command "checksum" do
|
4
|
+
banner "Usage: gem_mirror checksum [OPTIONS]"
|
5
|
+
description "Generates SHA512 checksums of all gems"
|
6
|
+
separator "\nOptions:\n"
|
7
|
+
|
8
|
+
on :h, :help, "Shows this help message" do
|
9
|
+
puts self
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
on :c=, :config=, "Path to the configuration file"
|
14
|
+
|
15
|
+
run do |opts, _args|
|
16
|
+
GemMirror::CLI.load_configuration(opts[:c])
|
17
|
+
|
18
|
+
config = GemMirror.configuration
|
19
|
+
|
20
|
+
unless File.directory?(config.checksums)
|
21
|
+
config.logger("The directory #{config.checksums} does not exist")
|
22
|
+
abort
|
23
|
+
end
|
24
|
+
|
25
|
+
unless File.directory?(config.destination)
|
26
|
+
config.logger("The directory #{config.destination} does not exist")
|
27
|
+
abort
|
28
|
+
end
|
29
|
+
|
30
|
+
Dir[File.join(config.gems_directory, "*.gem")].each do |gem|
|
31
|
+
basename = File.basename(gem)
|
32
|
+
name = "#{basename}.sha512"
|
33
|
+
|
34
|
+
config.logger.info("Creating checksum for #{basename}")
|
35
|
+
|
36
|
+
hash = Digest::SHA512.hexdigest(File.read(gem))
|
37
|
+
handle = File.open(File.join(config.checksums, name), "w")
|
38
|
+
|
39
|
+
handle.write(hash)
|
40
|
+
handle.close
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
GemMirror::CLI.options.command "index" do
|
4
|
+
banner "Usage: gem_mirror index [OPTIONS]"
|
5
|
+
description "Indexes a list of Gems"
|
6
|
+
separator "\nOptions:\n"
|
7
|
+
|
8
|
+
on :h, :help, "Shows this help message" do
|
9
|
+
puts self
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
on :c=, :config=, "Path to the configuration file"
|
14
|
+
|
15
|
+
run do |opts, _args|
|
16
|
+
GemMirror::CLI.load_configuration(opts[:c])
|
17
|
+
|
18
|
+
config = GemMirror.configuration
|
19
|
+
|
20
|
+
unless File.directory?(config.destination)
|
21
|
+
config.logger.error("The directory #{config.destination} does not exist")
|
22
|
+
abort
|
23
|
+
end
|
24
|
+
|
25
|
+
indexer = Gem::Indexer.new(config.destination, build_legacy: opts[:l])
|
26
|
+
|
27
|
+
config.logger.info("Generating Indexes")
|
28
|
+
|
29
|
+
indexer.generate_index
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
GemMirror::CLI.options.command "init" do
|
4
|
+
banner "Usage: gem_mirror init [DIRECTORY] [OPTIONS]"
|
5
|
+
description "Sets up a new mirror"
|
6
|
+
separator "\nOptions:\n"
|
7
|
+
|
8
|
+
on :h, :help, "Shows this help message" do
|
9
|
+
puts self
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
run do |_opts, args|
|
14
|
+
directory = File.expand_path(args[0] || Dir.pwd)
|
15
|
+
template = GemMirror::Configuration.template_directory
|
16
|
+
|
17
|
+
Dir.mkdir(directory) unless File.directory?(directory)
|
18
|
+
|
19
|
+
FileUtils.cp_r(File.join(template, "."), directory)
|
20
|
+
|
21
|
+
puts "Initialized empty mirror in #{directory}"
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
GemMirror::CLI.options.command "update" do
|
4
|
+
banner "Usage: gem_mirror update [OPTIONS]"
|
5
|
+
description "Updates the list of Gems"
|
6
|
+
separator "\nOptions:\n"
|
7
|
+
|
8
|
+
on :h, :help, "Shows this help message" do
|
9
|
+
puts self
|
10
|
+
exit
|
11
|
+
end
|
12
|
+
|
13
|
+
on :c=, :config=, "Path to the configuration file"
|
14
|
+
|
15
|
+
run do |opts, _args|
|
16
|
+
GemMirror::CLI.load_configuration(opts[:c])
|
17
|
+
|
18
|
+
GemMirror.configuration.sources.each do |source|
|
19
|
+
versions = GemMirror::VersionsFetcher.new(source).fetch
|
20
|
+
gems = GemMirror::GemsFetcher.new(source, versions)
|
21
|
+
|
22
|
+
gems.fetch
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Namespace for GemMirror
|
4
|
+
module GemMirror
|
5
|
+
##
|
6
|
+
# @return [GemMirror::Configuration]
|
7
|
+
#
|
8
|
+
def self.configuration
|
9
|
+
@configuration ||= Configuration.new
|
10
|
+
end
|
11
|
+
|
12
|
+
##
|
13
|
+
# Configuration class used for storing data about a mirror such as the
|
14
|
+
# destination directory, sources, ignored Gems, etc.
|
15
|
+
#
|
16
|
+
class Configuration < Confstruct::Configuration
|
17
|
+
##
|
18
|
+
# @return [Logger]
|
19
|
+
#
|
20
|
+
def logger
|
21
|
+
@logger = Logger.new($stdout,
|
22
|
+
progname: "gem_mirror",
|
23
|
+
formatter: proc do |severity, datetime, progname, msg|
|
24
|
+
d_format = datetime.strftime("%Y%m%dT%H%M%S%z")
|
25
|
+
"[#{d_format}] severity=#{severity} prog=#{progname} pid=#{Process.pid} message=#{msg}\n"
|
26
|
+
end)
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# @return [String]
|
31
|
+
#
|
32
|
+
def self.template_directory
|
33
|
+
File.expand_path("../../template", __dir__)
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# @return [String]
|
38
|
+
#
|
39
|
+
def self.default_configuration_file
|
40
|
+
File.expand_path("config.rb", Dir.pwd)
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Returns the name of the directory that contains the quick
|
45
|
+
# specification files.
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
#
|
49
|
+
def self.marshal_identifier
|
50
|
+
"Marshal.#{marshal_version}"
|
51
|
+
end
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns the name of the file that contains an index of all the versions.
|
55
|
+
#
|
56
|
+
# @return [String]
|
57
|
+
#
|
58
|
+
def self.versions_file
|
59
|
+
"specs.#{marshal_version}.gz"
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Returns a String containing the Marshal version.
|
64
|
+
#
|
65
|
+
# @return [String]
|
66
|
+
#
|
67
|
+
def self.marshal_version
|
68
|
+
"#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# @return [GemMirror::MirrorDirectory]
|
73
|
+
#
|
74
|
+
def mirror_directory
|
75
|
+
@mirror_directory ||= MirrorDirectory.new(gems_directory)
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @return [String]
|
80
|
+
#
|
81
|
+
def gems_directory
|
82
|
+
File.join(destination, "gems")
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Returns a Hash containing various Gems to ignore and their versions.
|
87
|
+
#
|
88
|
+
# @return [Hash]
|
89
|
+
#
|
90
|
+
def ignored_gems
|
91
|
+
@ignored_gems ||= Hash.new { |hash, key| hash[key] = [] }
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Adds a Gem to the list of Gems to ignore.
|
96
|
+
#
|
97
|
+
# @param [String] name
|
98
|
+
# @param [String] version
|
99
|
+
#
|
100
|
+
def ignore_gem(name, version)
|
101
|
+
ignored_gems[name] ||= []
|
102
|
+
ignored_gems[name] << version
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Checks if a Gem should be ignored.
|
107
|
+
#
|
108
|
+
# @param [String] name
|
109
|
+
# @param [String] version
|
110
|
+
# @return [TrueClass|FalseClass]
|
111
|
+
#
|
112
|
+
def ignore_gem?(name, version)
|
113
|
+
ignored_gems[name].include?(version)
|
114
|
+
end
|
115
|
+
|
116
|
+
##
|
117
|
+
# Returns a list of sources to mirror.
|
118
|
+
#
|
119
|
+
# @return [Array]
|
120
|
+
#
|
121
|
+
def sources
|
122
|
+
@sources ||= []
|
123
|
+
end
|
124
|
+
|
125
|
+
##
|
126
|
+
# Adds a new source to mirror.
|
127
|
+
#
|
128
|
+
# @param [String] name
|
129
|
+
# @param [String] url
|
130
|
+
# @param [Proc] block
|
131
|
+
# @yieldparam [GemMirror::Source] source
|
132
|
+
#
|
133
|
+
def source(name, url, &block)
|
134
|
+
source = Source.new(name, url)
|
135
|
+
source.instance_eval(&block)
|
136
|
+
|
137
|
+
sources << source
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|