autobuild 1.8.3 → 1.9.0.b1

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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +16 -7
  3. data/Rakefile +2 -0
  4. data/lib/autobuild/config.rb +21 -6
  5. data/lib/autobuild/configurable.rb +2 -2
  6. data/lib/autobuild/environment.rb +52 -27
  7. data/lib/autobuild/exceptions.rb +48 -22
  8. data/lib/autobuild/import/archive.rb +37 -16
  9. data/lib/autobuild/import/cvs.rb +26 -28
  10. data/lib/autobuild/import/darcs.rb +9 -8
  11. data/lib/autobuild/import/git.rb +324 -217
  12. data/lib/autobuild/import/hg.rb +6 -9
  13. data/lib/autobuild/import/svn.rb +190 -47
  14. data/lib/autobuild/importer.rb +80 -35
  15. data/lib/autobuild/package.rb +16 -35
  16. data/lib/autobuild/packages/autotools.rb +8 -8
  17. data/lib/autobuild/packages/cmake.rb +18 -12
  18. data/lib/autobuild/packages/genom.rb +1 -1
  19. data/lib/autobuild/packages/gnumake.rb +11 -12
  20. data/lib/autobuild/packages/orogen.rb +1 -1
  21. data/lib/autobuild/packages/ruby.rb +9 -5
  22. data/lib/autobuild/reporting.rb +10 -6
  23. data/lib/autobuild/subcommand.rb +110 -50
  24. data/lib/autobuild/test.rb +104 -0
  25. data/lib/autobuild/timestamps.rb +3 -3
  26. data/lib/autobuild/tools.rb +1 -1
  27. data/lib/autobuild/utility.rb +22 -10
  28. data/lib/autobuild/version.rb +1 -1
  29. data/test/data/gitrepo-with-extra-commit-and-tag.tar +0 -0
  30. data/test/data/gitrepo.tar +0 -0
  31. data/test/data/gitrepo/test +0 -0
  32. data/test/data/gitrepo/test2 +0 -0
  33. data/test/data/gitrepo/test3 +0 -0
  34. data/test/data/svnroot.tar +0 -0
  35. data/test/import/test_cvs.rb +51 -0
  36. data/test/import/test_git.rb +364 -0
  37. data/test/import/test_svn.rb +144 -0
  38. data/test/import/test_tar.rb +76 -0
  39. data/test/suite.rb +7 -0
  40. data/test/test_config.rb +1 -5
  41. data/test/test_environment.rb +88 -0
  42. data/test/test_reporting.rb +2 -14
  43. data/test/test_subcommand.rb +7 -22
  44. metadata +17 -14
  45. data/test/test_import_cvs.rb +0 -59
  46. data/test/test_import_svn.rb +0 -56
  47. data/test/test_import_tar.rb +0 -83
  48. data/test/tools.rb +0 -44
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 71fc9a4d13e16cb68906457a8d9afd08f8c3700c
4
- data.tar.gz: 4d940353cece1bc2681254bafb90cd48e0dbba46
3
+ metadata.gz: 89ad5685bb460bc80765d7677953c83335bad861
4
+ data.tar.gz: 74b187763b5789e40f6f0dd7aae2d58cfca004cf
5
5
  SHA512:
6
- metadata.gz: fcc2b5bc4bc96b0b27288e3478744dc91191a3e498a125bc71fd317142f7adbea64b60b826bc82bda595bf182d622091f6aa6df4630d97ea132267d1841c713e
7
- data.tar.gz: 993285ac044926d5867c956942fc778c7d05823eaca884eeeda22d6c867ba668947b672f252ae2f0afdccef8009dcbb22c7bc4eb5c955c8c6f324d42c1537d3e
6
+ metadata.gz: b3cf9d6af419fa355ec32fdde8c0c83ce8f41beb287eb9717a32f94b107fe7cbb9adc58e8bbce8bacbfb5b023ea087728b3af4b9889ad2d8e3bdd7337075d22b
7
+ data.tar.gz: f0445a03f3aff872a12e5b739388d37b5afcb87dddaf43ec5b658cc7aa9b580147c4d4c08101f0ed59f7b7b3e45e757cf2dfba71735fa843c2fa1c14eebb7eac
data/Manifest.txt CHANGED
@@ -28,22 +28,31 @@ lib/autobuild/packages/import.rb
28
28
  lib/autobuild/packages/orogen.rb
