gemirro 0.0.1

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.

Files changed (48) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +24 -0
  4. data/.travis.yml +7 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +674 -0
  7. data/MANIFEST +46 -0
  8. data/README.md +60 -0
  9. data/Rakefile +10 -0
  10. data/bin/gemirro +6 -0
  11. data/gemirro.gemspec +31 -0
  12. data/lib/gemirro.rb +37 -0
  13. data/lib/gemirro/cli.rb +63 -0
  14. data/lib/gemirro/cli/index.rb +24 -0
  15. data/lib/gemirro/cli/init.rb +17 -0
  16. data/lib/gemirro/cli/server.rb +19 -0
  17. data/lib/gemirro/cli/update.rb +18 -0
  18. data/lib/gemirro/configuration.rb +137 -0
  19. data/lib/gemirro/gem.rb +70 -0
  20. data/lib/gemirro/gems_fetcher.rb +126 -0
  21. data/lib/gemirro/http.rb +37 -0
  22. data/lib/gemirro/indexer.rb +56 -0
  23. data/lib/gemirro/mirror_directory.rb +59 -0
  24. data/lib/gemirro/mirror_file.rb +48 -0
  25. data/lib/gemirro/server.rb +164 -0
  26. data/lib/gemirro/source.rb +58 -0
  27. data/lib/gemirro/version.rb +5 -0
  28. data/lib/gemirro/versions_fetcher.rb +31 -0
  29. data/lib/gemirro/versions_file.rb +65 -0
  30. data/spec/gemirro/cli_spec.rb +51 -0
  31. data/spec/gemirro/configuration_spec.rb +88 -0
  32. data/spec/gemirro/gem_spec.rb +37 -0
  33. data/spec/gemirro/gems_fetcher_spec.rb +104 -0
  34. data/spec/gemirro/http_spec.rb +36 -0
  35. data/spec/gemirro/indexer_spec.rb +55 -0
  36. data/spec/gemirro/mirror_directory_spec.rb +37 -0
  37. data/spec/gemirro/mirror_file_spec.rb +23 -0
  38. data/spec/gemirro/server_spec.rb +96 -0
  39. data/spec/gemirro/source_spec.rb +44 -0
  40. data/spec/gemirro/versions_fetcher_spec.rb +25 -0
  41. data/spec/gemirro/versions_file_spec.rb +52 -0
  42. data/spec/spec_helper.rb +17 -0
  43. data/task/manifest.rake +9 -0
  44. data/task/rspec.rake +6 -0
  45. data/task/rubocop.rake +5 -0
  46. data/template/config.rb +25 -0
  47. data/template/public/gems/.gitkeep +0 -0
  48. metadata +230 -0
