"""distutils.core

The only module that needs to be imported to use the Distutils; provides
the 'setup' function (which must be called); the 'Distribution' class
(which may be subclassed if additional functionality is desired), and
the 'Command' class (which is used both internally by Distutils, and
may be subclassed by clients for still more flexibility)."""

# created 1999/03/01, Greg Ward

__rcsid__ = "$Id$"

import sys, os
import string, re
from types import *
from distutils.errors import *
from distutils.fancy_getopt import fancy_getopt
from distutils import util

# This is not *quite* the same as a Python NAME; I don't allow leading
# underscores.  The fact that they're very similar is no coincidence...
command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')

# Defining this as a global is probably inadequate -- what about
# listing the available options (or even commands, which can vary
# quite late as well)
usage = '%s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]' % sys.argv[0]



def setup (**attrs):
    """The gateway to the Distutils: do everything your setup script
       needs to do, in a highly flexible and user-driven way.  Briefly:
       create a Distribution instance; parse the command-line, creating
       and customizing instances of the command class for each command
       found on the command-line; run each of those commands.

       The Distribution instance might be an instance of a class
       supplied via the 'distclass' keyword argument to 'setup'; if no
       such class is supplied, then the 'Distribution' class (also in
       this module) is instantiated.  All other arguments to 'setup'
       (except for 'cmdclass') are used to set attributes of the
       Distribution instance.

       The 'cmdclass' argument, if supplied, is a dictionary mapping
       command names to command classes.  Each command encountered on the
       command line will be turned into a command class, which is in turn
       instantiated; any class found in 'cmdclass' is used in place of the
       default, which is (for command 'foo_bar') class 'FooBar' in module
       'distutils.command.foo_bar'.  The command object must provide an
       'options' attribute which is a list of option specifiers for
       'distutils.fancy_getopt'.  Any command-line options between the
       current and the next command are used to set attributes in the
       current command object.

       When the entire command-line has been successfully parsed, calls the
       'run' method on each command object in turn.  This method will be
       driven entirely by the Distribution object (which each command
       object has a reference to, thanks to its constructor), and the
       command-specific options that became attributes of each command
       object."""

    # Determine the distribution class -- either caller-supplied or
    # our Distribution (see below).
    klass = attrs.get ('distclass')
    if klass:
        del attrs['distclass']
    else:
        klass = Distribution

    # Create the Distribution instance, using the remaining arguments
    # (ie. everything except distclass) to initialize it
    dist = klass (attrs)

    # If we had a config file, this is where we would parse it: override
    # the client-supplied command options, but be overridden by the
    # command line.

    # Parse the command line; any command-line errors are the end-users
    # fault, so turn them into SystemExit to suppress tracebacks.
    try:
        dist.parse_command_line (sys.argv[1:])
    except DistutilsArgError, msg:
        raise SystemExit, msg

    # And finally, run all the commands found on the command line.
    dist.run_commands ()

# setup ()


