autobuild 0.3 → 0.4
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/README +62 -38
- data/bin/autobuild +15 -13
- data/lib/autobuild/config-interpolator.rb +29 -7
- data/lib/autobuild/config.rb +11 -18
- data/lib/autobuild/environment.rb +1 -1
- data/lib/autobuild/exceptions.rb +51 -0
- data/lib/autobuild/import/cvs.rb +4 -1
- data/lib/autobuild/importer.rb +5 -3
- data/lib/autobuild/package.rb +19 -3
- data/lib/autobuild/packages/autotools.rb +30 -23
- data/lib/autobuild/packages/genom.rb +10 -7
- data/lib/autobuild/packages/import.rb +1 -0
- data/lib/autobuild/reporting.rb +91 -0
- data/lib/autobuild/subcommand.rb +2 -2
- data/test/base.rb +2 -0
- data/test/tc_config.rb +5 -3
- data/test/tc_config_interpolation.rb +8 -1
- data/test/tc_import.rb +77 -0
- data/test/tc_subcommand.rb +7 -7
- data/test/tools.rb +39 -0
- metadata +7 -5
- data/lib/autobuild/logging.rb +0 -105
- data/test/conffile-generator.rb +0 -34
- data/test/dummy.ryml +0 -24
data/README
CHANGED
@@ -13,19 +13,20 @@ It takes the dependencies between packages into account in its build process.
|
|
13
13
|
1. This section is not used at all by autobuild. It is only here to define references
|
14
14
|
used in the reste of the config file
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
16
|
+
defines:
|
17
|
+
openrobots: ':ext:sjoyeux@cvs.laas.fr/cvs/openrobots'
|
18
|
+
openprs_cvs: ':ext:sjoyeux@cvs.laas.fr:/usr/local/openprs/CVS-Repository'
|
19
|
+
global_prefix: /home/doudou/laas/openrobots
|
20
|
+
srcdir: ${global_prefix}/tools
|
21
|
+
prefix: ${global_prefix}/build/tools
|
22
|
+
|
23
|
+
2. <tt>autobuild</tt> holds the configuration of the build tool itself. See the
|
23
24
|
<b>Autobuild configuration</b> section for the available configuration options.
|
24
25
|
|
25
|
-
autobuild
|
26
|
-
srcdir:
|
27
|
-
prefix:
|
28
|
-
|
26
|
+
autobuild:
|
27
|
+
srcdir: $srcdir
|
28
|
+
prefix: $prefix
|
29
|
+
clean_log: true
|
29
30
|
|
30
31
|
mail:
|
31
32
|
to: sjoyeux@laas.fr
|
@@ -47,11 +48,10 @@ It takes the dependencies between packages into account in its build process.
|
|
47
48
|
|
48
49
|
packages:
|
49
50
|
|
50
|
-
5. options in <tt>common
|
51
|
+
5. options in <tt>common</tt> are merged in each package configuration. See
|
51
52
|
<b>Configuring packages</b> for the detailed merging rules.
|
52
53
|
|
53
|
-
|
54
|
-
configureflags: *compilers
|
54
|
+
config:
|
55
55
|
prefix: ""
|
56
56
|
|
57
57
|
6. Tell autobuild to build the pocolibs package. Two common options here:
|
@@ -64,7 +64,7 @@ It takes the dependencies between packages into account in its build process.
|
|
64
64
|
pocolibs:
|
65
65
|
type: autotools
|
66
66
|
import: cvs
|
67
|
-
source: [
|
67
|
+
source: [ $openrobots, pocolibs ]
|
68
68
|
|
69
69
|
|
70
70
|
7. Autobuild takes the dependencies between packages into account. Just list in +depends+
|
@@ -73,7 +73,7 @@ It takes the dependencies between packages into account in its build process.
|
|
73
73
|
genom:
|
74
74
|
type: autotools
|
75
75
|
import: cvs
|
76
|
-
source: [
|
76
|
+
source: [ $openrobots, genom ]
|
77
77
|
depends: pocolibs
|
78
78
|
|
79
79
|
|
@@ -92,11 +92,11 @@ each element is a section:
|
|
92
92
|
|
93
93
|
In the documentation, I'll sometime use paths to reference the config options. For instance,
|
94
94
|
+option1+ is <tt>section1/option1</tt>. The +to+ option in the configuration example
|
95
|
-
is <tt>autobuild
|
95
|
+
is <tt>autobuild/mail/to</tt>
|
96
96
|
|
97
97
|
Autobuild uses three sections:
|
98
98
|
|
99
|
-
<b>autobuild
|
99
|
+
<b>autobuild</b>:: main autobuild configuration. See <b>Autobuild configuration</b> below
|
100
100
|
*programs*:: the programs used by importers and builders. See each tool
|
101
101
|
documentation for the list of used options
|
102
102
|
*packages*:: the list of packages to build. See <b>Package configuration</b> below
|
@@ -104,12 +104,12 @@ Autobuild uses three sections:
|
|
104
104
|
this section can be used later in other parts of the config files using
|
105
105
|
the $key or ${key} notation
|
106
106
|
|
107
|
-
== Autobuild configuration (<tt>autobuild
|
107
|
+
== Autobuild configuration (<tt>autobuild</tt>)
|
108
108
|
=== Misc options
|
109
109
|
*update*:: if false, do not update the packages that are already imported (default: true). You
|
110
110
|
can also use the <tt>--no-update</tt> on the command line
|
111
111
|
|
112
|
-
=== Directories (<tt>autobuild
|
112
|
+
=== Directories (<tt>autobuild/srcdir</tt>, <tt>autobuild/prefix</tt> and <tt>autobuild/logdir</tt>)
|
113
113
|
*srcdir*:: the path where programs are to be imported. See <b>Packages configuration</b> for
|
114
114
|
more information on how this option is used.
|
115
115
|
*prefix*:: the path where programs are to be installed. See <b>Packages configuration</b> for more
|
@@ -117,20 +117,20 @@ Autobuild uses three sections:
|
|
117
117
|
*logdir*:: by default, autobuild does not displays the output of each subcommand it launches.
|
118
118
|
Insteads, it saves this output in log files. These log files are saved in +logdir+.
|
119
119
|
The default value is <tt>prefix/autobuild</tt>
|
120
|
-
<b>
|
120
|
+
<b>clean_log</b>:: if we must remove all logfiles before each autobuild run or if we should append to them. The
|
121
121
|
default is +true+, that is log files are removed. Note that if mailing is active, all log
|
122
122
|
files are attached to notification mail.
|
123
123
|
*nice*:: The priority at which autobuild should launch subprocesses
|
124
124
|
|
125
125
|
|
126
|
-
=== Environment (<tt>autobuild
|
127
|
-
The <tt>autobuild
|
126
|
+
=== Environment (<tt>autobuild/environment</tt>)
|
127
|
+
The <tt>autobuild/environment</tt> section lists the initial values for
|
128
128
|
the environment variables. While packages builders shall update the environment
|
129
129
|
variables as needed, you can have to set up a proper initial environment. Arrays
|
130
130
|
are converted into strings by joining elements by ':'
|
131
131
|
|
132
132
|
For instance
|
133
|
-
autobuild
|
133
|
+
autobuild:
|
134
134
|
environment:
|
135
135
|
PATH: [ "/bin", "/usr/bin" ]
|
136
136
|
LD_LIBRARY_PATH:
|
@@ -143,11 +143,11 @@ sets
|
|
143
143
|
PKG_CONFIG_PATH=""
|
144
144
|
|
145
145
|
|
146
|
-
=== Mail (<tt>autobuild
|
146
|
+
=== Mail (<tt>autobuild/mail</tt>)
|
147
147
|
If you want to receive a mail when the build has finished (on success and failures), set
|
148
148
|
at least the +to+ option, like this:
|
149
149
|
|
150
|
-
autobuild
|
150
|
+
autobuild:
|
151
151
|
mail:
|
152
152
|
from: autobuild@mymachine.rubyrules.org
|
153
153
|
to: myself+autobuild@rubyrules.org
|
@@ -162,10 +162,10 @@ All log files relative to the current build are attached to the mail.
|
|
162
162
|
|
163
163
|
|
164
164
|
== Configuring packages (<tt>packages/*</tt>)
|
165
|
-
=== The <tt>packages/
|
165
|
+
=== The <tt>packages/config</tt> section
|
166
166
|
If you want to add common options in each package, just set it them here. Note that the options
|
167
167
|
are /merged/ in the package config. It neither replaces the values in the package nor be replaced
|
168
|
-
by them. The merging strategy depends on the way the <tt>common
|
168
|
+
by them. The merging strategy depends on the way the <tt>common</tt> is specified:
|
169
169
|
* if it is an array, the package option is converted to an array and the common option is appended
|
170
170
|
* if it is a string, the package option is converted to a string and the common option is appended
|
171
171
|
with a space inserted between the two
|
@@ -173,17 +173,17 @@ with a space inserted between the two
|
|
173
173
|
* any other values are forbidden
|
174
174
|
|
175
175
|
To ease the config file writing, all options that accept arrays also accept a string when there
|
176
|
-
is only one element. <b>Do not</b> do that in the <tt>common
|
176
|
+
is only one element. <b>Do not</b> do that in the <tt>common</tt> option.
|
177
177
|
|
178
178
|
=== Package definition
|
179
|
-
All subsections of the <tt>packages/</tt> section but <tt>common
|
179
|
+
All subsections of the <tt>packages/</tt> section but <tt>common</tt> are package definitions
|
180
180
|
The section name is used as the package name. The package definition sets up the importer to get the
|
181
181
|
source and the builder to build and install it.
|
182
182
|
|
183
183
|
*type*:: the package type. See the <b>Available package types</b> sections
|
184
184
|
|
185
185
|
*srcdir*:: where sources are to be imported. If this is a relative path, it is relative to the global
|
186
|
-
<tt>/autobuild
|
186
|
+
<tt>/autobuild/srcdir</tt> option. Otherwise, the absolute path is used. If no +srcdir+
|
187
187
|
is given, the package name is used, so that the default import dir is
|
188
188
|
<em>global srcdir</em>/<em>package_name</em>.
|
189
189
|
|
@@ -199,17 +199,16 @@ source and the builder to build and install it.
|
|
199
199
|
Since relative paths for patch files are relative to the autobuild working directory, I recommend
|
200
200
|
you put absolute paths here.
|
201
201
|
|
202
|
-
*source
|
203
|
-
where the importer should get the sources. The format of this options depends on
|
202
|
+
*source*:: where the importer should get the sources. The format of this options depends on
|
204
203
|
the importer used. See Available importers.
|
205
204
|
|
206
205
|
*prefix*:: where the program is to be installed. If this is a relative path, it is relative to the global
|
207
|
-
<tt>/autobuild
|
206
|
+
<tt>/autobuild/prefix</tt> option. Otherwise, the absolute path is used. If no prefix
|
208
207
|
is given, the package name is used, so that the default install dir is
|
209
208
|
<em>global prefix</em>/<em>package name</em>
|
210
209
|
|
211
210
|
*depends*:: the array of packages that should be built and installed before this one is built. <tt>depends: [ foo ]</tt>
|
212
|
-
is equivalent to <tt>depends: foo</tt>. To make the use of +depends+ in the <tt>common
|
211
|
+
is equivalent to <tt>depends: foo</tt>. To make the use of +depends+ in the <tt>common</tt>
|
213
212
|
section possible, this package name is automatically removed from the package +depends+ array.
|
214
213
|
*provides*:: defines aliases for this package. As for +depends+, an array with only element can be replaced
|
215
214
|
by the simple value.
|
@@ -227,7 +226,7 @@ source and the builder to build and install it.
|
|
227
226
|
packages:
|
228
227
|
foo:
|
229
228
|
import: svn
|
230
|
-
source: [
|
229
|
+
source: [ $my_home_repository, /trunk/foo ]
|
231
230
|
|
232
231
|
*svnup*:: options to add to svn up. Defaults to ''
|
233
232
|
*svnco*:: options to add to svn co. Defaults to ''
|
@@ -241,7 +240,7 @@ to set up the importer and +srcdir+. +prefix+ is ignored.
|
|
241
240
|
bar:
|
242
241
|
type: import
|
243
242
|
import: cvs
|
244
|
-
source: [
|
243
|
+
source: [ $my_repository, "bar" ]
|
245
244
|
srcdir: bar
|
246
245
|
|
247
246
|
=== Autotools (<tt>type: autotools</tt>)
|
@@ -286,10 +285,35 @@ The only program used during the build phase is +make+. The make command can too
|
|
286
285
|
The <tt>--daemon</tt> command line options makes autobuild go into daemon mode.
|
287
286
|
|
288
287
|
= Changes
|
288
|
+
== 0.3 to 0.4
|
289
|
+
* added support to split import and build. For instance
|
290
|
+
|
291
|
+
whole_tree:
|
292
|
+
type: import
|
293
|
+
import: cvs
|
294
|
+
source: [ a, repository ]
|
295
|
+
|
296
|
+
package1:
|
297
|
+
type: autotools
|
298
|
+
srcdir: whole_tree/package1
|
299
|
+
depends: whole_tree
|
300
|
+
|
301
|
+
package2:
|
302
|
+
type: autotools
|
303
|
+
srcdir: whole_tree/package2
|
304
|
+
depends: whole_tree
|
305
|
+
|
306
|
+
Now works well
|
307
|
+
|
308
|
+
* the <tt>autotools</tt> package has now an <tt>autogen</tt> options, which gives a name for the script
|
309
|
+
to run to create the autoconf environment
|
310
|
+
* renamed 'genomflags' -> 'genflags'
|
311
|
+
* variable interpolation checks for environment variables
|
312
|
+
* bugfixes
|
289
313
|
== 0.2 to 0.3
|
290
314
|
* added support for patching source code. Add patch: [ patches ] to the package configuration
|
291
315
|
* renamed autobuild-config, common-config and clean-log to autobuild, common and clean_log. Autobuild
|
292
|
-
warns if it finds one the previous spelling
|
316
|
+
warns if it finds one the previous spelling but ignores it anyway
|
293
317
|
|
294
318
|
= Copyright and license
|
295
319
|
Author:: Sylvain Joyeux <sylvain.joyeux@m4x.org>
|
data/bin/autobuild
CHANGED
@@ -8,7 +8,7 @@ require 'optparse'
|
|
8
8
|
|
9
9
|
require 'autobuild/options'
|
10
10
|
require 'autobuild/config'
|
11
|
-
require 'autobuild/
|
11
|
+
require 'autobuild/reporting'
|
12
12
|
require 'daemons'
|
13
13
|
|
14
14
|
DEFAULT_HTTP_PORT = 2000
|
@@ -63,19 +63,21 @@ if options.daemonize
|
|
63
63
|
Daemons.daemonize
|
64
64
|
end
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
Reporting.report do
|
67
|
+
begin
|
68
|
+
File.open(conffile) do |f|
|
69
|
+
Config.load(f, options)
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
if targets.empty?
|
73
|
+
Rake::Task[:default].invoke
|
74
|
+
else
|
75
|
+
targets.each { |t| Rake::Task[t.to_sym].invoke }
|
76
|
+
end
|
77
|
+
rescue ConfigException => e
|
78
|
+
e.target = conffile
|
79
|
+
raise
|
75
80
|
end
|
76
|
-
success
|
77
|
-
rescue BuildException => error
|
78
|
-
error(error, "Error during build of #{error.target}")
|
79
|
-
exit(1)
|
81
|
+
Reporting.success
|
80
82
|
end
|
81
83
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'autobuild/exceptions'
|
2
|
+
|
1
3
|
class Regexp
|
2
4
|
def each_match(string)
|
3
5
|
string = string.to_str
|
@@ -8,9 +10,17 @@ class Regexp
|
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
11
|
-
class UndefinedVariable <
|
13
|
+
class UndefinedVariable < ConfigException
|
12
14
|
attr_reader :name
|
13
|
-
|
15
|
+
attr_accessor :reference
|
16
|
+
def initialize(name, reference = [])
|
17
|
+
@name = name
|
18
|
+
@reference = reference
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"undefined variable '#{name}' in #{reference.join('/')}"
|
23
|
+
end
|
14
24
|
end
|
15
25
|
|
16
26
|
class Interpolator
|
@@ -37,8 +47,13 @@ class Interpolator
|
|
37
47
|
|
38
48
|
interpolated = Hash.new
|
39
49
|
@node.each do |k, v|
|
40
|
-
|
41
|
-
|
50
|
+
begin
|
51
|
+
next if k == VarDefKey
|
52
|
+
interpolated[k] = Interpolator.interpolate(v, self)
|
53
|
+
rescue UndefinedVariable => e
|
54
|
+
e.reference.unshift k
|
55
|
+
raise e
|
56
|
+
end
|
42
57
|
end
|
43
58
|
|
44
59
|
interpolated
|
@@ -47,7 +62,12 @@ class Interpolator
|
|
47
62
|
@node.collect { |v| Interpolator.interpolate(v, self) }
|
48
63
|
|
49
64
|
else
|
50
|
-
|
65
|
+
begin
|
66
|
+
each_interpolation(@node) { |varname| value_of(varname) }
|
67
|
+
rescue UndefinedVariable => e
|
68
|
+
e.reference.unshift @node.to_str if @node.respond_to?(:to_str)
|
69
|
+
raise e
|
70
|
+
end
|
51
71
|
end
|
52
72
|
end
|
53
73
|
|
@@ -59,7 +79,7 @@ class Interpolator
|
|
59
79
|
value_of(varname)
|
60
80
|
rescue UndefinedVariable => e
|
61
81
|
if e.varname == name
|
62
|
-
raise "
|
82
|
+
raise ConfigException, "cyclic reference found in definition of '#{name}'"
|
63
83
|
else
|
64
84
|
raise
|
65
85
|
end
|
@@ -69,8 +89,10 @@ class Interpolator
|
|
69
89
|
@variables[name]
|
70
90
|
elsif @parent
|
71
91
|
@parent.value_of(name)
|
92
|
+
elsif ENV[name.to_s]
|
93
|
+
ENV[name.to_s]
|
72
94
|
else
|
73
|
-
raise UndefinedVariable.new(name)
|
95
|
+
raise UndefinedVariable.new(name)
|
74
96
|
end
|
75
97
|
end
|
76
98
|
|
data/lib/autobuild/config.rb
CHANGED
@@ -2,7 +2,7 @@ require 'yaml'
|
|
2
2
|
require 'pathname'
|
3
3
|
|
4
4
|
require 'autobuild/config-interpolator'
|
5
|
-
require 'autobuild/
|
5
|
+
require 'autobuild/reporting'
|
6
6
|
require 'autobuild/package'
|
7
7
|
require 'autobuild/importer'
|
8
8
|
|
@@ -56,7 +56,7 @@ module Config
|
|
56
56
|
check_backward_compatibility(config)
|
57
57
|
config = config.keys_to_sym
|
58
58
|
if !config[:autobuild]
|
59
|
-
raise ConfigException, "no autobuild block"
|
59
|
+
raise ConfigException, "no toplevel autobuild config block"
|
60
60
|
end
|
61
61
|
|
62
62
|
# Merge user_options into the autobuild block
|
@@ -70,30 +70,20 @@ module Config
|
|
70
70
|
end
|
71
71
|
}
|
72
72
|
|
73
|
-
$VERBOSE =
|
74
|
-
$DEBUG =
|
73
|
+
$VERBOSE = autobuild_config[:verbose]
|
74
|
+
$trace = $DEBUG = autobuild_config[:debug]
|
75
75
|
|
76
76
|
get_autobuild_config(config)
|
77
77
|
get_package_config(config)
|
78
|
-
rescue ConfigException => error
|
79
|
-
error(error, "Error in config file '#{conffile}'")
|
80
|
-
exit(1)
|
81
|
-
rescue ImportException => error
|
82
|
-
error(error, "Error: unable to import #{p}")
|
83
|
-
exit(1)
|
84
78
|
end
|
85
79
|
|
86
80
|
def self.get_autobuild_config(config)
|
87
81
|
$PROGRAMS = (config[:programs] or "make")
|
88
82
|
|
89
83
|
autobuild = config[:autobuild]
|
90
|
-
$SRCDIR = autobuild[:srcdir]
|
91
|
-
$PREFIX = autobuild[:prefix]
|
92
|
-
|
93
|
-
raise ConfigException, 'you must at least set srcdir and prefix in the config files'
|
94
|
-
end
|
95
|
-
|
96
|
-
$LOGDIR = (autobuild[:logdir] || "#{$PREFIX}/autobuild")
|
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", $PREFIX)
|
97
87
|
|
98
88
|
FileUtils.mkdir_p $SRCDIR if !File.directory?($SRCDIR)
|
99
89
|
FileUtils.mkdir_p $LOGDIR if !File.directory?($LOGDIR)
|
@@ -131,7 +121,7 @@ module Config
|
|
131
121
|
config[:srcdir] ||= name.to_s
|
132
122
|
config[:prefix] ||= name.to_s
|
133
123
|
|
134
|
-
#
|
124
|
+
# Initializes the package
|
135
125
|
Package.build(package_type, name, config)
|
136
126
|
end
|
137
127
|
|
@@ -159,6 +149,9 @@ module Config
|
|
159
149
|
|
160
150
|
add_package(p, config)
|
161
151
|
end
|
152
|
+
|
153
|
+
# Post-import, pre-build pass
|
154
|
+
Package.each(false) { |name, pkg| pkg.prepare }
|
162
155
|
end
|
163
156
|
|
164
157
|
private_class_method :get_autobuild_config, :get_package_config, :add_package
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class SubcommandFailed < Exception
|
2
|
+
def mail?; false end
|
3
|
+
def fatal?; true end
|
4
|
+
|
5
|
+
attr_reader :target, :command, :logfile, :status
|
6
|
+
def initialize(target, command, logfile, status)
|
7
|
+
@target = target
|
8
|
+
@command = command
|
9
|
+
@logfile = logfile
|
10
|
+
@status = status
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class ConfigException < Exception
|
15
|
+
def mail?; false end
|
16
|
+
def fatal?; true end
|
17
|
+
|
18
|
+
def initialize(target = nil)
|
19
|
+
@target = target
|
20
|
+
end
|
21
|
+
attr_accessor :target
|
22
|
+
end
|
23
|
+
|
24
|
+
class PackageException < Exception
|
25
|
+
def mail?; true end
|
26
|
+
def fatal?; true end
|
27
|
+
|
28
|
+
def initialize(target = nil)
|
29
|
+
@target = target
|
30
|
+
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
|
+
|
47
|
+
def initialize(subcommand)
|
48
|
+
super(subcommand.target, subcommand.command, subcommand.logfile, subcommand.status)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
data/lib/autobuild/import/cvs.rb
CHANGED
@@ -11,6 +11,10 @@ class CVSImporter < Importer
|
|
11
11
|
@co = (options[:cvsco] || '-P')
|
12
12
|
super(options)
|
13
13
|
end
|
14
|
+
|
15
|
+
def modulename
|
16
|
+
@module
|
17
|
+
end
|
14
18
|
|
15
19
|
private
|
16
20
|
|
@@ -27,7 +31,6 @@ class CVSImporter < Importer
|
|
27
31
|
def checkout(package)
|
28
32
|
head, tail = File.split(package.srcdir)
|
29
33
|
cvsroot = @root
|
30
|
-
modulename = @module
|
31
34
|
|
32
35
|
FileUtils.mkdir_p(head) if !File.directory?(head)
|
33
36
|
Dir.chdir(head) {
|
data/lib/autobuild/importer.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'autobuild/exceptions'
|
2
|
+
|
1
3
|
class Importer
|
2
4
|
def initialize(options)
|
3
5
|
@options = options
|
@@ -15,14 +17,14 @@ class Importer
|
|
15
17
|
end
|
16
18
|
|
17
19
|
elsif File.exists?(srcdir)
|
18
|
-
raise
|
20
|
+
raise ConfigException, "#{srcdir} exists but is not a directory"
|
19
21
|
else
|
20
22
|
begin
|
21
23
|
checkout(package)
|
22
24
|
patch(package)
|
23
|
-
rescue ImportException
|
25
|
+
rescue ImportException
|
24
26
|
FileUtils.rm_rf package.srcdir
|
25
|
-
raise
|
27
|
+
raise
|
26
28
|
end
|
27
29
|
end
|
28
30
|
end
|
data/lib/autobuild/package.rb
CHANGED
@@ -4,16 +4,32 @@ require 'autobuild/subcommand'
|
|
4
4
|
|
5
5
|
class Package
|
6
6
|
@@packages = {}
|
7
|
+
@@provides = {}
|
7
8
|
|
8
9
|
attr_reader :dependencies
|
9
10
|
attr_reader :target, :srcdir, :prefix
|
10
11
|
|
11
12
|
def installstamp; "#{prefix}/#{target}-#{STAMPFILE}" end
|
12
|
-
def self.[](target); @@packages[target] end
|
13
13
|
|
14
|
+
def self.each(with_provides = false, &p)
|
15
|
+
@@packages.each(&p)
|
16
|
+
@@provides.each(&p) if with_provides
|
17
|
+
end
|
18
|
+
def self.[](target)
|
19
|
+
@@packages[target] or @@provides[target]
|
20
|
+
end
|
21
|
+
|
22
|
+
## Available options
|
23
|
+
# srcdir: the source dir. If a relative path, it is based on $SRCDIR
|
24
|
+
# prefix: the install dir. If a relative path, it is based on $PREFIX
|
25
|
+
# import: the package importer object
|
26
|
+
# depends: the list of package name we depend upon
|
27
|
+
# provides: a list of aliases for this package
|
28
|
+
#
|
29
|
+
# $SRCDIR and $PREFIX are supposed to be valid absolute paths
|
14
30
|
def initialize(target, options)
|
15
31
|
@target = Package.name2target(target)
|
16
|
-
raise ConfigException, "
|
32
|
+
raise ConfigException, "package #{target} is already defined" if Package[target]
|
17
33
|
|
18
34
|
@options = options
|
19
35
|
@dependencies = Array.new
|
@@ -50,7 +66,7 @@ class Package
|
|
50
66
|
|
51
67
|
def provides(p)
|
52
68
|
p = Package.name2target(p)
|
53
|
-
@@
|
69
|
+
@@provides[p] = self
|
54
70
|
puts "Defining #{p} as an alias to #{target}"
|
55
71
|
task p => target
|
56
72
|
|
@@ -41,10 +41,12 @@ class Autotools < Package
|
|
41
41
|
super(target, options)
|
42
42
|
|
43
43
|
@builddir = options[:builddir]
|
44
|
-
raise ConfigException, "
|
45
|
-
raise ConfigException, "
|
44
|
+
raise ConfigException, "autotools packages need a non-empty builddir" if (@builddir.nil? || @builddir.empty?)
|
45
|
+
raise ConfigException, "absolute builddirs are unsupported" if (Pathname.new(@builddir).absolute?)
|
46
46
|
@builddir = File.expand_path(builddir, srcdir)
|
47
|
+
end
|
47
48
|
|
49
|
+
def prepare
|
48
50
|
regen_targets
|
49
51
|
|
50
52
|
file "#{builddir}/config.status" => "#{srcdir}/configure" do
|
@@ -72,32 +74,38 @@ class Autotools < Package
|
|
72
74
|
conffile = "#{srcdir}/configure"
|
73
75
|
if File.exists?("#{conffile}.ac")
|
74
76
|
file conffile => [ "#{conffile}.ac" ]
|
75
|
-
|
77
|
+
elsif File.exists?("#{conffile}.in")
|
76
78
|
file conffile => [ "#{conffile}.in" ]
|
79
|
+
else
|
80
|
+
raise PackageException.new(target), "neither configure.ac nor configure.in present in #{srcdir}"
|
77
81
|
end
|
78
82
|
file conffile do
|
79
83
|
Dir.chdir(srcdir) {
|
80
|
-
$PROGRAMS[
|
81
|
-
$PROGRAMS[
|
82
|
-
$PROGRAMS[
|
83
|
-
$PROGRAMS[
|
84
|
+
$PROGRAMS[:aclocal] ||= 'aclocal'
|
85
|
+
$PROGRAMS[:autoconf] ||= 'autoconf'
|
86
|
+
$PROGRAMS[:autoheader] ||= 'autoheader'
|
87
|
+
$PROGRAMS[:automake] ||= 'automake'
|
84
88
|
|
85
89
|
begin
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
90
|
+
if @options[:autogen]
|
91
|
+
subcommand(target, 'configure', File.expand_path(@options[:autogen]))
|
92
|
+
else
|
93
|
+
# Autodetect autoconf/aclocal/automake
|
94
|
+
if @options[:autoconf].nil?
|
95
|
+
@options[:autoconf] =
|
96
|
+
File.exists?(File.join(srcdir, 'configure.in')) ||
|
97
|
+
File.exists?(File.join(srcdir, 'configure.ac'))
|
98
|
+
end
|
99
|
+
@options[:aclocal] ||= @options[:autoconf]
|
100
|
+
if @options[:automake].nil?
|
101
|
+
@options[:automake] = File.exists?(File.join(srcdir, 'Makefile.am'))
|
102
|
+
end
|
103
|
+
|
104
|
+
subcommand(target, 'configure', $PROGRAMS[:aclocal]) if @options[:aclocal]
|
105
|
+
subcommand(target, 'configure', $PROGRAMS[:autoconf]) if @options[:autoconf]
|
106
|
+
subcommand(target, 'configure', $PROGRAMS[:autoheader]) if @options[:autoheader]
|
107
|
+
subcommand(target, 'configure', $PROGRAMS[:automake]) if @options[:automake]
|
91
108
|
end
|
92
|
-
@options[:aclocal] ||= @options[:autoconf]
|
93
|
-
if @options[:automake].nil?
|
94
|
-
@options[:automake] = File.exists?(File.join(srcdir, 'Makefile.am'))
|
95
|
-
end
|
96
|
-
|
97
|
-
subcommand(target, 'configure', $PROGRAMS['aclocal']) if @options[:aclocal]
|
98
|
-
subcommand(target, 'configure', $PROGRAMS['autoconf']) if @options[:autoconf]
|
99
|
-
subcommand(target, 'configure', $PROGRAMS['autoheader']) if @options[:autoheader]
|
100
|
-
subcommand(target, 'configure', $PROGRAMS['automake']) if @options[:automake]
|
101
109
|
rescue SubcommandFailed => e
|
102
110
|
raise BuildException.new(e), "failed to build the configure environment of #{target}"
|
103
111
|
end
|
@@ -107,7 +115,7 @@ class Autotools < Package
|
|
107
115
|
|
108
116
|
def configure
|
109
117
|
if File.exists?(builddir) && !File.directory?(builddir)
|
110
|
-
raise
|
118
|
+
raise ConfigException, "#{builddir} already exists but is not a directory"
|
111
119
|
end
|
112
120
|
|
113
121
|
FileUtils.mkdir_p builddir if !File.directory?(builddir)
|
@@ -149,4 +157,3 @@ class Autotools < Package
|
|
149
157
|
end
|
150
158
|
end
|
151
159
|
|
152
|
-
|
@@ -2,16 +2,15 @@ require 'autobuild/packages/autotools'
|
|
2
2
|
require 'open3'
|
3
3
|
|
4
4
|
class GenomModule < Autotools
|
5
|
-
def
|
6
|
-
super
|
5
|
+
def prepare
|
6
|
+
super
|
7
7
|
get_requires
|
8
8
|
get_provides
|
9
9
|
end
|
10
|
-
|
11
10
|
def genomstamp; "#{srcdir}/.genom/genom-stamp" end
|
12
11
|
|
13
12
|
def cpp_options
|
14
|
-
@options[:
|
13
|
+
@options[:genflags].to_a.find_all { |opt| opt =~ /^-D/ }
|
15
14
|
end
|
16
15
|
|
17
16
|
def get_requires
|
@@ -21,7 +20,6 @@ class GenomModule < Autotools
|
|
21
20
|
if line =~ /^\s*requires\s*:\s*([\w\-]+(?:\s*,\s*[\w\-]+)*);/
|
22
21
|
$1.split(/, /).each { |name|
|
23
22
|
depends_on name
|
24
|
-
file genomstamp => Package.name2target(name)
|
25
23
|
}
|
26
24
|
elsif line =~ /^\s*requires/
|
27
25
|
puts "failed to match #{line}"
|
@@ -30,6 +28,11 @@ class GenomModule < Autotools
|
|
30
28
|
end
|
31
29
|
end
|
32
30
|
|
31
|
+
def depends_on(name)
|
32
|
+
super
|
33
|
+
file genomstamp => Package.name2target(name)
|
34
|
+
end
|
35
|
+
|
33
36
|
def get_provides
|
34
37
|
File.open("#{srcdir}/configure.ac.user") do |f|
|
35
38
|
f.each_line { |line|
|
@@ -44,7 +47,7 @@ class GenomModule < Autotools
|
|
44
47
|
|
45
48
|
|
46
49
|
def regen_targets
|
47
|
-
cmdline = [ 'genom', target ] | @options[:
|
50
|
+
cmdline = [ 'genom', target ] | @options[:genflags].to_a
|
48
51
|
|
49
52
|
file buildstamp => genomstamp
|
50
53
|
file genomstamp => [ :genom, "#{srcdir}/#{target}.gen" ] do
|
@@ -64,7 +67,7 @@ class GenomModule < Autotools
|
|
64
67
|
# since the generation takes care of rebuilding configure
|
65
68
|
# if .gen has changed
|
66
69
|
begin
|
67
|
-
subcommand(target, 'genom',
|
70
|
+
subcommand(target, 'genom', File.expand_path('autogen'))
|
68
71
|
rescue SubcommandFailed => e
|
69
72
|
raise BuildException.new(e), "failed to generate module #{target}"
|
70
73
|
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'rmail'
|
2
|
+
require 'rmail/serialize'
|
3
|
+
require 'net/smtp'
|
4
|
+
require 'socket'
|
5
|
+
|
6
|
+
module Reporting
|
7
|
+
def self.report
|
8
|
+
begin
|
9
|
+
yield
|
10
|
+
rescue Exception => e
|
11
|
+
raise unless e.respond_to?(:target)
|
12
|
+
error(e)
|
13
|
+
exit(1) if e.fatal?
|
14
|
+
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
|
+
|
23
|
+
def self.error(object)
|
24
|
+
if object.kind_of?(SubcommandFailed)
|
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}"
|
38
|
+
end
|
39
|
+
|
40
|
+
puts message
|
41
|
+
send_mail("Build failed", body) if $MAIL && object.mail?
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def self.send_mail(subject, body)
|
47
|
+
from = ($MAIL[:from] || "autobuild@#{Socket.gethostname}")
|
48
|
+
to = $MAIL[:to]
|
49
|
+
smtp = ($MAIL[:smtp] || "localhost" )
|
50
|
+
|
51
|
+
mail = RMail::Message.new
|
52
|
+
mail.header.date = Time.now
|
53
|
+
mail.header.from = from
|
54
|
+
mail.header.to = to
|
55
|
+
mail.header.subject = subject
|
56
|
+
|
57
|
+
part = RMail::Message.new
|
58
|
+
part.header.set('Content-Type', 'text/plain')
|
59
|
+
part.body = body
|
60
|
+
mail.add_part(part)
|
61
|
+
|
62
|
+
# Attach log files
|
63
|
+
Dir.glob("#{$LOGDIR}/*.log") do |file|
|
64
|
+
mail.add_file(file)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Send the mail
|
68
|
+
smtp = Net::SMTP.new(smtp, Integer($MAIL[:port] || 25))
|
69
|
+
smtp.start {
|
70
|
+
smtp.send_mail RMail::Serialize.write('', mail), from, to
|
71
|
+
}
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
module RMail
|
77
|
+
class Message
|
78
|
+
def add_file(path, content_type='text/plain')
|
79
|
+
part = RMail::Message.new
|
80
|
+
part.header.set('Content-Type', content_type)
|
81
|
+
part.header.set('Content-Disposition', 'attachment', 'filename' => File.basename(path))
|
82
|
+
part.body = ''
|
83
|
+
File.open(path) do |file|
|
84
|
+
part.body << file.readlines.join("\n")
|
85
|
+
end
|
86
|
+
self.add_part(part)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
data/lib/autobuild/subcommand.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'autobuild/
|
1
|
+
require 'autobuild/reporting'
|
2
2
|
|
3
3
|
def subcommand(target, type, *command)
|
4
4
|
# Filter nil and empty? in command
|
@@ -29,7 +29,7 @@ def subcommand(target, type, *command)
|
|
29
29
|
end
|
30
30
|
|
31
31
|
if !exec(*command)
|
32
|
-
raise "
|
32
|
+
raise SubcommandFailed.new(target, command.join(" "), logname, 0), "error running command"
|
33
33
|
end
|
34
34
|
}
|
35
35
|
|
data/test/base.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
1
2
|
$LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
|
2
3
|
require 'rubygems'
|
3
4
|
require 'test/unit'
|
4
5
|
require 'test/tc_config_interpolation.rb'
|
5
6
|
require 'test/tc_config.rb'
|
6
7
|
require 'test/tc_subcommand.rb'
|
8
|
+
require 'test/tc_import.rb'
|
data/test/tc_config.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
|
1
3
|
require 'test/unit'
|
2
|
-
require 'test/
|
4
|
+
require 'test/tools'
|
3
5
|
require 'autobuild/options'
|
4
6
|
require 'autobuild/config'
|
5
7
|
|
6
8
|
class TC_Config < Test::Unit::TestCase
|
7
9
|
def setup
|
8
|
-
@conffile =
|
10
|
+
@conffile = TestTools.build_config(binding, 'dummy')
|
9
11
|
@options_hash = File.open(@conffile) { |f| YAML.load(f) }
|
10
12
|
@options = File.open(@conffile) { |f| Config.load(f, Options.default) }
|
11
13
|
end
|
12
14
|
|
13
15
|
def teardown
|
14
|
-
|
16
|
+
TestTools.clean
|
15
17
|
end
|
16
18
|
|
17
19
|
def test_keys_to_sym
|
@@ -1,6 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
|
3
|
+
|
1
4
|
require 'test/unit'
|
2
|
-
require 'yaml'
|
3
5
|
require 'autobuild/config-interpolator'
|
6
|
+
|
7
|
+
require 'yaml'
|
4
8
|
require 'stringio'
|
5
9
|
|
6
10
|
class TC_ConfigInterpolation < Test::Unit::TestCase
|
@@ -15,6 +19,7 @@ autobuild:
|
|
15
19
|
srcdir: $srcdir
|
16
20
|
prefix: $prefix
|
17
21
|
nice: $nice
|
22
|
+
envvar: $ENVVAR
|
18
23
|
|
19
24
|
EOF
|
20
25
|
|
@@ -40,9 +45,11 @@ EOF
|
|
40
45
|
end
|
41
46
|
|
42
47
|
def test_interpolation
|
48
|
+
ENV['ENVVAR'] = 'envvar'
|
43
49
|
data = Interpolator.interpolate(@wellformed)
|
44
50
|
assert_equal('/home/doudou/src', data["autobuild"]["srcdir"])
|
45
51
|
assert_equal('/home/doudou/build', data["autobuild"]["prefix"])
|
52
|
+
assert_equal('envvar', data["autobuild"]["envvar"])
|
46
53
|
assert_equal(10, data["autobuild"]["nice"])
|
47
54
|
assert_kind_of(Fixnum, data["autobuild"]["nice"])
|
48
55
|
end
|
data/test/tc_import.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
|
3
|
+
require 'test/unit'
|
4
|
+
require 'test/tools'
|
5
|
+
require 'autobuild/import/cvs'
|
6
|
+
require 'autobuild/import/svn'
|
7
|
+
|
8
|
+
class TC_Import < Test::Unit::TestCase
|
9
|
+
Package = Struct.new :srcdir, :target
|
10
|
+
|
11
|
+
def setup
|
12
|
+
$PROGRAMS = {}
|
13
|
+
$UPDATE = true
|
14
|
+
$LOGDIR = "#{TestTools.tempdir}/log"
|
15
|
+
FileUtils.mkdir_p($LOGDIR)
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
$PROGRAMS = nil
|
21
|
+
$UPDATE = true
|
22
|
+
$LOGDIR = nil
|
23
|
+
TestTools.clean
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_cvs
|
27
|
+
TestTools.untar('cvsroot.tar')
|
28
|
+
cvsroot = File.join(TestTools.tempdir, 'cvsroot')
|
29
|
+
pkg_cvs = Package.new File.join(TestTools.tempdir, 'cvs'), :cvs
|
30
|
+
|
31
|
+
# Make a checkout
|
32
|
+
importer = Import.cvs [ cvsroot, 'cvs' ], {}
|
33
|
+
importer.import(pkg_cvs)
|
34
|
+
assert( File.exists?(File.join(pkg_cvs.srcdir, 'test')) )
|
35
|
+
|
36
|
+
# Make an update
|
37
|
+
importer.import(pkg_cvs)
|
38
|
+
|
39
|
+
# Make an update fail
|
40
|
+
FileUtils.rm_rf cvsroot
|
41
|
+
assert_raise(ImportException) { importer.import pkg_cvs }
|
42
|
+
|
43
|
+
# Make a checkout fail
|
44
|
+
FileUtils.rm_rf pkg_cvs.srcdir
|
45
|
+
assert_raise(ImportException) { importer.import pkg_cvs }
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_svn
|
49
|
+
TestTools.untar('svnroot.tar')
|
50
|
+
svnrepo = File.join(TestTools.tempdir, 'svnroot')
|
51
|
+
svnroot = "file:///#{svnrepo}"
|
52
|
+
pkg_svn = Package.new File.join(TestTools.tempdir, 'svn'), :svn
|
53
|
+
|
54
|
+
# Make a checkout with a splitted URL
|
55
|
+
importer = Import.svn [ svnroot, 'svn' ], {}
|
56
|
+
importer.import(pkg_svn)
|
57
|
+
assert( File.exists?(File.join(pkg_svn.srcdir, 'test')) )
|
58
|
+
|
59
|
+
# Make a checkout with an URL as a string
|
60
|
+
FileUtils.rm_rf pkg_svn.srcdir
|
61
|
+
importer = Import.svn File.join(svnroot, 'svn'), {}
|
62
|
+
importer.import(pkg_svn)
|
63
|
+
assert( File.exists?(File.join(pkg_svn.srcdir, 'test')) )
|
64
|
+
|
65
|
+
# Make an update
|
66
|
+
importer.import(pkg_svn)
|
67
|
+
|
68
|
+
# Make an update fail
|
69
|
+
FileUtils.rm_rf svnrepo
|
70
|
+
assert_raise(ImportException) { importer.import(pkg_svn) }
|
71
|
+
|
72
|
+
# Make a checkout fail
|
73
|
+
FileUtils.rm_rf pkg_svn.srcdir
|
74
|
+
assert_raise(ImportException) { importer.import(pkg_svn) }
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
data/test/tc_subcommand.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('..', File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
|
1
3
|
require 'test/unit'
|
2
|
-
require '
|
4
|
+
require 'test/tools'
|
3
5
|
require 'autobuild/options'
|
4
6
|
require 'autobuild/config'
|
5
|
-
require 'tmpdir'
|
6
|
-
|
7
|
-
require 'test/conffile-generator'
|
8
7
|
|
9
|
-
|
8
|
+
require 'tmpdir'
|
9
|
+
require 'fileutils'
|
10
10
|
|
11
11
|
class TC_Subcommand < Test::Unit::TestCase
|
12
12
|
EXAMPLE_1 = <<EOF
|
@@ -22,7 +22,7 @@ EOF
|
|
22
22
|
attr_reader :tmpdir
|
23
23
|
attr_reader :source1, :source2
|
24
24
|
def setup
|
25
|
-
conffile =
|
25
|
+
conffile = TestTools.build_config(binding, 'dummy')
|
26
26
|
@tmpdir = File.dirname(conffile)
|
27
27
|
|
28
28
|
options = Options.default
|
@@ -39,7 +39,7 @@ EOF
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def teardown
|
42
|
-
|
42
|
+
TestTools.clean
|
43
43
|
end
|
44
44
|
|
45
45
|
def test_subcommand
|
data/test/tools.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'erb'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module TestTools
|
6
|
+
DATADIR = File.join(File.dirname(__FILE__), 'data')
|
7
|
+
|
8
|
+
def self.tempdir
|
9
|
+
@tmpdir = File.join(Dir::tmpdir, "/autobuild-test-#{Process.uid}")
|
10
|
+
FileUtils.mkdir_p(@tmpdir, :mode => 0700)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.clean
|
14
|
+
FileUtils.rm_rf tempdir
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.build_config(bind, template)
|
18
|
+
eval "basedir = '#{self.tempdir}'", bind
|
19
|
+
ryml = File.open(File.join(DATADIR, "#{template}.ryml")) { |f| f.readlines }.join('')
|
20
|
+
result = ERB.new(ryml).result(bind)
|
21
|
+
|
22
|
+
yml = File.join(tempdir, "#{template}.yml")
|
23
|
+
File.open(yml, 'w+') { |f| f.write(result) }
|
24
|
+
|
25
|
+
return yml
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.untar(file)
|
29
|
+
file = File.expand_path(file, DATADIR)
|
30
|
+
dir = self.tempdir
|
31
|
+
Dir.chdir(dir) do
|
32
|
+
system("tar xf #{file}")
|
33
|
+
end
|
34
|
+
|
35
|
+
dir
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
metadata
CHANGED
@@ -3,8 +3,8 @@ 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.4"
|
7
|
+
date: 2005-09-27 00:00:00 +02:00
|
8
8
|
summary: Rake-based utility to build and install multiple packages with dependencies
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -36,10 +36,11 @@ files:
|
|
36
36
|
- lib/autobuild/config.rb
|
37
37
|
- lib/autobuild/environment.rb
|
38
38
|
- lib/autobuild/importer.rb
|
39
|
-
- lib/autobuild/
|
39
|
+
- lib/autobuild/reporting.rb
|
40
40
|
- lib/autobuild/package.rb
|
41
41
|
- lib/autobuild/subcommand.rb
|
42
42
|
- lib/autobuild/timestamps.rb
|
43
|
+
- lib/autobuild/exceptions.rb
|
43
44
|
- lib/autobuild/options.rb
|
44
45
|
- lib/autobuild/config-interpolator.rb
|
45
46
|
- lib/autobuild/import/cvs.rb
|
@@ -53,9 +54,10 @@ test_files:
|
|
53
54
|
- test/tc_subcommand.rb
|
54
55
|
- test/tc_config_interpolation.rb
|
55
56
|
- test/tc_config.rb
|
56
|
-
- test/
|
57
|
+
- test/tc_import.rb
|
57
58
|
- test/base.rb
|
58
|
-
- test/
|
59
|
+
- test/data
|
60
|
+
- test/tools.rb
|
59
61
|
rdoc_options:
|
60
62
|
- "--title"
|
61
63
|
- Autobuild
|
data/lib/autobuild/logging.rb
DELETED
@@ -1,105 +0,0 @@
|
|
1
|
-
require 'rmail'
|
2
|
-
require 'rmail/serialize'
|
3
|
-
require 'net/smtp'
|
4
|
-
require 'socket'
|
5
|
-
|
6
|
-
class SubcommandFailed < Exception
|
7
|
-
attr_reader :target, :command, :logfile, :status
|
8
|
-
def initialize(target, command, logfile, status)
|
9
|
-
@target = target
|
10
|
-
@command = command
|
11
|
-
@logfile = logfile
|
12
|
-
@status = status
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class ConfigException < Exception
|
17
|
-
def mail?; false end
|
18
|
-
end
|
19
|
-
|
20
|
-
class ImportException < SubcommandFailed
|
21
|
-
def mail?; true end
|
22
|
-
|
23
|
-
def initialize(subcommand)
|
24
|
-
super(subcommand.target, subcommand.command, subcommand.logfile, subcommand.status)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
class BuildException < SubcommandFailed
|
28
|
-
def mail?; true end
|
29
|
-
|
30
|
-
def initialize(subcommand)
|
31
|
-
super(subcommand.target, subcommand.command, subcommand.logfile, subcommand.status)
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def success
|
36
|
-
message = "Build finished successfully at #{Time.now}"
|
37
|
-
puts message
|
38
|
-
send_mail("Build success", message) if $MAIL
|
39
|
-
end
|
40
|
-
|
41
|
-
def error(object, place)
|
42
|
-
if object.kind_of?(SubcommandFailed)
|
43
|
-
body = <<EOF
|
44
|
-
#{place}: #{object.message}
|
45
|
-
command '#{object.command}' failed with status #{object.status}
|
46
|
-
see #{File.basename(object.logfile)} for details
|
47
|
-
EOF
|
48
|
-
|
49
|
-
message = <<EOF
|
50
|
-
#{place}: #{object.message}
|
51
|
-
command '#{object.command}' failed with status #{object.status}
|
52
|
-
see #{object.logfile} for details
|
53
|
-
EOF
|
54
|
-
else
|
55
|
-
body = message = "#{place}: #{object.message}"
|
56
|
-
end
|
57
|
-
|
58
|
-
puts message
|
59
|
-
send_mail("Build failed", body) if $MAIL
|
60
|
-
end
|
61
|
-
|
62
|
-
module RMail
|
63
|
-
class Message
|
64
|
-
def add_file(path, content_type='text/plain')
|
65
|
-
part = RMail::Message.new
|
66
|
-
part.header.set('Content-Type', content_type)
|
67
|
-
part.header.set('Content-Disposition', 'attachment', 'filename' => File.basename(path))
|
68
|
-
part.body = ''
|
69
|
-
File.open(path) do |file|
|
70
|
-
part.body << file.readlines.join("\n")
|
71
|
-
end
|
72
|
-
self.add_part(part)
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def send_mail(subject, body)
|
78
|
-
from = ($MAIL[:from] || "autobuild@#{Socket.gethostname}")
|
79
|
-
to = $MAIL[:to]
|
80
|
-
smtp = ($MAIL[:smtp] || "localhost" )
|
81
|
-
|
82
|
-
mail = RMail::Message.new
|
83
|
-
mail.header.date = Time.now
|
84
|
-
mail.header.from = from
|
85
|
-
mail.header.to = to
|
86
|
-
mail.header.subject = subject
|
87
|
-
|
88
|
-
part = RMail::Message.new
|
89
|
-
part.header.set('Content-Type', 'text/plain')
|
90
|
-
part.body = body
|
91
|
-
mail.add_part(part)
|
92
|
-
|
93
|
-
# Attach log files
|
94
|
-
Dir.glob("#{$LOGDIR}/*.log") do |file|
|
95
|
-
mail.add_file(file)
|
96
|
-
end
|
97
|
-
|
98
|
-
# Send the mail
|
99
|
-
smtp = Net::SMTP.new(smtp, Integer($MAIL[:port] || 25))
|
100
|
-
smtp.start {
|
101
|
-
smtp.send_mail RMail::Serialize.write('', mail), from, to
|
102
|
-
}
|
103
|
-
end
|
104
|
-
|
105
|
-
|
data/test/conffile-generator.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require 'tmpdir'
|
2
|
-
require 'erb'
|
3
|
-
|
4
|
-
DATADIR = File.dirname(__FILE__)
|
5
|
-
|
6
|
-
class ConffileGenerator
|
7
|
-
class << self
|
8
|
-
def tempdir
|
9
|
-
@tmpdir = Dir::tmpdir + "/autobuild-#{Process.uid}"
|
10
|
-
FileUtils.mkdir_p(@tmpdir, :mode => 0700)
|
11
|
-
end
|
12
|
-
|
13
|
-
def dummy(basedir = tempdir)
|
14
|
-
apply(binding, basedir, 'dummy')
|
15
|
-
end
|
16
|
-
|
17
|
-
def clean
|
18
|
-
FileUtils.rm_rf tempdir
|
19
|
-
end
|
20
|
-
|
21
|
-
private
|
22
|
-
|
23
|
-
def apply(binding, basedir, basename)
|
24
|
-
template = File.open(File.join(DATADIR, "#{basename}.ryml")) { |f| f.readlines }.join('')
|
25
|
-
result = ERB.new(template).result(binding)
|
26
|
-
|
27
|
-
yml = File.join(basedir, "#{basename}.yml")
|
28
|
-
File.open(yml, 'w+') { |f| f.write(result) }
|
29
|
-
|
30
|
-
return yml
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
data/test/dummy.ryml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
defines:
|
2
|
-
global_prefix: <%= "#{basedir}/prefix" %>
|
3
|
-
platform: B21R
|
4
|
-
buildname: i386-linux
|
5
|
-
mail: doudou@melix.net
|
6
|
-
nice: 0
|
7
|
-
|
8
|
-
autobuild:
|
9
|
-
prefix: ${global_prefix}/build
|
10
|
-
srcdir: ${global_prefix}/src
|
11
|
-
clean_log: true
|
12
|
-
nice: $nice
|
13
|
-
|
14
|
-
mail:
|
15
|
-
to: $mail
|
16
|
-
|
17
|
-
environment:
|
18
|
-
PATH: [ /bin, /usr/bin, $global_prefix/$buildname/tools/bin ]
|
19
|
-
PKG_CONFIG_PATH: $global_prefix/$buildname/tools/lib/pkgconfig
|
20
|
-
LD_LIBRARY_PATH:
|
21
|
-
|
22
|
-
programs:
|
23
|
-
aclocal: aclocal-1.9
|
24
|
-
|