autoproj 2.15.0 → 2.15.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,6 +9,12 @@ module Autoproj
9
9
  class AptDpkgManager < ShellScriptManager
10
10
  attr_accessor :status_file
11
11
 
12
+ class << self
13
+ def inherit
14
+ @inherit ||= Set.new
15
+ end
16
+ end
17
+
12
18
  def initialize(ws, status_file = "/var/lib/dpkg/status")
13
19
  @status_file = status_file
14
20
  @installed_packages = nil
@@ -129,6 +135,7 @@ module Autoproj
129
135
  end
130
136
  end
131
137
 
138
+ # rubocop:disable Metrics/AbcSize
132
139
  def install(packages, filter_uptodate_packages: false, install_only: false)
133
140
  if filter_uptodate_packages || install_only
134
141
  already_installed, missing = packages.partition do |package_name|
@@ -144,12 +151,13 @@ module Autoproj
144
151
  packages = missing + (need_update || [])
145
152
  end
146
153
 
147
- if super(packages)
154
+ if super(packages, inherit: self.class.inherit)
148
155
  # Invalidate caching of installed packages, as we just
149
156
  # installed new packages !
150
157
  @installed_packages = nil
151
158
  end
152
159
  end
160
+ # rubocop:enable Metrics/AbcSize
153
161
  end
154
162
  end
155
163
  end
@@ -370,7 +370,7 @@ module Autoproj
370
370
  end
371
371
 
372
372
  # Parse the contents of a gemfile into a set of
373
- def merge_gemfiles(*path, unlock: [])
373
+ def merge_gemfiles(*path, ruby_version: nil, unlock: [])
374
374
  gems_remotes = Set.new
375
375
  dependencies = Hash.new do |h, k|
376
376
  h[k] = Hash.new do |i, j|
@@ -410,6 +410,9 @@ module Autoproj
410
410
  g = g[0..-2] if g.end_with?("/")
411
411
  contents << "source '#{g}'"
412
412
  end
413
+ if ruby_version
414
+ contents << "ruby \"#{ruby_version}\" if respond_to?(:ruby)"
415
+ end
413
416
  valid_keys = %w[group groups git path glob name branch ref tag
414
417
  require submodules platform platforms type
415
418
  source install_if]
@@ -526,34 +529,32 @@ module Autoproj
526
529
  end
527
530
  end
528
531
 
529
- gemfiles = workspace_configuration_gemfiles
530
- gemfiles << File.join(ws.dot_autoproj_dir, "Gemfile")
531
-
532
- # Save the osdeps entries in a temporary gemfile and finally
533
- # merge the whole lot of it
534
- gemfile_contents = Tempfile.open "autoproj-gemfile" do |io|
535
- gems.map { |entry| GemEntry.parse(entry) }
536
- .sort_by(&:name)
537
- .each { |entry| io.puts entry.to_gemfile_line }
532
+ gemfiles = []
538
533
 
539
- io.flush
540
- gemfiles.unshift io.path
541
- # The autoproj gemfile needs to be last, we really don't
542
- # want to mess it up
543
- merge_gemfiles(*gemfiles)
534
+ unless gems.empty?
535
+ osdeps_gemfile_io = prepare_osdeps_gemfile(gems)
536
+ gemfiles << osdeps_gemfile_io.path
544
537
  end
545
538
 
539
+ gemfiles += workspace_configuration_gemfiles
540
+ # The autoproj gemfile needs to be last, we really don't
541
+ # want to mess it up
542
+ gemfiles << File.join(ws.dot_autoproj_dir, "Gemfile")
543
+
544
+ ruby_version = RUBY_VERSION.gsub(/\.\d+$/, ".0")
545
+ gemfile_contents =
546
+ merge_gemfiles(*gemfiles, ruby_version: "~> #{ruby_version}")
547
+
546
548
  FileUtils.mkdir_p root_dir
547
549
  updated = (!File.exist?(gemfile_path) ||
548
550
  File.read(gemfile_path) != gemfile_contents)
549
551
  if updated
550
552
  Ops.atomic_write(gemfile_path) do |io|
551
- io.puts "ruby \"#{RUBY_VERSION}\" if respond_to?(:ruby)"
552
553
  io.puts gemfile_contents
553
554
  end
554
555
  end
555
556
 
556
- options = Array.new
557
+ options = []
557
558
  binstubs_path = File.join(root_dir, "bin")
558
559
  if updated || !install_only || !File.file?("#{gemfile_path}.lock")
