From 298c0efec9e614cc33ba7026277115352461428c Mon Sep 17 00:00:00 2001 From: stevenknight Date: Thu, 24 Jan 2002 07:32:50 +0000 Subject: [PATCH] Provide an error message when a target hasn't been defined. git-svn-id: http://scons.tigris.org/svn/scons/trunk@222 fdb21ef1-2011-0410-befe-b5e4ea1792b1 --- src/CHANGES.txt | 3 +++ src/engine/SCons/Node/FS.py | 20 +++++++++----- src/engine/SCons/Node/FSTests.py | 17 ++++++++++++ src/engine/SCons/Script/__init__.py | 16 ++++++++--- test/nonexistent.py | 42 +++++++++++++++++++++++++++++ 5 files changed, 87 insertions(+), 11 deletions(-) create mode 100644 test/nonexistent.py diff --git a/src/CHANGES.txt b/src/CHANGES.txt index bdced280..9e2591b7 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 e21e193b..2ce11512 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 dc3c559f..12dfdbe7 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 acbd6c0b..f5ddbfe7 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 00000000..892a5cbf --- /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() -- 2.26.2