autobuild 1.5.20 → 1.5.21.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,15 @@
1
+ == Version 1.5.21
2
+ * add an argument to status() to avoid using the network (for importers that can
3
+ do that, i.e. git)
4
+ * disable changing the subprocess priorities by default. This is so that people
5
+ can use 'nice' on the autobuild script if they don't know that autobuild
6
+ supports changing the priority itself.
7
+ * add the Autobuild.ignore_errors option. If set, the build will go on even if
8
+ some errors occur. Errors are properly reported at the end of the build.
9
+ * git: update branch tracking information to track the specified branch
10
+ * git: offer a way to specify a push URL, in cases where having separate
11
+ read-only and read-write URLs make sense.
12
+
1
13
  == Version 1.5.20
2
14
  * cmake: inform the user if a CMake configuration value gets changed
3
15
 
@@ -1,6 +1,7 @@
1
1
  require 'optparse'
2
2
  require 'rake'
3
3
  require 'singleton'
4
+ require 'highline'
4
5
 
5
6
  # Evaluates +script+ in autobuild context
6
7
  def Autobuild(&script)
@@ -43,12 +44,22 @@ module Autobuild
43
44
  # The directory in which logs are saved. Defaults to PREFIX/log.
44
45
  attr_writer :logdir
45
46
 
47
+ # A HighLine object that allows to colorize the output
48
+ attr_reader :console
49
+
46
50
  # True if we build and if the build is applied on all packages
47
51
  def full_build?
48
52
  do_build && !only_doc && packages.empty?
49
53
  end
50
54
  end
51
- DEFAULT_OPTIONS = { :nice => 0,
55
+
56
+ @console = HighLine.new
57
+
58
+ def self.color(*args)
59
+ console.color(*args)
60
+ end
61
+
62
+ DEFAULT_OPTIONS = { :nice => nil,
52
63
  :srcdir => Dir.pwd, :prefix => Dir.pwd, :logdir => nil,
53
64
  :verbose => false, :debug => false, :do_build => true, :do_forced_build => false, :do_rebuild => false, :do_update => true,
54
65
  :daemonize => false, :packages => [], :default_packages => [],
@@ -76,22 +76,26 @@ module Autobuild
76
76
 
77
77
  def prepare
78
78
  Autobuild.source_tree srcdir do |pkg|
79
- pkg.exclude << Regexp.new("^#{Regexp.quote(builddir)}")
79
+ pkg.exclude << Regexp.new("^#{Regexp.quote(builddir)}")
80
80
  pkg.exclude << Regexp.new("^#{doc_dir}") if doc_dir
81
- end
81
+ end
82
82
 
83
83
  super
84
84
 
85
85
  stamps = dependencies.map { |pkg| Autobuild::Package[pkg].installstamp }
86
86
  file configurestamp => stamps do
87
- ensure_dependencies_installed
88
- configure
87
+ isolate_errors do
88
+ ensure_dependencies_installed
89
+ configure
90
+ end
89
91
  end
90
92
  task "#{name}-prepare" => configurestamp
91
93
 
92
94
  file buildstamp => [ srcdir, configurestamp ] do
93
- ensure_dependencies_installed
94
- build
95
+ isolate_errors do
96
+ ensure_dependencies_installed
97
+ build
98
+ end
95
99
  end
96
100
  task "#{name}-build" => buildstamp
97
101
 
@@ -116,4 +120,3 @@ module Autobuild
116
120
  end
117
121
  end
118
122
 
119
-
@@ -28,10 +28,11 @@ module Autobuild
28
28
  STDERR.puts "WARN: Autobuild.git 'git://github.com/doudou/autobuild.git', :branch => 'master'"
29
29
  end
30
30
 
31
- gitopts, common = Kernel.filter_options options, :branch => nil, :tag => nil, :commit => nil
31
+ gitopts, common = Kernel.filter_options options, :push_to => nil, :branch => nil, :tag => nil, :commit => nil
32
32
  if gitopts[:branch] && branch
33
33
  raise ConfigException, "git branch specified with both the option hash and the explicit parameter"
34
34
  end
35
+ @push_to = gitopts[:push_to]
35
36
  branch = gitopts[:branch] || branch
36
37
  tag = gitopts[:tag]
37
38
  commit = gitopts[:commit]
@@ -45,8 +46,18 @@ module Autobuild
45
46
  super(common)
46
47
  end
47
48
 
49
+ # The remote repository URL.
50
+ #
51
+ # See also #push_to
48
52
  attr_accessor :repository
49
53
 
54
+ # If set, this URL will be listed as a pushurl for the tracked branch.
55
+ # It makes it possible to have a read-only URL for fetching and specify
56
+ # a push URL for people that have commit rights
57
+ #
58
+ # #repository is always used for read-only operations
59
+ attr_reader :push_to
60
+
50
61
  # The branch this importer is tracking
51
62
  #
52
63
  # If set, both commit and tag have to be nil.
@@ -87,8 +98,18 @@ module Autobuild
87
98
  # Update the remote definition
88
99
  Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
89
100
  "--replace-all", "remote.autobuild.url", repository)
101
+ if push_to
102
+ Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
103
+ "--replace-all", "remote.autobuild.pushurl", push_to)
104
+ end
90
105
  Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
