Class: Gemirro::GemsFetcher

Inherits:
Object
  • Object
show all
Defined in:
lib/gemirro/gems_fetcher.rb

Overview

The GemsFetcher class is responsible for downloading Gems from an external source.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, versions_file) ⇒ GemsFetcher

Returns a new instance of GemsFetcher.

Parameters:



19
20
21
22
# File 'lib/gemirro/gems_fetcher.rb', line 19

def initialize(source, versions_file)
  @source        = source
  @versions_file = versions_file
end

Instance Attribute Details

#sourceSource (readonly)

Returns:



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/gemirro/gems_fetcher.rb', line 12

class GemsFetcher
  attr_reader :source, :versions_file

  ##
  # @param [Source] source
  # @param [Gemirro::VersionsFile] versions_file
  #
  def initialize(source, versions_file)
    @source        = source
    @versions_file = versions_file
  end

  ##
  # Fetches the Gems.
  #
  def fetch
    @source.gems.each do |gem|
      versions_for(gem).each do |version|
        filename  = gem.filename(version)
        satisfied = gem.requirement.satisfied_by?(version)
        name      = gem.name

        if gem_exists?(filename) || ignore_gem?(name, version) || !satisfied
          logger.debug("Skipping #{filename}")
          next
        end

        configuration.ignore_gem(gem.name, version)
        logger.info("Fetching #{filename}")
        gemfile = fetch_gem(gem, version)
        configuration.mirror_directory.add_file(filename, gemfile) if gemfile
      end
    end
  end

  ##
  # Returns an Array containing the versions that should be fetched for a
  # Gem.
  #
  # @param [Gemirro::Gem] gem
  # @return [Array]
  #
  def versions_for(gem)
    available       = @versions_file.versions_for(gem.name)
    versions        = gem.version? ? [gem.version] : available
    available_names = available.map(&:to_s)

    # Get rid of invalid versions. Due to Gem::Version having a custom ==
    # method, which treats "3.4" the same as "3.4.0" we'll have to compare
    # the versions as String instances.
    versions = versions.select do |version|
      available_names.include?(version.to_s)
    end

    versions = [available.last] if versions.empty?

    versions
  end

  ##
  # Tries to download the Gemfile for the specified Gem and version.
  #
  # @param [Gemirro::Gem] gem
  # @param [Gem::Version] version
  # @return [String]
  #
  def fetch_gem(gem, version)
    data  = nil
    filename = gem.filename(version)

    begin
      data = @source.fetch_gem(gem.name, version)
    rescue => e
      logger.error("Failed to retrieve #{filename}: #{e.message}")
      logger.debug("Adding #{filename} to the list of ignored Gems")

      configuration.ignore_gem(gem.name, version)
    end

    data
  end

  ##
  # @see Gemirro::Configuration#logger
  # @return [Logger]
  #
  def logger
    configuration.logger
  end

  ##
  # @see Gemirro.configuration
  #
  def configuration
    Gemirro.configuration
  end

  ##
  # Checks if a given Gem has already been downloaded.
  #
  # @param [String] filename
  # @return [TrueClass|FalseClass]
  #
  def gem_exists?(filename)
    configuration.mirror_directory.file_exists?(filename)
  end

  ##
  # @see Gemirro::Configuration#ignore_gem?
  #
  def ignore_gem?(*args)
    configuration.ignore_gem?(*args)
  end
end

#versions_fileGemirro::VersionsFile (readonly)



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/gemirro/gems_fetcher.rb', line 12

