summaryrefslogtreecommitdiff
path: root/lib/rdoc/ri/paths.rb
blob: a3c65bf928a1474224811c60b5aec6534b635f75 (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
require 'rdoc/ri'

##
# The directories where ri data lives.

module RDoc::RI::Paths

  #:stopdoc:
  require 'rbconfig'

  version = RbConfig::CONFIG['ruby_version']

  base    = if RbConfig::CONFIG.key? 'ridir' then
              File.join RbConfig::CONFIG['ridir'], version
            else
              File.join RbConfig::CONFIG['datadir'], 'ri', version
            end

  SYSDIR  = File.join base, "system"
  SITEDIR = File.join base, "site"

  homedir = begin
              File.expand_path('~')
            rescue ArgumentError
            end

  homedir ||= ENV['HOME'] ||
              ENV['USERPROFILE'] || ENV['HOMEPATH'] # for 1.8 compatibility

  HOMEDIR = if homedir then
              File.join homedir, ".rdoc"
            end
  #:startdoc:

  @gemdirs = nil

  ##
  # Iterates over each selected path yielding the directory and type.
  #
  # Yielded types:
  # :system:: Where Ruby's ri data is stored.  Yielded when +system+ is
  #           true
  # :site:: Where ri for installed libraries are stored.  Yielded when
  #         +site+ is true.  Normally no ri data is stored here.
  # :home:: ~/.rdoc.  Yielded when +home+ is true.
  # :gem:: ri data for an installed gem.  Yielded when +gems+ is true.
  # :extra:: ri data directory from the command line.  Yielded for each
  #          entry in +extra_dirs+

  def self.each system, site, home, gems, *extra_dirs # :yields: directory, type
    extra_dirs.each do |dir|
      yield dir, :extra
    end

    yield SYSDIR,  :system if system
    yield SITEDIR, :site   if site
    yield HOMEDIR, :home   if home and HOMEDIR

    gemdirs.each do |dir|
      yield dir, :gem
    end if gems

    nil
  end

  ##
  # The latest installed gems' ri directories

  def self.gemdirs
    return @gemdirs if @gemdirs

    require 'rubygems' unless defined?(Gem)

    # HACK dup'd from Gem.latest_partials and friends
    all_paths = []

    all_paths = Gem.path.map do |dir|
      Dir[File.join(dir, 'doc', '*', 'ri')]
    end.flatten

    ri_paths = {}

    all_paths.each do |dir|
      base = File.basename File.dirname(dir)
      if base =~ /(.*)-((\d+\.)*\d+)/ then
        name, version = $1, $2
        ver = Gem::Version.new version
        if ri_paths[name].nil? or ver > ri_paths[name][0] then
          ri_paths[name] = [ver, dir]
        end
      end
    end

    @gemdirs = ri_paths.map { |k,v| v.last }.sort
  rescue LoadError
    @gemdirs = []
  end

  ##
  # Returns existing directories from the selected documentation directories
  # as an Array.
  #
  # See also ::each

  def self.path(system, site, home, gems, *extra_dirs)
    path = raw_path system, site, home, gems, *extra_dirs

    path.select { |directory| File.directory? directory }
  end

  ##
  # Returns selected documentation directories including nonexistent
  # directories.
  #
  # See also ::each

  def self.raw_path(system, site, home, gems, *extra_dirs)
    path = []

    each(system, site, home, gems, *extra_dirs) do |dir, type|
      path << dir
    end

    path.compact
  end

end