autoproj 2.0.0.rc3 → 2.0.0.rc4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +9 -29
  3. data/bin/autoproj_bootstrap +159 -3150
  4. data/bin/autoproj_bootstrap.in +4 -256
  5. data/bin/autoproj_install +225 -0
  6. data/bin/autoproj_install.in +14 -0
  7. data/lib/autoproj.rb +2 -1
  8. data/lib/autoproj/autobuild.rb +2 -2
  9. data/lib/autoproj/cli/bootstrap.rb +0 -39
  10. data/lib/autoproj/cli/build.rb +0 -3
  11. data/lib/autoproj/cli/main.rb +13 -1
  12. data/lib/autoproj/cli/osdeps.rb +1 -1
  13. data/lib/autoproj/cli/show.rb +1 -1
  14. data/lib/autoproj/cli/update.rb +4 -4
  15. data/lib/autoproj/cli/upgrade.rb +71 -0
  16. data/lib/autoproj/configuration.rb +18 -1
  17. data/lib/autoproj/exceptions.rb +7 -0
  18. data/lib/autoproj/installation_manifest.rb +23 -12
  19. data/lib/autoproj/manifest.rb +22 -48
  20. data/lib/autoproj/ops/build.rb +2 -2
  21. data/lib/autoproj/ops/configuration.rb +1 -1
  22. data/lib/autoproj/ops/import.rb +1 -1
  23. data/lib/autoproj/ops/install.rb +211 -0
  24. data/lib/autoproj/ops/main_config_switcher.rb +1 -5
  25. data/lib/autoproj/os_package_installer.rb +348 -0
  26. data/lib/autoproj/{osdeps.rb → os_package_resolver.rb} +56 -392
  27. data/lib/autoproj/package_managers/apt_dpkg_manager.rb +2 -2
  28. data/lib/autoproj/package_managers/bundler_manager.rb +179 -0
  29. data/lib/autoproj/package_managers/emerge_manager.rb +2 -2
  30. data/lib/autoproj/package_managers/gem_manager.rb +7 -6
  31. data/lib/autoproj/package_managers/homebrew_manager.rb +2 -2
  32. data/lib/autoproj/package_managers/manager.rb +5 -6
  33. data/lib/autoproj/package_managers/pacman_manager.rb +2 -2
  34. data/lib/autoproj/package_managers/pip_manager.rb +8 -8
  35. data/lib/autoproj/package_managers/pkg_manager.rb +2 -2
  36. data/lib/autoproj/package_managers/port_manager.rb +2 -2
  37. data/lib/autoproj/package_managers/shell_script_manager.rb +4 -4
  38. data/lib/autoproj/package_managers/unknown_os_manager.rb +2 -2
  39. data/lib/autoproj/package_managers/yum_manager.rb +2 -2
  40. data/lib/autoproj/package_managers/zypper_manager.rb +2 -2
  41. data/lib/autoproj/package_set.rb +10 -10
  42. data/lib/autoproj/reporter.rb +3 -2
  43. data/lib/autoproj/system.rb +1 -4
  44. data/lib/autoproj/version.rb +1 -1
  45. data/lib/autoproj/workspace.rb +155 -32
  46. metadata +9 -3
@@ -5,9 +5,9 @@ module PackageManagers
5
5
  class AptDpkgManager < ShellScriptManager
6
6
  attr_accessor :status_file
7
7
 
8
- def initialize(status_file = "/var/lib/dpkg/status")
8
+ def initialize(ws, status_file = "/var/lib/dpkg/status")
9
9
  @status_file = status_file