559
560
  self.class.run_bundler_install(ws, gemfile_path, *options,
@@ -580,6 +581,25 @@ module Autoproj
580
581
  backup_clean(backups)
581
582
  end
582
583
 
584
+ # Prepare a Gemfile that contains osdeps gem declarations
585
+ #
586
+ # @param [Array<String,Hash>] gems osdeps declarations as understood
587
+ # by {GemEntry.parse}
588
+ # @return [File]
589
+ def prepare_osdeps_gemfile(gems)
590
+ io = Tempfile.open "autoproj-gemfile"
591
+ io.puts "source \"https://rubygems.org\""
592
+ gems.map { |entry| GemEntry.parse(entry) }
593
+ .sort_by(&:name)
594
+ .each { |entry| io.puts entry.to_gemfile_line }
595
+
596
+ io.flush
597
+ io
598
+ rescue Exception
599
+ io&.close
600
+ raise
601
+ end
602
+
583
603
  def discover_rubylib
584
604
  require "bundler"
585
605
  Tempfile.open "autoproj-rubylib" do |io|
@@ -27,24 +27,16 @@ module Autoproj
27
27
  end
28
28
 
29
29
  def guess_pip_program
30
- unless ws.config.has_value_for?("USE_PYTHON")
31
- Autoproj::Python.setup_python_configuration_options(ws: ws)
32
- end
33
- unless ws.config.get("USE_PYTHON")
34
- raise ConfigError,
35
- "Your current package selection requires the use of pip, but" \
36
- " the use of python is either unspecified or has been denied,"\
37
- " see setting of USE_PYTHON in your workspace configuration." \
38
- " Either remove all packages depending on pip packages " \
39
- " from the workspace layout (manifest) or " \
40
- " call 'autoproj reconfigure' to change the setting."
41
-
42
- end
43
-
30
+ activate_python
44
31
  Autobuild.programs["pip"] = "pip" unless Autobuild.programs["pip"]
45
32
  Autobuild.programs["pip"]
46
33
  end
47
34
 
35
+ def activate_python
36
+ Autoproj::Python.setup_python_configuration_options(ws: ws)
37
+ Autoproj::Python.assert_python_activated(ws: ws)
38
+ end
39
+
48
40
  def install(pips, filter_uptodate_packages: false, install_only: false)
49
41
  guess_pip_program
50
42
  pips = [pips] if pips.is_a?(String)
@@ -3,7 +3,8 @@ module Autoproj
3
3
  # Base class for all package managers that simply require the call of a
4
4
  # shell script to install packages (e.g. yum, apt, ...)
5
5
  class ShellScriptManager < Manager
6
- def self.execute(command_line, with_locking, with_root, env: Autobuild.env)
6
+ def self.execute(command_line, with_locking, with_root,
7
+ env: Autoproj.workspace.env, inherit: Set.new)
7
8
  if with_locking
8
9
  File.open("/tmp/autoproj_osdeps_lock", "w") do |lock_io|
9
10
  until lock_io.flock(File::LOCK_EX | File::LOCK_NB)
@@ -12,18 +13,28 @@ module Autoproj
12
13
  "installation"
13
14
  sleep 5
14
15
  end
15
- return execute(command_line, false, with_root, env: env)
16
+ return execute(command_line, false, with_root,
17
+ env: env, inherit: inherit)
16
18
  ensure
17
19
  lock_io.flock(File::LOCK_UN)
18
20
  end
19
21
  end
20
22
 
23
+ process_env = env
21
24
  if with_root
22
- sudo = Autobuild.tool_in_path("sudo", env: env)
23
- command_line = [sudo, *command_line]
25
+ process_env = Autobuild::Environment.new
26
+ process_env.isolate
27
+ process_env.add_path("PATH", "/usr/local/sbin",
28
+ "/usr/sbin", "/sbin")
29
+
30
+ inherit.each { |var| process_env.set(var, env[var]) }
31
+ sudo = Autobuild.tool_in_path("sudo", env: process_env)
32
+ command_line = [sudo, "--preserve-env", *command_line]
24
33
  end
25
34
 
26
- Autobuild::Subprocess.run "autoproj", "osdeps", *command_line
35
+ Autobuild::Subprocess.run "autoproj", "osdeps", *command_line,
36
+ env: process_env.resolved_env,
37
+ env_inherit: false
27
38
  end
28
39
 
29
40
  # Overrides the {#needs_locking?} flag
@@ -194,7 +205,8 @@ module Autoproj
194
205
  # @return [Boolean] true if packages got installed, false otherwise
195
206
  def install(packages, filter_uptodate_packages: false, install_only: false,
196
207
  auto_install_cmd: self.auto_install_cmd,
197
- user_install_cmd: self.user_install_cmd)
208
+ user_install_cmd: self.user_install_cmd,
209
+ inherit: Set.new)
198
210
  return if packages.empty?