class Distribution:
    """The core of the Distutils.  Most of the work hiding behind
       'setup' is really done within a Distribution instance, which
       farms the work out to the Distutils commands specified on the
       command line.

       Clients will almost never instantiate Distribution directly,
       unless the 'setup' function is totally inadequate to their needs.
       However, it is conceivable that a client might wish to subclass
       Distribution for some specialized purpose, and then pass the
       subclass to 'setup' as the 'distclass' keyword argument.  If so,
       it is necessary to respect the expectations that 'setup' has of
       Distribution: it must have a constructor and methods
       'parse_command_line()' and 'run_commands()' with signatures like
       those described below."""


    # 'global_options' describes the command-line options that may
    # be supplied to the client (setup.py) prior to any actual
    # commands.  Eg. "./setup.py -nv" or "./setup.py --verbose"
    # both take advantage of these global options.
    global_options = [('verbose', 'v', "run verbosely"),
                      ('dry-run', 'n', "don't actually do anything"),
                     ]


    # -- Creation/initialization methods -------------------------------
    
    def __init__ (self, attrs=None):
        """Construct a new Distribution instance: initialize all the
           attributes of a Distribution, and then uses 'attrs' (a
           dictionary mapping attribute names to values) to assign
           some of those attributes their "real" values.  (Any attributes
           not mentioned in 'attrs' will be assigned to some null
           value: 0, None, an empty list or dictionary, etc.)  Most
           importantly, initialize the 'command_obj' attribute
           to the empty dictionary; this will be filled in with real
           command objects by 'parse_command_line()'."""

        # Default values for our command-line options
        self.verbose = 0
        self.dry_run = 0

        # And the "distribution meta-data" options -- these can only
        # come from setup.py (the caller), not the command line
        # (or a hypothetical config file)..
        self.name = None
        self.version = None
        self.author = None
        self.author_email = None
        self.url = None
        self.licence = None
        self.description = None

        # 'cmdclass' maps command names to class objects, so we
        # can 1) quickly figure out which class to instantiate when
        # we need to create a new command object, and 2) have a way
        # for the client to override command classes
        self.cmdclass = {}

        # These options are really the business of various commands, rather
        # than of the Distribution itself.  We provide aliases for them in
        # Distribution as a convenience to the developer.
        # dictionary.        
        self.packages = None
        self.package_dir = None
        self.py_modules = None
        self.ext_modules = None
        self.ext_package = None
        self.include_dirs = None
        self.install_path = None

        # And now initialize bookkeeping stuff that can't be supplied by
        # the caller at all.  'command_obj' maps command names to
        # Command instances -- that's how we enforce that every command
        # class is a singleton.
        self.command_obj = {}

        # 'have_run' maps command names to boolean values; it keeps track
        # of whether we have actually run a particular command, to make it
        # cheap to "run" a command whenever we think we might need to -- if
        # it's already been done, no need for expensive filesystem
        # operations, we just check the 'have_run' dictionary and carry on.
        # It's only safe to query 'have_run' for a command class that has
        # been instantiated -- a false value will be inserted when the
        # command object is created, and replaced with a true value when
        # the command is succesfully run.  Thus it's probably best to use
        # '.get()' rather than a straight lookup.
        self.have_run = {}

        # Now we'll use the attrs dictionary (ultimately, keyword args from
        # the client) to possibly override any or all of these distribution
        # options.        
        if attrs:

            # Pull out the set of command options and work on them
            # specifically.  Note that this order guarantees that aliased
            # command options will override any supplied redundantly
            # through the general options dictionary.
            options = attrs.get ('options')
            if options:
                del attrs['options']
                for (command, cmd_options) in options.items():
                    cmd_obj = self.find_command_obj (command)
                    for (key, val) in cmd_options.items():
                        cmd_obj.set_option (key, val)
                # loop over commands
            # if any command options                        

            # Now work on the rest of the attributes.  Any attribute that's
            # not already defined is invalid!
            for (key,val) in attrs.items():
                if hasattr (self, key):
                    setattr (self, key, val)
                else:
                    raise DistutilsOptionError, \
                          "invalid distribution option '%s'" % key

    # __init__ ()


    def parse_command_line (self, args):
        """Parse the client's command line: set any Distribution
           attributes tied to command-line options, create all command
           objects, and set their options from the command-line.  'args'
           must be a list of command-line arguments, most likely
           'sys.argv[1:]' (see the 'setup()' function).  This list is
           first processed for "global options" -- options that set
           attributes of the Distribution instance.  Then, it is
           alternately scanned for Distutils command and options for
           that command.  Each new command terminates the options for
           the previous command.  The allowed options for a command are
           determined by the 'options' attribute of the command object
           -- thus, we instantiate (and cache) every command object
           here, in order to access its 'options' attribute.  Any error
           in that 'options' attribute raises DistutilsGetoptError; any
           error on the command-line raises DistutilsArgError.  If no
           Distutils commands were found on the command line, raises
           DistutilsArgError."""

        # We have to parse the command line a bit at a time -- global
        # options, then the first command, then its options, and so on --
        # because each command will be handled by a different class, and
        # the options that are valid for a particular class aren't
        # known until we instantiate the command class, which doesn't
        # happen until we know what the command is.

        self.commands = []
        args = fancy_getopt (self.global_options, self, sys.argv[1:])

        while args:
            # Pull the current command from the head of the command line
            command = args[0]
            if not command_re.match (command):
                raise SystemExit, "invalid command name '%s'" % command
            self.commands.append (command)

            # Make sure we have a command object to put the options into
            # (this either pulls it out of a cache of command objects,
            # or finds and instantiates the command class).
            cmd_obj = self.find_command_obj (command)

            # Require that the command class be derived from Command --
            # that way, we can be sure that we at least have the 'run'
            # and 'get_option' methods.
            if not isinstance (cmd_obj, Command):
                raise DistutilsClassError, \
                      "command class %s must subclass Command" % \
                      cmd_obj.__class__

            # Also make sure that the command object provides a list of its
            # known options
            if not (hasattr (cmd_obj, 'options') and
                    type (cmd_obj.options) is ListType):
                raise DistutilsClasserror, \
                      ("command class %s must provide an 'options' attribute "+
                       "(a list of tuples)") % \
                      cmd_obj.__class__

            args = fancy_getopt (cmd_obj.options, cmd_obj, args[1:])
            self.command_obj[command] = cmd_obj
            self.have_run[command] = 0

        # while args

        # Oops, no commands found -- an end-user error
        if not self.commands:
            sys.stderr.write (usage + "\n")
            raise DistutilsArgError, "no commands supplied"

    # parse_command_line()


    # -- Command class/object methods ----------------------------------

    # This is a method just so it can be overridden if desired; it doesn't
    # actually use or change any attributes of the Distribution instance.
    def find_command_class (self, command):
        """Given a command, derives the names of the module and class
           expected to implement the command: eg. 'foo_bar' becomes
           'distutils.command.foo_bar' (the module) and 'FooBar' (the
           class within that module).  Loads the module, extracts the
           class from it, and returns the class object.

           Raises DistutilsModuleError with a semi-user-targeted error
           message if the expected module could not be loaded, or the
           expected class was not found in it."""

        module_name = 'distutils.command.' + command
        klass_name = string.join \
            (map (string.capitalize, string.split (command, '_')), '')

        try:
            __import__ (module_name)
            module = sys.modules[module_name]
        except ImportError:
            raise DistutilsModuleError, \
                  "invalid command '%s' (no module named %s)" % \
                  (command, module_name)

        try:
            klass = vars(module)[klass_name]
        except KeyError:
            raise DistutilsModuleError, \
                  "invalid command '%s' (no class '%s' in module '%s')" \
                  % (command, klass_name, module_name)

        return klass

    # find_command_class ()


    def create_command_obj (self, command):
        """Figure out the class that should implement a command,
           instantiate it, cache and return the new "command object".
           The "command class" is determined either by looking it up in
           the 'cmdclass' attribute (this is the mechanism whereby
           clients may override default Distutils commands or add their
           own), or by calling the 'find_command_class()' method (if the
           command name is not in 'cmdclass'."""

        # Determine the command class -- either it's in the command_class
        # dictionary, or we have to divine the module and class name
        klass = self.cmdclass.get(command)
        if not klass:
            klass = self.find_command_class (command)
            self.cmdclass[command] = klass

        # Found the class OK -- instantiate it 
        cmd_obj = klass (self)
        return cmd_obj
    

    def find_command_obj (self, command, create=1):
        """Look up and return a command object in the cache maintained by
           'create_command_obj()'.  If none found, the action taken
           depends on 'create': if true (the default), create a new
           command object by calling 'create_command_obj()' and return
           it; otherwise, return None."""

        cmd_obj = self.command_obj.get (command)
        if not cmd_obj and create:
            cmd_obj = self.create_command_obj (command)
            self.command_obj[command] = cmd_obj

        return cmd_obj

        
    # -- Methods that operate on the Distribution ----------------------

    def announce (self, msg, level=1):
        """Print 'msg' if 'level' is greater than or equal to the verbosity
           level recorded in the 'verbose' attribute (which, currently,
           can be only 0 or 1)."""

        if self.verbose >= level:
            print msg


    def run_commands (self):
        """Run each command that was seen on the client command line.
           Uses the list of commands found and cache of command objects
           created by 'create_command_obj()'."""

        for cmd in self.commands:
            self.run_command (cmd)


    def get_option (self, option):
        """Return the value of a distribution option.  Raise
           DistutilsOptionError if 'option' is not known."""

        try:
            return getattr (self, opt)
        except AttributeError:
            raise DistutilsOptionError, \
                  "unknown distribution option %s" % option


    def get_options (self, *options):
        """Return (as a tuple) the values of several distribution
           options.  Raise DistutilsOptionError if any element of
           'options' is not known."""
        
        values = []
        try:
            for opt in options:
                values.append (getattr (self, opt))
        except AttributeError, name:
            raise DistutilsOptionError, \
                  "unknown distribution option %s" % name

        return tuple (values)


    # -- Methods that operate on its Commands --------------------------

    def run_command (self, command):

        """Do whatever it takes to run a command (including nothing at all,
           if the command has already been run).  Specifically: if we have
           already created and run the command named by 'command', return
           silently without doing anything.  If the command named by
           'command' doesn't even have a command object yet, create one.
           Then invoke 'run()' on that command object (or an existing
           one)."""

        # XXX currently, this is the only place where we invoke a
        # command object's 'run()' method -- so it might make sense to
        # put the 'set_final_options()' call here, too, instead of
        # requiring every command's 'run()' to call it first.        

        # Already been here, done that? then return silently.
        if self.have_run.get (command):
            return

        self.announce ("running " + command)
        cmd_obj = self.find_command_obj (command)
        cmd_obj.run ()
        self.have_run[command] = 1


    def get_command_option (self, command, option):
        """Create a command object for 'command' if necessary, finalize
           its option values by invoking its 'set_final_options()'
           method, and return the value of its 'option' option.  Raise
           DistutilsOptionError if 'option' is not known for
           that 'command'."""

        cmd_obj = self.find_command_obj (command)
        cmd_obj.set_final_options ()
        return cmd_obj.get_option (option)
        try:
            return getattr (cmd_obj, option)
        except AttributeError:
            raise DistutilsOptionError, \
                  "command %s: no such option %s" % (command, option)


    def get_command_options (self, command, *options):
        """Create a command object for 'command' if necessary, finalize
           its option values by invoking its 'set_final_options()'
           method, and return the values of all the options listed in
           'options' for that command.  Raise DistutilsOptionError if
           'option' is not known for that 'command'."""

        cmd_obj = self.find_command_obj (command)
        cmd_obj.set_final_options ()
        values = []
        try:
            for opt in options:
                values.append (getattr (cmd_obj, option))
        except AttributeError, name:
            raise DistutilsOptionError, \
                  "command %s: no such option %s" % (command, name)

        return tuple (values)

