autoproj 2.0.0.rc4 → 2.0.0.rc5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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)