autobuild 1.8.3 → 1.9.0.b1

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