autobuild 1.5.34 → 1.5.35

Sign up to get free protection for your applications and to get access to all the features.
data/Changes.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == Version 1.5.35
2
+ * fix some bad behaviour when using fallback importers
3
+ - git does not update the git configuration with the bad URLs anymore
4
+ * orogen: removed automatic dependency detection, it was half-broken anyway.
5
+ * orogen: avoid unnecessary regeneration (experimental, disabled by default).
6
+ It can be enabled by setting Autobuild::Orogen.always_regenerate = true
7
+
1
8
  == Version 1.5.34
2
9
  * make sure oroGen handlers will trigger a new generation
3
10
  on force-build
data/README.txt CHANGED
@@ -1,8 +1,6 @@
1
- Copyright (c) 2006-2009 Sylvain Joyeux <sylvain.joyeux@m4x.org>
1
+ Copyright (c) 2006-2011 Sylvain Joyeux <sylvain.joyeux@m4x.org> and contributors
2
2
 
3
- * http://doudou.github.com/autobuild
4
- * http://github.com/doudou/autobuild
5
- * http://doudou.github.com/autoproj
3
+ * http://rock-robotics.org
6
4
 
7
5
  This work is licensed under the GPLv2 license. See License.txt for details
8
6
 
@@ -71,28 +71,34 @@ module Autobuild
71
71
  send("#{name}=", value)
72
72
  end
73
73
 
74
+ @post_install_handlers = Array.new
74
75
  def self.post_install(*args, &block)
75
76
  if args.empty?
76
- @post_install_handler = block
77
+ @post_install_handlers << block
77
78
  elsif !block
78
- @post_install_handler = args
79
+ @post_install_handlers << args
79
80
  else
80
81
  raise ArgumentError, "cannot set both arguments and block"
81
82
  end
82
83
  end
83
- attr_reader :post_install_handler
84
+ class << self
85
+ attr_reader :post_install_handlers
86
+ end
84
87
 
85
- def self.apply_post_install(name, info)
88
+ def self.apply_post_install(pkg, info)
86
89
  return unless info
87
90
 
88
91
  case info
89
92
  when Array
90
93
  args = info.dup
91
94
  tool = Autobuild.tool(args.shift)
92
-
93
- Autobuild::Subprocess.run name, 'post-install', tool, *args
95
+ pkg.run 'post-install', tool, *args
94
96
  when Proc
95
- info.call
97
+ if info.arity == 1
98
+ info.call(pkg)
99
+ else
100
+ info.call
101
+ end
96
102
  end
97
103
  end
98
104
 
@@ -23,9 +23,9 @@ module Autobuild
23
23
  if branch
24
24
  STDERR.puts "WARN: the git importer now expects you to provide the branch as a named option"
25
25
  STDERR.puts "WARN: this form is deprecated:"
26
- STDERR.puts "WARN: Autobuild.git 'git://github.com/doudou/autobuild.git', 'master'"
26
+ STDERR.puts "WARN: Autobuild.git 'git://gitorious.org/rock/buildconf.git', 'master'"
27
27
  STDERR.puts "WARN: and should be replaced by"
28
- STDERR.puts "WARN: Autobuild.git 'git://github.com/doudou/autobuild.git', :branch => 'master'"
28
+ STDERR.puts "WARN: Autobuild.git 'git://gitorious.org/rock/buildconf.git', :branch => 'master'"
29
29
  end
30
30
 
31
31
  gitopts, common = Kernel.filter_options options, :push_to => nil, :branch => nil, :tag => nil, :commit => nil
@@ -121,7 +121,20 @@ module Autobuild
121
121
  def fetch_remote(package)
122
122
  validate_srcdir(package)
123
123
  Dir.chdir(package.srcdir) do
124
- # Update the remote definition
124
+ # If we are checking out a specific commit, we don't know which
125
+ # branch to refer to in git fetch. So, we have to set up the
126
+ # remotes and call git fetch directly (so that all branches get
127
+ # fetch)
128
+ #
129
+ # Otherwise, do git fetch now
130
+ #
131
+ # Doing it now is better as it makes sure that we replace the
132
+ # configuration parameters only if the repository and branch are
133
+ # OK (i.e. we keep old working configuration instead)
134
+ if !commit
135
+ Subprocess.run(package, :import, Autobuild.tool('git'), 'fetch', repository, branch || tag)
136
+ end
137
+
125
138
  Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
126
139
  "--replace-all", "remote.autobuild.url", repository)
127
140
  if push_to
@@ -146,11 +159,8 @@ module Autobuild
146
159
  "--replace-all", "branch.#{local_branch}.merge", "refs/heads/#{branch}")