10
- super(['apt-dpkg'], true,
10
+ super(ws, true,
11
11
  "apt-get install '%s'",
12
12
  "export DEBIAN_FRONTEND=noninteractive; apt-get install -y '%s'")
13
13
  end
@@ -0,0 +1,179 @@
1
+ module Autoproj
2
+ module PackageManagers
3
+ # Package manager interface for the RubyGems system
4
+ class BundlerManager < Manager
5
+ class << self
6
+ attr_writer :with_prerelease
7
+ attr_accessor :with_doc
8
+ end
9
+ @with_prerelease = false
10
+ @with_doc = false
11
+
12
+ def self.with_prerelease(*value)
13
+ if value.empty?
14
+ @with_prerelease
15
+ else
16
+ begin
17
+ saved_flag = @with_prerelease
18
+ @with_prerelease = value.first
19
+ yield
20
+ ensure
21
+ @with_prerelease = saved_flag
22
+ end
23
+ end
24
+ end
25
+
26
+ # Filters all paths that come from other autoproj installations out
27
+ # of GEM_PATH
28
+ def initialize_environment
29
+ env = ws.env
30
+
31
+ env.original_env['GEM_PATH'] =
32
+ (env['GEM_PATH'] || "").split(File::PATH_SEPARATOR).find_all do |p|
33
+ !Workspace.in_autoproj_project?(p)
34
+ end.join(File::PATH_SEPARATOR)
35
+ env.inherit 'GEM_PATH'
36
+ env.init_from_env 'GEM_PATH'
37
+ orig_gem_path = env.original_env['GEM_PATH'].split(File::PATH_SEPARATOR)
38
+ env.system_env['GEM_PATH'] = Gem.default_path
39
+ env.original_env['GEM_PATH'] = orig_gem_path.join(File::PATH_SEPARATOR)
40
+
41
+ env.init_from_env 'RUBYLIB'
42
+ env.inherit 'RUBYLIB'
43
+ original_rubylib =
44
+ (env['RUBYLIB'] || "").split(File::PATH_SEPARATOR).find_all do |p|
45
+ !Workspace.in_autoproj_project?(p)
46
+ !p.start_with?(Bundler.rubygems.gem_dir) &&
47
+ !Bundler.rubygems.gem_path.any? { |gem_p| p.start_with?(p) }
48
+ end
49
+ system_rubylib = discover_rubylib
50
+ env.system_env['RUBYLIB'] = []
51
+ env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
52
+
53
+ dot_autoproj = ws.dot_autoproj_dir
54
+ if ws.config.private_bundler?
55
+ env.push_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
56
+ end
57
+ if ws.config.private_autoproj?
58
+ env.push_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
59
+ end
60
+
61
+ ws.manifest.each_reused_autoproj_installation do |p|
62
+ reused_w = ws.new(p)
63
+ reused_c = reused_w.load_config
64
+ if reused_c.private_gems?
65
+ env.push_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
66
+ end
67
+ env.push_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
68
+ end
69
+
70
+
71
+ gem_home = File.join(ws.prefix_dir, "gems")
72
+ if ws.config.private_gems?
73
+ env.set 'GEM_HOME', gem_home
74
+ env.push_path 'GEM_PATH', gem_home
75
+ end
76
+
77
+ FileUtils.mkdir_p gem_home
78
+ gemfile = File.join(gem_home, 'Gemfile')
79
+ if !File.exists?(gemfile)
80
+ File.open(gemfile, 'w') do |io|
81
+ io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
82
+ end
83
+ end
84
+
85
+ env.set 'BUNDLE_GEMFILE', File.join(gem_home, 'Gemfile')
86
+ env.push_path 'PATH', File.join(ws.dot_autoproj_dir, 'autoproj', 'bin')
87
+ env.push_path 'PATH', File.join(gem_home, 'bin')
88
+ Autobuild.programs['bundler'] = File.join(ws.dot_autoproj_dir, 'autoproj', 'bin', 'bundler')
89
+
90
+ update_env_rubylib(system_rubylib)
91
+ end
92
+
93
+ def update_env_rubylib(system_rubylib = discover_rubylib)
94
+ rubylib = discover_bundle_rubylib
95
+ current = ws.env.resolved_env['RUBYLIB'].split(File::PATH_SEPARATOR) + system_rubylib
96
+ (rubylib - current).each do |p|
97
+ ws.env.push_path('RUBYLIB', p)
98
+ end
99
+ end
100
+
101
+ def parse_package_entry(entry)
102
+ if entry =~ /^([^><=~]*)([><=~]+.*)$/
103
+ [$1.strip, $2.strip]
104
+ else
105
+ [entry]
106
+ end
107
+ end
108
+
109
+ def install(gems)
110
+ # Generate the gemfile
111
+ gems = gems.sort.map do |name|
112
+ name, version = parse_package_entry(name)
113
+ "gem \"#{name}\", \"#{version || ">= 0"}\""
114
+ end.join("\n")
115
+
116
+ root_dir = File.join(ws.prefix_dir, 'gems')
117
+ FileUtils.mkdir_p root_dir
118
+ gemfile = File.join(root_dir, 'Gemfile')
119
+ File.open(gemfile, 'w') do |io|
120
+ io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
121
+ io.puts gems
122
+ end
123
+
124
+ File.open(File.join(root_dir, 'Gemfile.lock'), 'w') do |io|
125
+ io.write File.read(File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile.lock'))
126
+ end
127
+
128
+ if ws.config.private_gems?
129
+ options = ['--path', root_dir]
130
+ end
131
+
132
+ Bundler.with_clean_env do
133
+ connections = Set.new
134
+ Autobuild::Subprocess.run 'autoproj', 'osdeps',
135
+ Autobuild.tool('bundler'), 'install',
136
+ "--gemfile=#{gemfile}", *options,
137
+ "--binstubs", File.join(root_dir, 'bin'),
138
+ env: Hash['BUNDLE_GEMFILE' => gemfile] do |line|
139
+
140
+ case line
141
+ when /Installing (.*)/
142
+ Autobuild.message " bundler: installing #{$1}"
143
+ when /Fetching.*from (.*)/
144
+ host = $1.gsub(/\.+$/, '')
145
+ if !connections.include?(host)
146
+ Autobuild.message " bundler: connected to #{host}"
147
+ connections << host
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ update_env_rubylib
154
+ end
155
+
156
+ def discover_rubylib
157
+ r, w = IO.pipe
158
+ Bundler.clean_system(
159
+ Hash['RUBYLIB' => nil],
160
+ Autobuild.tool('ruby'), '-e', 'puts $LOAD_PATH',
161
+ out: w)
162
+ w.close
163
+ r.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
164
+ end
165
+
166
+ def discover_bundle_rubylib
167
+ gemfile = File.join(ws.prefix_dir, 'gems', 'Gemfile')
168
+ r, w = IO.pipe
169
+ Bundler.clean_system(
170
+ Hash['BUNDLE_GEMFILE' => gemfile],
171
+ Autobuild.tool('bundler'), 'exec', 'ruby', '-e', 'puts $LOAD_PATH',
172
+ out: w)
173
+ w.close
174
+ r.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
175
+ end
176
+ end
177
+ end
178
+ end
179
+
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Package manager interface for systems that use emerge (i.e. gentoo) as
4
4
  # their package manager
5
5
  class EmergeManager < ShellScriptManager
6
- def initialize
7
- super(['emerge'], true,
6
+ def initialize(ws)
7
+ super(ws, true,
8
8
  "emerge '%s'",
9
9
  "emerge --noreplace '%s'")
10
10
  end
@@ -25,7 +25,8 @@ def self.with_prerelease(*value)
25
25
 
26
26
  # Filters all paths that come from other autoproj installations out
27
27
  # of GEM_PATH
28
- def self.initialize_environment(env = Autobuild.env, manifest = Autoproj.manifest, root_dir = Autoproj.root_dir)
28
+ def initialize_environment
29
+ env = ws.env
29
30
  env.original_env['GEM_PATH'] =
30
31
  (env['GEM_PATH'] || "").split(File::PATH_SEPARATOR).find_all do |p|
31
32
  !Autoproj.in_autoproj_installation?(p)
@@ -37,7 +38,7 @@ def self.initialize_environment(env = Autobuild.env, manifest = Autoproj.manifes
37
38
  env.system_env['GEM_PATH'] = Gem.default_path
38
39
  env.original_env['GEM_PATH'] = orig_gem_path.join(File::PATH_SEPARATOR)
39
40
 
40
- manifest.each_reused_autoproj_installation do |p|
41
+ ws.manifest.each_reused_autoproj_installation do |p|
41
42
  p_gems = File.join(p, '.gems')
42
43
  if File.directory?(p_gems)
43
44
  env.push_path 'GEM_PATH', p_gems
@@ -45,7 +46,7 @@ def self.initialize_environment(env = Autobuild.env, manifest = Autoproj.manifes
45
46
  end
46
47
  end
47
48
 
48
- @gem_home = (ENV['AUTOPROJ_GEM_HOME'] || File.join(root_dir, ".gems"))
49
+ @gem_home = (ENV['AUTOPROJ_GEM_HOME'] || File.join(ws.root_dir, ".gems"))
49
50
  env.push_path 'GEM_PATH', gem_home
50
51
  env.set 'GEM_HOME', gem_home
51
52
  env.push_path 'PATH', "#{gem_home}/bin"
@@ -99,8 +100,8 @@ def self.default_install_options
99
100
  @default_install_options ||= ['--no-user-install', '--no-format-executable']
100
101
  end
101
102
 
102
- def initialize
103
- super(['gem'])
103
+ def initialize(ws)
104
+ super(ws)
104
105
  @installed_gems = Set.new
105
106
  end
106
107
 
@@ -274,7 +275,7 @@ def parse_package_entry(entry)
274
275
  end
275
276
 
276
277
  def gems_interaction(gems, cmdlines)
277
- if OSDependencies.force_osdeps
278
+ if OSPackageInstaller.force_osdeps
278
279
  return true
279
280
  elsif enabled?
280
281
  return true
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Package manager interface for Mac OS using homebrew as
4
4
  # its package manager
5
5
  class HomebrewManager < ShellScriptManager
6
- def initialize
7
- super(['brew'], true,
6
+ def initialize(ws)
7
+ super(ws, true,
8
8
  "brew install '%s'",
9
9
  "brew install '%s'",
10
10
  false)
@@ -7,9 +7,8 @@ module PackageManagers
7
7
  # Package managers must be registered in PACKAGE_HANDLERS and
8
8
  # (if applicable) OS_PACKAGE_HANDLERS.
9
9
  class Manager
10
- # @return [Array<String>] the various names this package manager is
11
- # known about
12
- attr_reader :names
10
+ # @return [Workspace] the workspace
11
+ attr_reader :ws
13
12
 
14
13
  attr_writer :enabled
15
14
  def enabled?; !!@enabled end
@@ -22,8 +21,8 @@ def silent?; !!@silent end
22
21
  # @param [Array<String>] names the package manager names. It MUST be
23
22
  # different from the OS names that autoproj uses. See the comment
24
23
  # for OS_PACKAGE_HANDLERS for an explanation
25
- def initialize(names = [])
26
- @names = names.dup
24
+ def initialize(ws)
25
+ @ws = ws
27
26
  @enabled = true
28
27
  @silent = true
29
28
  end
@@ -37,7 +36,7 @@ def name
37
36
  # order to have a properly functioning package manager
38
37
  #
39
38
  # This is e.g. needed for python pip or rubygems
40
- def self.initialize_environment(_env = nil, _manifest = nil, _root_dir = Autoproj.root_dir)
39
+ def initialize_environment
41
40
  end
42
41
  end
43
42
  end
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Package manager interface for systems that use pacman (i.e. arch) as
4
4
  # their package manager
5
5
  class PacmanManager < ShellScriptManager
6
- def initialize
7
- super(['pacman'], true,
6
+ def initialize(ws)
7
+ super(ws, true,
8
8
  "pacman -Sy --needed '%s'",
9
9
  "pacman -Sy --needed --noconfirm '%s'")
10
10
  end
@@ -4,18 +4,18 @@ module PackageManagers
4
4
  class PipManager < Manager
5
5
  attr_reader :installed_pips
6
6
 
7
- def self.initialize_environment(env = Autobuild.env, _manifest = nil, root_dir = Autoproj.root_dir)
8
- env.set 'PYTHONUSERBASE', pip_home(env, root_dir)
7
+ def initialize_environment
8
+ ws.env.set 'PYTHONUSERBASE', pip_home
9
9
  end
10
10
 
11
11
  # Return the directory where python packages are installed to.
12
12
  # The actual path is pip_home/lib/pythonx.y/site-packages.
13
- def self.pip_home(env = Autobuild.env, root_dir = Autoproj.root_dir)
14
- env['AUTOPROJ_PYTHONUSERBASE'] || File.join(root_dir,".pip")
13
+ def pip_home
14
+ ws.env['AUTOPROJ_PYTHONUSERBASE'] || File.join(ws.prefix_dir, "pip")
15
15
  end
16
16
 
17
- def initialize
18
- super(['pip'])
17
+ def initialize(ws)
18
+ super(ws)
19
19
  @installed_pips = Set.new
20
20
  end
21
21
 
@@ -52,7 +52,7 @@ def install(pips)
52
52
  end
53
53
 
54
54
  def pips_interaction(pips, cmdlines)
55
- if OSDependencies.force_osdeps
55
+ if OSPackageInstaller.force_osdeps
56
56
  return true
57
57
  elsif enabled?
58
58
  return true
@@ -69,7 +69,7 @@ def pips_interaction(pips, cmdlines)
69
69
 
70
70
  #{cmdlines.map { |c| c.join(" ") }.join("\n ")}
71
71
 
72
- Autoproj expects these Python packages to be installed in #{PipManager.pip_home} This can
72
+ Autoproj expects these Python packages to be installed in #{pip_home} This can
73
73
  be overridden by setting the AUTOPROJ_PYTHONUSERBASE environment variable manually
74
74
 
75
75
  EOMSG
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Package manager interface for systems that use pkg (i.e. FreeBSD) as
4
4
  # their package manager
5
5
  class PkgManager < ShellScriptManager
6
- def initialize
7
- super(['pkg'], true,
6
+ def initialize(ws)
7
+ super(ws, true,
8
8
  "pkg install -y '%s'",
9
9
  "pkg install -y '%s'")
10
10
  end
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Package manager interface for systems that use port (i.e. MacPorts/Darwin) as
4
4
  # their package manager
5
5
  class PortManager < ShellScriptManager
6
- def initialize
7
- super(['macports'], true,
6
+ def initialize(ws)
7
+ super(ws, true,
8
8
  "port install '%s'",
9
9
  "port install '%s'")
10
10
  end
@@ -93,8 +93,8 @@ def needs_root?; !!@needs_root end
93
93
  # itself, see {#auto_install_cmd}.
94
94
  # @param [Boolean] needs_root if the command lines should be started
95
95
  # as root or not. See {#needs_root?}
96
- def initialize(names, needs_locking, user_install_cmd, auto_install_cmd,needs_root=true)
97
- super(names)
96
+ def initialize(ws, needs_locking, user_install_cmd, auto_install_cmd,needs_root=true)
97
+ super(ws)
98
98
  @needs_locking, @user_install_cmd, @auto_install_cmd,@needs_root =
99
99
  needs_locking, user_install_cmd, auto_install_cmd, needs_root
100
100
  end
@@ -139,7 +139,7 @@ def generate_auto_os_script(os_packages, options = Hash.new)
139
139
  # @return [Boolean] true if the packages should be installed
140
140
  # automatically, false otherwise
141
141
  def osdeps_interaction(os_packages, shell_script)
142
- if OSDependencies.force_osdeps
142
+ if OSPackageInstaller.force_osdeps
143
143
  return true
144
144
  elsif enabled?
145
145
  return true
@@ -184,7 +184,7 @@ def osdeps_interaction(os_packages, shell_script)
184
184
  # packages. See the option in {#generate_auto_os_script}
185
185
  # @return [Boolean] true if packages got installed, false otherwise
186
186
  def install(packages, options = Hash.new)
187
- handled_os = OSDependencies.supported_operating_system?
187
+ handled_os = OSPackageResolver.supported_operating_system?
188
188
  if handled_os
189
189
  shell_script = generate_auto_os_script(packages, options)
190
190
  user_shell_script = generate_user_os_script(packages, options)
@@ -3,8 +3,8 @@ module PackageManagers
3
3
  # Dummy package manager used for unknown OSes. It simply displays a
4
4
  # message to the user when packages are needed
5
5
  class UnknownOSManager < Manager
6
- def initialize
7
- super(['unknown'])
6
+ def initialize(ws)
7
+ super(ws)
8
8
  @installed_osdeps = Set.new
9
9
  end
10
10
 
@@ -2,8 +2,8 @@ module Autoproj
2
2
  module PackageManagers
3
3
  # Package manager interface for systems that use yum
4
4
  class YumManager < ShellScriptManager
5
- def initialize
6
- super(['yum'], true,
5
+ def initialize(ws)
6
+ super(ws, true,
7
7
  "yum install '%s'",
8
8
  "yum install -y '%s'")
9
9
  end
@@ -2,8 +2,8 @@ module Autoproj
2
2
  module PackageManagers
3
3
  #Package manger for OpenSuse and Suse (untested)
4
4
  class ZypperManager < ShellScriptManager
5
- def initialize
6
- super(['zypper'], true,
5
+ def initialize(ws)
6
+ super(ws, true,
7
7
  "zypper install '%s'",
8
8
  "zypper -n install '%s'")
9
9
  end
@@ -36,13 +36,13 @@ def add_source_file(name)
36
36
  # local? returns true.
37
37
  attr_accessor :vcs
38
38
 
39
- # The set of OSDependencies object that represent the osdeps files
39
+ # The set of OSPackageResolver object that represent the osdeps files
40
40
  # available in this package set
41
41
  attr_reader :all_osdeps
42
42
 
43
- # The OSDependencies which is a merged version of all OSdeps in
43
+ # The OSPackageResolver which is a merged version of all OSdeps in
44
44
  # #all_osdeps
45
- attr_reader :osdeps
45
+ attr_reader :os_package_resolver
46
46
 
47
47
  # If this package set has been imported from another package set, this
48
48
  # is the other package set object
@@ -90,7 +90,7 @@ def default_packages
90
90
  def initialize(manifest, vcs)
91
91
  @manifest = manifest
92
92
  @vcs = vcs
93
- @osdeps = OSDependencies.new
93
+ @os_package_resolver = OSPackageResolver.new
94
94
  @all_osdeps = []
95
95
  @overrides = Array.new
96
96
 
@@ -104,15 +104,15 @@ def initialize(manifest, vcs)
104
104
 
105
105
  # Load a new osdeps file for this package set
106
106
  def load_osdeps(file)
107
- new_osdeps = OSDependencies.load(file)
108
- @all_osdeps << new_osdeps
109
- @osdeps.merge(@all_osdeps.last)
107
+ new_osdeps = OSPackageResolver.load(file)
108
+ all_osdeps << new_osdeps
109
+ os_package_resolver.merge(all_osdeps.last)
110
110
  new_osdeps
111
111
  end
112
112
 
113
113
  # Enumerate all osdeps package names from this package set
114
114
  def each_osdep(&block)
115
- @osdeps.definitions.each_key(&block)
115
+ os_package_resolver.definitions.each_key(&block)
116
116
  end
117
117
 
118
118
  # True if this source has already been checked out on the local autoproj
@@ -222,7 +222,7 @@ def repository_id
222
222
  end
223
223
 
224
224
  # Remote sources can be accessed through a hidden directory in
225
- # $AUTOPROJ_ROOT/.remotes, or through a symbolic link in
225
+ # {Workspace#remotes_dir}, or through a symbolic link in
226
226
  # autoproj/remotes/
227
227
  #
228
228
  # This returns the former. See #user_local_dir for the latter.
@@ -233,7 +233,7 @@ def raw_local_dir
233
233
  end
234
234
 
235
235
  # Remote sources can be accessed through a hidden directory in
236
- # $AUTOPROJ_ROOT/.remotes, or through a symbolic link in
236
+ # {Workspace#remotes_dir}, or through a symbolic link in
237
237
  # autoproj/remotes/
238
238
  #
239
239
  # This returns the latter. See #raw_local_dir for the former.