29
29
  lib/autobuild/packages/pkgconfig.rb
30
30
  lib/autobuild/packages/ruby.rb
31
- lib/autobuild/utility.rb
32
31
  lib/autobuild/parallel.rb
33
32
  lib/autobuild/pkgconfig.rb
33
+ lib/autobuild/rake_task_extension.rb
34
34
  lib/autobuild/reporting.rb
35
35
  lib/autobuild/subcommand.rb
36
- lib/autobuild/tools.rb
36
+ lib/autobuild/test.rb
37
37
  lib/autobuild/timestamps.rb
38
+ lib/autobuild/tools.rb
39
+ lib/autobuild/utility.rb
38
40
  lib/autobuild/version.rb
39
- lib/autobuild/rake_task_extension.rb
40
41
  samples/openrobots.autobuild
41
42
  test/data/cvsroot.tar
43
+ test/data/gitrepo-with-extra-commit-and-tag.tar
44
+ test/data/gitrepo.tar
45
+ test/data/gitrepo/test
46
+ test/data/gitrepo/test2
47
+ test/data/gitrepo/test3
42
48
  test/data/svnroot.tar
43
49
  test/data/tarimport.tar.gz
44
- test/test_import_cvs.rb
45
- test/test_import_svn.rb
46
- test/test_import_tar.rb
50
+ test/import/test_cvs.rb
51
+ test/import/test_git.rb
52
+ test/import/test_svn.rb
53
+ test/import/test_tar.rb
54
+ test/suite.rb
55
+ test/test_config.rb
56
+ test/test_environment.rb
47
57
  test/test_reporting.rb
48
58
  test/test_subcommand.rb
49
- test/tools.rb
data/Rakefile CHANGED
@@ -17,6 +17,8 @@ Utilrb::Rake.hoe do
17
17
  ['rake', '>= 0.9.0'] <<
18
18
  ['utilrb', '>= 1.6.0'] <<
19
19
  ['highline', '>= 0']
20
+
21
+ self.test_globs = ['test/suite.rb']
20
22
  end
21
23
  Rake.clear_tasks(/publish_docs/, /default/)
22
24
  end
@@ -44,8 +44,19 @@ module Autobuild
44
44
  # @see {register_utility_class}
45
45
  attr_reader :utilities
46
46
 
47
- def register_utility_class(name, klass)
48
- utilities[name] = klass
47
+ # Yields all known utility classes
48
+ #
49
+ # @yieldparam [String] utility name
50
+ # @yieldparam [Class] utility class
51
+ # @yieldparam [Hash] utility options
52
+ # @return [void]
53
+ def each_utility
54
+ return enum_for(__method__) if !block_given?
55
+ utilities.each { |name, (utl, options)| yield(name, utl, options) }
56
+ end
57
+
58
+ def register_utility_class(name, klass, options = Hash.new)
59
+ utilities[name] = [klass, options]
49
60
  singleton_class.class_eval do
50
61
  attr_accessor "only_#{name}"
51
62
  attr_accessor "do_#{name}"
@@ -59,8 +70,12 @@ module Autobuild
59
70
  end
60
71
 
61
72
  def create_utility(utility_name, package)
62
- if klass = utilities[utility_name]
63
- package.utilities[utility_name] = klass.new(utility_name, package)
73
+ klass, options = utilities[utility_name]
74
+ if klass
75
+ utility = klass.new(utility_name, package)
76
+ package.utilities[utility_name] = utility
77
+ utility.enabled = !options[:disabled_by_default]
78
+ utility
64
79
  else raise ArgumentError, "there is no utility called #{utility_name}, available utilities are #{utilities.keys.sort.join(", ")}"
