autobuild 0.4 → 0.5
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.
- data/CHANGES +57 -0
- data/README +29 -46
- data/Rakefile +161 -0
- data/lib/autobuild/config-interpolator.rb +80 -91
- data/lib/autobuild/config.rb +21 -6
- data/lib/autobuild/environment.rb +13 -11
- data/lib/autobuild/exceptions.rb +46 -45
- data/lib/autobuild/import/cvs.rb +34 -39
- data/lib/autobuild/import/svn.rb +23 -29
- data/lib/autobuild/import/tar.rb +120 -0
- data/lib/autobuild/importer.rb +4 -6
- data/lib/autobuild/options.rb +18 -11
- data/lib/autobuild/package.rb +1 -1
- data/lib/autobuild/packages/autotools.rb +107 -121
- data/lib/autobuild/packages/genom.rb +56 -62
- data/lib/autobuild/packages/import.rb +14 -12
- data/lib/autobuild/reporting.rb +91 -55
- data/lib/autobuild/subcommand.rb +89 -46
- data/lib/autobuild/timestamps.rb +47 -37
- metadata +43 -78
- data/bin/autobuild +0 -83
- data/test/base.rb +0 -8
- data/test/tc_config.rb +0 -40
- data/test/tc_config_interpolation.rb +0 -57
- data/test/tc_import.rb +0 -77
- data/test/tc_subcommand.rb +0 -61
- data/test/tools.rb +0 -39
@@ -1,20 +1,22 @@
|
|
1
1
|
require 'autobuild/timestamps'
|
2
2
|
require 'autobuild/package'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
def initialize(target, options)
|
9
|
-
super(target, options)
|
10
|
-
source_tree srcdir, installstamp
|
11
|
-
file installstamp => srcdir do
|
12
|
-
touch_stamp installstamp
|
4
|
+
module Autobuild
|
5
|
+
class ImporterPackage < Package
|
6
|
+
def installstamp
|
7
|
+
"#{srcdir}/#{STAMPFILE}"
|
13
8
|
end
|
14
|
-
|
15
|
-
|
9
|
+
def initialize(target, options)
|
10
|
+
super(target, options)
|
11
|
+
source_tree srcdir, installstamp
|
12
|
+
file installstamp => srcdir do
|
13
|
+
touch_stamp installstamp
|
14
|
+
end
|
15
|
+
end
|
16
|
+
def prepare; end
|
16
17
|
|
17
|
-
|
18
|
+
factory :import, ImporterPackage
|
19
|
+
end
|
18
20
|
end
|
19
21
|
|
20
22
|
|
data/lib/autobuild/reporting.rb
CHANGED
@@ -2,77 +2,113 @@ require 'rmail'
|
|
2
2
|
require 'rmail/serialize'
|
3
3
|
require 'net/smtp'
|
4
4
|
require 'socket'
|
5
|
+
require 'etc'
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
7
|
+
require 'autobuild/exceptions'
|
8
|
+
|
9
|
+
module Autobuild
|
10
|
+
class Reporting
|
11
|
+
@@reporters = Array.new
|
12
|
+
|
13
|
+
def self.report
|
14
|
+
begin
|
15
|
+
yield
|
16
|
+
rescue Autobuild::Exception => e
|
17
|
+
raise unless e.kind_of?(Autobuild::Exception)
|
18
|
+
error(e)
|
19
|
+
exit(1) if e.fatal?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.success
|
24
|
+
@@reporters.each do |rep| rep.success end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.error(error)
|
28
|
+
@@reporters.each do |rep| rep.error(error) end
|
14
29
|
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.success
|
18
|
-
message = "Build finished successfully at #{Time.now}"
|
19
|
-
puts message
|
20
|
-
send_mail("Build success", message) if $MAIL
|
21
|
-
end
|
22
30
|
|
23
|
-
|
24
|
-
|
25
|
-
body = <<EOF
|
26
|
-
#{object.target}: #{object.message}
|
27
|
-
command '#{object.command}' failed with status #{object.status}
|
28
|
-
see #{File.basename(object.logfile)} for details
|
29
|
-
EOF
|
30
|
-
|
31
|
-
message = <<EOF
|
32
|
-
#{object.target}: #{object.message}
|
33
|
-
command '#{object.command}' failed with status #{object.status}
|
34
|
-
see #{object.logfile} for details
|
35
|
-
EOF
|
36
|
-
else
|
37
|
-
body = message = "#{object.target}: #{object.message}"
|
31
|
+
def self.<<(reporter)
|
32
|
+
@@reporters << reporter
|
38
33
|
end
|
39
34
|
|
40
|
-
|
41
|
-
|
35
|
+
def self.each_log(&iter)
|
36
|
+
Dir.glob("#{$LOGDIR}/*.log", &iter)
|
37
|
+
end
|
42
38
|
end
|
43
39
|
|
44
|
-
|
40
|
+
class Reporter
|
41
|
+
def error(error); end
|
42
|
+
def success; end
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
45
|
+
class StdoutReporter < Reporter
|
46
|
+
def error(error)
|
47
|
+
puts "Build failed: #{error}"
|
48
|
+
end
|
49
|
+
def success
|
50
|
+
puts "Build finished successfully at #{Time.now}"
|
51
|
+
end
|
52
|
+
end
|
50
53
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
54
|
+
class MailReporter < Reporter
|
55
|
+
def default_mail
|
56
|
+
Etc::endpwent
|
57
|
+
uname = while (pwent = Etc::getpwent)
|
58
|
+
break (pwent.name) if pwent.uid == Process.uid
|
59
|
+
end
|
56
60
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
+
raise "FATAL: cannot find a user with uid=#{Process.uid}" unless uname
|
62
|
+
"#{pwent.name}@#{Socket.gethostname}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def initialize(config)
|
66
|
+
@from = (config[:from] || default_mail)
|
67
|
+
@to = (config[:to] || default_mail)
|
68
|
+
@smtp = (config[:smtp] || "localhost" )
|
69
|
+
@port = Integer(config[:port] || Socket.getservbyname('smtp'))
|
70
|
+
end
|
71
|
+
|
72
|
+
def error(error)
|
73
|
+
if error.mail?
|
74
|
+
send_mail("Build failed", error.to_s)
|
75
|
+
end
|
76
|
+
end
|
61
77
|
|
62
|
-
|
63
|
-
|
64
|
-
mail.add_file(file)
|
78
|
+
def success
|
79
|
+
send_mail("Build success", "finished successfully at #{Time.now}")
|
65
80
|
end
|
66
81
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
82
|
+
def send_mail(subject, body)
|
83
|
+
mail = RMail::Message.new
|
84
|
+
mail.header.date = Time.now
|
85
|
+
mail.header.from = @from
|
86
|
+
mail.header.to = @to
|
87
|
+
mail.header.subject = subject
|
88
|
+
|
89
|
+
part = RMail::Message.new
|
90
|
+
part.header.set('Content-Type', 'text/plain')
|
91
|
+
part.body = body
|
92
|
+
mail.add_part(part)
|
93
|
+
|
94
|
+
# Attach log files
|
95
|
+
Reporting.each_log do |file|
|
96
|
+
mail.add_file(file)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Send the mail
|
100
|
+
smtp = Net::SMTP.new(@smtp, @port)
|
101
|
+
smtp.start {
|
102
|
+
smtp.send_mail RMail::Serialize.write('', mail), @from, @to
|
103
|
+
}
|
104
|
+
|
105
|
+
# Notify the sending
|
106
|
+
puts "Sent notification mail to #{@to} with source #{@from}"
|
107
|
+
|
108
|
+
end
|
72
109
|
end
|
73
110
|
end
|
74
111
|
|
75
|
-
|
76
112
|
module RMail
|
77
113
|
class Message
|
78
114
|
def add_file(path, content_type='text/plain')
|
data/lib/autobuild/subcommand.rb
CHANGED
@@ -1,58 +1,101 @@
|
|
1
1
|
require 'autobuild/reporting'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
puts "#{target}: running #{command.join(" ")}\n (output goes to #{logname})"
|
9
|
-
|
10
|
-
input_streams = command.collect { |o| $1 if o =~ /^\<(.+)/ }.compact
|
11
|
-
command.reject! { |o| o =~ /^\<(.+)/ }
|
12
|
-
|
13
|
-
status = File.open(logname, "a") do |logfile|
|
14
|
-
pread, pwrite = IO.pipe
|
15
|
-
|
16
|
-
pid = fork {
|
17
|
-
Process.setpriority(Process::PRIO_PROCESS, 0, $NICE) if $NICE
|
18
|
-
if $VERBOSE
|
19
|
-
$stderr.dup.reopen(logfile.dup)
|
20
|
-
$stdout.dup.reopen(logfile.dup)
|
21
|
-
else
|
22
|
-
$stderr.reopen(logfile.dup)
|
23
|
-
$stdout.reopen(logfile.dup)
|
24
|
-
end
|
3
|
+
module Autobuild::Subprocess
|
4
|
+
@@nice = 0
|
5
|
+
def self.nice=(value)
|
6
|
+
@@nice = value
|
7
|
+
end
|
25
8
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
9
|
+
class Failed < Exception
|
10
|
+
attr_reader :status
|
11
|
+
def initialize(status = 0)
|
12
|
+
@status = status
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
CONTROL_COMMAND_NOT_FOUND = 1
|
17
|
+
CONTROL_UNEXPECTED = 2
|
18
|
+
def self.run(target, phase, *command)
|
19
|
+
# Filter nil and empty? in command
|
20
|
+
command.reject! { |o| o.nil? || (o.respond_to?(:empty?) && o.empty?) }
|
21
|
+
command.collect! { |o| o.to_s }
|
22
|
+
logname = "#{$LOGDIR}/#{target}-#{phase}.log"
|
23
|
+
|
24
|
+
puts "#{target}: running #{command.join(" ")}\n (output goes to #{logname})"
|
25
|
+
|
26
|
+
input_streams = command.collect { |o| $1 if o =~ /^\<(.+)/ }.compact
|
27
|
+
command.reject! { |o| o =~ /^\<(.+)/ }
|
28
|
+
|
29
|
+
status = File.open(logname, "a") do |logfile|
|
30
|
+
pread, pwrite = IO.pipe # to feed subprocess stdin
|
31
|
+
cread, cwrite = IO.pipe # to control that exec goes well
|
32
|
+
|
33
|
+
pid = fork {
|
34
|
+
cwrite.sync = true
|
35
|
+
begin
|
36
|
+
Process.setpriority(Process::PRIO_PROCESS, 0, @@nice)
|
37
|
+
if $VERBOSE
|
38
|
+
$stderr.dup.reopen(logfile.dup)
|
39
|
+
$stdout.dup.reopen(logfile.dup)
|
40
|
+
else
|
41
|
+
$stderr.reopen(logfile.dup)
|
42
|
+
$stdout.reopen(logfile.dup)
|
43
|
+
end
|
44
|
+
|
45
|
+
if !input_streams.empty?
|
46
|
+
pwrite.close
|
47
|
+
$stdin.reopen(pread)
|
48
|
+
end
|
49
|
+
|
50
|
+
exec(*command)
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
cwrite.write([CONTROL_COMMAND_NOT_FOUND].pack('I'))
|
53
|
+
raise
|
54
|
+
rescue Exception
|
55
|
+
cwrite.write([CONTROL_UNEXPECTED].pack('I'))
|
56
|
+
raise
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
# Feed the input
|
61
|
+
pread.close
|
62
|
+
begin
|
63
|
+
input_streams.each do |infile|
|
64
|
+
File.open(infile) do |instream|
|
65
|
+
instream.each_line { |line| pwrite.write(line) }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
rescue Errno::ENOENT => e
|
69
|
+
raise Failed.new, "cannot open input files: #{e.message}"
|
33
70
|
end
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
71
|
+
pwrite.close
|
72
|
+
|
73
|
+
# Get control status
|
74
|
+
cwrite.close
|
75
|
+
value = cread.read(4)
|
76
|
+
if value
|
77
|
+
# An error occured
|
78
|
+
value = value.unpack('I').first
|
79
|
+
if value == CONTROL_COMMAND_NOT_FOUND
|
80
|
+
raise Failed.new, "file not found"
|
81
|
+
else
|
82
|
+
raise Failed.new, "something unexpected happened"
|
42
83
|
end
|
43
84
|
end
|
44
|
-
|
45
|
-
|
46
|
-
|
85
|
+
|
86
|
+
childpid, childstatus = Process.wait2(pid)
|
87
|
+
childstatus
|
47
88
|
end
|
48
|
-
pwrite.close
|
49
89
|
|
50
|
-
|
51
|
-
|
52
|
-
|
90
|
+
if status.exitstatus > 0
|
91
|
+
raise Failed.new(status.exitstatus), "command returned with status #{status.exitstatus}"
|
92
|
+
end
|
53
93
|
|
54
|
-
|
55
|
-
|
94
|
+
rescue Failed => e
|
95
|
+
error = SubcommandFailed.new(target, command.join(" "), logname, e.status)
|
96
|
+
error.phase = phase
|
97
|
+
raise error, e.message
|
56
98
|
end
|
99
|
+
|
57
100
|
end
|
58
101
|
|
data/lib/autobuild/timestamps.rb
CHANGED
@@ -4,47 +4,57 @@ require 'fileutils'
|
|
4
4
|
|
5
5
|
STAMPFILE = "autobuild-stamp"
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
module Autobuild
|
8
|
+
def tree_timestamp(path, *exclude)
|
9
|
+
# Exclude autobuild timestamps
|
10
|
+
exclude << "*-#{STAMPFILE}"
|
11
|
+
|
12
|
+
puts "getting tree timestamp for #{path}" if $DEBUG
|
13
|
+
latest = Time.at(0)
|
14
|
+
latest_file = ""
|
15
|
+
|
16
|
+
exclude.collect! { |e| File.expand_path(e, path) }
|
17
|
+
Find.find(path) { |p|
|
18
|
+
Find.prune if File.basename(p) =~ /^\./
|
19
|
+
exclude.each { |pattern|
|
20
|
+
if File.fnmatch?(pattern, p)
|
21
|
+
puts " excluding #{p}" if $DEBUG
|
22
|
+
Find.prune
|
23
|
+
end
|
24
|
+
}
|
25
|
+
next if File.directory?(p)
|
26
|
+
|
27
|
+
p_time = File.mtime(p)
|
28
|
+
if latest < p_time
|
29
|
+
latest = p_time
|
30
|
+
latest_file = p
|
31
|
+
end
|
17
32
|
}
|
18
|
-
next if File.directory?(p)
|
19
33
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
latest_file = p
|
24
|
-
end
|
25
|
-
}
|
26
|
-
|
27
|
-
return latest
|
28
|
-
end
|
34
|
+
puts " #{latest}" if $DEBUG
|
35
|
+
return latest
|
36
|
+
end
|
29
37
|
|
30
|
-
class SourceTreeTask < Rake::Task
|
31
|
-
|
32
|
-
|
33
|
-
|
38
|
+
class SourceTreeTask < Rake::Task
|
39
|
+
attr_accessor :exclude
|
40
|
+
def timestamp
|
41
|
+
tree_timestamp(name, "*CVS", *@exclude)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
def source_tree(path, exclude, &block)
|
45
|
+
task = SourceTreeTask.define_task(path, &block)
|
46
|
+
task.exclude = exclude
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_stamp(stampfile)
|
50
|
+
return Time.at(0) if !File.exists?(stampfile)
|
51
|
+
return File.mtime(stampfile)
|
34
52
|
end
|
35
|
-
end
|
36
|
-
def source_tree(path, exclude, &block)
|
37
|
-
task = SourceTreeTask.define_task(path, &block)
|
38
|
-
task.exclude = exclude
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_stamp(stampfile)
|
42
|
-
return Time.at(0) if !File.exists?(stampfile)
|
43
|
-
return File.mtime(stampfile)
|
44
|
-
end
|
45
53
|
|
46
|
-
def touch_stamp(stampfile)
|
47
|
-
|
48
|
-
|
54
|
+
def touch_stamp(stampfile)
|
55
|
+
puts "Touching #{stampfile}" if $DEBUG
|
56
|
+
FileUtils.touch(stampfile)
|
57
|
+
sleep(1)
|
58
|
+
end
|
49
59
|
end
|
50
60
|
|
metadata
CHANGED
@@ -3,100 +3,65 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: autobuild
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: "0.
|
7
|
-
date: 2005-09
|
6
|
+
version: "0.5"
|
7
|
+
date: 2005-12-09 00:00:00 +01:00
|
8
8
|
summary: Rake-based utility to build and install multiple packages with dependencies
|
9
9
|
require_paths:
|
10
|
-
|
11
|
-
- lib
|
10
|
+
- lib
|
12
11
|
email: sylvain.joyeux@m4x.org
|
13
|
-
homepage:
|
14
|
-
rubyforge_project:
|
15
|
-
description:
|
16
|
-
C/C++ autotools packages for now) with dependencies. It can be used in
|
17
|
-
community-based software development to make sure that nothing is broken in the
|
18
|
-
build process of a set of packages."
|
12
|
+
homepage: http://autobuild.rubyforge.org
|
13
|
+
rubyforge_project: autobuild
|
14
|
+
description: Autobuild imports, configures, builds and installs various kinds of software packages. It can be used in software development to make sure that nothing is broken in the build process of a set of packages, or can be used as an automated installation tool.
|
19
15
|
autorequire:
|
20
16
|
default_executable:
|
21
17
|
bindir: bin
|
22
18
|
has_rdoc: true
|
23
19
|
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
24
20
|
requirements:
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
version: 0.0.0
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
29
24
|
version:
|
30
25
|
platform: ruby
|
31
26
|
signing_key:
|
32
27
|
cert_chain:
|
33
28
|
authors:
|
34
|
-
|
29
|
+
- Sylvain Joyeux
|
35
30
|
files:
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
- test/tc_import.rb
|
58
|
-
- test/base.rb
|
59
|
-
- test/data
|
60
|
-
- test/tools.rb
|
31
|
+
- README
|
32
|
+
- Rakefile
|
33
|
+
- CHANGES
|
34
|
+
- lib/autobuild/importer.rb
|
35
|
+
- lib/autobuild/config-interpolator.rb
|
36
|
+
- lib/autobuild/subcommand.rb
|
37
|
+
- lib/autobuild/options.rb
|
38
|
+
- lib/autobuild/environment.rb
|
39
|
+
- lib/autobuild/package.rb
|
40
|
+
- lib/autobuild/reporting.rb
|
41
|
+
- lib/autobuild/timestamps.rb
|
42
|
+
- lib/autobuild/exceptions.rb
|
43
|
+
- lib/autobuild/config.rb
|
44
|
+
- lib/autobuild/import/svn.rb
|
45
|
+
- lib/autobuild/import/cvs.rb
|
46
|
+
- lib/autobuild/import/tar.rb
|
47
|
+
- lib/autobuild/packages/import.rb
|
48
|
+
- lib/autobuild/packages/autotools.rb
|
49
|
+
- lib/autobuild/packages/genom.rb
|
50
|
+
test_files: []
|
51
|
+
|
61
52
|
rdoc_options:
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
53
|
+
- --title
|
54
|
+
- Autobuild
|
55
|
+
- --main
|
56
|
+
- README
|
66
57
|
extra_rdoc_files:
|
67
|
-
|
68
|
-
|
69
|
-
|
58
|
+
- README
|
59
|
+
- CHANGES
|
60
|
+
executables: []
|
61
|
+
|
70
62
|
extensions: []
|
63
|
+
|
71
64
|
requirements: []
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
version_requirement:
|
76
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
77
|
-
requirements:
|
78
|
-
-
|
79
|
-
- ">="
|
80
|
-
- !ruby/object:Gem::Version
|
81
|
-
version: 0.6.0
|
82
|
-
version:
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rmail
|
85
|
-
version_requirement:
|
86
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
87
|
-
requirements:
|
88
|
-
-
|
89
|
-
- ">"
|
90
|
-
- !ruby/object:Gem::Version
|
91
|
-
version: 0.0.0
|
92
|
-
version:
|
93
|
-
- !ruby/object:Gem::Dependency
|
94
|
-
name: daemons
|
95
|
-
version_requirement:
|
96
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
97
|
-
requirements:
|
98
|
-
-
|
99
|
-
- ">"
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: 0.0.0
|
102
|
-
version:
|
65
|
+
|
66
|
+
dependencies: []
|
67
|
+
|