91
106
  "--replace-all", "remote.autobuild.fetch", "+refs/heads/*:refs/remotes/autobuild/*")
107
+ if branch
108
+ Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
109
+ "--replace-all", "branch.#{branch}.remote", "autobuild")
110
+ Subprocess.run(package, :import, Autobuild.tool('git'), 'config',
111
+ "--replace-all", "branch.#{branch}.merge", "refs/heads/#{branch}")
112
+ end
92
113
 
93
114
  # We are checking out a specific commit. We just call git fetch
94
115
  if commit
@@ -119,12 +140,19 @@ module Autobuild
119
140
 
120
141
  # Returns a Importer::Status object that represents the status of this
121
142
  # package w.r.t. the root repository
122
- def status(package)
123
- validate_srcdir(package)
143
+ def status(package, only_local = false)
124
144
  Dir.chdir(package.srcdir) do
125
- remote_commit = fetch_remote(package)
126
- if !remote_commit
127
- return
145
+ validate_srcdir(package)
146
+ remote_commit = nil
147
+ if only_local
148
+ Dir.chdir(package.srcdir) do
149
+ remote_commit = `git show-ref -s refs/heads/#{branch}`.chomp
150
+ end
151
+ else
152
+ remote_commit = fetch_remote(package)
153
+ if !remote_commit
154
+ return
155
+ end
128
156
  end
129
157
 
130
158
  status = merge_status(remote_commit)
@@ -4,6 +4,10 @@ require 'autobuild/subcommand'
4
4
 
5
5
  module Autobuild
6
6
  TARGETS = %w{import prepare build}
7
+
8
+ class << self
9
+ attr_accessor :ignore_errors
10
+ end
7
11
 
8
12
  # Basic block for the autobuilder
9
13
  #
@@ -112,11 +116,15 @@ module Autobuild
112
116
  @doc_target_dir ||= name
113
117
 
114
118
  # Define the default tasks
115
- task "#{name}-import" do import end
119
+ task "#{name}-import" do
120
+ isolate_errors { import }
121
+ end
116
122
  task :import => "#{name}-import"
117
123
 
118
124
  # Define the prepare task
119
- task "#{name}-prepare" => "#{name}-import" do prepare end
125
+ task "#{name}-prepare" => "#{name}-import" do
126
+ isolate_errors { prepare }
127
+ end
120
128
  task :prepare => "#{name}-prepare"
121
129
 
122
130
  task "#{name}-build" => "#{name}-prepare"
@@ -154,14 +162,53 @@ module Autobuild
154
162
  end
155
163
  end
156
164
 
