autoproj 2.0.0.rc4 → 2.0.0.rc5

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.
@@ -317,7 +317,11 @@ def install(packages, options = Hash.new)
317
317
 
318
318
  packages = os_package_resolver.resolve_os_packages(packages)
319
319
  packages = packages.map do |handler_name, list|
320
- [package_managers[handler_name], list]
320
+ if manager = package_managers[handler_name]
321
+ [package_managers[handler_name], list]
322
+ else
323
+ raise ArgumentError, "no package manager called #{handler_name} found"
324
+ end
321
325
  end
322
326
 
323
327
  needs_filter = (filter_uptodate_packages? || filter_options[:install_only])
@@ -122,6 +122,12 @@ def load_default
122
122
  # information in +definitions+ originates. It is a mapping from the
123
123
  # package name to the osdeps file' full path
124
124
  attr_reader :sources
125
+ # Controls whether the package resolver will prefer installing
126
+ # OS-independent packages (such as e.g. Gems) over their OS-provided
127
+ # equivalent (e.g. the packaged version of a gem)
128
+ def prefer_indep_over_os_packages?; !!@prefer_indep_over_os_packages end
129
+ # (see prefer_indep_over_os_packages?)
130
+ def prefer_indep_over_os_packages=(flag); @prefer_indep_over_os_packages = flag end
125
131
 
126
132
  # Use to override the autodetected OS-specific package handler
127
133
  attr_writer :os_package_manager
@@ -144,15 +150,15 @@ def os_package_manager
144
150
  # Returns the set of known package managers
145
151
  #
146
152
  # @return [Array<String>]
147
- def package_managers
148
- PACKAGE_MANAGERS
149
- end
153
+ attr_reader :package_managers
150
154
 
151
155
  # The Gem::SpecFetcher object that should be used to query RubyGems, and
152
156
  # install RubyGems packages
153
157
  def initialize(defs = Hash.new, file = nil)
154
158
  @definitions = defs.to_hash
155
159
  @all_definitions = Hash.new { |h, k| h[k] = Array.new }
160
+ @package_managers = PACKAGE_MANAGERS.dup
161
+ @prefer_indep_over_os_packages = false
156
162
 
157
163
  @sources = Hash.new
158
164
  @installed_packages = Set.new
@@ -200,7 +206,7 @@ def merge(info)
200
206
  osdep_h
201
207
  end
202
208
  if old_resolved != new_resolved
203
- Autoproj.warn("osdeps definition for #{h}, previously defined in #{old} overridden by #{new}")
209
+ Autoproj.warn("osdeps definition for #{h}, previously defined in #{old} overridden by #{new}: resp. #{old_resolved} and #{new_resolved}")
204
210
  end
205
211
  end
206
212
  v2
@@ -491,7 +497,11 @@ def resolve_package(name)
491
497
 
492
498
  os_names, os_versions = self.class.operating_system
493
499
  os_names = os_names.dup
494
- os_names << 'default'
500
+ if prefer_indep_over_os_packages?
501
+ os_names.unshift 'default'
502
+ else
503
+ os_names.push 'default'
504
+ end
495
505
 
496
506
  dep_def = definitions[name]
497
507
  if !dep_def
@@ -28,16 +28,18 @@ def self.with_prerelease(*value)
28
28
  def initialize_environment
29
29
  env = ws.env
30
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
31
  env.inherit 'GEM_PATH'
36
32
  env.init_from_env 'GEM_PATH'
37
- orig_gem_path = env.original_env['GEM_PATH'].split(File::PATH_SEPARATOR)
33
+ orig_gem_path = (env['GEM_PATH'] || "").split(File::PATH_SEPARATOR).find_all do |p|
34
+ !Workspace.in_autoproj_project?(p)
35
+ end
38
36
  env.system_env['GEM_PATH'] = Gem.default_path
39
37
  env.original_env['GEM_PATH'] = orig_gem_path.join(File::PATH_SEPARATOR)
40
38
 
39
+ if Workspace.in_autoproj_project?(env['GEM_HOME'])
40
+ env.unset('GEM_HOME')
41
+ end
42
+
41
43
  env.init_from_env 'RUBYLIB'
42
44
  env.inherit 'RUBYLIB'
43
45
  original_rubylib =
@@ -46,32 +48,33 @@ def initialize_environment
46
48
  !p.start_with?(Bundler.rubygems.gem_dir) &&
47
49
  !Bundler.rubygems.gem_path.any? { |gem_p| p.start_with?(p) }
48
50
  end
49
- system_rubylib = discover_rubylib
50
- env.system_env['RUBYLIB'] = []
51
- env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
51
+ if system_rubylib = discover_rubylib
52
+ env.system_env['RUBYLIB'] = []
53
+ env.original_env['RUBYLIB'] = (original_rubylib - system_rubylib).join(File::PATH_SEPARATOR)
54
+ end
52
55
 
