Class: Rails::VendorGemSourceIndex

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rails/vendor_gem_source_index.rb

Constant Summary collapse

@@silence_spec_warnings =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(installed_index, vendor_dir = Rails::GemDependency.unpacked_path) ⇒ VendorGemSourceIndex

Returns a new instance of VendorGemSourceIndex.



26
27
28
29
30
# File 'lib/rails/vendor_gem_source_index.rb', line 26

def initialize(installed_index, vendor_dir=Rails::GemDependency.unpacked_path)
  @installed_source_index = installed_index
  @vendor_dir = vendor_dir
  refresh!
end

Instance Attribute Details

#installed_source_indexObject (readonly)

Returns the value of attribute installed_source_index.



13
14
15
# File 'lib/rails/vendor_gem_source_index.rb', line 13

def installed_source_index
  @installed_source_index
end

#vendor_source_indexObject (readonly)

Returns the value of attribute vendor_source_index.



14
15
16
# File 'lib/rails/vendor_gem_source_index.rb', line 14

def vendor_source_index
  @vendor_source_index
end

Class Method Details

.silence_spec_warningsObject



18
19
20
# File 'lib/rails/vendor_gem_source_index.rb', line 18

def self.silence_spec_warnings
  @@silence_spec_warnings
end

.silence_spec_warnings=(v) ⇒ Object



22
23
24
# File 'lib/rails/vendor_gem_source_index.rb', line 22

def self.silence_spec_warnings=(v)
  @@silence_spec_warnings = v
end

Instance Method Details

#add_spec(spec) ⇒ Object



127
128
129
# File 'lib/rails/vendor_gem_source_index.rb', line 127

def add_spec(spec)
  @vendor_source_index.add_spec spec
end

#each(&block) ⇒ Object



122
123
124
125
# File 'lib/rails/vendor_gem_source_index.rb', line 122

def each(&block)
  @vendor_source_index.each(&block)
  @installed_source_index.each(&block)
end

#find_name(*args) ⇒ Object



113
114
115
# File 'lib/rails/vendor_gem_source_index.rb', line 113

def find_name(*args)
  @installed_source_index.find_name(*args) + @vendor_source_index.find_name(*args)
end

#load_specification(gem_dir) ⇒ Object



108
109
110
111
# File 'lib/rails/vendor_gem_source_index.rb', line 108

def load_specification(gem_dir)
  spec_file = File.join(gem_dir, '.specification')
  YAML.load_file(spec_file) if File.exist?(spec_file)
end

#refresh!Object



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
# File 'lib/rails/vendor_gem_source_index.rb', line 32

def refresh!
  # reload the installed gems
  # HACK: I don't think this is needed: @installed_source_index.refresh!
  vendor_gems = {}

  # handle vendor Rails gems - they are identified by having loaded_from set to ""
  # we add them manually to the list, so that other gems can find them via dependencies
  Gem.loaded_specs.each do |n, s|
    next unless s.loaded_from.to_s.empty?
    vendor_gems[s.full_name] = s
  end

  # load specifications from vendor/gems
  Dir[File.join(Rails::GemDependency.unpacked_path, '*')].each do |d|
    dir_name = File.basename(d)
    dir_version = version_for_dir(dir_name)
    spec = load_specification(d)
    if spec
      if spec.full_name != dir_name
        # mismatched directory name and gem spec - produced by 2.1.0-era unpack code
        if dir_version
          # fix the spec version - this is not optimal (spec.files may be wrong)
          # but it's better than breaking apps. Complain to remind users to get correct specs.
          # use ActiveSupport::Deprecation.warn, as the logger is not set yet
          $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has a mismatched specification file."+
                       " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
          spec.version = dir_version
        else
          $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems is not in a versioned directory"+
                       "(should be #{spec.full_name}).") unless @@silence_spec_warnings
          # continue, assume everything is OK
        end
      end
    else
      # no spec - produced by early-2008 unpack code
      # emulate old behavior, and complain.
      $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems has no specification file."+
                   " Run 'rake gems:refresh_specs' to fix this.") unless @@silence_spec_warnings
      if dir_version
        spec = Gem::Specification.new
        spec.version = dir_version
        spec.require_paths = ['lib']
        ext_path = File.join(d, 'ext')
        spec.require_paths << 'ext' if File.exist?(ext_path)
        spec.name = /^(.*)-[^-]+$/.match(dir_name)[1]
        files = ['lib']
        # set files to everything in lib/
        files += Dir[File.join(d, 'lib', '*')].map { |v| v.gsub(/^#{d}\//, '') }
        files += Dir[File.join(d, 'ext', '*')].map { |v| v.gsub(/^#{d}\//, '') } if ext_path
        spec.files = files
      else
        $stderr.puts("config.gem: Unpacked gem #{dir_name} in vendor/gems not in a versioned directory."+
                     " Giving up.") unless @@silence_spec_warnings
        next
      end
    end
    spec.loaded_from = File.join(d, '.specification')
    # finally, swap out full_gem_path
    # it would be better to use a Gem::Specification subclass, but the YAML loads an explicit class
    class << spec
      def full_gem_path
        path = File.join installation_path, full_name
        return path if File.directory? path
        File.join installation_path, original_name
      end
    end
    vendor_gems[File.basename(d)] = spec
  end
  @vendor_source_index = Gem::SourceIndex.new(vendor_gems)
end

#remove_spec(spec) ⇒ Object



131
132
133
# File 'lib/rails/vendor_gem_source_index.rb', line 131

def remove_spec(spec)
  @vendor_source_index.remove_spec spec
end

#search(*args) ⇒ Object



117
118
119
120
# File 'lib/rails/vendor_gem_source_index.rb', line 117

def search(*args)
  # look for vendor gems, and then installed gems - later elements take priority
  @installed_source_index.search(*args) + @vendor_source_index.search(*args)
end

#sizeObject



135
136
137
# File 'lib/rails/vendor_gem_source_index.rb', line 135

def size
  @vendor_source_index.size + @installed_source_index.size
end

#version_for_dir(d) ⇒ Object



103
104
105
106
# File 'lib/rails/vendor_gem_source_index.rb', line 103

def version_for_dir(d)
  version = d.split('-').find { |s| s.match(/^\d(\.\d|\.\w+)*$/) }
  Gem::Version.new(version)
end