summaryrefslogtreecommitdiffstats
path: root/src/engine/SCons
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/SCons')
-rw-r--r--src/engine/SCons/Options.py67
-rw-r--r--src/engine/SCons/OptionsTests.py35
2 files changed, 93 insertions, 9 deletions
diff --git a/src/engine/SCons/Options.py b/src/engine/SCons/Options.py
index 84365af..d43be28 100644
--- a/src/engine/SCons/Options.py
+++ b/src/engine/SCons/Options.py
@@ -30,6 +30,7 @@ variables to a scons build.
__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
import SCons.Errors
+import SCons.Util
import os.path
@@ -38,13 +39,20 @@ class Options:
Holds all the options, updates the environment with the variables,
and renders the help text.
"""
- def __init__(self, file=None):
+ def __init__(self, files=None):
"""
- file - [optional] the name of the customizable file.
+ files - [optional] List of option configuration files to load
+ (backward compatibility) If a single string is passed it is
+ automatically placed in a file list
"""
self.options = []
- self.file = file
+ self.files = None
+ if SCons.Util.is_String(files):
+ self.files = [ files ]
+ elif files:
+ self.files = files
+
def Add(self, key, help="", default=None, validater=None, converter=None):
"""
@@ -54,8 +62,9 @@ class Options:
help - optional help text for the options
default - optional default value
validater - optional function that is called to validate the option's value
+ Called with (key, value, environment)
converter - optional function that is called to convert the option's value before
- putting it in the environment.
+ putting it in the environment.
"""
class Option:
@@ -67,6 +76,7 @@ class Options:
option.default = default
option.validater = validater
option.converter = converter
+ option.should_save = 0
self.options.append(option)
@@ -86,11 +96,24 @@ class Options:
values[option.key] = option.default
# next set the value specified in the options file
- if self.file and os.path.exists(self.file):
- execfile(self.file, values)
+ if self.files:
+ for filename in self.files:
+ if os.path.exists(filename):
+ execfile(filename, values)
# finally set the values specified on the command line
values.update(args)
+
+ # Update the should save state
+ # This will mark options that have either been set on command line
+ # or in a loaded option file
+ # KeyError occurs when an option has default of None and has not been set
+ for option in self.options:
+ try:
+ if values[option.key] != option.default:
+ option.should_save = 1
+ except KeyError:
+ pass
# put the variables in the environment:
# (don't copy over variables that are not declared
@@ -114,8 +137,38 @@ class Options:
# Finally validate the values:
for option in self.options:
if option.validater:
- option.validater(option.key, env.subst('${%s}'%option.key))
+ option.validater(option.key, env.subst('${%s}'%option.key), env)
+
+
+
+ def Save(self, filename, env):
+ """
+ Saves all the options in the given file. This file can
+ then be used to load the options next run. This can be used
+ to create an option cache file.
+
+ filename - Name of the file to save into
+ env - the environment get the option values from
+ """
+
+ # Create the file and write out the header
+ try:
+ fh = open(filename, 'w')
+
+ # Make an assignment in the file for each option within the environment
+ # that was assigned a value other than the default.
+ for option in self.options:
+ try:
+ value = env[option.key]
+ if option.should_save:
+ fh.write('%s = \'%s\'\n' % (option.key, value))
+ except KeyError:
+ pass
+
+ fh.close()
+ except IOError, x:
+ raise SCons.Errors.UserError, 'Error writing options to file: %s\n%s' % (filename, x)
def GenerateHelpText(self, env):
"""
diff --git a/src/engine/SCons/OptionsTests.py b/src/engine/SCons/OptionsTests.py
index 3a02eb8..7020787 100644
--- a/src/engine/SCons/OptionsTests.py
+++ b/src/engine/SCons/OptionsTests.py
@@ -29,6 +29,7 @@ import SCons.Options
import sys
import string
+
class Environment:
def __init__(self):
self.dict = {}
@@ -42,8 +43,16 @@ class Environment:
return self.dict.has_key(key)
-def check(key,value):
+def check(key,value, env):
assert value == 6 * 9,key
+
+# Check saved option file by executing and comparing against
+# the expected dictionary
+def checkSave(file, expected):
+ gdict = {}
+ ldict = {}
+ execfile(file, gdict, ldict)
+ assert expected == ldict
class OptionsTestCase(unittest.TestCase):
def test_Add(self):
@@ -62,12 +71,13 @@ class OptionsTestCase(unittest.TestCase):
assert o.default == None
assert o.validater == None
assert o.converter == None
+ assert o.should_save == 0
o = opts.options[1]
assert o.key == 'ANSWER'
assert o.help == 'THE answer to THE question'
assert o.default == "42"
- o.validater(o.key, o.converter(o.default))
+ o.validater(o.key, o.converter(o.default), {})
def test_Update(self):
@@ -132,6 +142,27 @@ class OptionsTestCase(unittest.TestCase):
opts.Update(env, {'ANSWER':'42'})
assert env['ANSWER'] == 54
+
+ def test_Save(self):
+
+ test = TestSCons.TestSCons()
+ cache_file = test.workpath('cached.options')
+ opts = SCons.Options.Options()
+
+ # test saving out empty file
+ opts.Add('OPT_VAL',
+ 'An option to test',
+ 21,
+ None,
+ None)
+
+ env = Environment()
+ opts.Update(env, {})
+ assert env['OPT_VAL'] == 21
+ opts.Save(cache_file, env)
+ checkSave(cache_file, {})
+
+
def test_GenerateHelpText(self):
opts = SCons.Options.Options()