65
80
  end
66
81
  end
@@ -76,8 +91,8 @@ module Autobuild
76
91
  end
77
92
  end
78
93
  @utilities = Hash.new
79
- register_utility_class 'doc', Utility
80
- register_utility_class 'test', Utility
94
+ register_utility_class 'doc', Utility, disabled_by_default: false
95
+ register_utility_class 'test', Utility, disabled_by_default: true
81
96
 
82
97
  @console = HighLine.new
83
98
 
@@ -74,7 +74,7 @@ module Autobuild
74
74
  def prepare_for_rebuild
75
75
  super
76
76
 
77
- if File.exists?(builddir) && builddir != srcdir
77
+ if File.exist?(builddir) && builddir != srcdir
78
78
  FileUtils.rm_rf builddir
79
79
  end
80
80
  end
@@ -117,7 +117,7 @@ module Autobuild
117
117
 
118
118
  # Configure the builddir directory before starting make
119
119
  def configure
120
- if File.exists?(builddir) && !File.directory?(builddir)
120
+ if File.exist?(builddir) && !File.directory?(builddir)
121
121
  raise ConfigException.new(self, 'configure'), "#{builddir} already exists but is not a directory"
122
122
  end
123
123
  FileUtils.mkdir_p builddir if !File.directory?(builddir)
@@ -68,14 +68,6 @@ module Autobuild
68
68
  #
69
69
  # export VARNAME=new_value:new_value
70
70
  attr_reader :inherited_environment
71
-
72
- # List of files that should be sourced in the generated environment
73
- # variable setting shell scripts
74
- attr_reader :env_source_before
75
-
76
- # List of files that should be sourced in the generated environment
77
- # variable setting shell scripts
78
- attr_reader :env_source_after
79
71
  end
80
72
 
81
73
  # Resets the value of +name+ to its original value. If it is inherited from
@@ -86,8 +78,8 @@ module Autobuild
86
78
  inherited_environment.delete(name)
87
79
  env_init_from_env(name)
88
80
  else
89
- environment.keys.each do |name|
90
- env_reset(name)
81
+ environment.keys.each do |env_key|
82
+ env_reset(env_key)
91
83
  end
92
84
  end
93
85
  end
@@ -105,15 +97,15 @@ module Autobuild
105
97
  inherited_environment[name] = nil
106
98
  env_update_var(name)
107
99
  else
108
- environment.keys.each do |name|
109
- env_clear(name)
100
+ environment.keys.each do |env_key|
101
+ env_clear(env_key)
110
102
  end
111
103
  end
112
104
  end
113
105
 
114
106
  # Set a new environment variable
115
107
  def self.env_set(name, *values)
116
- env_reset(name)
108
+ environment.delete(name)
117
109
  env_add(name, *values)
118
110
  end
119
111
 
@@ -160,10 +152,26 @@ module Autobuild
160
152
  #
161
153
  # @see env_inherit? env_inherit=
162
154
  def self.env_inherit(*names)
163
- @env_inherited_variables |= names
164
- names.each do |env_name|
165
- env_init_from_env(env_name)
155
+ flag =
156
+ if !names.last.respond_to?(:to_str)
157
+ names.pop
158
+ else true
159
+ end
160
+
161
+ if flag
162
+ @env_inherited_variables |= names
163
+ names.each do |env_name|
164
+ env_init_from_env(env_name)
165
+ end
166
+ else
167
+ names.each do |n|
168
+ if @env_inherited_variables.include?(n)
169
+ @env_inherited_variables.delete(n)
170
+ env_init_from_env(n)
171
+ end
172
+ end
166
173
  end
174
+
167
175
  @env_inherit
168
176
  end
169
177
 
@@ -266,7 +274,7 @@ module Autobuild
266
274
  end
267
275
 