# end class Distribution


class Command:
    """Abstract base class for defining command classes, the "worker bees"
       of the Distutils.  A useful analogy for command classes is to
       think of them as subroutines with local variables called
       "options".  The options are "declared" in 'set_initial_options()'
       and "initialized" (given their real values) in
       'set_final_options()', both of which must be defined by every
       command class.  The distinction between the two is necessary
       because option values might come from the outside world (command
       line, option file, ...), and any options dependent on other
       options must be computed *after* these outside influences have
       been processed -- hence 'set_final_values()'.  The "body" of the
       subroutine, where it does all its work based on the values of its
       options, is the 'run()' method, which must also be implemented by
       every command class."""

    # -- Creation/initialization methods -------------------------------

    def __init__ (self, dist):
        """Create and initialize a new Command object.  Most importantly,
           invokes the 'set_default_options()' method, which is the
           real initializer and depends on the actual command being
           instantiated."""

        if not isinstance (dist, Distribution):
            raise TypeError, "dist must be a Distribution instance"
        if self.__class__ is Command:
            raise RuntimeError, "Command is an abstract class"

        self.distribution = dist
        self.set_default_options ()

    # end __init__ ()

    # Subclasses must define:
    #   set_default_options()
    #     provide default values for all options; may be overridden
    #     by Distutils client, by command-line options, or by options
    #     from option file
    #   set_final_options()
    #     decide on the final values for all options; this is called
    #     after all possible intervention from the outside world
    #     (command-line, option file, etc.) has been processed
    #   run()
    #     run the command: do whatever it is we're here to do,
    #     controlled by the command's various option values

    def set_default_options (self):
        """Set default values for all the options that this command
           supports.  Note that these defaults may be overridden
           by the command-line supplied by the user; thus, this is
           not the place to code dependencies between options; generally,
           'set_default_options()' implementations are just a bunch
           of "self.foo = None" assignments.
           
           This method must be implemented by all command classes."""
           
        raise RuntimeError, \
              "abstract method -- subclass %s must override" % self.__class__
        
    def set_final_options (self):
        """Set final values for all the options that this command
           supports.  This is always called as late as possible, ie.
           after any option assignments from the command-line or from
           other commands have been done.  Thus, this is the place to to
           code option dependencies: if 'foo' depends on 'bar', then it
           is safe to set 'foo' from 'bar' as long as 'foo' still has
           the same value it was assigned in 'set_default_options()'.

           This method must be implemented by all command classes."""
           
        raise RuntimeError, \
              "abstract method -- subclass %s must override" % self.__class__

    def run (self):
        """A command's raison d'etre: carry out the action it exists
           to perform, controlled by the options initialized in
           'set_initial_options()', customized by the user and other
           commands, and finalized in 'set_final_options()'.  All
           terminal output and filesystem interaction should be done by
           'run()'.

           This method must be implemented by all command classes."""

        raise RuntimeError, \
              "abstract method -- subclass %s must override" % self.__class__

    def announce (self, msg, level=1):
        """If the Distribution instance to which this command belongs
           has a verbosity level of greater than or equal to 'level'
           print 'msg' to stdout."""
        if self.distribution.verbose >= level:
            print msg


    # -- Option query/set methods --------------------------------------

    def get_option (self, option):
        """Return the value of a single option for this command.  Raise
           DistutilsOptionError if 'option' is not known."""
        try:
            return getattr (self, option)
        except AttributeError:
            raise DistutilsOptionError, \
                  "command %s: no such option %s" % \
                  (self.get_command_name(), option)


    def get_options (self, *options):
        """Return (as a tuple) the values of several options for this
           command.  Raise DistutilsOptionError if any of the options in
           'options' are not known."""

        values = []
        try:
            for opt in options:
                values.append (getattr (self, opt))
        except AttributeError, name:
            raise DistutilsOptionError, \
                  "command %s: no such option %s" % \
                  (self.get_command_name(), name)
            
        return tuple (values)
    

    def set_option (self, option, value):
        """Set the value of a single option for this command.  Raise
           DistutilsOptionError if 'option' is not known."""

        if not hasattr (self, option):
            raise DistutilsOptionError, \
                  "command '%s': no such option '%s'" % \
                  (self.get_command_name(), option)
        if value is not None:
            setattr (self, option, value)

    def set_options (self, **optval):
        """Set the values of several options for this command.  Raise
           DistutilsOptionError if any of the options specified as
           keyword arguments are not known."""

        for k in optval.keys():
            if optval[k] is not None:
                self.set_option (k, optval[k])


    # -- Convenience methods for commands ------------------------------

    def get_command_name (self):
        if hasattr (self, 'command_name'):
            return self.command_name
        else:
            class_name = self.__class__.__name__

            # The re.split here returs empty strings delimited by the
            # words we're actually interested in -- e.g.  "FooBarBaz"
            # splits to ['', 'Foo', '', 'Bar', '', 'Baz', ''].  Hence
            # the 'filter' to strip out the empties.            
            words = filter (None, re.split (r'([A-Z][a-z]+)', class_name))
            self.command_name = string.join (map (string.lower, words), "_")
            return self.command_name


    def set_undefined_options (self, src_cmd, *option_pairs):
        """Set the values of any "undefined" options from corresponding
           option values in some other command object.  "Undefined" here
           means "is None", which is the convention used to indicate
           that an option has not been changed between
           'set_initial_values()' and 'set_final_values()'.  Usually
           called from 'set_final_values()' for options that depend on
           some other command rather than another option of the same
           command.  'src_cmd' is the other command from which option
           values will be taken (a command object will be created for it
           if necessary); the remaining arguments are
           '(src_option,dst_option)' tuples which mean "take the value
           of 'src_option' in the 'src_cmd' command object, and copy it
           to 'dst_option' in the current command object"."""

        # Option_pairs: list of (src_option, dst_option) tuples

        src_cmd_obj = self.distribution.find_command_obj (src_cmd)
        src_cmd_obj.set_final_options ()
        try:
            for (src_option, dst_option) in option_pairs:
                if getattr (self, dst_option) is None:
                    self.set_option (dst_option,
                                     src_cmd_obj.get_option (src_option))
        except AttributeError, name:
            # duh, which command?
            raise DistutilsOptionError, "unknown option %s" % name


    def set_peer_option (self, command, option, value):
        """Attempt to simulate a command-line override of some option
           value in another command.  Creates a command object for
           'command' if necessary, sets 'option' to 'value', and invokes
           'set_final_options()' on that command object.  This will only
           have the desired effect if the command object for 'command'
           has not previously been created.  Generally this is used to
           ensure that the options in 'command' dependent on 'option'
           are computed, hopefully (but not necessarily) deriving from
           'value'.  It might be more accurate to call this method
           'influence_dependent_peer_options()'."""        

        cmd_obj = self.distribution.find_command_obj (command)
        cmd_obj.set_option (option, value)
        cmd_obj.set_final_options ()


    def get_peer_option (self, command, option):
        cmd_obj = self.distribution.find_command_obj (command)
        return cmd_obj.get_option (option)


    def run_peer (self, command):
        """Run some other command: uses the 'run_command()' method of
           Distribution, which creates the command object if necessary
           and then invokes its 'run()' method."""

        self.distribution.run_command (command)


    # -- External world manipulation -----------------------------------

    def warn (self, msg):
        sys.stderr.write ("warning: %s: %s\n" %
                          (self.get_command_name(), msg))


    def execute (self, func, args, msg=None, level=1):
        """Perform some action that affects the outside world (eg.
           by writing to the filesystem).  Such actions are special because
           they should be disabled by the "dry run" flag (carried around by
           the Command's Distribution), and should announce themselves if
           the current verbosity level is high enough.  This method takes
           care of all that bureaucracy for you; all you have to do is
           supply the funtion to call and an argument tuple for it (to
           embody the "external action" being performed), a message to
           print if the verbosity level is high enough, and an optional
           verbosity threshold."""


        # Generate a message if we weren't passed one
        if msg is None:
            msg = "%s %s" % (func.__name__, `args`)
            if msg[-2:] == ',)':        # correct for singleton tuple 
                msg = msg[0:-2] + ')'

        # Print it if verbosity level is high enough
        self.announce (msg, level)

        # And do it, as long as we're not in dry-run mode
        if not self.distribution.dry_run:
            apply (func, args)

    # execute()


    def mkpath (self, name, mode=0777):
        util.mkpath (name, mode,
                     self.distribution.verbose, self.distribution.dry_run)


    def copy_file (self, infile, outfile,
                   preserve_mode=1, preserve_times=1, update=1, level=1):
        """Copy a file respecting verbose and dry-run flags."""

        return util.copy_file (infile, outfile,
                               preserve_mode, preserve_times,
                               update, self.distribution.verbose >= level,
                               self.distribution.dry_run)


    def copy_tree (self, infile, outfile,
                   preserve_mode=1, preserve_times=1, preserve_symlinks=0,
                   update=1, level=1):
        """Copy an entire directory tree respecting verbose and dry-run
           flags."""

        return util.copy_tree (infile, outfile, 
                               preserve_mode,preserve_times,preserve_symlinks,
                               update, self.distribution.verbose >= level,
                               self.distribution.dry_run)


    def move_file (self, src, dst, level=1):
        """Move a file respecting verbose and dry-run flags."""
        return util.move_file (src, dst,
                               self.distribution.verbose >= level,
                               self.distribution.dry_run)


    def make_file (self, infiles, outfile, func, args,
                    exec_msg=None, skip_msg=None, level=1):

        """Special case of 'execute()' for operations that process one or
           more input files and generate one output file.  Works just like
           'execute()', except the operation is skipped and a different
           message printed if 'outfile' already exists and is newer than
           all files listed in 'infiles'."""


        if exec_msg is None:
            exec_msg = "generating %s from %s" % \
                       (outfile, string.join (infiles, ', '))
        if skip_msg is None:
            skip_msg = "skipping %s (inputs unchanged)" % outfile
        

        # Allow 'infiles' to be a single string
        if type (infiles) is StringType:
            infiles = (infiles,)
        elif type (infiles) not in (ListType, TupleType):
            raise TypeError, \
                  "'infiles' must be a string, or a list or tuple of strings"

        # XXX this stuff should probably be moved off to a function
        # in 'distutils.util'
        from stat import *

        if os.path.exists (outfile):
            out_mtime = os.stat (outfile)[ST_MTIME]

            # Loop over all infiles.  If any infile is newer than outfile,
            # then we'll have to regenerate outfile
            for f in infiles:
                in_mtime = os.stat (f)[ST_MTIME]
                if in_mtime > out_mtime:
                    runit = 1
                    break
            else:
                runit = 0

        else:
            runit = 1

        # If we determined that 'outfile' must be regenerated, then
        # perform the action that presumably regenerates it
        if runit:
            self.execute (func, args, exec_msg, level)

        # Otherwise, print the "skip" message
        else:
            self.announce (skip_msg, level)

    # make_file ()


#     def make_files (self, infiles, outfiles, func, args,
#                     exec_msg=None, skip_msg=None, level=1):

#         """Special case of 'execute()' for operations that process one or
#            more input files and generate one or more output files.  Works
#            just like 'execute()', except the operation is skipped and a
#            different message printed if all files listed in 'outfiles'
#            already exist and are newer than all files listed in
#            'infiles'."""

#         pass
    
    

# end class Command