53
56
  dot_autoproj = ws.dot_autoproj_dir
54
57
  if ws.config.private_bundler?
55
- env.push_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
58
+ env.add_path 'GEM_PATH', File.join(dot_autoproj, 'bundler')
56
59
  end
57
60
  if ws.config.private_autoproj?
58
- env.push_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
61
+ env.add_path 'GEM_PATH', File.join(dot_autoproj, 'autoproj')
59
62
  end
60
63
 
61
64
  ws.manifest.each_reused_autoproj_installation do |p|
62
65
  reused_w = ws.new(p)
63
66
  reused_c = reused_w.load_config
64
67
  if reused_c.private_gems?
65
- env.push_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
68
+ env.add_path 'GEM_PATH', File.join(reused_w.prefix_dir, 'gems')
66
69
  end
67
- env.push_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
70
+ env.add_path 'PATH', File.join(reused_w.prefix_dir, 'gems', 'bin')
68
71
  end
69
72
 
70
73
 
71
74
  gem_home = File.join(ws.prefix_dir, "gems")
72
75
  if ws.config.private_gems?
73
76
  env.set 'GEM_HOME', gem_home
74
- env.push_path 'GEM_PATH', gem_home
77
+ env.add_path 'GEM_PATH', gem_home
75
78
  end
76
79
 
77
80
  FileUtils.mkdir_p gem_home
@@ -83,18 +86,19 @@ def initialize_environment
83
86
  end
84
87
 
85
88
  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')
89
+ env.add_path 'PATH', File.join(gem_home, 'bin')
90
+ env.add_path 'PATH', File.join(ws.dot_autoproj_dir, 'autoproj', 'bin')
88
91
  Autobuild.programs['bundler'] = File.join(ws.dot_autoproj_dir, 'autoproj', 'bin', 'bundler')
89
92
 
90
- update_env_rubylib(system_rubylib)
93
+ if bundle_rubylib = discover_bundle_rubylib
94
+ update_env_rubylib(bundle_rubylib, system_rubylib)
95
+ end
91
96
  end
92
97
 
93
- def update_env_rubylib(system_rubylib = discover_rubylib)
94
- rubylib = discover_bundle_rubylib
98
+ def update_env_rubylib(bundle_rubylib, system_rubylib = discover_rubylib)
95
99
  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)
100
+ (bundle_rubylib - current).each do |p|
101
+ ws.env.add_path('RUBYLIB', p)
98
102
  end
99
103
  end
100
104
 
@@ -106,24 +110,56 @@ def parse_package_entry(entry)
106
110
  end
107
111
  end
108
112
 
113
+ class NotCleanState < RuntimeError; end
114
+
115
+ def backup_files(mapping)
116
+ mapping.each do |file, backup_file|
117
+ if File.file?(file)
118
+ FileUtils.cp file, backup_file
119
+ end
120
+ end
121
+ end
122
+
123
+ def backup_restore(mapping)
124
+ mapping.each do |file, backup_file|
125
+ if File.file?(backup_file)
126
+ FileUtils.cp backup_file, file
127
+ end
128
+ end
129
+ end
130
+
131
+ def backup_clean(mapping)
132
+ mapping.each do |file, backup_file|
133
+ if File.file?(backup_file)
134
+ FileUtils.rm backup_file
135
+ end
136
+ end
137
+ end
138
+
109
139
  def install(gems)
110
- # Generate the gemfile
140
+ root_dir = File.join(ws.prefix_dir, 'gems')
141
+ gemfile_path = File.join(root_dir, 'Gemfile')
142
+ gemfile_lock_path = "#{gemfile_path}.lock"
143
+ backups = Hash[
144
+ gemfile_path => "#{gemfile_path}.orig",
145
+ gemfile_lock_path => "#{gemfile_lock_path}.orig"
146
+ ]
147
+
148
+ # Back up the existing gemfile, we'll restore it if something is
149
+ # wrong to avoid leaving bundler in an inconsistent state
150
+ backup_files(backups)
151
+
152
+ # Generate the gemfile and remove the lockfile
111
153
  gems = gems.sort.map do |name|
112
154
  name, version = parse_package_entry(name)
113
155
  "gem \"#{name}\", \"#{version || ">= 0"}\""
114
156
  end.join("\n")
115
-
116
- root_dir = File.join(ws.prefix_dir, 'gems')
117
157
  FileUtils.mkdir_p root_dir
118
- gemfile = File.join(root_dir, 'Gemfile')
119
- File.open(gemfile, 'w') do |io|
158
+ File.open(gemfile_path, 'w') do |io|
120
159
  io.puts "eval_gemfile \"#{File.join(ws.dot_autoproj_dir, 'autoproj', 'Gemfile')}\""
