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
data/lib/autobuild/config.rb
CHANGED
@@ -29,7 +29,7 @@ class Hash
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
module Config
|
32
|
+
module Autobuild::Config
|
33
33
|
def self.check_backward_compatibility(config)
|
34
34
|
if config.has_key?('autobuild-config')
|
35
35
|
puts 'WARNING: the \'autobuild-config\' block is now named \'autobuild\''
|
@@ -70,7 +70,7 @@ module Config
|
|
70
70
|
end
|
71
71
|
}
|
72
72
|
|
73
|
-
$VERBOSE = autobuild_config[:verbose]
|
73
|
+
$verbose = $VERBOSE = autobuild_config[:verbose]
|
74
74
|
$trace = $DEBUG = autobuild_config[:debug]
|
75
75
|
|
76
76
|
get_autobuild_config(config)
|
@@ -81,9 +81,10 @@ module Config
|
|
81
81
|
$PROGRAMS = (config[:programs] or "make")
|
82
82
|
|
83
83
|
autobuild = config[:autobuild]
|
84
|
-
$SRCDIR
|
85
|
-
$PREFIX
|
86
|
-
$LOGDIR
|
84
|
+
$SRCDIR = File.expand_path(autobuild[:srcdir], Dir.pwd)
|
85
|
+
$PREFIX = File.expand_path(autobuild[:prefix], Dir.pwd)
|
86
|
+
$LOGDIR = File.expand_path(autobuild[:logdir] || "autobuild/log", $PREFIX)
|
87
|
+
$CACHEDIR = File.expand_path(autobuild[:cachedir] || "autobuild/cache", $PREFIX)
|
87
88
|
|
88
89
|
FileUtils.mkdir_p $SRCDIR if !File.directory?($SRCDIR)
|
89
90
|
FileUtils.mkdir_p $LOGDIR if !File.directory?($LOGDIR)
|
@@ -92,7 +93,21 @@ module Config
|
|
92
93
|
FileUtils.rm_rf Dir.glob("#{$LOGDIR}/*.log")
|
93
94
|
end
|
94
95
|
|
95
|
-
$
|
96
|
+
FileUtils.mkdir_p $CACHEDIR if !File.directory?($CACHEDIR)
|
97
|
+
|
98
|
+
if autobuild[:mail]
|
99
|
+
if autobuild[:mail].respond_to?(:[])
|
100
|
+
mail_config = autobuild[:mail]
|
101
|
+
elsif autobuild[:mail].respond_to?(:to_str)
|
102
|
+
Hash[:to => autobuild[:mail].to_str]
|
103
|
+
elsif autobuild[:mail] == true
|
104
|
+
mail_config = {}
|
105
|
+
else
|
106
|
+
raise ConfigException, "mail configuration should be either a option hash or a string"
|
107
|
+
|
108
|
+
end
|
109
|
+
Reporting << MailReporter.new(mail_config)
|
110
|
+
end
|
96
111
|
$UPDATE = autobuild[:update]
|
97
112
|
$NICE = autobuild[:nice]
|
98
113
|
|
@@ -1,16 +1,18 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
1
|
+
module Autobuild
|
2
|
+
def self.pathvar(path, varname)
|
3
|
+
if File.directory?(path)
|
4
|
+
oldpath = ENV[varname]
|
5
|
+
if oldpath.empty?
|
6
|
+
ENV[varname] = path
|
7
|
+
else
|
8
|
+
ENV[varname] = "#{path}:#{oldpath}"
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
|
-
end
|
11
12
|
|
12
|
-
def update_environment(newprefix)
|
13
|
-
|
14
|
-
|
13
|
+
def self.update_environment(newprefix)
|
14
|
+
pathvar("#{newprefix}/bin", 'PATH')
|
15
|
+
pathvar("#{newprefix}/lib/pkgconfig", 'PKG_CONFIG_PATH')
|
16
|
+
end
|
15
17
|
end
|
16
18
|
|
data/lib/autobuild/exceptions.rb
CHANGED
@@ -1,51 +1,52 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
def initialize(target = nil)
|
19
|
-
@target = target
|
1
|
+
module Autobuild
|
2
|
+
class Exception < RuntimeError
|
3
|
+
def mail?; false end
|
4
|
+
def fatal?; true end
|
5
|
+
attr_accessor :target, :phase
|
6
|
+
|
7
|
+
def initialize(target = nil, phase = nil)
|
8
|
+
@target = target
|
9
|
+
@phase = phase
|
10
|
+
end
|
11
|
+
|
12
|
+
alias :exception_message :to_s
|
13
|
+
def to_s
|
14
|
+
"#{target}: failed in #{phase} phase"
|
15
|
+
" #{super}"
|
16
|
+
end
|
20
17
|
end
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
class PackageException < Exception
|
25
|
-
def mail?; true end
|
26
|
-
def fatal?; true end
|
27
|
-
|
28
|
-
def initialize(target = nil)
|
29
|
-
@target = target
|
18
|
+
class ConfigException < Exception; end
|
19
|
+
class PackageException < Exception
|
20
|
+
def mail?; true end
|
30
21
|
end
|
31
|
-
attr_accessor :target
|
32
|
-
end
|
33
|
-
|
34
|
-
class ImportException < SubcommandFailed
|
35
|
-
def mail?; true end
|
36
|
-
def fatal?; true end
|
37
|
-
|
38
|
-
def initialize(subcommand)
|
39
|
-
super(subcommand.target, subcommand.command, subcommand.logfile, subcommand.status)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
class BuildException < SubcommandFailed
|
44
|
-
def mail?; true end
|
45
|
-
def fatal?; true end
|
46
22
|
|
47
|
-
|
48
|
-
|
23
|
+
class CommandNotFound < Exception; end
|
24
|
+
class SubcommandFailed < Exception
|
25
|
+
def mail?; true end
|
26
|
+
attr_reader :command, :logfile, :status
|
27
|
+
def initialize(*args)
|
28
|
+
if args.size == 1
|
29
|
+
sc = args[0]
|
30
|
+
target, command, logfile, status =
|
31
|
+
sc.target, sc.command, sc.logfile, sc.status
|
32
|
+
@orig_message = sc.exception_message
|
33
|
+
elsif args.size == 4
|
34
|
+
target, command, logfile, status = *args
|
35
|
+
else
|
36
|
+
raise ArgumentError, "wrong number of arguments, should be 1 or 4"
|
37
|
+
end
|
38
|
+
|
39
|
+
super(target)
|
40
|
+
@command = command
|
41
|
+
@logfile = logfile
|
42
|
+
@status = status
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_s
|
46
|
+
prefix = "#{super}\n command '#{command}' failed"
|
47
|
+
prefix << ": " + @orig_message if @orig_message
|
48
|
+
prefix << "\n see #{File.basename(logfile)} for details\n"
|
49
|
+
end
|
49
50
|
end
|
50
51
|
end
|
51
52
|
|
data/lib/autobuild/import/cvs.rb
CHANGED
@@ -1,51 +1,46 @@
|
|
1
1
|
require 'autobuild/subcommand'
|
2
2
|
require 'autobuild/importer'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
module Autobuild
|
5
|
+
class CVSImporter < Importer
|
6
|
+
def initialize(root, name, options)
|
7
|
+
@root = root
|
8
|
+
@module = name
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
@program = ($PROGRAMS[:cvs] || 'cvs')
|
11
|
+
@options_up = ( options[:cvsup] || '-dP' ).to_a
|
12
|
+
@options_co = ( options[:cvsco] || '-P' ).to_a
|
13
|
+
super(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
def modulename
|
17
|
+
@module
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
+
private
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
raise ImportException.new(e), "failed to update #{modulename}"
|
27
|
-
end
|
28
|
-
}
|
29
|
-
end
|
22
|
+
def update(package)
|
23
|
+
Dir.chdir(package.srcdir) {
|
24
|
+
Subprocess.run(package.target, :import, @program, 'up', *@options_up)
|
25
|
+
}
|
26
|
+
end
|
30
27
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
42
|
-
}
|
28
|
+
def checkout(package)
|
29
|
+
head, tail = File.split(package.srcdir)
|
30
|
+
cvsroot = @root
|
31
|
+
|
32
|
+
FileUtils.mkdir_p(head) if !File.directory?(head)
|
33
|
+
Dir.chdir(head) {
|
34
|
+
options = [ @program, '-d', cvsroot, 'co', '-d', tail ] + @options_co + [ modulename ]
|
35
|
+
Subprocess.run(package.target, :import, *options)
|
36
|
+
}
|
37
|
+
end
|
43
38
|
end
|
44
|
-
end
|
45
39
|
|
46
|
-
module Import
|
47
|
-
|
48
|
-
|
40
|
+
module Import
|
41
|
+
def self.cvs(source, package_options)
|
42
|
+
CVSImporter.new(source[0], source[1], package_options)
|
43
|
+
end
|
49
44
|
end
|
50
45
|
end
|
51
46
|
|
data/lib/autobuild/import/svn.rb
CHANGED
@@ -1,41 +1,35 @@
|
|
1
|
-
require 'autobuild/subcommand'
|
1
|
+
require 'autobuild/subcommand'
|
2
2
|
require 'autobuild/importer'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
module Autobuild
|
5
|
+
class SVNImporter < Importer
|
6
|
+
def initialize(source, options)
|
7
|
+
@source = source.to_a.join("/")
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
end
|
9
|
+
@program = ($PROGRAMS[:svn] || 'svn')
|
10
|
+
@options_up = options[:svnup].to_a
|
11
|
+
@options_co = options[:svnco].to_a
|
12
|
+
super(options)
|
13
|
+
end
|
14
14
|
|
15
|
-
|
15
|
+
private
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
raise ImportException.new(e), "failed to update #{package.target}"
|
23
|
-
end
|
24
|
-
}
|
25
|
-
end
|
17
|
+
def update(package)
|
18
|
+
Dir.chdir(package.srcdir) {
|
19
|
+
Subprocess.run(package.target, :import, @program, 'up', *@options_up)
|
20
|
+
}
|
21
|
+
end
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
rescue SubcommandFailed => e
|
31
|
-
raise ImportException.new(e), "failed to check out #{package.target}"
|
23
|
+
def checkout(package)
|
24
|
+
options = [ @program, 'co' ] + @options_co + [ @source, package.srcdir ]
|
25
|
+
Subprocess.run(package.target, :import, *options)
|
32
26
|
end
|
33
27
|
end
|
34
|
-
end
|
35
28
|
|
36
|
-
module Import
|
37
|
-
|
38
|
-
|
29
|
+
module Import
|
30
|
+
def self.svn(source, options)
|
31
|
+
SVNImporter.new(source, options)
|
32
|
+
end
|
39
33
|
end
|
40
34
|
end
|
41
35
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
|
3
|
+
module Autobuild
|
4
|
+
class TarImporter < Importer
|
5
|
+
Plain = 0
|
6
|
+
Gzip = 1
|
7
|
+
Bzip = 2
|
8
|
+
|
9
|
+
TAR_OPTION = {
|
10
|
+
Plain => '',
|
11
|
+
Gzip => 'z',
|
12
|
+
Bzip => 'j'
|
13
|
+
}
|
14
|
+
|
15
|
+
VALID_URI_SCHEMES = [ 'file', 'http', 'ftp' ]
|
16
|
+
|
17
|
+
def self.url_to_mode(url)
|
18
|
+
ext = File.extname(url)
|
19
|
+
mode = case ext
|
20
|
+
when '.tar'; Plain
|
21
|
+
when '.gz'; Gzip
|
22
|
+
when '.bz2'; Bzip
|
23
|
+
end
|
24
|
+
|
25
|
+
unless ext == '.tar'
|
26
|
+
raise "Invalid file type in #{url}" unless File.basename(url, ext) != '.tar'
|
27
|
+
end
|
28
|
+
mode
|
29
|
+
end
|
30
|
+
|
31
|
+
def update_cache
|
32
|
+
do_update = true
|
33
|
+
|
34
|
+
if File.file?(cachefile)
|
35
|
+
cached_size = File.lstat(cachefile).size
|
36
|
+
cached_mtime = File.lstat(cachefile).mtime
|
37
|
+
|
38
|
+
size, mtime = nil
|
39
|
+
open @url, :content_length_proc => lambda { |size| } do |file|
|
40
|
+
mtime = file.last_modified
|
41
|
+
end
|
42
|
+
|
43
|
+
if mtime && size
|
44
|
+
do_update = (size != cached_size || mtime > cached_mtime)
|
45
|
+
elsif mtime
|
46
|
+
$stderr.puts "WARNING: size is not available for #{@url}, relying on modification time"
|
47
|
+
do_update = (mtime > cached_mtime)
|
48
|
+
elsif size
|
49
|
+
$stderr.puts "WARNING: modification time is not available for #{@url}, relying on size"
|
50
|
+
do_update = (size != cached_size)
|
51
|
+
else
|
52
|
+
$stderr.puts "WARNING: neither size nor modification time available for #{@url}, will always update"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
if do_update
|
57
|
+
puts "downloading #{url}"
|
58
|
+
FileUtils.mkdir_p(cachedir)
|
59
|
+
File.open(cachefile, 'w') do |cache|
|
60
|
+
open @url do |file|
|
61
|
+
while block = file.read(4096)
|
62
|
+
cache.write block
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
true
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def url=(url)
|
71
|
+
@url = URI.parse(url)
|
72
|
+
raise ConfigException, "invalid URL #{url}" unless VALID_URI_SCHEMES.include?(@url.scheme)
|
73
|
+
|
74
|
+
@mode = TarImporter.url_to_mode(url)
|
75
|
+
if @url.scheme == 'file'
|
76
|
+
@cachefile = @url
|
77
|
+
else
|
78
|
+
@cachefile = File.join(cachedir, File.basename(@url.path))
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
attr_reader :url, :cachefile, :mode
|
83
|
+
def cachedir; @options[:cachedir] end
|
84
|
+
|
85
|
+
def initialize(url, options)
|
86
|
+
@options = options.dup
|
87
|
+
@options[:cachedir] ||= $CACHEDIR
|
88
|
+
self.url = url
|
89
|
+
end
|
90
|
+
|
91
|
+
def update(package)
|
92
|
+
checkout if update_cache
|
93
|
+
rescue OpenURI::HTTPError
|
94
|
+
raise Autobuild::Exception.new(package.target, :import)
|
95
|
+
end
|
96
|
+
|
97
|
+
def checkout(package)
|
98
|
+
update_cache
|
99
|
+
|
100
|
+
base_dir = File.dirname(package.srcdir)
|
101
|
+
FileUtils.mkdir_p base_dir
|
102
|
+
cmd = [ 'tar', "x#{TAR_OPTION[mode]}f", cachefile, '-C', base_dir ]
|
103
|
+
|
104
|
+
Subprocess.run(package.target, :import, *cmd)
|
105
|
+
|
106
|
+
rescue OpenURI::HTTPError
|
107
|
+
raise Autobuild::Exception.new(package.target, :import)
|
108
|
+
rescue SubcommandFailed
|
109
|
+
FileUtils.rm_f cachefile
|
110
|
+
raise
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
module Import
|
115
|
+
def self.tar(source, package_options)
|
116
|
+
TarImporter.new(source, package_options)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|