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
@@ -0,0 +1,58 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Gemirro
3
+ ##
4
+ # The Source class is used for storing information about an external source
5
+ # such as the name and the Gems to mirror.
6
+ #
7
+ # @!attribute [r] name
8
+ # @return [String]
9
+ # @!attribute [r] host
10
+ # @return [String]
11
+ # @!attribute [r] gems
12
+ # @return [Array]
13
+ #
14
+ class Source
15
+ attr_reader :name, :host, :gems
16
+
17
+ ##
18
+ # @param [String] name
19
+ # @param [String] host
20
+ # @param [Array] gems
21
+ #
22
+ def initialize(name, host, gems = [])
23
+ @name = name.downcase.gsub(/\s+/, '_')
24
+ @host = host.chomp('/')
25
+ @gems = gems
26
+ end
27
+
28
+ ##
29
+ # Fetches a list of all the available Gems and their versions.
30
+ #
31
+ # @return [String]
32
+ #
33
+ def fetch_versions
34
+ Http.get(host + '/' + Configuration.versions_file).body
35
+ end
36
+
37
+ ##
38
+ # Fetches the `.gem` file of a given Gem and version.
39
+ #
40
+ # @param [String] name
41
+ # @param [String] version
42
+ # @return [String]
43
+ #
44
+ def fetch_gem(name, version)
45
+ Http.get(host + "/gems/#{name}-#{version}.gem").body
46
+ end
47
+
48
+ ##
49
+ # Adds a new Gem to the source.
50
+ #
51
+ # @param [String] name
52
+ # @param [String] requirement
53
+ #
54
+ def gem(name, requirement = nil)
55
+ gems << Gem.new(name, requirement)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Gemirro Version
3
+ module Gemirro
4
+ VERSION = '0.0.1'
5
+ end
@@ -0,0 +1,31 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Gemirro
3
+ ##
4
+ # The VersionsFetcher class is used for retrieving the file that contains all
5
+ # registered Gems and their versions.
6
+ #
7
+ # @!attribute [r] source
8
+ # @return [Source]
9
+ #
10
+ class VersionsFetcher
11
+ attr_reader :source
12
+
13
+ ##
14
+ # @param [Source] source
15
+ #
16
+ def initialize(source)
17
+ @source = source
18
+ end
19
+
20
+ ##
21
+ # @return [Gemirro::VersionsFile]
22
+ #
23
+ def fetch
24
+ Gemirro.configuration.logger.info(
25
+ "Updating #{source.name} (#{source.host})"
26
+ )
27
+
28
+ VersionsFile.load(source.fetch_versions)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,65 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Gemirro
3
+ ##
4
+ # The VersionsFile class acts as a small Ruby wrapper around the RubyGems
5
+ # file that contains all Gems and their associated versions.
6
+ #
7
+ # @!attribute [r] versions
8
+ # @return [Array]
9
+ # @!attribute [r] versions_hash
10
+ # @return [Hash]
11
+ #
12
+ class VersionsFile
13
+ attr_reader :versions, :versions_hash
14
+
15
+ ##
16
+ # Reads the versions file from the specified String.
17
+ #
18
+ # @param [String] content
19
+ # @return [Gemirro::VersionsFile]
20
+ #
21
+ def self.load(content)
22
+ buffer = StringIO.new(content)
23
+ reader = Zlib::GzipReader.new(buffer)
24
+ instance = new(Marshal.load(reader.read))
25
+
26
+ reader.close
27
+
28
+ instance
29
+ end
30
+
31
+ ##
32
+ # @param [Array] versions
33
+ #
34
+ def initialize(versions)
35
+ @versions = versions
36
+ @versions_hash = create_versions_hash
37
+ end
38
+
39
+ ##
40
+ # Creates a Hash based on the Array containing all versions. This Hash is
41
+ # used to more easily (and faster) iterate over all the gems/versions.
42
+ #
43
+ # @return [Hash]
44
+ #
45
+ def create_versions_hash
46
+ hash = Hash.new { |h, k| h[k] = [] }
47
+
48
+ versions.each do |version|
49
+ hash[version[0]] << version
50
+ end
51
+
52
+ hash
53
+ end
54
+
55
+ ##
56
+ # Returns an Array containing all the available versions for a Gem.
57
+ #
58
+ # @param [String] gem
59
+ # @return [Array]
60
+ #
61
+ def versions_for(gem)
62
+ versions_hash[gem].map { |version| version[1] }
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'gemirro/cli'
4
+ require 'gemirro/mirror_file'
5
+ require 'slop'
6
+
7
+ # Gemirro tests
8
+ module Gemirro
9
+ # CLI tests
10
+ module CLI
11
+ describe 'CLI' do
12
+ include FakeFS::SpecHelpers
13
+
14
+ it 'should return options' do
15
+ options = CLI.options
16
+ expect(options).to be_a(::Slop)
17
+ expect(options.config[:strict]).to be_truthy
18
+ expect(options.config[:banner])
19
+ .to eq('Usage: gemirro [COMMAND] [OPTIONS]')
20
+ expect(options.to_s)
21
+ .to match(/-v, --version(\s+)Shows the current version/)
22
+ expect(options.to_s)
23
+ .to match(/-h, --help(\s+)Display this help message./)
24
+
25
+ version = options.fetch_option(:v)
26
+ expect(version.short).to eq('v')
27
+ expect(version.long).to eq('version')
28
+ expect(version.call).to be_nil
29
+ end
30
+
31
+ it 'should retrieve version information' do
32
+ expect(CLI.version_information).to eq(
33
+ "gemirro v#{VERSION} on #{RUBY_DESCRIPTION}"
34
+ )
35
+ end
36
+
37
+ it 'should raise SystemExit if file does not exists' do
38
+ CLI.should_receive(:abort)
39
+ .with('The configuration file /config.rb does not exist')
40
+ .and_raise SystemExit
41
+ expect { CLI.load_configuration('config.rb') }.to raise_error SystemExit
42
+ end
43
+
44
+ it 'should raise LoadError if content isn\'t ruby' do
45
+ file = MirrorFile.new('./config.rb')
46
+ file.write('test')
47
+ expect { CLI.load_configuration('config.rb') }.to raise_error LoadError
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,88 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'gemirro/mirror_directory'
4
+ require 'gemirro/configuration'
5
+ require 'gemirro/source'
6
+
7
+ # Configuration tests
8
+ module Gemirro
9
+ describe 'Configuration' do
10
+ include FakeFS::SpecHelpers
11
+
12
+ it 'should return configuration' do
13
+ expect(Gemirro.configuration).to be_a Configuration
14
+ end
15
+
16
+ it 'should return logger' do
17
+ expect(Gemirro.configuration.logger).to be_a Logger
18
+ end
19
+
20
+ it 'should return template directory' do
21
+ FakeFS::FileSystem.clone(
22
+ File.expand_path(
23
+ './',
24
+ Pathname.new(__FILE__).realpath
25
+ )
26
+ )
27
+ expect(Configuration.template_directory).to eq(
28
+ File.expand_path(
29
+ '../../../template',
30
+ Pathname.new(__FILE__).realpath
31
+ )
32
+ )
33
+ end
34
+
35
+ it 'should return default config file' do
36
+ expect(Configuration.default_configuration_file).to eq('/config.rb')
37
+ end
38
+
39
+ it 'should return marshal identifier' do
40
+ expect(Configuration.marshal_identifier).to match(/Marshal\.(\d+)\.(\d+)/)
41
+ end
42
+
43
+ it 'should return versions file' do
44
+ expect(Configuration.versions_file).to match(/specs\.(\d+)\.(\d+).gz/)
45
+ end
46
+
47
+ it 'should return marshal file' do
48
+ expect(Configuration.marshal_version).to eq(
49
+ "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
50
+ )
51
+ end
52
+ end
53
+
54
+ describe 'Configuration::instance' do
55
+ before(:each) do
56
+ @config = Configuration.new
57
+ end
58
+
59
+ it 'return mirror directory' do
60
+ @config.should_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')
63
+ end
64
+
65
+ it 'should return gems directory' do
66
+ @config.should_receive(:destination).once.and_return('/tmp')
67
+ expect(@config.gems_directory).to eq('/tmp/gems')
68
+ end
69
+
70
+ it 'should return ignored gems' do
71
+ expect(@config.ignored_gems).to eq(Hash.new)
72
+ expect(@config.ignore_gem?('rake', '1.0.0')).to be_falsy
73
+ expect(@config.ignore_gem('rake', '1.0.0')).to eq(['1.0.0'])
74
+ expect(@config.ignored_gems).to eq('rake' => ['1.0.0'])
75
+ expect(@config.ignore_gem?('rake', '1.0.0')).to be_truthy
76
+ end
77
+
78
+ it 'should add and return source' do
79
+ expect(@config.source).to eq(nil)
80
+ result = @config.define_source('RubyGems', 'https://rubygems.org') do
81
+ end
82
+ expect(result).to be_a(Source)
83
+ expect(result.gems).to eq([])
84
+ expect(result.host).to eq('https://rubygems.org')
85
+ expect(result.name).to eq('rubygems')
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,37 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'gemirro/gem'
4
+
5
+ # Gem tests
6
+ module Gemirro
7
+ describe 'Gem' do
8
+ before(:each) do
9
+ @gem = Gem.new('gemirro', '0.0.1')
10
+ end
11
+
12
+ it 'should be initialized with string' do
13
+ gem = Gem.new('gemirro', '0.0.1')
14
+ expect(gem.name).to eq('gemirro')
15
+ expect(gem.requirement).to eq(::Gem::Requirement.new(['= 0.0.1']))
16
+ end
17
+
18
+ it 'should be initialized with ::Gem::Requirement' do
19
+ requirement = ::Gem::Requirement.new('0.0.1')
20
+ gem = Gem.new('gemirro', requirement)
21
+ expect(gem.name).to eq('gemirro')
22
+ expect(gem.requirement).to be(requirement)
23
+ end
24
+
25
+ it 'should return version' do
26
+ expect(@gem.version).to eq(::Gem::Version.new('0.0.1'))
27
+ end
28
+
29
+ it 'should check version' do
30
+ expect(@gem.version?).to be_truthy
31
+ end
32
+
33
+ it 'should return gem filename' do
34
+ expect(@gem.filename).to eq('gemirro-0.0.1.gem')
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,104 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'spec_helper'
3
+ require 'gemirro/source'
4
+ require 'gemirro/gem'
5
+ require 'gemirro/versions_file'
6
+ require 'gemirro/mirror_file'
7
+ require 'gemirro/gems_fetcher'
8
+
9
+ # GemsFetcher tests
10
+ module Gemirro
11
+ describe 'GemsFetcher' do
12
+ include FakeFS::SpecHelpers
13
+
14
+ before(:each) do
15
+ @source = Source.new('RubyGems', 'https://rubygems.org')
16
+ @versions_file = VersionsFile.new(['0.0.1'])
17
+ @fetcher = GemsFetcher.new(@source, @versions_file)
18
+ end
19
+
20
+ it 'should be initialized' do
21
+ expect(@fetcher.source).to be(@source)
22
+ expect(@fetcher.versions_file).to be(@versions_file)
23
+ end
24
+
25
+ it 'should return configuration' do
26
+ expect(@fetcher.configuration).to be(Gemirro.configuration)
27
+ end
28
+
29
+ it 'should return logger' do
30
+ expect(@fetcher.logger).to be(Gemirro.configuration.logger)
31
+ end
32
+
33
+ it 'should test if gem exists' do
34
+ @fetcher.configuration.destination = './'
35
+ expect(@fetcher.gem_exists?('test')).to be_falsy
36
+ MirrorDirectory.new('./').add_directory('gems')
37
+ MirrorFile.new('gems/test').write('content')
38
+ expect(@fetcher.gem_exists?('test')).to be_truthy
39
+ end
40
+
41
+ it 'should ignore gem' do
42
+ expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_falsy
43
+ @fetcher.configuration.ignore_gem('gemirro', '0.0.1')
44
+ expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_truthy
45
+ end
46
+
47
+ it 'should log error when fetch gem failed' do
48
+ gem = Gem.new('gemirro')
49
+ version = ::Gem::Version.new('0.0.1')
50
+ @source.should_receive(:fetch_gem)
51
+ .once.with('gemirro', version).and_raise(ArgumentError)
52
+ @fetcher.logger.should_receive(:error)
53
+ .once.with(/Failed to retrieve/)
54
+ @fetcher.logger.should_receive(:debug)
55
+ .once.with(/Adding (.*) to the list of ignored Gems/)
56
+
57
+ expect(@fetcher.fetch_gem(gem, version)).to be_nil
58
+ expect(@fetcher.ignore_gem?('gemirro', '0.0.1')).to be_truthy
59
+ end
60
+
61
+ it 'should fetch gem' do
62
+ gem = Gem.new('gemirro')
63
+ version = ::Gem::Version.new('0.0.1')
64
+ @source.should_receive(:fetch_gem)
65
+ .once.with('gemirro', version).and_return('gemirro')
66
+
67
+ expect(@fetcher.fetch_gem(gem, version)).to eq('gemirro')
68
+ end
69
+
70
+ it 'should retrieve versions for specific gem' do
71
+ gem = Gem.new('gemirro', '0.0.2')
72
+ @versions_file.should_receive(:versions_for)
73
+ .once.with('gemirro').and_return(['0.0.1', '0.0.2'])
74
+ expect(@fetcher.versions_for(gem)).to eq([::Gem::Version.new('0.0.2')])
75
+ end
76
+
77
+ it 'should fetch all gems and log debug if gem is not satisfied' do
78
+ gem = Gem.new('gemirro', '0.0.1')
79
+ gem.requirement.should_receive(:satisfied_by?)
80
+ .once.with(nil).and_return(false)
81
+ @fetcher.source.gems << gem
82
+ @fetcher.logger.should_receive(:debug)
83
+ .once.with('Skipping gemirro-0.0.1.gem')
84
+ expect(@fetcher.fetch).to eq([gem])
85
+ end
86
+
87
+ it 'should fetch all gems' do
88
+ gem = Gem.new('gemirro', '0.0.2')
89
+ @fetcher.source.gems << gem
90
+ @fetcher.should_receive(:versions_for).once.and_return(['0.0.2'])
91
+ gem.requirement.should_receive(:satisfied_by?)
92
+ .once.with('0.0.2').and_return(true)
93
+ @fetcher.should_receive(:fetch_gem)
94
+ .once.with(gem, '0.0.2').and_return('gemfile')
95
+ @fetcher.configuration.should_receive(:ignore_gem)
96
+ .once.with('gemirro', '0.0.2')
97
+ @fetcher.logger.should_receive(:info)
98
+ .once.with('Fetching gemirro-0.0.2.gem')
99
+ @fetcher.configuration.mirror_directory.should_receive(:add_file)
100
+ .once.with('gemirro-0.0.2.gem', 'gemfile')
101
+ expect(@fetcher.fetch).to eq([gem])
102
+ end
103
+ end
104
+ end