aboutsummaryrefslogtreecommitdiffstats
path: root/lib/rubygems/basic_specification.rb
blob: 2e47f32986e4ed2b5d8365528887ab5115e5b986 (plain)
1
2
3
4
5
6
7
8
9
10
11
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
module Gem
  # BasicSpecification is an abstract class which implements some common code used by
  # both Specification and StubSpecification.
  class BasicSpecification
    def self.default_specifications_dir
      File.join(Gem.default_dir, "specifications", "default")
    end

    ##
    # Name of the gem

    def name
      raise NotImplementedError
    end

    ##
    # Version of the gem

    def version
      raise NotImplementedError
    end

    ##
    # Platform of the gem

    def platform
      raise NotImplementedError
    end

    ##
    # Require paths of the gem

    def require_paths
      raise NotImplementedError
    end

    ##
    # True when the gem has been activated

    def activated?
      raise NotImplementedError
    end

    ##
    # Return a Gem::Specification from this gem

    def to_spec
      raise NotImplementedError
    end

    ##
    # The filename of the gem specification
    attr_reader :filename

    ##
    # Set the filename of the Specification was loaded from. +path+ is converted
    # to a String.

    def filename= path
      @filename      = path && path.to_s

      @full_gem_path = nil
      @gems_dir      = nil
      @base_dir      = nil
    end

    ##
    # Return true if this spec can require +file+.

    def contains_requirable_file? file
      root     = full_gem_path
      suffixes = Gem.suffixes

      require_paths.any? do |lib|
        base = "#{root}/#{lib}/#{file}"
        suffixes.any? { |suf| File.file? "#{base}#{suf}" }
      end
    end

    ##
    # The full path to the gem (install path + full name).

    def full_gem_path
      # TODO: This is a heavily used method by gems, so we'll need
      # to aleast just alias it to #gem_dir rather than remove it.
      @full_gem_path ||= find_full_gem_path
    end

    # :nodoc:
    def find_full_gem_path
      # TODO: also, shouldn't it default to full_name if it hasn't been written?
      path = File.expand_path File.join(gems_dir, full_name)
      path.untaint
      path if File.directory? path
    end
    private :find_full_gem_path

    ##
    # Returns the full path to the gems directory containing this spec's
    # gem directory. eg: /usr/local/lib/ruby/1.8/gems

    def gems_dir
      # TODO: this logic seems terribly broken, but tests fail if just base_dir
      @gems_dir ||= File.join(filename && base_dir || Gem.dir, "gems")
    end

    ##
    # Returns the full path to the base gem directory.
    #
    # eg: /usr/local/lib/ruby/gems/1.8

    def base_dir
      return Gem.dir unless filename
      @base_dir ||= if default_gem? then
                      File.dirname File.dirname File.dirname filename
                    else
                      File.dirname File.dirname filename
                    end
    end

    def default_gem?
      filename &&
        File.dirname(filename) == self.class.default_specifications_dir
    end

    ##
    # Returns the full name (name-version) of this Gem.  Platform information
    # is included (name-version-platform) if it is specified and not the
    # default Ruby platform.

    def full_name
      if platform == Gem::Platform::RUBY or platform.nil? then
        "#{name}-#{version}".untaint
      else
        "#{name}-#{version}-#{platform}".untaint
      end
    end
  end
end