165
+ # Returns true if one of the operations applied on this package failed
166
+ def failed?
167
+ !!@failure
168
+ end
169
+
170
+ # If something failed on this package, returns the corresponding
171
+ # exception object. Otherwise, returns nil
172
+ attr_reader :failure
173
+
174
+ # If Autobuild.ignore_errors is set, an exception raised from within the
175
+ # provided block will be filtered out, only displaying a message instead
176
+ # of stopping the build
177
+ #
178
+ # Moreover, the package will be marked as "failed" and isolate_errors
179
+ # will subsequently be a noop. I.e. if +build+ fails, +install+ will do
180
+ # nothing.
181
+ def isolate_errors
182
+ # Don't do anything if we already have failed
183
+ return if failed?
184
+
185
+ begin yield
186
+ rescue Exception => e
187
+ @failure = e
188
+
189
+ if Autobuild.ignore_errors
190
+ lines = e.to_s.split("\n")
191
+ progress(lines.shift, :red, :bold)
192
+ lines.each do |line|
193
+ progress(line)
194
+ end
195
+ nil
196
+ else
197
+ raise
198
+ end
199
+ end
200
+ end
201
+
157
202
  # Call the importer if there is one. Autodetection of "provides" should
158
203
  # be done there as well. See the documentation of Autobuild::Package for
159
204
  # more information.
160
205
  def import
161
- @importer.import(self) if @importer
206
+ if @importer
207
+ @importer.import(self)
208
+ end
162
209
 
163
- # Add the dependencies declared in spec
164
- depends_on *@spec_dependencies if @spec_dependencies
210
+ # Add the dependencies declared in spec
211
+ depends_on *@spec_dependencies if @spec_dependencies
165
212
 
166
213
  if File.directory?(prefix)
167
214
  Autobuild.update_environment prefix
@@ -176,22 +223,36 @@ module Autobuild
176
223
 
177
224
  stamps = dependencies.map { |p| Package[p].installstamp }
178
225
 
179
- file installstamp => stamps do
180
- install
181
- end
226
+ file installstamp => stamps do
227
+ isolate_errors { install }
228
+ end
182
229
  task "#{name}-build" => installstamp
183
230
  end
184
231
 
185
232
  # Display a progress message. %s in the string is replaced by the
186
233
  # package name
187
- def progress(msg)
188
- Autobuild.progress(msg % [name])
234
+ def progress(*args)
235
+ if !args.empty?
236
+ begin args[0] = args[0] % [name]
237
+ rescue ArgumentError
238
+ # Don't try to format strings that can't be formatted
239
+ end
240
+
241
+ Autobuild.progress(*args)
242
+ else
243
+ Autobuild.progress
244
+ end
189
245
  end
190
246
 
191
247
  # Display a progress message, and later on update it with a progress
192
248
  # value. %s in the string is replaced by the package name
193
- def progress_with_value(msg)
194
- Autobuild.progress_with_value(msg % [name])
249
+ def progress_with_value(*args)
250
+ if !args.empty?
251
+ args[0] = args[0] % [name]
252
+ Autobuild.progress_with_value(*args)
253
+ else
254
+ Autobuild.progress_with_value
255
+ end
195
256
  end
196
257
 
197
258
  def progress_value(value)
@@ -179,6 +179,7 @@ module Autobuild
179
179
  end
180
180
 
181
181
  file conffile do
182
+ isolate_errors do
182
183
  Dir.chdir(srcdir) do
183
184
  if using[:autogen].nil?
184
185
  using[:autogen] = %w{autogen autogen.sh}.find { |f| File.exists?(f) }
@@ -205,6 +206,7 @@ module Autobuild
205
206
  end
206
207
  end
207
208
  end
209
+ end
208
210
  end
209
211
 
210
212
  return conffile
@@ -131,19 +131,23 @@ module Autobuild
131
131
  file buildstamp => genomstamp
132
132
  file genomstamp => genom_dependencies
133
133
  file genomstamp => srcdir do