121
160
  io.puts gems
122
161
  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
162
+ FileUtils.rm File.join(root_dir, 'Gemfile.lock')
127
163
 
128
164
  if ws.config.private_gems?
129
165
  options = ['--path', root_dir]
@@ -133,9 +169,9 @@ def install(gems)
133
169
  connections = Set.new
134
170
  Autobuild::Subprocess.run 'autoproj', 'osdeps',
135
171
  Autobuild.tool('bundler'), 'install',
136
- "--gemfile=#{gemfile}", *options,
172
+ "--gemfile=#{gemfile_path}", *options,
137
173
  "--binstubs", File.join(root_dir, 'bin'),
138
- env: Hash['BUNDLE_GEMFILE' => gemfile] do |line|
174
+ env: Hash['BUNDLE_GEMFILE' => gemfile_path] do |line|
139
175
 
140
176
  case line
141
177
  when /Installing (.*)/
@@ -150,28 +186,44 @@ def install(gems)
150
186
  end
151
187
  end
152
188
 
153
- update_env_rubylib
189
+ if bundle_rubylib = discover_bundle_rubylib
190
+ update_env_rubylib(bundle_rubylib)
191
+ else
192
+ raise NotCleanState, "bundler executed successfully, but the result is not in a clean state"
193
+ end
194
+
195
+ rescue Exception => e
196
+ backup_restore(backups)
197
+ raise
198
+ ensure
199
+ backup_clean(backups)
154
200
  end
155
201
 
156
202
  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? }
203
+ Tempfile.open 'autoproj-rubylib' do |io|
204
+ result = Bundler.clean_system(
205
+ Hash['RUBYLIB' => nil],
206
+ Autobuild.tool('ruby'), '-e', 'puts $LOAD_PATH',
207
+ out: io)
208
+ #err: '/dev/null')
209
+ if result
210
+ io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
211
+ end
212
+ end
164
213
  end
165
214
 
166
215
  def discover_bundle_rubylib
167
216
  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? }
217
+ Tempfile.open 'autoproj-rubylib' do |io|
218
+ result = Bundler.clean_system(
219
+ Hash['BUNDLE_GEMFILE' => gemfile],
220
+ Autobuild.tool('bundler'), 'exec', 'ruby', '-e', 'puts $LOAD_PATH',
221
+ out: io)
222
+ #err: '/dev/null')
223
+ if result
224
+ io.readlines.map { |l| l.chomp }.find_all { |l| !l.empty? }
225
+ end
226
+ end
175
227
  end
176
228
  end
177
229
  end
@@ -571,8 +571,9 @@ def provides?(name)
571
571
 
572
572
  # Specialization of the PackageSet class for the overrides listed in autoproj/
573
573
  class LocalPackageSet < PackageSet
574
- def initialize(manifest)
574
+ def initialize(manifest, local_dir = nil)
575
575
  super(manifest, manifest.vcs)
576
+ @local_dir = local_dir
576
577
  end
577
578
 
578
579
  def name
@@ -592,14 +593,10 @@ def local?
592
593
  end
593
594
 
594
595
  def local_dir
595
- if manifest.file
596
- File.dirname(manifest.file)
597
- end
596
+ @local_dir || (File.dirname(manifest.file) if manifest.file)
598
597
  end
599
598
 
600
- def raw_local_dir
601
- local_dir
602
- end
599
+ def raw_local_dir; local_dir end
603
600
 
604
601
  def manifest_path
605
602
  manifest.file
@@ -58,6 +58,8 @@ def self.report(options = Hash.new)
58
58
  silent: false,
59
59
  debug: Autobuild.debug
60
60
 
61
+ reporter = Autoproj::Reporter.new
62
+ Autobuild::Reporting << reporter
61
63
  Autobuild::Reporting.report do
62
64
  yield
63
65
  end
@@ -86,6 +88,8 @@ def self.report(options = Hash.new)
86
88
  if options[:debug] then raise
87
89
  else exit 1
88
90
  end
91
+ ensure
92
+ Autobuild::Reporting.remove(reporter) if reporter
89
93
  end
90
94
  end
91
95
 
@@ -11,7 +11,7 @@ def self.create_symlink(from, to)
11
11
 
12
12
  # Returns true if +path+ is part of an autoproj installation
13
13
  def self.in_autoproj_installation?(path)
14
- !!Workspace.find_workspace_dir(path, 'workspace')
14
+ !!find_workspace_dir(path, 'workspace')
15
15
  end
16
16
 
17
17
  # Forcefully sets the root directory
