autoproj 2.15.0 → 2.15.1

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.
@@ -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
@@ -793,6 +793,23 @@ module Autoproj
793
793
  vcs
794
794
  end
795
795
 
796
+ # Recursively resolve imports for a given package set
797
+ def self.resolve_imports(pkg_set, parents = Set.new)
798
+ return Set.new if pkg_set.imports.empty?
799
+
800
+ updated_parents = parents | [pkg_set]
801
+
802
+ imports = pkg_set.imports.dup
803
+ pkg_set.imports.each do |p|
804
+ if parents.include?(p)
805
+ raise "Cycling dependency between package sets encountered:" \
806
+ "#{p.name} <--> #{pkg_set.name}"
807
+ end
808
+ imports.merge(resolve_imports(p, updated_parents))
809
+ end
810
+ imports
811
+ end
812
+
796
813
  # Enumerates the Autobuild::Package instances that are defined in this
797
814
  # source
798
815
  def each_package
@@ -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.1"
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"