147
160
  end
148
161
 
149
- # We are checking out a specific commit. We just call git fetch
150
- if commit
162
+ if commit
151
163
  Subprocess.run(package, :import, Autobuild.tool('git'), 'fetch', 'autobuild')
152
- else
153
- Subprocess.run(package, :import, Autobuild.tool('git'), 'fetch', repository, branch || tag)
154
164
  end
155
165
 
156
166
  # Now get the actual commit ID from the FETCH_HEAD file, and
@@ -180,14 +190,12 @@ module Autobuild
180
190
  validate_srcdir(package)
181
191
  remote_commit = nil
182
192
  if only_local
183
- Dir.chdir(package.srcdir) do
184
- remote_commit = `git show-ref -s refs/heads/#{local_branch}`.chomp
185
- end
193
+ remote_commit = `git show-ref -s refs/heads/#{local_branch}`.chomp
186
194
  else
187
195
  remote_commit =
188
196
  begin fetch_remote(package)
189
197
  rescue Exception => e
190
- fallback(e, package, :status, package, only_local)
198
+ return fallback(e, package, :status, package, only_local)
191
199
  end
192
200
 
193
201
  if !remote_commit
@@ -205,6 +213,11 @@ module Autobuild
205
213
 
206
214
  end
207
215
 
216
+ def has_local_branch?
217
+ `git show-ref -q --verify refs/heads/#{local_branch}`
218
+ $?.exitstatus == 0
219
+ end
220
+
208
221
  # Checks if the current branch is the target branch. Expects that the
209
222
  # current directory is the package's directory
210
223
  def on_target_branch?
@@ -258,7 +271,7 @@ module Autobuild
258
271
 
259
272
  def merge_status(fetch_commit)
260
273
  common_commit = `git merge-base HEAD #{fetch_commit}`.chomp
261
- head_commit = `git rev-parse #{local_branch}`.chomp
274
+ head_commit = `git rev-parse HEAD`.chomp
262
275
 
263
276
  status = if common_commit != fetch_commit
264
277
  if common_commit == head_commit
@@ -88,6 +88,8 @@ class Importer
88
88
  update(package)
89
89
  patch(package)
90
90
  package.updated = true
91
+ rescue Interrupt
92
+ raise
91
93
  rescue ::Exception => e
92
94
  fallback(e, package, :import, package)
93
95
  end
@@ -124,7 +126,10 @@ class Importer
124
126
  Importer.fallback_handlers.each do |handler|
125
127
  fallback_importer = handler.call(package, self)
126
128
  if fallback_importer.kind_of?(Importer)
127
- return fallback_importer.send(*args, &block)
129
+ begin fallback_importer.send(*args, &block)
130
+ rescue Exception
131
+ raise error
132
+ end
128
133
  end
129
134
  end
130
135
  raise error
@@ -195,15 +195,26 @@ module Autobuild
195
195
  # Don't do anything if we already have failed
196
196
  return if failed?
197
197
 
198
- begin yield
198
+ begin
199
+ do_isolate = Autobuild.ignore_errors
200
+ Autobuild.ignore_errors = false
201
+ yield
202
+ rescue Interrupt
203
+ raise
199
204
  rescue ::Exception => e
200
205
  @failures << e
201
206
  if mark_as_failed
202
207
  @failed = true
203
208
  end
204
209
 
205
- if Autobuild.ignore_errors
210
+ if do_isolate
206
211
  lines = e.to_s.split("\n")
212
+ if lines.empty?
213
+ lines = e.message.split("\n")
214
+ end
215
+ if lines.empty?
216
+ lines = ["unknown error"]
217
+ end
207
218
  progress(lines.shift, :red, :bold)
208
219
  lines.each do |line|
209
220
  progress(line)
@@ -212,6 +223,8 @@ module Autobuild
212
223
  else
213
224
  raise
214
225
  end
226
+ ensure
227
+ Autobuild.ignore_errors = do_isolate
215
228
  end
216
229
  end
217
230
 
@@ -282,8 +295,11 @@ module Autobuild
282
295
  # Install the result in prefix
283
296
  def install
284
297
  Dir.chdir(srcdir) do
298
+ Autobuild.post_install_handlers.each do |b|
299
+ Autobuild.apply_post_install(self, b)
300
+ end
285
301
  @post_install_blocks.each do |b|
286
- Autobuild.apply_post_install(name, b)
302
+ Autobuild.apply_post_install(self, b)
287
303
  end
288
304
  end
289
305
  Autobuild.touch_stamp(installstamp)
@@ -3,136 +3,9 @@ module Autobuild
3
3
  Orogen.new(opts, &proc)