data/MANIFEST ADDED
@@ -0,0 +1,46 @@
1
+ .gitignore
2
+ .rubocop.yml
3
+ .travis.yml
4
+ Gemfile
5
+ LICENSE
6
+ MANIFEST
7
+ README.md
8
+ Rakefile
9
+ bin/gemirro
10
+ gemirro.gemspec
11
+ lib/gemirro.rb
12
+ lib/gemirro/cli.rb
13
+ lib/gemirro/cli/index.rb
14
+ lib/gemirro/cli/init.rb
15
+ lib/gemirro/cli/server.rb
16
+ lib/gemirro/cli/update.rb
17
+ lib/gemirro/configuration.rb
18
+ lib/gemirro/gem.rb
19
+ lib/gemirro/gems_fetcher.rb
20
+ lib/gemirro/http.rb
21
+ lib/gemirro/indexer.rb
22
+ lib/gemirro/mirror_directory.rb
23
+ lib/gemirro/mirror_file.rb
24
+ lib/gemirro/server.rb
25
+ lib/gemirro/source.rb
26
+ lib/gemirro/version.rb
27
+ lib/gemirro/versions_fetcher.rb
28
+ lib/gemirro/versions_file.rb
29
+ spec/gemirro/cli_spec.rb
30
+ spec/gemirro/configuration_spec.rb
31
+ spec/gemirro/gem_spec.rb
32
+ spec/gemirro/gems_fetcher_spec.rb
33
+ spec/gemirro/http_spec.rb
34
+ spec/gemirro/indexer_spec.rb
35
+ spec/gemirro/mirror_directory_spec.rb
36
+ spec/gemirro/mirror_file_spec.rb
37
+ spec/gemirro/server_spec.rb
38
+ spec/gemirro/source_spec.rb
39
+ spec/gemirro/versions_fetcher_spec.rb
40
+ spec/gemirro/versions_file_spec.rb
41
+ spec/spec_helper.rb
42
+ task/manifest.rake
43
+ task/rspec.rake
44
+ task/rubocop.rake
45
+ template/config.rb
46
+ template/public/gems/.gitkeep
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # Gemirro | [![Build Status](https://travis-ci.org/PierreRambaud/gemirro.svg)](https://travis-ci.org/PierreRambaud/gemirro)
2
+
3
+ Gemirro is a Ruby application that makes it easy way to create your own RubyGems mirror without having to push or write all gem you wanted in a configuration file.
4
+ It does mirroring only, it has no authentication and you can't upload Gems to it.
5
+ More you only need to launch the server and gems will automaticly be downloaded when requests come.
6
+
7
+ ## Requirements
8
+
9
+ * Ruby 1.9.2 or newer
10
+ * Enough space to store Gems
11
+
12
+ ## Installation
13
+
14
+ Assuming RubyGems isn't down you can install the Gem as following:
15
+
16
+ ```bash
17
+ $ gem install gemirro
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ The process of setting up a mirror is fairly easy and can be done in few seconds.
23
+
24
+ The first step is to set up a new, empty mirror directory.
25
+ This is done by running the `gemirro init` command.
26
+
27
+ ```bash
28
+ $ gemirro init /srv/http/mirror.com/
29
+ ```
30
+
31
+ Once created you can edit the main configuration file called `config.rb`.
32
+ This configuration file specifies what source to mirror, destination directory, server host and port, etc.
33
+
34
+ Once configured and if you add gem in the `define_source`, you can pull them by running the following command:
35
+
36
+ ```bash
37
+ $ gemirro update
38
+ ```
39
+
40
+ Once all the Gems have been downloaded you'll need to generate an index of all the installed files. This can be done as following:
41
+
42
+ ```bash
43
+ $ gemirro index
44
+ ```
45
+
46
+
47
+ Last, launch the `TCPServer`, and all requests will check if gems are detected, and download them if necessary and generate index immediately.
48
+
49
+ ```bash
50
+ $ gemirro server
51
+ ```
52
+
53
+ If you want to use a custom configuration file not located in the current directory, use the `-c` or `--config` option.
54
+
55
+
56
+ ##Apache configuration
57
+ TODO
58
+
59
+ ##Nginx configuration
60
+ TODO
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'bundler/gem_tasks'
3
+
4
+ GEMSPEC = Gem::Specification.load('gemirro.gemspec')
5
+
6
+ Dir['./task/*.rake'].each do |task|
7
+ import(task)
8
+ end
9
+
10
+ task default: [:rubocop, :spec]
data/bin/gemirro ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- coding: utf-8 -*-
3
+
4
+ require File.expand_path('../../lib/gemirro', __FILE__)
5
+
6
+ Gemirro::CLI.options.parse
data/gemirro.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path('../lib/gemirro/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'gemirro'
6
+ s.version = Gemirro::VERSION
7
+ s.date = '2014-08-19'
8
+ s.authors = ['Pierre Rambaud']
9
+ s.email = 'pierre.rambaud86@gmail.com'
10
+ s.license = 'GPL-3.0'
11
+ s.summary = 'Gem for easily creating your own RubyGems mirror.'
12
+ s.homepage = 'https://github.com/PierreRambaud/gemirro'
13
+ s.description = 'Create your own gem mirro with a simple TCPServer.'
14
+ s.executables = ['gemirro']
15
+
16
+ s.files = File.read(File.expand_path('../MANIFEST', __FILE__)).split("\n")
17
+
18
+ s.required_ruby_version = '~> 1.9.2'
19
+
20
+ s.add_dependency 'slop', '~>3.6'
21
+ s.add_dependency 'httpclient', '~>2.4'
22
+ s.add_dependency 'confstruct', '~>0.2'
23
+ s.add_dependency 'builder', '~>3.2'
24
+
25
+ s.add_development_dependency 'mime-types', '~>2.3'
26
+ s.add_development_dependency 'rake', '~>10.0'
27
+ s.add_development_dependency 'rspec', '~>3.0'
28
+ s.add_development_dependency 'simplecov', '~>0.9'
29
+ s.add_development_dependency 'rubocop', '~>0.25'
30
+ s.add_development_dependency 'fakefs', '~>0.5'
31
+ end
data/lib/gemirro.rb ADDED
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'rubygems'
3
+ require 'rubygems/user_interaction'
4
+ require 'rubygems/indexer'
5
+ require 'slop'
6
+ require 'fileutils'
7
+ require 'digest/sha2'
8
+ require 'confstruct'
9
+ require 'zlib'
10
+ require 'httpclient'
11
+ require 'logger'
12
+ require 'stringio'
13
+ require 'socket'
14
+ require 'mime/types'
15
+
16
+ unless $LOAD_PATH.include?(File.expand_path('../', __FILE__))
17
+ $LOAD_PATH.unshift(File.expand_path('../', __FILE__))
18
+ end
19
+
20
+ require 'gemirro/version'
21
+ require 'gemirro/configuration'
22
+ require 'gemirro/gem'
23
+ require 'gemirro/http'
24
+ require 'gemirro/indexer'
25
+ require 'gemirro/server'
26
+ require 'gemirro/source'
27
+ require 'gemirro/mirror_directory'
28
+ require 'gemirro/mirror_file'
29
+ require 'gemirro/versions_file'
30
+ require 'gemirro/versions_fetcher'
31
+ require 'gemirro/gems_fetcher'
32
+
33
+ require 'gemirro/cli'
34
+ require 'gemirro/cli/init'
35
+ require 'gemirro/cli/update'
36
+ require 'gemirro/cli/index'
37
+ require 'gemirro/cli/server'
@@ -0,0 +1,63 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Gemirro
3
+ # CLI mode
4
+ module CLI
5
+ ##
6
+ # Hash containing the default Slop options.
7
+ #
8
+ # @return [Hash]
9
+ #
10
+ SLOP_OPTIONS = {
11
+ strict: true,
12
+ help: true,
13
+ banner: 'Usage: gemirro [COMMAND] [OPTIONS]'
14
+ }
15
+
16
+ ##
17
+ # @return [Slop]
18
+ #
19
+ def self.options
20
+ @options ||= default_options
21
+ end
22
+
23
+ ##
24
+ # Loads the specified configuration file or displays an error if it doesn't
25
+ # exist.
26
+ #
27
+ # @param [String] config_file
28
+ # @return [Gemirro::Configuration]
29
+ #
30
+ def self.load_configuration(config_file)
31
+ config_file ||= Configuration.default_configuration_file
32
+ config_file = File.expand_path(config_file, Dir.pwd)
33
+
34
+ unless File.file?(config_file)
35
+ abort "The configuration file #{config_file} does not exist"
36
+ end
37
+
38
+ require(config_file)
39
+ end
40
+
41
+ ##
42
+ # @return [Slop]
43
+ #
44
+ def self.default_options
45
+ Slop.new(SLOP_OPTIONS.dup) do
46
+ separator "\nOptions:\n"
47
+
48
+ on :v, :version, 'Shows the current version' do
49
+ puts CLI.version_information
50
+ end
51
+ end
52
+ end
53
+
54
+ ##
55
+ # Returns a String containing some platform/version related information.
56
+ #
57
+ # @return [String]
58
+ #
59
+ def self.version_information
60
+ "gemirro v#{VERSION} on #{RUBY_DESCRIPTION}"
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ Gemirro::CLI.options.command 'index' do
3
+ banner 'Usage: gemirro index [OPTIONS]'
4
+ description 'Retrieve specs list from source.'
5
+ separator "\nOptions:\n"
6
+
7
+ on :c=, :config=, 'Path to the configuration file'
8
+
9
+ run do |opts, _args|
10
+ Gemirro::CLI.load_configuration(opts[:c])
11
+ config = Gemirro.configuration
12
+
13
+ unless File.directory?(config.destination)
14
+ config.logger.error("The directory #{config.destination} does not exist")
15
+ abort
16
+ end
17
+
18
+ indexer = Gemirro::Indexer.new(config.destination)
19
+ indexer.ui = Gem::SilentUI.new
20
+
21
+ config.logger.info('Generating indexes')
22
+ indexer.generate_index
23
+ end
24
+ end
@@ -0,0 +1,17 @@
1
+ # -*- coding: utf-8 -*-
2
+ Gemirro::CLI.options.command 'init' do
3
+ banner 'Usage: gemirro init [DIRECTORY] [OPTIONS]'
4
+ description 'Sets up a new mirror'
5
+ separator "\nOptions:\n"
6
+
7
+ run do |_opts, args|
8
+ directory = File.expand_path(args[0] || Dir.pwd)
9
+ template = Gemirro::Configuration.template_directory
10
+
11
+ Dir.mkdir(directory) unless File.directory?(directory)
12
+
13
+ FileUtils.cp_r(File.join(template, '.'), directory)
14
+
15
+ puts "Initialized empty mirror in #{directory}"
16
+ end
17
+ end
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ Gemirro::CLI.options.command 'server' do
3
+ banner 'Usage: gemirro server [OPTIONS]'
4
+ description 'Run web server'
5
+ separator "\nOptions:\n"
6
+
7
+ on :c=, :config=, 'Path to the configuration file'
8
+
9
+ run do |opts, _args|
10
+ Gemirro::CLI.load_configuration(opts[:c])
11
+ config = Gemirro.configuration
12
+ unless File.directory?(config.destination)
13
+ config.logger.error("The directory #{config.destination} does not exist")
14
+ abort
15
+ end
16
+
17
+ Gemirro::Server.new.run
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ # -*- coding: utf-8 -*-
2
+ Gemirro::CLI.options.command 'update' do
3
+ banner 'Usage: gemirro update [OPTIONS]'
4
+ description 'Updates the list of Gems'
5
+ separator "\nOptions:\n"
6
+
7
+ on :c=, :config=, 'Path to the configuration file'
8
+
9
+ run do |opts, _args|
10
+ Gemirro::CLI.load_configuration(opts[:c])
11
+
12
+ source = Gemirro.configuration.source
13
+ versions = Gemirro::VersionsFetcher.new(source).fetch
14
+ gems = Gemirro::GemsFetcher.new(source, versions)
15
+
16
+ gems.fetch
17
+ end
18
+ end
@@ -0,0 +1,137 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Configuration
3
+ module Gemirro
4
+ ##
5
+ # @return [Gemirro::Configuration]
6
+ #
7
+ def self.configuration
8
+ @configuration ||= Configuration.new
9
+ end
10
+
11
+ ##
12
+ # Configuration class used for storing data about a mirror such as the
13
+ # destination directory, source, ignored Gems, etc.
14
+ #
15
+ class Configuration < Confstruct::Configuration
16
+ attr_reader :logger, :mirror_directory
17
+ attr_accessor :source, :ignored_gems
18
+
19
+ ##
20
+ # Returns the logger
21
+ #
22
+ # @return [Logger]
23
+ #
24
+ def logger
25
+ @logger ||= Logger.new(STDOUT)
26
+ end
27
+
28
+ ##
29
+ # Returns the template path to init directory
30
+ #
31
+ # @return [String]
32
+ #
33
+ def self.template_directory
34
+ File.expand_path('../../../template', __FILE__)
35
+ end
36
+
37
+ ##
38
+ # Returns default configuration file path
39
+ #
40
+ # @return [String]
41
+ #
42
+ def self.default_configuration_file
43
+ File.expand_path('config.rb', Dir.pwd)
44
+ end
45
+
46
+ ##
47
+ # Returns the name of the directory that contains the quick
48
+ # specification files.
49
+ #
50
+ # @return [String]
51
+ #
52
+ def self.marshal_identifier
53
+ "Marshal.#{marshal_version}"
54
+ end
55
+
56
+ ##
57
+ # Returns the name of the file that contains an index of all the versions.
58
+ #
59
+ # @return [String]
60
+ #
61
+ def self.versions_file
62
+ "specs.#{marshal_version}.gz"
63
+ end
64
+
65
+ ##
66
+ # Returns a String containing the Marshal version.
67
+ #
68
+ # @return [String]
69
+ #
70
+ def self.marshal_version
71
+ "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
72
+ end
73
+
74
+ ##
75
+ # Return mirror directory
76
+ #
77
+ # @return [Gemirro::MirrorDirectory]
78
+ #
79
+ def mirror_directory
80
+ @mirror_directory ||= MirrorDirectory.new(gems_directory)
81
+ end
82
+
83
+ ##
84
+ # Returns gems directory
85
+ #
86
+ # @return [String]
87
+ #
88
+ def gems_directory
89
+ File.join(destination, 'gems')
90
+ end
91
+
92
+ ##
93
+ # Returns a Hash containing various Gems to ignore and their versions.
94
+ #
95
+ # @return [Hash]
96
+ #
97
+ def ignored_gems
98
+ @ignored_gems ||= Hash.new { |hash, key| hash[key] = [] }
99
+ end
100
+
101
+ ##
102
+ # Adds a Gem to the list of Gems to ignore.
103
+ #
104
+ # @param [String] name
105
+ # @param [String] version
106
+ #
107
+ def ignore_gem(name, version)
108
+ ignored_gems[name] ||= []
109
+ ignored_gems[name] << version
110
+ end
111
+
112
+ ##
113
+ # Checks if a Gem should be ignored.
114
+ #
115
+ # @param [String] name
116
+ # @param [String] version
117
+ # @return [TrueClass|FalseClass]
118
+ #
119
+ def ignore_gem?(name, version)
120
+ ignored_gems[name].include?(version)
121
+ end
122
+
123
+ ##
124
+ # Define the source to mirror.
125
+ #
126
+ # @param [String] name
127
+ # @param [String] url
128
+ # @param [Proc] block
129
+ #
130
+ def define_source(name, url, &block)
131
+ source = Source.new(name, url)
132
+ source.instance_eval(&block)
133
+
134
+ @source = source
135
+ end
136
+ end
137
+ end