diff options
author | Steven Knight <knight@baldmt.com> | 2003-09-15 14:01:28 (GMT) |
---|---|---|
committer | Steven Knight <knight@baldmt.com> | 2003-09-15 14:01:28 (GMT) |
commit | c41dc6daf69787a9f4d4984aec727af705445e46 (patch) | |
tree | 24ce63856445f3ab2b29f4593bd0cb886cd4f4ba /src/engine | |
parent | f36ff530132ecfe7941f80d2d6e5f03f75decf41 (diff) | |
download | SCons-c41dc6daf69787a9f4d4984aec727af705445e46.zip SCons-c41dc6daf69787a9f4d4984aec727af705445e46.tar.gz SCons-c41dc6daf69787a9f4d4984aec727af705445e46.tar.bz2 |
Turn more global functions into Environment methods. (clone of 0.92.C121)
Diffstat (limited to 'src/engine')
-rw-r--r-- | src/engine/SCons/Environment.py | 10 | ||||
-rw-r--r-- | src/engine/SCons/EnvironmentTests.py | 16 | ||||
-rw-r--r-- | src/engine/SCons/Script/SConscript.py | 202 | ||||
-rw-r--r-- | src/engine/SCons/Script/__init__.py | 33 |
4 files changed, 158 insertions, 103 deletions
diff --git a/src/engine/SCons/Environment.py b/src/engine/SCons/Environment.py index 2e95d81..f2beb38 100644 --- a/src/engine/SCons/Environment.py +++ b/src/engine/SCons/Environment.py @@ -171,7 +171,7 @@ class BuilderDict(UserDict): for i, v in dict.items(): self.__setitem__(i, v) -class Environment: +class Base: """Base class for construction Environments. These are the primary objects used to communicate dependency and construction information to the build engine. @@ -847,3 +847,11 @@ class Environment: self._build_signature = 0 else: raise SCons.Errors.UserError, "Unknown target signature type '%s'"%type + +# The entry point that will be used by the external world +# to refer to a construction environment. This allows the wrapper +# interface to extend a construction environment for its own purposes +# by subclassing SCons.Environment.Base and then assigning the +# class to SCons.Environment.Environment. + +Environment = Base diff --git a/src/engine/SCons/EnvironmentTests.py b/src/engine/SCons/EnvironmentTests.py index aa5dbac..36f4112 100644 --- a/src/engine/SCons/EnvironmentTests.py +++ b/src/engine/SCons/EnvironmentTests.py @@ -1494,6 +1494,22 @@ class EnvironmentTestCase(unittest.TestCase): env.TargetSignatures('$C') assert env._build_signature == 0, env._build_signature + def test_Environment(type): + """Test setting Environment variable to an Environment.Base subclass""" + class MyEnv(SCons.Environment.Base): + def xxx(self, string): + return self.subst(string) + + SCons.Environment.Environment = MyEnv + + env = SCons.Environment.Environment(FOO = 'foo') + + f = env.subst('$FOO') + assert f == 'foo', f + + f = env.xxx('$FOO') + assert f == 'foo', f + if __name__ == "__main__": suite = unittest.makeSuite(EnvironmentTestCase, 'test_') diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py index 8614235..cc9562d 100644 --- a/src/engine/SCons/Script/SConscript.py +++ b/src/engine/SCons/Script/SConscript.py @@ -212,12 +212,11 @@ def GetSConscriptFilenames(ls, kw): return (files, exports) -def SConscript(*ls, **kw): +def _SConscript(fs, *ls, **kw): files, exports = GetSConscriptFilenames(ls, kw) - default_fs = SCons.Node.FS.default_fs - top = default_fs.Top - sd = default_fs.SConstruct_dir.rdir() + top = fs.Top + sd = fs.SConstruct_dir.rdir() # evaluate each SConscript file results = [] @@ -231,14 +230,13 @@ def SConscript(*ls, **kw): if isinstance(fn, SCons.Node.Node): f = fn else: - f = default_fs.File(str(fn)) + f = fs.File(str(fn)) _file_ = None # Change directory to the top of the source # tree to make sure the os's cwd and the cwd of - # SCons.Node.FS.default_fs match so we can open the - # SConscript. - default_fs.chdir(top, change_os_dir=1) + # fs match so we can open the SConscript. + fs.chdir(top, change_os_dir=1) if f.rexists(): _file_ = open(f.rstr(), "r") elif f.has_src_builder(): @@ -262,17 +260,17 @@ def SConscript(*ls, **kw): # where the SConstruct and SConscript files might be # in different Repositories. For now, cross that # bridge when someone comes to it. - ldir = default_fs.Dir(f.dir.get_path(sd)) + ldir = fs.Dir(f.dir.get_path(sd)) try: - default_fs.chdir(ldir, change_os_dir=sconscript_chdir) + fs.chdir(ldir, change_os_dir=sconscript_chdir) except OSError: # There was no local directory, so we should be # able to chdir to the Repository directory. # Note that we do this directly, not through - # default_fs.chdir(), because we still need to + # fs.chdir(), because we still need to # interpret the stuff within the SConscript file # relative to where we are logically. - default_fs.chdir(ldir, change_os_dir=0) + fs.chdir(ldir, change_os_dir=0) os.chdir(f.rfile().dir.get_abspath()) # Append the SConscript directory to the beginning @@ -295,12 +293,12 @@ def SConscript(*ls, **kw): sys.path = old_sys_path frame = stack.pop() try: - default_fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir) + fs.chdir(frame.prev_dir, change_os_dir=sconscript_chdir) except OSError: # There was no local directory, so chdir to the # Repository directory. Like above, we do this # directly. - default_fs.chdir(frame.prev_dir, change_os_dir=0) + fs.chdir(frame.prev_dir, change_os_dir=0) os.chdir(frame.prev_dir.rdir().get_abspath()) results.append(frame.retval) @@ -355,31 +353,96 @@ def annotate(node): # leave this disabled until we find a more efficient mechanism. #SCons.Node.Annotate = annotate -def Help(text): - HelpFunction(text) +class SConsEnvironment(SCons.Environment.Base): + """An Environment subclass that contains all of the methods that + are particular to the wrapper SCons interface and which aren't + (or shouldn't be) part of the build engine itself. + """ -def Export(*vars): - for var in vars: - global_exports.update(compute_exports(var)) + # + # Private functions of an SConsEnvironment. + # -def Import(*vars): - try: + def _check_version(self, major, minor, version_string): + """Return 0 if 'major' and 'minor' are greater than the version + in 'version_string', and 1 otherwise.""" + try: + v_major, v_minor, v_micro, release, serial = sys.version_info + except AttributeError: + version = string.split(string.split(version_string, ' ')[0], '.') + v_major = int(version[0]) + v_minor = int(re.match('\d+', version[1]).group()) + if major > v_major or (major == v_major and minor > v_minor): + return 0 + else: + return 1 + + # + # Public functions of an SConsEnvironment. These get + # entry points in the global name space so they can be called + # as global functions. + # + + def EnsureSConsVersion(self, major, minor): + """Exit abnormally if the SCons version is not late enough.""" + if not self._check_version(major,minor,SCons.__version__): + print "SCons %d.%d or greater required, but you have SCons %s" %(major,minor,SCons.__version__) + sys.exit(2) + + def EnsurePythonVersion(self, major, minor): + """Exit abnormally if the Python version is not late enough.""" + if not self._check_version(major,minor,sys.version): + v = string.split(sys.version, " ", 1)[0] + print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v) + sys.exit(2) + + def Exit(self, value=0): + sys.exit(value) + + def Export(self, *vars): for var in vars: - var = SCons.Util.Split(var) - for v in var: - if v == '*': - stack[-1].globals.update(global_exports) - stack[-1].globals.update(stack[-1].exports) - else: - if stack[-1].exports.has_key(v): - stack[-1].globals[v] = stack[-1].exports[v] + global_exports.update(compute_exports(var)) + + def GetLaunchDir(self): + global launch_dir + return launch_dir + + def GetOption(self, name): + name = self.subst(name) + return SCons.Script.ssoptions.get(name) + + def Help(self, text): + text = self.subst(text, raw=1) + HelpFunction(text) + + def Import(self, *vars): + try: + for var in vars: + var = SCons.Util.Split(var) + for v in var: + if v == '*': + stack[-1].globals.update(global_exports) + stack[-1].globals.update(stack[-1].exports) else: - stack[-1].globals[v] = global_exports[v] - except KeyError,x: - raise SCons.Errors.UserError, "Import of non-existant variable '%s'"%x + if stack[-1].exports.has_key(v): + stack[-1].globals[v] = stack[-1].exports[v] + else: + stack[-1].globals[v] = global_exports[v] + except KeyError,x: + raise SCons.Errors.UserError, "Import of non-existant variable '%s'"%x + + def SConscript(self, *ls, **kw): + ls = map(lambda l, self=self: self.subst(l), ls) + return apply(_SConscript, [self.fs,] + ls, kw) -def GetLaunchDir(): - return launch_dir + def SetOption(self, name, value): + name = self.subst(name) + SCons.Script.ssoptions.set(name, value) + +# +# +# +SCons.Environment.Environment = SConsEnvironment def SetBuildSignatureType(type): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, @@ -397,33 +460,6 @@ class Options(SCons.Options.Options): def __init__(self, files=None, args=arguments): SCons.Options.Options.__init__(self, files, args) -def CheckVersion(major, minor, version_string): - """Return 0 if 'major' and 'minor' are greater than the version - in 'version_string', and 1 otherwise.""" - try: - v_major, v_minor, v_micro, release, serial = sys.version_info - except AttributeError: - version = string.split(string.split(version_string, ' ')[0], '.') - v_major = int(version[0]) - v_minor = int(re.match('\d+', version[1]).group()) - if major > v_major or (major == v_major and minor > v_minor): - return 0 - else: - return 1 - -def EnsureSConsVersion(major, minor): - """Exit abnormally if the SCons version is not late enough.""" - if not CheckVersion(major,minor,SCons.__version__): - print "SCons %d.%d or greater required, but you have SCons %s" %(major,minor,SCons.__version__) - sys.exit(2) - -def EnsurePythonVersion(major, minor): - """Exit abnormally if the Python version is not late enough.""" - if not CheckVersion(major,minor,sys.version): - v = string.split(sys.version, " ", 1)[0] - print "Python %d.%d or greater required, but you have Python %s" %(major,minor,v) - sys.exit(2) - def GetJobs(): SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "The GetJobs() function has been deprecated;\n" +\ @@ -437,9 +473,6 @@ def SetJobs(num): "\tuse SetOption('num_jobs', num) instead.") SetOption('num_jobs', num) -def Exit(value=0): - sys.exit(value) - def Alias(name): alias = SCons.Node.Alias.default_ans.lookup(name) @@ -447,12 +480,6 @@ def Alias(name): alias = SCons.Node.Alias.default_ans.Alias(name) return alias -def SetOption(name, value): - SCons.Script.ssoptions.set(name, value) - -def GetOption(name): - return SCons.Script.ssoptions.get(name) - # _DefaultEnvironmentProxy = None @@ -495,35 +522,27 @@ def BuildDefaultGlobals(): globals['Configure'] = SCons.SConf.SConf globals['CScan'] = SCons.Defaults.CScan globals['DefaultEnvironment'] = SCons.Defaults.DefaultEnvironment - globals['EnsurePythonVersion'] = EnsurePythonVersion - globals['EnsureSConsVersion'] = EnsureSConsVersion globals['Environment'] = SCons.Environment.Environment - globals['Exit'] = Exit - globals['Export'] = Export globals['GetCommandHandler'] = SCons.Action.GetCommandHandler - globals['GetJobs'] = GetJobs - globals['GetLaunchDir'] = GetLaunchDir - globals['GetOption'] = GetOption - globals['Help'] = Help - globals['Import'] = Import globals['Literal'] = SCons.Util.Literal globals['Options'] = Options globals['ParseConfig'] = SCons.Util.ParseConfig globals['Platform'] = SCons.Platform.Platform globals['Return'] = Return - globals['SConscript'] = SConscript globals['SConscriptChdir'] = SConscriptChdir globals['Scanner'] = SCons.Scanner.Base - globals['SetBuildSignatureType'] = SetBuildSignatureType globals['SetCommandHandler'] = SCons.Action.SetCommandHandler - globals['SetContentSignatureType'] = SetContentSignatureType - globals['SetJobs'] = SetJobs - globals['SetOption'] = SetOption globals['Split'] = SCons.Util.Split globals['Tool'] = SCons.Tool.Tool globals['Value'] = SCons.Node.Python.Value globals['WhereIs'] = SCons.Util.WhereIs + # Deprecated functions, leave this here for now. + globals['GetJobs'] = GetJobs + globals['SetBuildSignatureType'] = SetBuildSignatureType + globals['SetContentSignatureType'] = SetContentSignatureType + globals['SetJobs'] = SetJobs + class DefaultEnvironmentCall: """A class that implements "global function" calls of Environment methods by fetching the specified method from the @@ -567,7 +586,20 @@ def BuildDefaultGlobals(): 'TargetSignatures', ] - for name in EnvironmentMethods: + SConsEnvironmentMethods = [ + 'EnsurePythonVersion', + 'EnsureSConsVersion', + 'Exit', + 'Export', + 'GetLaunchDir', + 'GetOption', + 'Help', + 'Import', + 'SConscript', + 'SetOption', + ] + + for name in EnvironmentMethods + SConsEnvironmentMethods: globals[name] = DefaultEnvironmentCall(name) return globals diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py index 61e7561..ee8a4fa 100644 --- a/src/engine/SCons/Script/__init__.py +++ b/src/engine/SCons/Script/__init__.py @@ -695,6 +695,7 @@ class SConscriptSettableOptions: def _main(args, parser): targets = [] + fs = SCons.Node.FS.default_fs # Enable deprecated warnings by default. SCons.Warnings._warningOut = _scons_internal_warning @@ -730,11 +731,11 @@ def _main(args, parser): SCons.Action.print_actions = None if options.cache_disable: def disable(self): pass - SCons.Node.FS.default_fs.CacheDir = disable + fs.CacheDir = disable if options.cache_force: - SCons.Node.FS.default_fs.cache_force = 1 + fs.cache_force = 1 if options.cache_show: - SCons.Node.FS.default_fs.cache_show = 1 + fs.cache_show = 1 if options.directory: cdir = _create_path(options.directory) try: @@ -766,7 +767,7 @@ def _main(args, parser): else: raise SCons.Errors.UserError, "No SConstruct file found." - SCons.Node.FS.default_fs.set_toplevel_dir(os.getcwd()) + fs.set_toplevel_dir(os.getcwd()) scripts = [] if options.file: @@ -789,10 +790,10 @@ def _main(args, parser): raise SCons.Errors.UserError, "No SConstruct file found." if scripts[0] == "-": - d = SCons.Node.FS.default_fs.getcwd() + d = fs.getcwd() else: - d = SCons.Node.FS.default_fs.File(scripts[0]).dir - SCons.Node.FS.default_fs.set_SConstruct_dir(d) + d = fs.File(scripts[0]).dir + fs.set_SConstruct_dir(d) class Unbuffered: def __init__(self, file): @@ -810,14 +811,14 @@ def _main(args, parser): global repositories for rep in repositories: - SCons.Node.FS.default_fs.Repository(rep) + fs.Repository(rep) progress_display("scons: Reading SConscript files ...") try: start_time = time.time() try: for script in scripts: - SCons.Script.SConscript.SConscript(script) + SCons.Script.SConscript._SConscript(fs, script) except SCons.Errors.StopError, e: # We had problems reading an SConscript file, such as it # couldn't be copied in to the BuildDir. Since we're just @@ -837,7 +838,7 @@ def _main(args, parser): sys.exit(0) progress_display("scons: done reading SConscript files.") - SCons.Node.FS.default_fs.chdir(SCons.Node.FS.default_fs.Top) + fs.chdir(fs.Top) if options.help_msg: # They specified -h, but there was no Help() inside the @@ -855,7 +856,7 @@ def _main(args, parser): # used -u, -U or -D, we have to look up targets relative # to the top, but we build whatever they specified. if target_top: - lookup_top = SCons.Node.FS.default_fs.Dir(target_top) + lookup_top = fs.Dir(target_top) target_top = None else: # There are no targets specified on the command line, @@ -864,7 +865,7 @@ def _main(args, parser): if target_top: if options.climb_up == 1: # -u, local directory and below - target_top = SCons.Node.FS.default_fs.Dir(target_top) + target_top = fs.Dir(target_top) lookup_top = target_top elif options.climb_up == 2: # -D, all Default() targets @@ -872,7 +873,7 @@ def _main(args, parser): lookup_top = None elif options.climb_up == 3: # -U, local SConscript Default() targets - target_top = SCons.Node.FS.default_fs.Dir(target_top) + target_top = fs.Dir(target_top) def check_dir(x, target_top=target_top): if hasattr(x, 'cwd') and not x.cwd is None: cwd = x.cwd.srcnode() @@ -893,7 +894,7 @@ def _main(args, parser): targets = SCons.Environment.DefaultTargets if targets is None: - targets = [SCons.Node.FS.default_fs.Dir('.')] + targets = [fs.Dir('.')] if not targets: sys.stderr.write("scons: *** No targets specified and no Default() targets found. Stop.\n") @@ -905,9 +906,7 @@ def _main(args, parser): else: node = SCons.Node.Alias.default_ans.lookup(x) if node is None: - node = SCons.Node.FS.default_fs.Entry(x, - directory = ltop, - create = 1) + node = fs.Entry(x, directory=ltop, create=1) if ttop and not node.is_under(ttop): if isinstance(node, SCons.Node.FS.Dir) and ttop.is_under(node): node = ttop |