4
4
  end
5
5
 
6
-
7
- # This discards everything but the calls to import_types_from,
8
- # using_task_library and using_toolkit. This is used to automatically
9
- # discover the dependencies without resorting to an actual build
10
- class FakeOrogenEnvironment
11
- class BlackHole
12
- def initialize(*args)
13
- end
14
- def method_missing(*args)
15
- self
16
- end
17
- def self.method_missing(*args)
18
- self
19
- end
20
- def self.const_missing(*args)
21
- self
22
- end
23
- end
24
- StaticDeployment = BlackHole
25
- StaticDeployment::Logger = BlackHole
26
- TaskContext = BlackHole
27
-
28
- class FakeDeployment
29
- attr_reader :env
30
- def initialize(env, name)
31
- @env = env
32
- env.provides << "pkgconfig/orogen-#{name}"
33
- end
34
- def add_default_logger
35
- env.using_task_library 'logger'
36
- BlackHole
37
- end
38
- def task(*args)
39
- method_missing(*args)
40
- end
41
- def const_missing(*args)
42
- BlackHole
43
- end
44
- def method_missing(*args)
45
- BlackHole
46
- end
47
- def self.const_missing(*args)
48
- BlackHole
49
- end
50
- end
51
-
52
- attr_reader :orogen_file
53
- attr_reader :base_dir
54
- attr_reader :project_name, :dependencies, :provides
55
- def self.load(pkg, file)
56
- FakeOrogenEnvironment.new(pkg).load(file)
57
- end
58
-
59
- # The Autobuild::Orogen instance we are working for
60
- attr_reader :pkg
61
-
62
- def initialize(pkg)
63
- @pkg = pkg
64
- @dependencies = Array.new
65
- @provides = Array.new
66
- end
67
-
68
- def load(file)
69
- @orogen_file = file
70
- @base_dir = File.dirname(file)
71
-
72
- begin
73
- Kernel.eval(File.read(file), binding, file, 0)
74
- rescue ::Exception => e
75
- backtrace = e.backtrace.dup
76
- message = e.message.dup
77
-
78
- backtrace.delete_if { |line| line !~ /(\s|^)#{Regexp.quote(file)}:/ }
79
- if message =~ /^(#{Regexp.quote(file)}:\d+): (.*)/m
80
- backtrace.unshift $1
81
- message = $2
82
- end
83
- raise e, message, backtrace
84
- end
85
-
86
- self
87
- end
88
-
89
- def name(name)
90
- @project_name = name
91
- nil
92
- end
93
- def using_library(*names)
94
- @dependencies.concat(names)
95
- nil
96
- end
97
- def import_types_from(name, *args)
98
- if !File.file?(File.join(base_dir, name)) && name.downcase !~ /\.(hh|hpp|h)/
99
- using_toolkit name
100
- end
101
- end
102
- def using_toolkit(*names)
103
- names = names.map { |n| "#{n}-toolkit-#{pkg.orocos_target}" }
104
- @dependencies.concat(names)
105
- nil
106
- end
107
- def using_task_library(*names)
108
- names = names.map { |n| "#{n}-tasks-#{pkg.orocos_target}" }
109
- @dependencies.concat(names)
110
- nil
111
- end
112
-
113
- def static_deployment(name = nil, &block)
114
- deployment("test_#{project_name}", &block)
115
- end
116
- def deployment(name, &block)
117
- deployment = FakeDeployment.new(self, name)
118
- deployment.instance_eval(&block) if block
119
- deployment
120
- end
121
-
122
- def self.const_missing(*args)
123
- BlackHole
124
- end
125
- def const_missing(*args)
126
- BlackHole
127
- end
128
- def method_missing(*args)
129
- BlackHole
130
- end
131
- end
132
-
133
6
  # This class represents packages generated by orogen. oroGen is a
134
7
  # specification and code generation tool for the Orocos/RTT integration
135
- # framework. See http://doudou.github.com/orogen for more information.
8
+ # framework. See http://rock-robotics.org for more information.
136
9
  #
137
10
  # This class extends the CMake package class to handle the code generation
138
11
  # step. Moreover, it will load the orogen specification and automatically
@@ -150,10 +23,33 @@ module Autobuild
150
23
  class Orogen < CMake
151
24
  class << self
152
25
  attr_accessor :corba
26
+
27
+ # If set to true, all components are generated with the
28
+ # --extended-states option
29
+ #
30
+ # The default is false
153
31
  attr_accessor :extended_states
32
+
33
+ # See #always_regenerate?
34
+ attr_reader :always_regenerate
35
+
36
+ # If true (the default), the oroGen component will be regenerated
37
+ # every time a dependency is newer than the package itself.
38
+ #
39
+ # Otherwise, autobuild tries to regenerate it only when needed
40
+ #
41
+ # This is still considered experimental. Use
42
+ # Orogen.always_regenerate= to set it
43
+ def always_regenerate?
44
+ !!@always_regenerate
45
+ end
154
46
  end
155
47
 
48
+ @always_regenerate = true
49
+
156
50
  @orocos_target = nil
51
+
52
+ # The target that should be used to generate and build orogen components
157
53
  def self.orocos_target
158
54
  user_target = ENV['OROCOS_TARGET']
159
55
  if @orocos_target
@@ -173,6 +69,7 @@ module Autobuild
173
69
  @default_type_export_policy = :used
174
70
  @transports = %w{corba typelib}
175
71
 
72
+ # Path to the orogen tool
176
73
  def self.orogen_bin
177
74
  if @orogen_bin
178
75
  @orogen_bin
@@ -186,6 +83,7 @@ module Autobuild
186
83
  end
187
84
  end
188
85
 
86
+ # Path to the root of the orogen package
189
87
  def self.orogen_root
190
88
  if @orogen_root
191
89
  @orogen_root
@@ -194,6 +92,10 @@ module Autobuild
194
92
  end
195
93
  end
196
94
 
95
+ # The version of orogen, given as a string
96
+ #
97
+ # It is used to enable/disable some configuration features based on the
98
+ # orogen version string
197
99
  def self.orogen_version
198
100
  if !@orogen_version && root = orogen_root
199
101
  version_file = File.join(root, 'orogen', 'version.rb')
@@ -205,7 +107,16 @@ module Autobuild
205
107
  @orogen_version
206
108
  end
207
109
 
110
+ # Overrides the global Orocos.orocos_target for this particular package
208
111
  attr_writer :orocos_target
112
+
113
+ # The orocos target that should be used for this particular orogen
114
+ # package
115
+ #
116
+ # By default, it is the same than Orogen.orocos_target. It can be set by
117
+ # doing
118
+ #
119
+ # package.orocos_target = 'target_name'
209
120
  def orocos_target
210
121
  if @orocos_target.nil?
211
122
  Orogen.orocos_target
@@ -214,19 +125,22 @@ module Autobuild
214
125
  end
215
126
  end
216
127
 
217
- attr_reader :orogen_spec
218
-
219
128
  attr_writer :corba
220
129
  def corba
221
130
  @corba || (@corba.nil? && Orogen.corba)
222
131
  end
223
132
 
133
+ # Overrides the global Orocos.extended_states for this particular package
224
134
  attr_writer :extended_states
225
135
  def extended_states
226
136
  @extended_states || (@extended_states.nil? && Orogen.extended_states)
227
137
  end
228
138
 
139
+ # Path to the orogen file used for this package
140
+ #
141
+ # If present, it defaults to the package name with '.orogen' appended
229
142
  attr_accessor :orogen_file
143
+
230
144
  def initialize(*args, &config)
231
145
  super
232
146
 
@@ -241,13 +155,6 @@ module Autobuild
241
155
 
242
156
  def import
243
157
  super
244
-
245
- @orogen_spec = FakeOrogenEnvironment.load(self, File.join(srcdir, orogen_file))
246
- provides "pkgconfig/#{orogen_spec.project_name}-toolkit-#{orocos_target}"
247
- provides "pkgconfig/#{orogen_spec.project_name}-tasks-#{orocos_target}"
248
- orogen_spec.provides.each do |name|
249
- provides name
250
- end
251
158
  end
252
159
 
253
160
  def update_environment
@@ -272,26 +179,18 @@ module Autobuild
272
179
  depends_on rtt.name
273
180
  end
274
181
 
275
- # If required, load the component's specification and add
276
- # dependencies based on the orogen specification.
277
- orogen_spec.dependencies.each do |pkg_name|
278
- target = "pkgconfig/#{pkg_name}"
279
- if Autobuild::Package[target]
280
- depends_on target
281
- end
182
+ # Find out where orogen is, and make sure the configurestamp depend
183
+ # on it. Ignore if orogen is too old to have a --base-dir option
184
+ if orogen_root = self.class.orogen_root
185
+ orogen_tree = Autobuild.source_tree(orogen_root)
282
186
  end
283
187
 
284
188
  # Check if there is an orogen package registered. If it is the case,
285
189
  # simply depend on it. Otherwise, look out for orogen --base-dir
286
190
  if Autobuild::Package['orogen']
287
191
  depends_on "orogen"
288
- else
289
- # Find out where orogen is, and make sure the configurestamp depend
290
- # on it. Ignore if orogen is too old to have a --base-dir option
291
- if orogen_root = self.class.orogen_root
292
- orogen_root = File.join(orogen_root, 'orogen')
293
- file genstamp => Autobuild.source_tree(orogen_root)
294
- end
192
+ elsif orogen_tree
193
+ file genstamp => orogen_tree
295
194
  end
296
195
 
297
196
  file configurestamp => genstamp
@@ -319,7 +218,7 @@ module Autobuild
319
218
  end
320
219
 
321
220
  def regen
322
- cmdline = [guess_ruby_name, self.class.orogen_bin]
221
+ cmdline = []
323
222
  cmdline << '--corba' if corba
324
223
 
325
224
  ext_states = extended_states
@@ -330,7 +229,6 @@ module Autobuild
330
229
  cmdline << '--no-extended-states'
331
230
  end
332
231
  end
333
- cmdline << orogen_file
334
232
 
335
233
  if (version = Orogen.orogen_version)
336
234
  if version >= "1.0"
@@ -338,13 +236,50 @@ module Autobuild
338
236
  end
339
237
  if version >= "1.1"
340
238
  cmdline << "--type-export-policy=#{Orogen.default_type_export_policy}"
341
- cmdline << "--transports=#{Orogen.transports.join(",")}"
239
+ cmdline << "--transports=#{Orogen.transports.sort.uniq.join(",")}"
342
240
  end
343
241
  end
242
+ cmdline = cmdline.sort
243
+ cmdline << orogen_file
244
+
245
+ needs_regen = Autobuild::Orogen.always_regenerate?
246
+
247
+ # Try to avoid unnecessary regeneration as generation can be pretty
248
+ # long
249
+ #
250
+ # First, check if the command line changed
251
+ needs_regen ||=
252
+ if File.exists?(genstamp)
253
+ last_cmdline = File.read(genstamp).split("\n")
254
+ last_cmdline != cmdline
255
+ else
256
+ true
257
+ end
258
+
259
+ # Then, if it has already been built, check what the check-uptodate
260
+ # target says
261
+ needs_regen ||=
262
+ if File.directory?(builddir)
263
+ Dir.chdir(builddir) do
264
+ !system("#{Autobuild.tool('make')} check-uptodate > /dev/null 2>&1")
265
+ end
266
+ else
267
+ true
268
+ end
269
+
270
+ # Finally, verify that orogen itself did not change
271
+ needs_regen ||= (Rake::Task[Orogen.orogen_root].timestamp > Rake::Task[genstamp].timestamp)
344
272
 
345
- progress "generating oroGen project %s"
346
- Dir.chdir(srcdir) do
347
- Subprocess.run self, 'orogen', *cmdline
273
+ if needs_regen
274
+ progress "generating oroGen project %s"
275
+ Dir.chdir(srcdir) do
276
+ Subprocess.run self, 'orogen', guess_ruby_name, self.class.orogen_bin, *cmdline
277
+ File.open(genstamp, 'w') do |io|
278
+ io.print cmdline.join("\n")
279
+ end
280
+ end
281
+ else
282
+ progress "no need to regenerate the oroGen project %s"
348
283
  Autobuild.touch_stamp genstamp
349
284
  end
350
285
  end
@@ -1,5 +1,5 @@
1
1
  module Autobuild
2
- VERSION = "1.5.34" unless defined? Autobuild::VERSION
2
+ VERSION = "1.5.35" unless defined? Autobuild::VERSION
3
3
  end
4
4
 
5
5
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: autobuild
3
3
  version: !ruby/object:Gem::Version
4
- hash: 71
5
- prerelease: false
4
+ hash: 69
5
+ prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 5
9
- - 34
10
- version: 1.5.34
9
+ - 35
10
+ version: 1.5.35
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sylvain Joyeux
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-02-02 00:00:00 +01:00
18
+ date: 2011-05-02 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -166,7 +166,7 @@ files:
166
166
  - test/test_subcommand.rb
167
167
  - test/tools.rb
168
168
  has_rdoc: true
169
- homepage: http://github.com/doudou/autobuild
169
+ homepage:
170
170
  licenses: []
171
171
 
172
172
  post_install_message:
@@ -196,7 +196,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
196
196
  requirements: []
197
197
 
198
198
  rubyforge_project: autobuild
199
- rubygems_version: 1.3.7
199
+ rubygems_version: 1.6.2
200
200
  signing_key:
201
201
  specification_version: 3
202
202
  summary: Rake-based utility to build and install multiple packages with dependencies