summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/CHANGES.txt3
-rw-r--r--src/engine/SCons/Node/FS.py20
-rw-r--r--src/engine/SCons/Node/FSTests.py17
-rw-r--r--src/engine/SCons/Script/__init__.py16
-rw-r--r--test/nonexistent.py42
5 files changed, 87 insertions, 11 deletions
diff --git a/src/CHANGES.txt b/src/CHANGES.txt
index bdced28..9e2591b 100644
--- a/src/CHANGES.txt
+++ b/src/CHANGES.txt
@@ -51,6 +51,9 @@ RELEASE 0.04 -
- Add the Ignore() method to ignore dependencies.
+ - Provide an error message when a nonexistent target is specified
+ on the command line.
+
From Steve Leblanc:
- Add var=value command-line arguments.
diff --git a/src/engine/SCons/Node/FS.py b/src/engine/SCons/Node/FS.py
index e21e193..2ce1151 100644
--- a/src/engine/SCons/Node/FS.py
+++ b/src/engine/SCons/Node/FS.py
@@ -128,7 +128,7 @@ class FS:
(node.__class__.__name__, str(node), klass.__name__)
return node
- def __doLookup(self, fsclass, name, directory=None):
+ def __doLookup(self, fsclass, name, directory = None, create = 1):
"""This method differs from the File and Dir factory methods in
one important way: the meaning of the directory parameter.
In this method, if directory is None or not supplied, the supplied
@@ -144,6 +144,8 @@ class FS:
try:
directory = self.Root[drive_path]
except KeyError:
+ if not create:
+ raise UserError
dir = Dir(drive, ParentOfRoot())
dir.path = dir.path + os.sep
dir.abspath = dir.abspath + os.sep
@@ -160,6 +162,8 @@ class FS:
directory = self.__checkClass(directory.entries[path_norm],
Dir)
except KeyError:
+ if not create:
+ raise UserError
dir_temp = Dir(path_name, directory)
directory.entries[path_norm] = dir_temp
directory.add_wkid(dir_temp)
@@ -168,6 +172,8 @@ class FS:
try:
ret = self.__checkClass(directory.entries[file_name], fsclass)
except KeyError:
+ if not create:
+ raise UserError
ret = fsclass(path_comp[-1], directory)
directory.entries[file_name] = ret
directory.add_wkid(ret)
@@ -198,7 +204,7 @@ class FS:
if not dir is None:
self._cwd = dir
- def Entry(self, name, directory = None):
+ def Entry(self, name, directory = None, create = 1):
"""Lookup or create a generic Entry node with the specified name.
If the name is a relative path (begins with ./, ../, or a file
name), then it is looked up relative to the supplied directory
@@ -206,9 +212,9 @@ class FS:
construction time) if no directory is supplied.
"""
name, directory = self.__transformPath(name, directory)
- return self.__doLookup(Entry, name, directory)
+ return self.__doLookup(Entry, name, directory, create)
- def File(self, name, directory = None):
+ def File(self, name, directory = None, create = 1):
"""Lookup or create a File node with the specified name. If
the name is a relative path (begins with ./, ../, or a file name),
then it is looked up relative to the supplied directory node,
@@ -219,9 +225,9 @@ class FS:
specified path.
"""
name, directory = self.__transformPath(name, directory)
- return self.__doLookup(File, name, directory)
+ return self.__doLookup(File, name, directory, create)
- def Dir(self, name, directory = None):
+ def Dir(self, name, directory = None, create = 1):
"""Lookup or create a Dir node with the specified name. If
the name is a relative path (begins with ./, ../, or a file name),
then it is looked up relative to the supplied directory node,
@@ -232,7 +238,7 @@ class FS:
specified path.
"""
name, directory = self.__transformPath(name, directory)
- return self.__doLookup(Dir, name, directory)
+ return self.__doLookup(Dir, name, directory, create)
def BuildDir(self, build_dir, src_dir, duplicate=1):
"""Link the supplied build directory to the source directory
diff --git a/src/engine/SCons/Node/FSTests.py b/src/engine/SCons/Node/FSTests.py
index dc3c559..12dfdbe 100644
--- a/src/engine/SCons/Node/FSTests.py
+++ b/src/engine/SCons/Node/FSTests.py
@@ -421,6 +421,23 @@ class FSTestCase(unittest.TestCase):
f1 = SCons.Node.FS.default_fs.File(test.workpath("binary_file"))
assert f1.get_contents() == "Foo\x1aBar", f1.get_contents()
+ def nonexistent(method, str):
+ try:
+ x = method(str, create = 0)
+ except UserError:
+ pass
+ else:
+ raise TestFailed, "did not catch expected UserError"
+
+ nonexistent(fs.Entry, 'nonexistent')
+ nonexistent(fs.Entry, 'nonexistent/foo')
+
+ nonexistent(fs.File, 'nonexistent')
+ nonexistent(fs.File, 'nonexistent/foo')
+
+ nonexistent(fs.Dir, 'nonexistent')
+ nonexistent(fs.Dir, 'nonexistent/foo')
+
#XXX test current() for directories
#XXX test sconsign() for directories
diff --git a/src/engine/SCons/Script/__init__.py b/src/engine/SCons/Script/__init__.py
index acbd6c0..f5ddbfe 100644
--- a/src/engine/SCons/Script/__init__.py
+++ b/src/engine/SCons/Script/__init__.py
@@ -640,10 +640,18 @@ def _main():
def Entry(x):
if isinstance(x, SCons.Node.Node):
return x
- else:
- return SCons.Node.FS.default_fs.Entry(x)
-
- nodes = map(Entry, targets)
+ try:
+ node = SCons.Node.FS.default_fs.Entry(x, create = 0)
+ except UserError:
+ str = "scons: *** Do not know how to make target `%s'." % x
+ if not keep_going_on_error:
+ sys.stderr.write(str + " Stop.\n")
+ sys.exit(2)
+ sys.stderr.write(str + "\n")
+ node = None
+ return node
+
+ nodes = filter(lambda x: x is not None, map(Entry, targets))
if not calc:
calc = SCons.Sig.Calculator(SCons.Sig.MD5)
diff --git a/test/nonexistent.py b/test/nonexistent.py
new file mode 100644
index 0000000..892a5cb
--- /dev/null
+++ b/test/nonexistent.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+#
+# Copyright (c) 2001 Steven Knight
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"
+
+import sys
+import TestSCons
+
+test = TestSCons.TestSCons()
+
+test.write('SConstruct', "")
+
+test.run(arguments = 'foo',
+ stderr = "scons: *** Do not know how to make target `foo'. Stop.\n")
+
+test.run(arguments = '-k foo/bar foo',
+ stderr = """scons: *** Do not know how to make target `foo/bar'.
+scons: *** Do not know how to make target `foo'.
+""")
+
+test.pass_test()