268
276
  def self.env_add_path(name, *paths)
269
- oldpath = environment[name] || Array.new
277
+ oldpath = (environment[name] ||= Array.new)
270
278
  paths.reverse.each do |path|
271
279
  next if oldpath.include?(path)
272
280
 
@@ -286,9 +294,8 @@ module Autobuild
286
294
  end
287
295
 
288
296
  def self.env_push_path(name, *values)
289
- if current = environment[name]
297
+ if current = environment.delete(name)
290
298
  current = current.dup
291
- env_clear(name)
292
299
  env_add_path(name, *values)
293
300
  env_add_path(name, *current)
294
301
  else
@@ -302,16 +309,34 @@ module Autobuild
302
309
  env_source_after(file)
303
310
  end
304
311
 
305
- # Require that generated environment variable scripts source the given shell
306
- # script
307
- def self.env_source_before(file)
308
- @env_source_before << file
312
+ # @overload env_source_before
313
+ # List of scripts that should be sourced at the top of env.sh
314
+ #
315
+ # @return [Array<String>] a list of paths that should be sourced at the
316
+ # beginning of the shell script generated by {export_env_sh}
317
+ #
318
+ # @overload env_source_before(path)
319
+ # @param [String] path a path that should be added to env_source_before
320
+ #
321
+ def self.env_source_before(file = nil)
322
+ if file
323
+ @env_source_before << file
324
+ end
309
325
  end
310
326
 
311
- # Require that generated environment variable scripts source the given shell
312
- # script
313
- def self.env_source_after(file)
314
- @env_source_after << file
327
+ # @overload env_source_after
328
+ # List of scripts that should be sourced at the end of env.sh
329
+ #
330
+ # @return [Array<String>] a list of paths that should be sourced at the
331
+ # end of the shell script generated by {export_env_sh}
332
+ #
333
+ # @overload env_source_after(path)
334
+ # @param [String] path a path that should be added to env_source_after
335
+ #
336
+ def self.env_source_after(file = nil)
337
+ if file
338
+ @env_source_after << file
339
+ end
315
340
  end
316
341
 
317
342
  # Generates a shell script that sets the environment variable listed in
@@ -5,12 +5,16 @@ module Autobuild
5
5
  def mail?; false end
6
6
  ## If the error is fatal
7
7
  def fatal?; true end
8
+ ## If the error can be retried
9
+ def retry?; @retry end
8
10
  attr_accessor :target, :phase
9
11
 
10
12
  ## Creates a new exception which occured while doing *phase*
11
13
  # in *target*
12
- def initialize(target = nil, phase = nil)
14
+ def initialize(target = nil, phase = nil, options = Hash.new)
15
+ options = Kernel.validate_options options, retry: true
13
16
  @target, @phase = target, phase
17
+ @retry = options[:retry]
14
18
  end
15
19
 
16
20
  alias :exception_message :to_s
@@ -36,10 +40,27 @@ module Autobuild
36
40
  end
37
41
 
38
42
  ## There is an error/inconsistency in the configuration
39
- class ConfigException < Exception; end
43
+ class ConfigException < Exception
44
+ def initialize(target = nil, phase = nil, options = Hash.new)
45
+ options, other_options = Kernel.filter_options options,
46
+ retry: false
47
+ super(target, phase, options.merge(other_options))
48
+ end
49
+ end
40
50
  ## An error occured in a package
41
51
  class PackageException < Exception
42
52
  def mail?; true end
53
+
54
+ def initialize(target = nil, phase = nil, options = Hash.new)
55
+ options, other_options = Kernel.filter_options options,
56
+ retry: false
57
+ super(target, phase, options.merge(other_options))
58
+ end
59
+ end
60
+
61
+ # Exception thrown by importers when calling update with the reset flag but
62
+ # some conditiions make the reset impossible
63
+ class ImporterCannotReset < PackageException
43
64
  end
44
65
 
45
66
  ## The subcommand is not found