class GemsFetcher
  attr_reader :source, :versions_file

  ##
  # @param [Source] source
  # @param [Gemirro::VersionsFile] versions_file
  #
  def initialize(source, versions_file)
    @source        = source
    @versions_file = versions_file
  end

  ##
  # Fetches the Gems.
  #
  def fetch
    @source.gems.each do |gem|
      versions_for(gem).each do |version|
        filename  = gem.filename(version)
        satisfied = gem.requirement.satisfied_by?(version)
        name      = gem.name

        if gem_exists?(filename) || ignore_gem?(name, version) || !satisfied
          logger.debug("Skipping #{filename}")
          next
        end

        configuration.ignore_gem(gem.name, version)
        logger.info("Fetching #{filename}")
        gemfile = fetch_gem(gem, version)
        configuration.mirror_directory.add_file(filename, gemfile) if gemfile
      end
    end
  end

  ##
  # Returns an Array containing the versions that should be fetched for a
  # Gem.
  #
  # @param [Gemirro::Gem] gem
  # @return [Array]
  #
  def versions_for(gem)
    available       = @versions_file.versions_for(gem.name)
    versions        = gem.version? ? [gem.version] : available
    available_names = available.map(&:to_s)

    # Get rid of invalid versions. Due to Gem::Version having a custom ==
    # method, which treats "3.4" the same as "3.4.0" we'll have to compare
    # the versions as String instances.
    versions = versions.select do |version|
      available_names.include?(version.to_s)
    end

    versions = [available.last] if versions.empty?

    versions
  end

  ##
  # Tries to download the Gemfile for the specified Gem and version.
  #
  # @param [Gemirro::Gem] gem
  # @param [Gem::Version] version
  # @return [String]
  #
  def fetch_gem(gem, version)
    data  = nil
    filename = gem.filename(version)

    begin
      data = @source.fetch_gem(gem.name, version)
    rescue => e
      logger.error("Failed to retrieve #{filename}: #{e.message}")
      logger.debug("Adding #{filename} to the list of ignored Gems")

      configuration.ignore_gem(gem.name, version)
    end

    data
  end

  ##
  # @see Gemirro::Configuration#logger
  # @return [Logger]
  #
  def logger
    configuration.logger
  end

  ##
  # @see Gemirro.configuration
  #
  def configuration
    Gemirro.configuration
  end

  ##
  # Checks if a given Gem has already been downloaded.
  #
  # @param [String] filename
  # @return [TrueClass|FalseClass]
  #
  def gem_exists?(filename)
    configuration.mirror_directory.file_exists?(filename)
  end

  ##
  # @see Gemirro::Configuration#ignore_gem?
  #
  def ignore_gem?(*args)
    configuration.ignore_gem?(*args)
  end
end

Instance Method Details

#configurationObject



105
106
107
# File 'lib/gemirro/gems_fetcher.rb', line 105

def configuration
  Gemirro.configuration
end

#fetchObject

Fetches the Gems.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/gemirro/gems_fetcher.rb', line 27

def fetch
  @source.gems.each do |gem|
    versions_for(gem).each do |version|
      filename  = gem.filename(version)
      satisfied = gem.requirement.satisfied_by?(version)
      name      = gem.name

      if gem_exists?(filename) || ignore_gem?(name, version) || !satisfied
        logger.debug("Skipping #{filename}")
        next
      end

      configuration.ignore_gem(gem.name, version)
      logger.info("Fetching #{filename}")
      gemfile = fetch_gem(gem, version)
      configuration.mirror_directory.add_file(filename, gemfile) if gemfile
    end
  end
end

#fetch_gem(gem, version) ⇒ String

Tries to download the Gemfile for the specified Gem and version.

Parameters:

Returns:

  • (String)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/gemirro/gems_fetcher.rb', line 78

def fetch_gem(gem, version)
  data  = nil
  filename = gem.filename(version)

  begin
    data = @source.fetch_gem(gem.name, version)
  rescue => e
    logger.error("Failed to retrieve #{filename}: #{e.message}")
    logger.debug("Adding #{filename} to the list of ignored Gems")

    configuration.ignore_gem(gem.name, version)
  end

  data
end

#gem_exists?(filename) ⇒ TrueClass|FalseClass

Checks if a given Gem has already been downloaded.

Parameters:

  • filename (String)

Returns:

  • (TrueClass|FalseClass)


115
116
117
# File 'lib/gemirro/gems_fetcher.rb', line 115

def gem_exists?(filename)
  configuration.mirror_directory.file_exists?(filename)
end

#ignore_gem?(*args) ⇒ Boolean

Returns:

  • (Boolean)

See Also:



122
123
124
# File 'lib/gemirro/gems_fetcher.rb', line 122

def ignore_gem?(*args)
  configuration.ignore_gem?(*args)
end

#loggerLogger

Returns:

  • (Logger)

See Also:



98
99
100
# File 'lib/gemirro/gems_fetcher.rb', line 98

def logger
  configuration.logger
end

#versions_for(gem) ⇒ Array

Returns an Array containing the versions that should be fetched for a Gem.

Parameters:

Returns:

  • (Array)


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/gemirro/gems_fetcher.rb', line 54

def versions_for(gem)
  available       = @versions_file.versions_for(gem.name)
  versions        = gem.version? ? [gem.version] : available
  available_names = available.map(&:to_s)

  # Get rid of invalid versions. Due to Gem::Version having a custom ==
  # method, which treats "3.4" the same as "3.4.0" we'll have to compare
  # the versions as String instances.
  versions = versions.select do |version|
    available_names.include?(version.to_s)
  end

  versions = [available.last] if versions.empty?

  versions
end