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/CHANGES
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= Autobuild changelog
|
2
|
+
|
3
|
+
== Version 0.5
|
4
|
+
|
5
|
+
Fixes the mail default behaviour. Added the 'tar' importer.
|
6
|
+
|
7
|
+
* all the API is now in a separate module
|
8
|
+
* genflags has been renamed back to genomflags. The convention is now to
|
9
|
+
have a <tool>flags option. For instance: genomflags, configureflags
|
10
|
+
* added the --[no-]build option to do only import
|
11
|
+
* changed behaviour for mail reports:
|
12
|
+
- set sensible default options for mail
|
13
|
+
- mail: true uses default options
|
14
|
+
- mail: <string> is equivalent to
|
15
|
+
mail:
|
16
|
+
to: <string>
|
17
|
+
* if a value is undefined in the config file, parameter expansion tries to get
|
18
|
+
it from the program environment, and raises an error if it is not present in
|
19
|
+
the environment vars
|
20
|
+
* changed the names of log files. All importers now uses <package>-<import>.log
|
21
|
+
* added the 'tar' importer, which downloads and uncompress a tarball
|
22
|
+
|
23
|
+
|
24
|
+
== Version 0.4
|
25
|
+
|
26
|
+
* added support to split import and build. For instance
|
27
|
+
|
28
|
+
whole_tree:
|
29
|
+
type: import
|
30
|
+
import: cvs
|
31
|
+
source: [ a, repository ]
|
32
|
+
|
33
|
+
package1:
|
34
|
+
type: autotools
|
35
|
+
srcdir: whole_tree/package1
|
36
|
+
depends: whole_tree
|
37
|
+
|
38
|
+
package2:
|
39
|
+
type: autotools
|
40
|
+
srcdir: whole_tree/package2
|
41
|
+
depends: whole_tree
|
42
|
+
|
43
|
+
Works as it should
|
44
|
+
|
45
|
+
* the <tt>autotools</tt> package has now an <tt>autogen</tt> options, which gives a name for a script
|
46
|
+
which creates the autotools environment
|
47
|
+
* renamed 'genomflags' -> 'genflags'
|
48
|
+
* variable interpolation checks for environment variables
|
49
|
+
* bugfixes
|
50
|
+
|
51
|
+
== Version 0.3
|
52
|
+
|
53
|
+
* added support for patching source code. Add patch: [ patches ] to the package configuration
|
54
|
+
* renamed autobuild-config, common-config and clean-log to autobuild, common and clean_log. Autobuild
|
55
|
+
warns if it finds one the previous spelling but ignores it anyway
|
56
|
+
|
57
|
+
|
data/README
CHANGED
@@ -109,6 +109,7 @@ Autobuild uses three sections:
|
|
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
|
+
|
112
113
|
=== Directories (<tt>autobuild/srcdir</tt>, <tt>autobuild/prefix</tt> and <tt>autobuild/logdir</tt>)
|
113
114
|
*srcdir*:: the path where programs are to be imported. See <b>Packages configuration</b> for
|
114
115
|
more information on how this option is used.
|
@@ -144,30 +145,27 @@ sets
|
|
144
145
|
|
145
146
|
|
146
147
|
=== Mail (<tt>autobuild/mail</tt>)
|
147
|
-
|
148
|
-
at least the +to+ option, like this:
|
148
|
+
Use this options if you want to receive a mail when the build has finished (on success and failures)
|
149
149
|
|
150
150
|
autobuild:
|
151
|
-
mail:
|
152
|
-
from: autobuild@mymachine.rubyrules.org
|
153
|
-
to: myself+autobuild@rubyrules.org
|
154
|
-
smtp: localhost
|
151
|
+
mail: true
|
155
152
|
|
156
|
-
|
157
|
-
*
|
153
|
+
Valid options are:
|
154
|
+
*to*:: the mail destination, default is <tt>user@hostname</tt> (for instance sylvain@localhost for a user 'sylvain')
|
155
|
+
*from*:: the mail source, default is <tt>user@hostname</tt>
|
158
156
|
*smtp*:: the stmp server to use. Default is +localhost+
|
157
|
+
*port*:: the port the server is running on. Default is the smtp port (25)
|
159
158
|
|
160
159
|
All log files relative to the current build are attached to the mail.
|
161
160
|
|
162
161
|
|
163
|
-
|
164
162
|
== Configuring packages (<tt>packages/*</tt>)
|
165
163
|
=== The <tt>packages/config</tt> section
|
166
164
|
If you want to add common options in each package, just set it them here. Note that the options
|
167
|
-
are /merged/ in the package config. It neither replaces the values in the package nor
|
168
|
-
|
169
|
-
* if it is an array, the package option is converted to an array and the common
|
170
|
-
* if it is a string, the package option is converted to a string and the common option
|
165
|
+
are /merged/ in the package config. It neither replaces the values in the package nor the package
|
166
|
+
options replaces them. The merging strategy depends on the way the option is specified in this common section:
|
167
|
+
* if it is an array, the package option is converted to an array and the common options are appended
|
168
|
+
* if it is a string, the package option is converted to a string and the common option are appended
|
171
169
|
with a space inserted between the two
|
172
170
|
* if it is a boolean value, it is <em>overriden</em> by the package value
|
173
171
|
* any other values are forbidden
|
@@ -231,6 +229,22 @@ source and the builder to build and install it.
|
|
231
229
|
*svnup*:: options to add to svn up. Defaults to ''
|
232
230
|
*svnco*:: options to add to svn co. Defaults to ''
|
233
231
|
|
232
|
+
=== Tar (<tt>type: tar</tt>)
|
233
|
+
This importer gets a tarball file, which may be on a remote server, and un-tars
|
234
|
+
it. For now, it cannot determine itself what is the directory included in the tarball,
|
235
|
+
so you should set the srcdir: appropriately.
|
236
|
+
|
237
|
+
For instance, a tarball with one directory <tt>package-0.1</tt> in it will
|
238
|
+
need a <tt>srcdir</tt> option of <tt>package-0.1</tt>. If you do
|
239
|
+
not set +srcdir+, autobuild will untar the package in the global srcdir
|
240
|
+
(as intended) but will search for <tt>$global_srcdir/package</tt>
|
241
|
+
|
242
|
+
*source*:: the source URL. For now, http, ftp and file URLs are supported
|
243
|
+
*cachedir*:: the directory where the local copy of the file should be saved
|
244
|
+
(for http and ftp URLs only)
|
245
|
+
|
246
|
+
|
247
|
+
|
234
248
|
== Available package types (<tt>packages/</tt><em>name</em><tt>/type</tt>)
|
235
249
|
=== Source only (<tt>type: import</tt>)
|
236
250
|
Use +import+ if you need the package sources but don't need to build it. You just need
|
@@ -275,8 +289,8 @@ The only program used during the build phase is +make+. The make command can too
|
|
275
289
|
make: gnumake
|
276
290
|
|
277
291
|
==== Other options
|
278
|
-
*builddir*:: the directory where the build takes place. For now, it has to be a relative path,
|
279
|
-
which
|
292
|
+
*builddir*:: the directory where the build takes place. For now, it has to be a relative path,
|
293
|
+
which will be considered relative to the source directory.
|
280
294
|
*configureflags*:: array of options to add to the +configure+ command line
|
281
295
|
configureflags: [ --with-bar-source=$srcdir/$bar_srcdir ]
|
282
296
|
depends: bar
|
@@ -284,37 +298,6 @@ The only program used during the build phase is +make+. The make command can too
|
|
284
298
|
= Running autobuild in daemon mode
|
285
299
|
The <tt>--daemon</tt> command line options makes autobuild go into daemon mode.
|
286
300
|
|
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
|
313
|
-
== 0.2 to 0.3
|
314
|
-
* added support for patching source code. Add patch: [ patches ] to the package configuration
|
315
|
-
* renamed autobuild-config, common-config and clean-log to autobuild, common and clean_log. Autobuild
|
316
|
-
warns if it finds one the previous spelling but ignores it anyway
|
317
|
-
|
318
301
|
= Copyright and license
|
319
302
|
Author:: Sylvain Joyeux <sylvain.joyeux@m4x.org>
|
320
303
|
Copyright:: Copyright (c) 2005 Sylvain Joyeux
|
data/Rakefile
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
# Rakefile for Autobuild
|
2
|
+
# Copyright 2005 by Sylvain Joyeux (sylvain.joyeux@m4x.org)
|
3
|
+
|
4
|
+
# Based on the Rakefile for MetaProject
|
5
|
+
# Copyright 2005 by Aslak Hellesoy (aslak.hellesoy@gmail.org)
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# This file is may be distributed under an MIT style license. See
|
9
|
+
# MIT-LICENSE for details.
|
10
|
+
|
11
|
+
$:.unshift('lib')
|
12
|
+
require 'meta_project'
|
13
|
+
require 'rake/gempackagetask'
|
14
|
+
require 'rake/contrib/rubyforgepublisher'
|
15
|
+
require 'rake/contrib/xforge'
|
16
|
+
require 'rake/clean'
|
17
|
+
require 'rake/testtask'
|
18
|
+
require 'rake/rdoctask'
|
19
|
+
|
20
|
+
# Versioning scheme: MAJOR.MINOR.PATCH
|
21
|
+
# MAJOR bumps when API is broken backwards
|
22
|
+
# MINOR bumps when the API is broken backwards in a very slight/subtle (but not fatal) way
|
23
|
+
# -OR when a new release is made and propaganda is sent out.
|
24
|
+
# PATCH is bumped for every API addition and/or bugfix (ideally for every commit)
|
25
|
+
# Later DamageControl can bump PATCH automatically.
|
26
|
+
#
|
27
|
+
# REMEMBER TO KEEP PKG_VERSION IN SYNC WITH THE CHANGES FILE!
|
28
|
+
PKG_NAME = "autobuild"
|
29
|
+
PKG_VERSION = "0.5"
|
30
|
+
PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
|
31
|
+
PKG_FILES = FileList[
|
32
|
+
'[A-Z]*',
|
33
|
+
'lib/**/*.rb',
|
34
|
+
'doc/**/*'
|
35
|
+
]
|
36
|
+
|
37
|
+
task :default => [:gem]
|
38
|
+
|
39
|
+
# Create a task to build the RDOC documentation tree.
|
40
|
+
rd = Rake::RDocTask.new("rdoc") do |rdoc|
|
41
|
+
rdoc.rdoc_dir = 'html'
|
42
|
+
# rdoc.template = 'kilmer'
|
43
|
+
# rdoc.template = 'css2'
|
44
|
+
# rdoc.template = 'doc/jamis.rb'
|
45
|
+
rdoc.title = "Autobuild"
|
46
|
+
rdoc.options << '--main' << 'README'
|
47
|
+
rdoc.rdoc_files.include('README', 'CHANGES')
|
48
|
+
rdoc.rdoc_files.include('lib/**/*.rb', 'doc/**/*.rdoc')
|
49
|
+
rdoc.rdoc_files.exclude('doc/**/*_attrs.rdoc')
|
50
|
+
end
|
51
|
+
|
52
|
+
# ====================================================================
|
53
|
+
# Create a task that will package the Rake software into distributable
|
54
|
+
# tar, zip and gem files.
|
55
|
+
|
56
|
+
spec = Gem::Specification.new do |s|
|
57
|
+
|
58
|
+
#### Basic information.
|
59
|
+
|
60
|
+
s.name = PKG_NAME
|
61
|
+
s.version = PKG_VERSION
|
62
|
+
s.summary = 'Rake-based utility to build and install multiple packages with dependencies'
|
63
|
+
s.description = <<EOF
|
64
|
+
Autobuild imports, configures, builds and installs various kinds of software packages.
|
65
|
+
It can be used in software development to make sure that nothing is broken in the
|
66
|
+
build process of a set of packages, or can be used as an automated installation tool.
|
67
|
+
EOF
|
68
|
+
|
69
|
+
s.files = PKG_FILES.to_a
|
70
|
+
s.require_path = 'lib'
|
71
|
+
|
72
|
+
#### Documentation and testing.
|
73
|
+
|
74
|
+
s.has_rdoc = true
|
75
|
+
s.extra_rdoc_files = rd.rdoc_files.reject { |fn| fn =~ /\.rb$/ }.to_a
|
76
|
+
s.rdoc_options <<
|
77
|
+
'--title' << 'Autobuild' <<
|
78
|
+
'--main' << 'README'
|
79
|
+
|
80
|
+
#### Author and project details.
|
81
|
+
|
82
|
+
s.author = "Sylvain Joyeux"
|
83
|
+
s.email = "sylvain.joyeux@m4x.org"
|
84
|
+
s.homepage = "http://autobuild.rubyforge.org"
|
85
|
+
s.rubyforge_project = "autobuild"
|
86
|
+
end
|
87
|
+
|
88
|
+
# Fix 1.8.4 - 1.8.3 issue
|
89
|
+
class << spec
|
90
|
+
def to_yaml
|
91
|
+
out = super
|
92
|
+
out = '--- ' + out unless out =~ /^---/
|
93
|
+
out
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc "Build Gem"
|
98
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
99
|
+
pkg.need_zip = true
|
100
|
+
pkg.need_tar = true
|
101
|
+
end
|
102
|
+
|
103
|
+
# Support Tasks ------------------------------------------------------
|
104
|
+
|
105
|
+
desc "Look for TODO and FIXME tags in the code"
|
106
|
+
task :todo do
|
107
|
+
Pathname.new(File.dirname(__FILE__)).egrep(/#.*(FIXME|TODO|TBD|DEPRECATED)/) do |match|
|
108
|
+
puts match
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
task :release => [:release_files, :publish_doc, :tag] # :publish_news,
|
113
|
+
|
114
|
+
task :verify_env_vars do
|
115
|
+
raise "RUBYFORGE_USER environment variable not set!" unless ENV['RUBYFORGE_USER']
|
116
|
+
raise "RUBYFORGE_PASSWORD environment variable not set!" unless ENV['RUBYFORGE_PASSWORD']
|
117
|
+
end
|
118
|
+
|
119
|
+
task :publish_doc => :verify_env_vars do
|
120
|
+
publisher = Rake::RubyForgePublisher.new('autobuild', ENV['RUBYFORGE_USER'])
|
121
|
+
publisher.upload
|
122
|
+
end
|
123
|
+
|
124
|
+
desc "Release files on RubyForge"
|
125
|
+
task :release_files => [:gem, :verify_env_vars] do
|
126
|
+
release_files = FileList[
|
127
|
+
"pkg/#{PKG_FILE_NAME}.gem"
|
128
|
+
]
|
129
|
+
|
130
|
+
Rake::XForge::Release.new(MetaProject::Project::XForge::RubyForge.new('autobuild')) do |release|
|
131
|
+
# Never hardcode user name and password in the Rakefile!
|
132
|
+
release.user_name = ENV['RUBYFORGE_USER']
|
133
|
+
release.password = ENV['RUBYFORGE_PASSWORD']
|
134
|
+
release.files = release_files.to_a
|
135
|
+
release.release_name = "Autobuild #{PKG_VERSION}"
|
136
|
+
# The rest of the options are defaults (among others, release_notes and release_changes, parsed from CHANGES)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
desc "Publish news on RubyForge"
|
141
|
+
task :publish_news => [:gem, :verify_env_vars] do
|
142
|
+
release_files = FileList[
|
143
|
+
"pkg/#{PKG_FILE_NAME}.gem"
|
144
|
+
]
|
145
|
+
|
146
|
+
Rake::XForge::NewsPublisher.new(MetaProject::Project::XForge::RubyForge.new('autobuild')) do |news|
|
147
|
+
# Never hardcode user name and password in the Rakefile!
|
148
|
+
news.user_name = ENV['RUBYFORGE_USER']
|
149
|
+
news.password = ENV['RUBYFORGE_PASSWORD']
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
desc "Tag all the svn files with the latest release number (REL=x.y.z)"
|
154
|
+
task :tag do
|
155
|
+
reltag = "RELEASE_#{PKG_VERSION.gsub(/\./, '_')}"
|
156
|
+
puts "Tagging svn with [#{reltag}]"
|
157
|
+
base_url = %{svn+ssh://#{RUBYFORGE_USER}@rubyforge.org/var/svn/autobuild}
|
158
|
+
sh %{svn cp #{base_url}/trunk/autobuild #{base_url}/tags/#{reltag}}
|
159
|
+
end
|
160
|
+
|
161
|
+
|
@@ -1,117 +1,106 @@
|
|
1
1
|
require 'autobuild/exceptions'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
module Autobuild
|
4
|
+
class UndefinedVariable < ConfigException
|
5
|
+
attr_reader :name
|
6
|
+
attr_accessor :reference
|
7
|
+
def initialize(name, reference = [])
|
8
|
+
@name = name
|
9
|
+
@reference = reference
|
9
10
|
end
|
10
|
-
end
|
11
|
-
end
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
def initialize(name, reference = [])
|
17
|
-
@name = name
|
18
|
-
@reference = reference
|
12
|
+
def to_s
|
13
|
+
"undefined variable '#{name}' in #{reference.join('/')}"
|
14
|
+
end
|
19
15
|
end
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
class Interpolator
|
18
|
+
VarDefKey = 'defines'
|
19
|
+
MatchExpr = '\$\{([^}]+)\}|\$(\w+)'
|
20
|
+
PartialMatch = Regexp.new(MatchExpr)
|
21
|
+
WholeMatch = Regexp.new("^(?:#{MatchExpr})$")
|
25
22
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
PartialMatch = Regexp.new(MatchExpr)
|
30
|
-
WholeMatch = Regexp.new("^(?:#{MatchExpr})$")
|
23
|
+
def self.interpolate(config, parent = nil)
|
24
|
+
Interpolator.new(config, parent).interpolate
|
25
|
+
end
|
31
26
|
|
32
|
-
|
33
|
-
|
34
|
-
|
27
|
+
def initialize(node, parent = nil, variables = {})
|
28
|
+
@node = node
|
29
|
+
@variables = {}
|
30
|
+
@defines = {}
|
31
|
+
@parent = parent
|
32
|
+
end
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
34
|
+
def interpolate
|
35
|
+
case @node
|
36
|
+
when Hash
|
37
|
+
@defines = (@node[VarDefKey] || {})
|
38
|
+
|
39
|
+
interpolated = Hash.new
|
40
|
+
@node.each do |k, v|
|
41
|
+
begin
|
42
|
+
next if k == VarDefKey
|
43
|
+
interpolated[k] = Interpolator.interpolate(v, self)
|
44
|
+
rescue UndefinedVariable => e
|
45
|
+
e.reference.unshift k
|
46
|
+
raise e
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
interpolated
|
42
51
|
|
43
|
-
|
44
|
-
|
45
|
-
when Hash
|
46
|
-
@defines = (@node[VarDefKey] || {})
|
52
|
+
when Array
|
53
|
+
@node.collect { |v| Interpolator.interpolate(v, self) }
|
47
54
|
|
48
|
-
|
49
|
-
@node.each do |k, v|
|
55
|
+
else
|
50
56
|
begin
|
51
|
-
|
52
|
-
interpolated[k] = Interpolator.interpolate(v, self)
|
57
|
+
each_interpolation(@node) { |varname| value_of(varname) }
|
53
58
|
rescue UndefinedVariable => e
|
54
|
-
e.reference.unshift
|
59
|
+
e.reference.unshift @node.to_str if @node.respond_to?(:to_str)
|
55
60
|
raise e
|
56
61
|
end
|
57
62
|
end
|
58
|
-
|
59
|
-
interpolated
|
60
|
-
|
61
|
-
when Array
|
62
|
-
@node.collect { |v| Interpolator.interpolate(v, self) }
|
63
|
-
|
64
|
-
else
|
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
|
71
63
|
end
|
72
|
-
end
|
73
64
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
65
|
+
def value_of(name)
|
66
|
+
if @defines.has_key?(name)
|
67
|
+
value = @defines.delete(name)
|
68
|
+
@variables[name] = each_interpolation(value) { |varname|
|
69
|
+
begin
|
70
|
+
value_of(varname)
|
71
|
+
rescue UndefinedVariable => e
|
72
|
+
if e.varname == name
|
73
|
+
raise ConfigException, "cyclic reference found in definition of '#{name}'"
|
74
|
+
else
|
75
|
+
raise
|
76
|
+
end
|
85
77
|
end
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
@
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
78
|
+
}
|
79
|
+
elsif @variables.has_key?(name)
|
80
|
+
@variables[name]
|
81
|
+
elsif @parent
|
82
|
+
@parent.value_of(name)
|
83
|
+
elsif ENV[name.to_s]
|
84
|
+
ENV[name.to_s]
|
85
|
+
else
|
86
|
+
raise UndefinedVariable.new(name)
|
87
|
+
end
|
96
88
|
end
|
97
|
-
end
|
98
89
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
90
|
+
def each_interpolation(value)
|
91
|
+
return value if (!value.respond_to?(:to_str) || value.empty?)
|
92
|
+
|
93
|
+
# Special case: if 'value' is *only* an interpolation, avoid
|
94
|
+
# conversion to string
|
95
|
+
if match = WholeMatch.match(value)
|
96
|
+
return yield($1 || $2)
|
97
|
+
end
|
107
98
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
interpolated << data.pre_match << yield(varname)
|
99
|
+
return value.gsub(PartialMatch) { |match|
|
100
|
+
varname = $1 || $2
|
101
|
+
yield(varname)
|
102
|
+
}
|
113
103
|
end
|
114
|
-
return data ? (interpolated << data.post_match) : value
|
115
104
|
end
|
116
105
|
end
|
117
106
|
|