@@ -33,7 +33,7 @@ def self.root_dir(dir = Dir.pwd)
33
33
  if @root_dir
34
34
  return @root_dir
35
35
  end
36
- path = Workspace.find_root_dir(dir)
36
+ path = Autoproj.find_workspace_dir(dir)
37
37
  if !path
38
38
  raise UserError, "not in a Autoproj installation"
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module Autoproj
2
- VERSION = "2.0.0.rc4"
2
+ VERSION = "2.0.0.rc5"
3
3
  end
@@ -19,10 +19,7 @@ def initialize(root_dir)
19
19
  env.source_before(File.join(dot_autoproj_dir, 'env.sh'))
20
20
  @manifest = Manifest.new
21
21
  @os_package_installer = OSPackageInstaller.new(self, os_package_resolver)
22
-
23
- Autobuild.env = nil
24
22
  env.prepare(root_dir)
25
-
26
23
  super(root_dir)
27
24
  end
28
25
 
@@ -53,21 +50,25 @@ def self.from_pwd
53
50
  # and the one from +dir+ mismatch
54
51
  # @raise [NotWorkspace] if dir is not within an autoproj workspace
55
52
  def self.from_dir(dir)
56
- if path = find_workspace_dir(dir)
53
+ if path = Autoproj.find_workspace_dir(dir)
57
54
  # Make sure that the currently loaded env.sh is actually us
58
55
  env = autoproj_current_root
59
56
  if env && env != path
60
57
  raise MismatchingWorkspace, "the current environment is for #{env}, but you are in #{path}, make sure you are loading the right #{ENV_FILENAME} script !"
61
58
  end
62
59
  Workspace.new(path)
60
+ elsif find_v1_workspace_dir(dir)
61
+ raise OutdatedWorkspace, "#{dir} looks like a v1 workspace, run autoproj upgrade before continuing"
63
62
  else
64
63
  raise NotWorkspace, "not in a Autoproj installation"
65
64
  end
66
65
  end
67
66
 
68
67
  def self.from_environment
69
- if path = (find_workspace_dir || autoproj_current_root)
68
+ if path = Autoproj.find_workspace_dir
70
69
  from_dir(path)
70
+ elsif Autoproj.find_v1_workspace_dir(dir = Autoproj.defaulT_find_base_dir)
71
+ raise OutdatedWorkspace, "#{dir} looks like a v1 workspace, run autoproj upgrade before continuing"
71
72
  else
72
73
  raise NotWorkspace, "not in an Autoproj installation, and no env.sh has been loaded so far"
73
74
  end
@@ -76,64 +77,7 @@ def self.from_environment
76
77
  # Tests whether the given path is under a directory tree managed by
77
78
  # autoproj
78
79
  def self.in_autoproj_project?(path)
79
- !!find_workspace_dir(path)
80
- end
81
-
82
- # @private
83
- #
84
- # Finds an autoproj "root directory" that contains a given directory. It
85
- # can either be the root of a workspace or the root of an install
86
- # directory
87
- #
88
- # @param [String] base_dir the start of the search
89
- # @param [String] config_field_name the name of a field in the root's
90
- # configuration file, that should be returned instead of the root
91
- # itself
92
- # @return [String,nil] the root of the workspace directory, or nil if
93
- # there's none
94
- def self.find_root_dir(base_dir, config_field_name)
95
- path = Pathname.new(base_dir)
96
- while !path.root?
97
- if (path + ".autoproj").exist?
98
- break
99
- end
100
- path = path.parent
101
- end
102
-
103
- if path.root?
104
- return
105
- end
106
-
107
- config_path = path + ".autoproj" + "config.yml"
108
- if config_path.exist?
109
- config = YAML.load(config_path.read) || Hash.new
110
- result = config[config_field_name] || path.to_s
111
- result = File.expand_path(result, path.to_s)
112
- else
113
- result = path.to_s
114
- end
115
-
116
- # I don't know if this is still useful or not ... but it does not hurt
117
- #
118
- # Preventing backslashed in path, that might be confusing on some path compares
119
- if Autobuild.windows?
120
- result = result.gsub(/\\/,'/')
121
- end
122
- result
123
- end
124
-
125
- # Finds the workspace root that contains a directory
126
- #
127
- # @return [String,nil]
128
- def self.find_workspace_dir(base_dir = Dir.pwd)
129
- find_root_dir(base_dir, 'workspace')
130
- end
131
-
132
- # Looks for the autoproj prefix that contains a given directory
133
- #
134
- # @return [String,nil]
135
- def self.find_prefix_dir(base_dir = Dir.pwd)
136
- find_root_dir(base_dir, 'prefix')
80
+ !!Autoproj.find_workspace_dir(path)
137
81
  end
138
82
 
139
83
  def load(*args)