199
211
 
200
212
  handled_os = ws.supported_operating_system?
@@ -218,7 +230,7 @@ module Autoproj
218
230
 
219
231
  ShellScriptManager.execute(
220
232
  [*auto_install_cmd, *packages], needs_locking?,
221
- needs_root?, env: ws.env
233
+ needs_root?, env: ws.env, inherit: inherit
222
234
  )
223
235
  return true
224
236
  end
@@ -17,7 +17,7 @@ module Autoproj
17
17
  # @return [PackageManifest]
18
18
  # @see parse
19
19
  def self.load(package, file, ros_manifest: false)
20
- loader_class = ros_manifest ? RosLoader : Loader
20
+ loader_class = ros_manifest ? RosPackageManifest::Loader : Loader
21
21
  parse(package, File.read(file), path: file, loader_class: loader_class)
22
22
  end
23
23
 
@@ -32,7 +32,7 @@ module Autoproj
32
32
  # @see load
33
33
  def self.parse(package, contents,
34
34
  path: "<loaded from string>", loader_class: Loader)
35
- manifest = PackageManifest.new(package, path)
35
+ manifest = loader_class::MANIFEST_CLASS.new(package, path)
36
36
  loader = loader_class.new(path, manifest)
37
37
  begin
38
38
  REXML::Document.parse_stream(contents, loader)
@@ -167,6 +167,7 @@ module Autoproj
167
167
  end
168
168
 
169
169
  def text(text)
170
+ @tag_text = @tag_text.dup
170
171
  @tag_text << text if @tag_text
171
172
  end
172
173
  end
@@ -178,6 +179,8 @@ module Autoproj
178
179
  class Loader < BaseLoader
179
180
  attr_reader :path, :manifest
180
181
 
182
+ MANIFEST_CLASS = PackageManifest
183
+
181
184
  def initialize(path, manifest)
182
185
  super()
183
186
  @path = path
@@ -249,55 +252,5 @@ module Autoproj
249
252
  @tag_text = nil
250
253
  end
251
254
  end
252
-
253
- # @api private
254
- #
255
- # REXML stream parser object used to load the XML contents into a
256
- # {PackageManifest} object
257
- class RosLoader < Loader
258
- SUPPORTED_MODES = %w[test doc].freeze
259
- DEPEND_TAGS = %w[depend build_depend build_export_depend
260
- buildtool_depend buildtool_export_depend
261
- exec_depend test_depend run_depend doc_depend].to_set.freeze
262
-
263
- def toplevel_tag_start(name, attributes)
264
- if DEPEND_TAGS.include?(name)
265
- @tag_text = ""
266
- elsif TEXT_FIELDS.include?(name)
267
- @tag_text = ""
268
- elsif AUTHOR_FIELDS.include?(name)
269
- @author_email = attributes["email"]
270
- @tag_text = ""
271
- else
272
- @tag_text = nil
273
- end
274
- end
275
-
276
- def toplevel_tag_end(name)
277
- if DEPEND_TAGS.include?(name)
278
- if @tag_text.strip.empty?
279
- raise InvalidPackageManifest, "found '#{name}' tag in #{path} "\
280
- "without content"
281
- end
282
-
283
- mode = []
284
- if (m = /^(\w+)_depend$/.match(name))
285
- mode = SUPPORTED_MODES & [m[1]]
286
- end
287
-
288
- manifest.add_dependency(@tag_text, modes: mode)
289
- elsif AUTHOR_FIELDS.include?(name)
290
- author_name = @tag_text.strip
291
- email = @author_email ? @author_email.strip : nil
292
- email = nil if email&.empty?
293
- contact = ContactInfo.new(author_name, email)
294
- manifest.send("#{name}s").concat([contact])
295
- elsif TEXT_FIELDS.include?(name)
296
- field = @tag_text.strip
297
- manifest.send("#{name}=", field) unless field.empty?
298
- end
299
- @tag_text = nil
300
- end
301
- end
302
255
  end
303
256
  end
@@ -168,18 +168,18 @@ module Autoproj
168
168
  end
169
169
  end
170
170
 