@@ -47,48 +68,53 @@ module Autobuild
47
68
  ## An error occured while running a subcommand
48
69
  class SubcommandFailed < Exception
49
70
  def mail?; true end
50
- attr_reader :command, :logfile, :status
71
+ attr_writer :retry
72
+ attr_reader :command, :logfile, :status, :output
51
73
  def initialize(*args)
52
74
  if args.size == 1
53
75
  sc = args[0]
54
- target, command, logfile, status =
55
- sc.target, sc.command, sc.logfile, sc.status
76
+ target, command, logfile, status, output =
77
+ sc.target, sc.command, sc.logfile, sc.status, sc.output
56
78
  @orig_message = sc.exception_message
57
- elsif args.size == 4
58
- target, command, logfile, status = *args
79
+ elsif args.size == 4 || args.size == 5
80
+ target, command, logfile, status, output = *args
59
81
  else
60
- raise ArgumentError, "wrong number of arguments, should be 1 or 4"
82
+ raise ArgumentError, "wrong number of arguments, should be 1 or 4..5"
61
83
  end
62
84
 
63
85
  super(target)
64
86
  @command = command
65
87
  @logfile = logfile
66
88
  @status = status
89
+ @output = output || Array.new
67
90
  end
68
91
 
69
- ERROR_LINES = 10
70
-
71
92
  def to_s
72
- prefix = super
93
+ msg = super
73
94
  if @orig_message
74
- prefix << "\n #{@orig_message}"
95
+ msg << "\n #{@orig_message}"
75
96
  end
76
- prefix << "\n see #{logfile} for details"
97
+ msg << "\n see #{logfile} for details"
77
98
 
78
99
  # If we do not have a status, it means an error occured in the
79
100
  # launching process. More importantly, it means we already have a
80
101
  # proper explanation for it. Don't display the logfile at all.
81
- if status
82
- lines = File.readlines(logfile)
83
- if lines.size > ERROR_LINES
84
- lines = lines[-ERROR_LINES, ERROR_LINES]
85
- end
86
- prefix << "\n last #{lines.size} lines are:\n\n"
87
- lines.each do |l|
88
- prefix << " #{l}"
102
+ if status
103
+ if File.file?(logfile)
104
+ lines = File.readlines(logfile)
105
+ logsize = Autobuild.displayed_error_line_count
106
+ if logsize != Float::INFINITY && lines.size > logsize
107
+ lines = lines[-logsize, logsize]
108
+ end
109
+ msg << "\n last #{lines.size} lines are:\n\n"
110
+ lines.each do |l|
111
+ msg << " #{l}"
112
+ end
113
+ else
114
+ msg << "\n the log file does not seem to be present on disk anymore"
89
115
  end
90
116
  end
91
- prefix
117
+ msg
92
118
  end
93
119
  end
94
120
  end
@@ -72,14 +72,25 @@ module Autobuild
72
72
  @cachedir = nil
73
73
 
74
74
  # Returns the unpack mode from the file name
75
- def self.filename_to_mode(filename)
75
+ #
76
+ # @return [Integer,nil] either one of the pack constants (Zip, Plain,
77
+ # ...) or nil if it cannot be inferred
78
+ # @see filename_to_mode
79
+ def self.find_mode_from_filename(filename)
76
80
  case filename
77
- when /\.zip$/; Zip
78
- when /\.tar$/; Plain
79
- when /\.tar\.gz$|\.tgz$/; Gzip
80
- when /\.bz2$/; Bzip
81
- else
82
- raise "unknown file type '#{filename}'"
81
+ when /\.zip$/; Zip
82
+ when /\.tar$/; Plain
83
+ when /\.tar\.gz$|\.tgz$/; Gzip
84
+ when /\.bz2$/; Bzip
85
+ end
86
+ end
87
+
88
+ # Returns the unpack mode from the file name
89
+ def self.filename_to_mode(filename)
90
+ if mode = find_mode_from_filename(filename)
91
+ mode
92
+ else
93
+ raise "cannot infer the archive type from '#{filename}', use the mode: option"
83
94
  end
