summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CHANGES.txt5
-rw-r--r--src/engine/SCons/Script/SConscript.py17
-rw-r--r--src/engine/SCons/Script/__init__.py25
-rw-r--r--src/engine/SCons/Util.py45
-rw-r--r--src/engine/SCons/UtilTests.py52
5 files changed, 130 insertions, 14 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index 3869feb..f719883 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -19,6 +19,11 @@ RELEASE 0.10 - XXX
- Remove Python bytecode (*.pyc) files from the scons-local packages.
+ From Steve Leblanc:
+
+ - Add a Clean() method to support removing user-specified targets
+ when using the -c option.
+
From Anthony Roach:
- Add SetJobs() and GetJobs() methods to allow configuration of the
diff --git a/src/engine/SCons/Script/SConscript.py b/src/engine/SCons/Script/SConscript.py
index 15f116f..fcb08cf 100644
--- a/src/engine/SCons/Script/SConscript.py
+++ b/src/engine/SCons/Script/SConscript.py
@@ -51,6 +51,7 @@ def do_nothing(text): pass
HelpFunction = do_nothing
default_targets = []
+clean_targets = {}
arguments = {}
launch_dir = os.path.abspath(os.curdir)
@@ -315,6 +316,21 @@ def SetJobs(num):
except ValueError, x:
raise SCons.Errors.UserError, "A positive integer is required: %s"%repr(num)
+def Clean(target, files):
+ target = str(target)
+ if not SCons.Util.is_List(files):
+ files = [files]
+ nodes = []
+ for f in files:
+ if isinstance(f, SCons.Node.Node):
+ nodes.append(f)
+ else:
+ nodes.extend(SCons.Node.arg2nodes(f, SCons.Node.FS.default_fs.Entry))
+ if clean_targets.has_key(target):
+ clean_targets[target].extend(nodes)
+ else:
+ clean_targets[target] = nodes
+
def BuildDefaultGlobals():
"""
Create a dictionary containing all the default globals for
@@ -326,6 +342,7 @@ def BuildDefaultGlobals():
globals['ARGUMENTS'] = arguments
globals['BuildDir'] = BuildDir
globals['Builder'] = SCons.Builder.Builder
+ globals['Clean'] = Clean
globals['CScan'] = SCons.Defaults.CScan
globals['Default'] = Default
globals['Dir'] = SCons.Node.FS.default_fs.Dir
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index 0068e8c..b4afb3c 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -65,6 +65,7 @@ import SCons.Builder
import SCons.Script.SConscript
import SCons.Warnings
from SCons.Optik import OptionParser, SUPPRESS_HELP, OptionValueError
+from SCons.Util import display
#
@@ -146,6 +147,10 @@ class CleanTask(SCons.Taskmaster.Task):
def show(self):
if self.targets[0].builder or self.targets[0].side_effect:
display("Removed " + str(self.targets[0]))
+ if SCons.Script.SConscript.clean_targets.has_key(str(self.targets[0])):
+ files = SCons.Script.SConscript.clean_targets[str(self.targets[0])]
+ for f in files:
+ SCons.Utils.fs_delete(str(f), 0)
def remove(self):
if self.targets[0].builder or self.targets[0].side_effect:
@@ -157,6 +162,10 @@ class CleanTask(SCons.Taskmaster.Task):
else:
if removed:
display("Removed " + str(t))
+ if SCons.Script.SConscript.clean_targets.has_key(str(self.targets[0])):
+ files = SCons.Script.SConscript.clean_targets[str(self.targets[0])]
+ for f in files:
+ SCons.Util.fs_delete(str(f))
execute = remove
@@ -192,11 +201,6 @@ repositories = []
sig_module = None
num_jobs = 1 # this is modifed by SConscript.SetJobs()
-def print_it(text):
- print text
-
-display = print_it
-
# Exceptions for this module
class PrintHelp(Exception):
pass
@@ -408,10 +412,8 @@ class OptParser(OptionParser):
"--touch", action="callback", callback=opt_ignore,
help="Ignored for compatibility.")
- def opt_c(option, opt, value, parser):
- setattr(parser.values, 'clean', 1)
- self.add_option('-c', '--clean', '--remove', action="callback",
- callback=opt_c,
+ self.add_option('-c', '--clean', '--remove', action="store_true",
+ default=0, dest="clean",
help="Remove specified targets and dependencies.")
self.add_option('-C', '--directory', type="string", action = "append",
@@ -662,10 +664,7 @@ def _main():
SCons.Node.FS.execute_actions = None
CleanTask.execute = CleanTask.show
if options.no_progress or options.silent:
- global display
- def dont_print_it(text):
- pass
- display = dont_print_it
+ display.set_mode(0)
if options.silent:
SCons.Action.print_actions = None
if options.directory:
diff --git a/src/engine/SCons/Util.py b/src/engine/SCons/Util.py
index 17b2882..5a1c078 100644
--- a/src/engine/SCons/Util.py
+++ b/src/engine/SCons/Util.py
@@ -326,6 +326,22 @@ class CmdStringHolder:
def __cmp__(self, rhs):
return cmp(self.flatdata, str(rhs))
+class DisplayEngine:
+ def __init__(self):
+ self.__call__ = self.print_it
+
+ def print_it(self, text):
+ print text
+
+ def dont_print(self, text):
+ pass
+
+ def set_mode(self, mode):
+ if mode:
+ self.__call__ = self.print_it
+ else:
+ self.__call__ = self.dont_print
+
def scons_subst_list(strSubst, globals, locals, remove=None):
"""
@@ -722,3 +738,32 @@ def ParseConfig(env, command, function=None):
if type(command) is type([]):
command = string.join(command)
return function(env, os.popen(command).read())
+
+def dir_index(directory):
+ files = []
+ for file in os.listdir(directory):
+ fullname = os.path.join(directory, file)
+ files.append(fullname)
+ return files
+
+def fs_delete(path, remove=1):
+ try:
+ if os.path.exists(path):
+ if os.path.isfile(path):
+ if remove: os.unlink(path)
+ display("Removed " + path)
+ elif os.path.isdir(path) and not os.path.islink(path):
+ # delete everything in the dir
+ for p in dir_index(path):
+ if os.path.isfile(p):
+ if remove: os.unlink(p)
+ display("Removed " + p)
+ else:
+ fs_delete(p, remove)
+ # then delete dir itself
+ if remove: os.rmdir(path)
+ display("Removed directory " + path)
+ except OSError, e:
+ print "scons: Could not remove '%s':" % str(t), e.strerror
+
+display = DisplayEngine()
diff --git a/src/engine/SCons/UtilTests.py b/src/engine/SCons/UtilTests.py
index 1f609ab..2da792f 100644
--- a/src/engine/SCons/UtilTests.py
+++ b/src/engine/SCons/UtilTests.py
@@ -35,6 +35,15 @@ import SCons.Node.FS
from SCons.Util import *
import TestCmd
+
+class OutBuffer:
+ def __init__(self):
+ self.buffer = ""
+
+ def write(self, str):
+ self.buffer = self.buffer + str
+
+
class UtilTestCase(unittest.TestCase):
def test_subst(self):
"""Test the subst function."""
@@ -496,7 +505,48 @@ class UtilTestCase(unittest.TestCase):
env=DummyEnv()
res=mapPaths('bleh', dir, env)
assert res[0] == os.path.normpath('foo/bar'), res[1]
-
+
+ def test_display(self):
+ old_stdout = sys.stdout
+ sys.stdout = OutBuffer()
+ SCons.Util.display("line1")
+ display.set_mode(0)
+ SCons.Util.display("line2")
+ display.set_mode(1)
+ SCons.Util.display("line3")
+
+ assert sys.stdout.buffer == "line1\nline3\n"
+ sys.stdout = old_stdout
+
+ def test_fs_delete(self):
+ test = TestCmd.TestCmd(workdir = '')
+ base = test.workpath('')
+ xxx = test.workpath('xxx.xxx')
+ sub1_yyy = test.workpath('sub1', 'yyy.yyy')
+ test.subdir('sub1')
+ test.write(xxx, "\n")
+ test.write(sub1_yyy, "\n")
+
+ old_stdout = sys.stdout
+ sys.stdout = OutBuffer()
+
+ exp = "Removed " + os.path.join(base, sub1_yyy) + '\n' + \
+ "Removed directory " + os.path.join(base, 'sub1') + '\n' + \
+ "Removed " + os.path.join(base, xxx) + '\n' + \
+ "Removed directory " + base + '\n'
+
+ SCons.Util.fs_delete(base, remove=0)
+ assert sys.stdout.buffer == exp
+ assert os.path.exists(sub1_yyy)
+
+ sys.stdout.buffer = ""
+ SCons.Util.fs_delete(base, remove=1)
+ assert sys.stdout.buffer == exp
+ assert not os.path.exists(base)
+
+ test._dirlist = None
+ sys.stdout = old_stdout
+
if __name__ == "__main__":
suite = unittest.makeSuite(UtilTestCase, 'test_')