171
- def self.remove_python_shims(root_dir)
172
- shim_path = File.join(root_dir, "install", "bin", "python")
171
+ def self.remove_python_shims(prefix_dir)
172
+ shim_path = File.join(prefix_dir, "bin", "python")
173
173
  FileUtils.rm shim_path if File.exist?(shim_path)
174
174
  end
175
175
 
176
- def self.remove_pip_shims(root_dir)
177
- shim_path = File.join(root_dir, "install", "bin", "pip")
176
+ def self.remove_pip_shims(prefix_dir)
177
+ shim_path = File.join(prefix_dir, "bin", "pip")
178
178
  FileUtils.rm shim_path if File.exist?(shim_path)
179
179
  end
180
180
 
181
- def self.rewrite_python_shims(python_executable, root_dir)
182
- shim_path = File.join(root_dir, "install", "bin")
181
+ def self.rewrite_python_shims(python_executable, prefix_dir)
182
+ shim_path = File.join(prefix_dir, "bin")
183
183
  unless File.exist?(shim_path)
184
184
  FileUtils.mkdir_p shim_path
185
185
  Autoproj.warn "Autoproj::Python.rewrite_python_shims: creating "\
@@ -196,8 +196,8 @@ module Autoproj
196
196
  python_path
197
197
  end
198
198
 
199
- def self.rewrite_pip_shims(python_executable, root_dir)
200
- shim_path = File.join(root_dir, "install", "bin")
199
+ def self.rewrite_pip_shims(python_executable, prefix_dir)
200
+ shim_path = File.join(prefix_dir, "bin")
201
201
  unless File.exist?(shim_path)
202
202
  FileUtils.mkdir_p shim_path
203
203
  Autoproj.warn "Autoproj::Python.rewrite_pip_shims: creating "\
@@ -224,14 +224,14 @@ module Autoproj
224
224
 
225
225
  ws.osdep_suffixes << "python#{$1}" if version =~ /^([0-9]+)\./
226
226
 
227
- rewrite_python_shims(bin, ws.root_dir)
228
- rewrite_pip_shims(bin, ws.root_dir)
227
+ rewrite_python_shims(bin, ws.dot_autoproj_dir)
228
+ rewrite_pip_shims(bin, ws.dot_autoproj_dir)
229
229
  [bin, version]
230
230
  end
231
231
 
232
232
  def self.deactivate_python(ws: Autoproj.workspace)
233
- remove_python_shims(ws.root_dir)
234
- remove_pip_shims(ws.root_dir)
233
+ remove_python_shims(ws.dot_autoproj_dir)
234
+ remove_pip_shims(ws.dot_autoproj_dir)
235
235
  ws.config.reset("python_executable")
236
236
  ws.config.reset("python_version")
237
237
  end
@@ -260,6 +260,18 @@ module Autoproj
260
260
  [bin, version, path]
261
261
  end
262
262
 
263
+ def self.assert_python_activated(ws: Autoproj.workspace)
264
+ return true if ws.config.get("USE_PYTHON")
265
+
266
+ raise ConfigError,
267
+ "Your current package selection requires the use of python," \
268
+ " but this is either unspecified or has been denied,"\
269
+ " see setting of USE_PYTHON in your workspace configuration." \
270
+ " Either remove all packages depending on pip packages " \
271
+ " from the workspace layout (manifest) or " \
272
+ " call 'autoproj reconfigure' to change the setting."
273
+ end
274
+
263
275
  def self.setup_python_configuration_options(ws: Autoproj.workspace)
264
276
  ws.config.declare "USE_PYTHON", "boolean",
265
277
  default: "no",
@@ -267,8 +279,8 @@ module Autoproj
267
279
 
268
280
  if ws.config.get("USE_PYTHON")
269
281
  unless ws.config.has_value_for?("python_executable")
270
- remove_python_shims(ws.root_dir)
271
- remove_pip_shims(ws.root_dir)
282
+ remove_python_shims(ws.dot_autoproj_dir)
283
+ remove_pip_shims(ws.dot_autoproj_dir)
272
284
  python_bin, = auto_resolve_python(ws: ws)
273
285
  end
274
286
 
@@ -173,7 +173,7 @@ module Autoproj
173
173
  id
174
174
  )
175
175
  else