84
95
  end
85
96
 
@@ -183,7 +194,7 @@ module Autobuild
183
194
  if retries = self.retries
184
195
  additional_options << "--tries" << retries
185
196
  end
186
- Subprocess.run(package, :import, Autobuild.tool('wget'), '-q', '-P', cachedir, *additional_options, @url, '-O', "#{cachefile}.partial")
197
+ package.run(:import, Autobuild.tool('wget'), '-q', '-P', cachedir, *additional_options, @url, '-O', "#{cachefile}.partial", retry: true)
187
198
  end
188
199
  rescue Exception
189
200
  FileUtils.rm_f "#{cachefile}.partial"
@@ -233,6 +244,16 @@ module Autobuild
233
244
  # It defaults to the global ArchiveImporter.retries
234
245
  attr_accessor :retries
235
246
 
247
+ # The filename that should be used locally (for remote files)
248
+ #
249
+ # This is usually inferred by using the URL's basename, but some
250
+ # download URLs do not allow this (for instance bitbucket tarballs)
251
+ #
252
+ # Change it by calling {relocate}
253
+ #
254
+ # @retun [String]
255
+ attr_reader :filename
256
+
236
257
  # The timeout (in seconds) used during downloading.
237
258
  #
238
259
  # With wget, it is the timeout used for DNS resolution, connection and
@@ -279,9 +300,9 @@ module Autobuild
279
300
  @repository_id = options[:repository_id] || parsed_url
280
301
  @source_id = options[:source_id] || parsed_url
281
302
 
282
- filename = options[:filename] || File.basename(url).gsub(/\?.*/, '')
303
+ @filename = options[:filename] || @filename || File.basename(url).gsub(/\?.*/, '')
283
304
 
284
- @mode = options[:mode] || ArchiveImporter.filename_to_mode(filename)
305
+ @mode = options[:mode] || ArchiveImporter.find_mode_from_filename(filename) || @mode
285
306
  if @url.scheme == 'file'
286
307
  @cachefile = @url.path
287
308
  else
@@ -289,9 +310,9 @@ module Autobuild
289
310
  end
290
311
  end
291
312
 
292
- def update(package,only_local = false) # :nodoc:
293
- if only_local
294
- Autobuild.warn "The importer #{self.class} does not support local updates, skipping #{self}"
313
+ def update(package, options = Hash.new) # :nodoc:
314
+ if options[:only_local]
315
+ package.warn "%s: the archive importer does not support local updates, skipping"
295
316
  return
296
317
  end
297
318
  needs_update = update_cache(package)
@@ -368,7 +389,7 @@ module Autobuild
368
389
 
369
390
  FileUtils.mkdir_p base_dir
370
391
  cmd = [ '-o', cachefile, '-d', main_dir ]
371
- Subprocess.run(package, :import, Autobuild.tool('unzip'), *cmd)
392
+ package.run(:import, Autobuild.tool('unzip'), *cmd)
372
393
 
373
394
  archive_dir = (self.archive_dir || File.basename(package.name))
374
395
  if archive_dir != File.basename(package.srcdir)
@@ -387,13 +408,13 @@ module Autobuild
387
408
  if(WINDOWS)
388
409
  extract_tar_on_windows(cachefile,package.srcdir)
389
410
  else
390
- Subprocess.run(package, :import, Autobuild.tool('tar'), *cmd)
411
+ package.run(:import, Autobuild.tool('tar'), *cmd)
391
412
  end
392
413
  end
393
414
  write_checkout_digest_stamp(package)
394
415
 
395
416
  rescue OpenURI::HTTPError
396
- raise Autobuild::Exception.new(package.name, :import)
417
+ raise Autobuild::PackageException.new(package.name, :import)
397
418
  rescue SubcommandFailed
398
419
  FileUtils.rm_f cachefile
399
420
  raise