134
- Dir.chdir(srcdir) do
135
- progress "generating GenoM files for %s"
136
- Subprocess.run(self, 'genom', *cmdline)
137
- end
134
+ isolate_errors do
135
+ Dir.chdir(srcdir) do
136
+ progress "generating GenoM files for %s"
137
+ Subprocess.run(self, 'genom', *cmdline)
138
+ end
139
+ end
138
140
  end
139
141
 
140
142
  acuser = File.join(srcdir, "configure.ac.user")
141
143
  file File.join(srcdir, 'configure') => acuser do
142
- # configure does not depend on the .gen file
143
- # since the generation takes care of rebuilding configure
144
- # if .gen has changed
145
- progress "generating build system for %s"
146
- Dir.chdir(srcdir) { Subprocess.run(self, 'genom', File.expand_path('autogen')) }
144
+ isolate_errors do
145
+ # configure does not depend on the .gen file
146
+ # since the generation takes care of rebuilding configure
147
+ # if .gen has changed
148
+ progress "generating build system for %s"
149
+ Dir.chdir(srcdir) { Subprocess.run(self, 'genom', File.expand_path('autogen')) }
150
+ end
147
151
  end
148
152
 
149
153
  super("#{srcdir}/autoconf/configure.ac")
@@ -272,7 +272,7 @@ module Autobuild
272
272
 
273
273
  file configurestamp => genstamp
274
274
  file genstamp => File.join(srcdir, orogen_file) do
275
- regen
275
+ isolate_errors { regen }
276
276
  end
277
277
 
278
278
  with_doc
@@ -15,24 +15,52 @@ require 'autobuild/config'
15
15
  require 'autobuild/exceptions'
16
16
 
17
17
  module Autobuild
18
- def self.progress(msg)
18
+ def self.progress(*args)
19
19
  if @last_msg
20
20
  progress_value(100)
21
21
  puts
22
22
  end
23
23
  @last_msg = nil
24
- puts " #{msg}"
24
+
25
+ if args.empty?
26
+ puts
27
+ else
28
+ puts " #{color(*args)}"
29
+ end
25
30
  end
26
- def self.progress_with_value(msg)
31
+ def self.progress_with_value(*args)
27
32
  if @last_msg
28
33
  progress_value(100)
29
34
  puts
30
35
  end
31
- @last_msg = msg
32
- print " #{msg}"
36
+ @last_msg = " #{color(args[0], *args[1..-1])}"
37
+
38
+ print @last_msg
33
39
  end
34
40
  def self.progress_value(value)
35
- print "\r #{@last_msg} (#{value}%)"
41
+ print "\r#{@last_msg} (#{value}%)"
42
+ end
43
+
44
+ # The exception type that is used to report multiple errors that occured
45
+ # when ignore_errors is set
46
+ class CompositeException < Autobuild::Exception
47
+ # The array of exception objects representing all the errors that
48
+ # occured during the build
49
+ attr_reader :original_errors
50
+
51
+ def initialize(original_errors)
52
+ @original_errors = original_errors
53
+ end
54
+
55
+ def mail?; true end
56
+
57
+ def to_s
58
+ result = ["#{original_errors.size} errors occured"]
59
+ original_errors.each_with_index do |e, i|
60
+ result << "(#{i}) #{e.to_s}"
61
+ end
62
+ result.join("\n")
63
+ end
36
64
  end
37
65
 
38
66
  ## The reporting module provides the framework
@@ -48,6 +76,21 @@ module Autobuild
48
76
  def self.report
49
77
  begin
50
78
  yield
79
+
80
+ # If ignore_erorrs is true, check if some packages have failed
81
+ # on the way. If so, raise an exception to inform the user about
82
+ # it
83
+ errors = []
84
+ Autobuild::Package.each do |name, pkg|
85
+ if pkg.failed?
86
+ errors << pkg.failure
87
+ end
88
+ end
89
+
90
+ if !errors.empty?
91
+ raise CompositeException.new(errors)
92
+ end
93
+
51
94
  rescue Autobuild::Exception => e