176
- open(origin) do |io|
176
+ URI(origin).open do |io|
177
177
  Autobuild::Subprocess.run(
178
178
  "autoproj",
179
179
  "osrepos",
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "parslet"
4
+ require "autoproj/exceptions"
5
+ require "autoproj/variable_expansion"
6
+
7
+ module Autoproj
8
+ # Parses a conditional expression
9
+ # Syntax and rules as defined in https://www.ros.org/reps/rep-0149.html#id20
10
+ class RosConditionParser < Parslet::Parser
11
+ def initialize(context)
12
+ @context = context
13
+ super()
14
+ end
15
+
16
+ def expand(var)
17
+ Autoproj.expand(var, @context)
18
+ rescue StandardError
19
+ ""
20
+ end
21
+
22
+ # Evaluates the Abstract Syntax Tree generated by the parser
23
+ class Transform < Parslet::Transform
24
+ rule(literal: simple(:x)) { String(x) }
25
+ rule(variable: simple(:x)) { expander.call(String(x)) }
26
+ rule(op: simple(:o), lhs: simple(:l), rhs: simple(:r)) { l.send(o, r) }
27
+ rule(op: "and", lhs: simple(:l), rhs: simple(:r)) { l && r }
28
+ rule(op: "or", lhs: simple(:l), rhs: simple(:r)) { l || r }
29
+ end
30
+
31
+ def evaluate(expr)
32
+ Transform.new.apply(parse(expr.strip), expander: method(:expand))
33
+ rescue Parslet::ParseFailed => e
34
+ raise Autoproj::ConfigError, e.message
35
+ end
36
+
37
+ def any_of(strings)
38
+ strings = strings.dup
39
+ strings.reduce(str(strings.shift)) { |acc, s| acc | str(s) }
40
+ end
41
+
42
+ def quoted_literal(quote)
43
+ str(quote) >> (
44
+ str(quote).absent? >> any
45
+ ).repeat.maybe.as(:literal) >> str(quote)
46
+ end
47
+
48
+ def chain(lhs, operator, operation)
49
+ (lhs.as(:lhs) >> operator >> operation.as(:rhs)) | lhs
50
+ end
51
+
52
+ RESERVED = %w[and or].freeze
53
+
54
+ rule(:space) { match['\s\t'].repeat(1) }
55
+ rule(:space?) { space.maybe }
56
+ rule(:lparen) { str("(") >> space? }
57
+ rule(:rparen) { str(")") >> space? }
58
+ rule(:comp_operator) { any_of(%w[== != >= <= > <]).as(:op) >> space? }
59
+ rule(:and_operator) { str("and").as(:op) >> space? }
60
+ rule(:or_operator) { str("or").as(:op) >> space? }
61
+ rule(:literal) do
62
+ (any_of(RESERVED) >> space).absent? >>
63
+ (match('\w') | match["_-"]).repeat(1)
64
+ .as(:literal)
65
+ end
66
+ rule(:double_quote) { quoted_literal('"') }
67
+ rule(:single_quote) { quoted_literal("'") }
68
+ rule(:variable) do
69
+ (
70
+ str("$") >> match('\d').absent? >> (
71
+ match('\w') | match["_"]
72
+ ).repeat(1)
73
+ ).as(:variable)
74
+ end
75
+
76
+ rule(:term) { (literal | single_quote | double_quote | variable) >> space? }
77
+ rule(:primary) { (lparen >> or_operation >> rparen) | term }
78
+ rule(:comp_operation) { chain(primary, comp_operator, comp_operation) }
79
+ rule(:and_operation) { chain(comp_operation, and_operator, and_operation) }
80
+ rule(:or_operation) { chain(and_operation, or_operator, or_operation) }
81
+
82
+ root(:or_operation)
83
+ end
84
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Autoproj
4
+ # Access to the information contained in a package's package.xml file
5
+ #
6
+ # Use PackageManifest.load to create
7
+ class RosPackageManifest < PackageManifest
8
+ attr_accessor :name
9
+ attr_writer :build_type
10
+
11
+ def build_type
12
+ @build_type || "catkin"
13
+ end
14
+
15
+ # @api private
16
+ #
17
+ # REXML stream parser object used to load the XML contents into a
18
+ # {PackageManifest} object
19
+ class Loader < PackageManifest::Loader
20
+ MANIFEST_CLASS = RosPackageManifest
21
+ SUPPORTED_MODES = %w[test doc].freeze
22
+ DEPEND_TAGS = %w[depend build_depend build_export_depend
23
+ buildtool_depend buildtool_export_depend
24
+ exec_depend test_depend run_depend doc_depend].to_set.freeze
25
+
26
+ def initialize(path, manifest)
27
+ super
28
+ @env = manifest.package.ws.env
29
+ @condition_parser = RosConditionParser.new(@env)
30
+ end
31
+
32
+ def tag_start(name, attributes)
33
+ super
34
+ exportlevel_tag_start(name, attributes) if @export_level
35
+ end
36
+
37
+ def tag_end(name)
38
+ super
39
+ exportlevel_tag_end(name) if @export_level
40
+ if @tag_level == 0 && name == "package" &&
41
+ (!manifest.name || manifest.name.empty?)
42
+ raise InvalidPackageManifest, "Package name missiing in #{path}"
43
+ end
44
+ end
45
+
46
+ def exportlevel_tag_start(name, attributes)
47
+ return unless name == "build_type"
48
+
49
+ @build_type_condition = attributes["condition"]
50
+ @tag_text = ""
51
+ end
52
+
53
+ def exportlevel_tag_end(name)
54
+ return unless name == "build_type"
55
+ return unless handle_condition(@build_type_condition)
56
+
57
+ manifest.build_type = @tag_text.strip
58
+ end
59
+
60
+ def toplevel_tag_start(name, attributes)
61
+ if DEPEND_TAGS.include?(name)
62
+ @depend_condition = attributes["condition"]
63
+ @tag_text = ""
64
+ elsif TEXT_FIELDS.include?(name)
65
+ @tag_text = ""
66
+ elsif AUTHOR_FIELDS.include?(name)
67
+ @author_email = attributes["email"]
68
+ @tag_text = ""
69
+ elsif name == "name"
70
+ @tag_text = ""
71
+ elsif name == "export"
72
+ @export_level = true
73
+ else
74
+ @tag_text = nil
75
+ end
76
+ end
77
+
78
+ def handle_condition(expr)
79
+ return true unless expr && !expr.empty?
80
+
81
+ @condition_parser.evaluate(expr)
82
+ end
83
+
84
+ def depend_tag_end(name)
85
+ return unless handle_condition(@depend_condition)
86
+
87
+ if @tag_text.strip.empty?
88
+ raise InvalidPackageManifest, "found '#{name}' tag in #{path} "\
89
+ "without content"
90
+ end
91
+
92
+ mode = []
93
+ if (m = /^(\w+)_depend$/.match(name))
94
+ mode = SUPPORTED_MODES & [m[1]]
95
+ end
96
+
97
+ manifest.add_dependency(@tag_text, modes: mode)
98
+ end
99
+
100
+ def author_tag_end(name)
101
+ author_name = @tag_text.strip
102
+ email = @author_email ? @author_email.strip : nil
103
+ email = nil if email&.empty?
104
+ contact = PackageManifest::ContactInfo.new(author_name, email)
105
+ manifest.send("#{name}s").concat([contact])
106
+ end
107
+
108
+ def toplevel_tag_end(name)
109
+ if DEPEND_TAGS.include?(name)
110
+ depend_tag_end(name)
111
+ elsif AUTHOR_FIELDS.include?(name)
112
+ author_tag_end(name)
113
+ elsif TEXT_FIELDS.include?(name)
114
+ field = @tag_text.strip
115
+ manifest.send("#{name}=", field) unless field.empty?
116
+ elsif name == "name"
117
+ manifest.name = @tag_text.strip
118
+ elsif name == "export"
119
+ @export_level = false
120
+ end
121
+ @tag_text = nil
122
+ end
123
+ end
124
+ end
125
+ end
@@ -1,3 +1,3 @@
1
1
  module Autoproj
2
- VERSION = "2.15.0"
2
+ VERSION = "2.15.3"
3
3
  end
data/lib/autoproj.rb CHANGED
@@ -27,7 +27,9 @@ require "autoproj/package_definition"
27
27
  require "autoproj/package_selection"
28
28
  require "autoproj/metapackage"
29
29
  require "autoproj/manifest"
30
+ require "autoproj/ros_condition_parser"
30
31
  require "autoproj/package_manifest"
32
+ require "autoproj/ros_package_manifest"
31
33
  require "autoproj/installation_manifest"
32
34
  require "autoproj/os_package_installer"
33
35
  require "autoproj/os_package_resolver"
@@ -61,7 +63,7 @@ require "utilrb/logger"
61
63
 
62
64
  module Autoproj
63
65
  class << self
64
- attr_reader :logger
66
+ attr_accessor :logger
65
67
  end
66
68
  @logger = Logger.new(STDOUT)
67
69
  logger.level = Logger::WARN