52
95
  error(e)
53
96
  exit(1) if e.fatal?
@@ -143,7 +143,9 @@ module Autobuild::Subprocess
143
143
  pid = fork do
144
144
  cwrite.sync = true
145
145
  begin
146
- Process.setpriority(Process::PRIO_PROCESS, 0, Autobuild.nice)
146
+ if Autobuild.nice
147
+ Process.setpriority(Process::PRIO_PROCESS, 0, Autobuild.nice)
148
+ end
147
149
 
148
150
  if outwrite
149
151
  outread.close
@@ -1,5 +1,5 @@
1
1
  module Autobuild
2
- VERSION = "1.5.20" unless defined? Autobuild::VERSION
2
+ VERSION = "1.5.21.rc1" 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: 43
5
- prerelease: false
4
+ prerelease: true
6
5
  segments:
7
6
  - 1
8
7
  - 5
9
- - 20
10
- version: 1.5.20
8
+ - 21
9
+ - rc1
10
+ version: 1.5.21.rc1
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: 2010-08-16 00:00:00 +02:00
18
+ date: 2010-10-21 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -26,7 +26,6 @@ dependencies:
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- hash: 3
30
29
  segments:
31
30
  - 0
32
31
  - 7
@@ -42,7 +41,6 @@ dependencies:
42
41
  requirements:
43
42
  - - ">="
44
43
  - !ruby/object:Gem::Version
45
- hash: 15
46
44
  segments:
47
45
  - 1
48
46
  - 0
@@ -57,7 +55,6 @@ dependencies:
57
55
  requirements:
58
56
  - - ">="
59
57
  - !ruby/object:Gem::Version
60
- hash: 11
61
58
  segments:
62
59
  - 0
63
60
  - 0
@@ -72,7 +69,6 @@ dependencies:
72
69
  requirements:
73
70
  - - ">="
74
71
  - !ruby/object:Gem::Version
75
- hash: 29
76
72
  segments:
77
73
  - 1
78
74
  - 3
@@ -88,7 +84,6 @@ dependencies:
88
84
  requirements:
89
85
  - - ">="
90
86
  - !ruby/object:Gem::Version
91
- hash: 7
92
87
  segments:
93
88
  - 2
94
89
  - 0
@@ -104,12 +99,11 @@ dependencies:
104
99
  requirements:
105
100
  - - ">="
106
101
  - !ruby/object:Gem::Version
107
- hash: 21
108
102
  segments:
109
103
  - 2
110
104
  - 6
111
- - 1
112
- version: 2.6.1
105
+ - 2
106
+ version: 2.6.2
113
107
  type: :development
114
108
  version_requirements: *id006
115
109
  description: |-
@@ -196,19 +190,19 @@ required_ruby_version: !ruby/object:Gem::Requirement
196
190
  requirements:
197
191
  - - ">="
198
192
  - !ruby/object:Gem::Version
199
- hash: 3
200
193
  segments:
201
194
  - 0
202
195
  version: "0"
203
196
  required_rubygems_version: !ruby/object:Gem::Requirement
204
197
  none: false
205
198
  requirements:
206
- - - ">="
199
+ - - ">"
207
200
  - !ruby/object:Gem::Version
208
- hash: 3
209
201
  segments:
210
- - 0
211
- version: "0"
202
+ - 1
203
+ - 3
204
+ - 1
205
+ version: 1.3.1
212
206
  requirements: []
213
207
 
214
208
  rubyforge_project: autobuild
@@ -217,7 +211,7 @@ signing_key:
217
211
  specification_version: 3
218
212
  summary: Rake-based utility to build and install multiple packages with dependencies
219
213
  test_files:
220
- - test/test_import_tar.rb
221
- - test/test_import_cvs.rb
222
214
  - test/test_import_svn.rb
215
+ - test/test_import_tar.rb
223
216
  - test/test_subcommand.rb
217
+ - test/test_import_cvs.rb