PyXR

c:\python24\lib \ distutils \ cmd.py



0001 """distutils.cmd
0002 
0003 Provides the Command class, the base class for the command classes
0004 in the distutils.command package.
0005 """
0006 
0007 # This module should be kept compatible with Python 1.5.2.
0008 
0009 __revision__ = "$Id: cmd.py,v 1.38 2004/07/18 06:14:42 tim_one Exp $"
0010 
0011 import sys, os, string, re
0012 from types import *
0013 from distutils.errors import *
0014 from distutils import util, dir_util, file_util, archive_util, dep_util
0015 from distutils import log
0016 
0017 class Command:
0018     """Abstract base class for defining command classes, the "worker bees"
0019     of the Distutils.  A useful analogy for command classes is to think of
0020     them as subroutines with local variables called "options".  The options
0021     are "declared" in 'initialize_options()' and "defined" (given their
0022     final values, aka "finalized") in 'finalize_options()', both of which
0023     must be defined by every command class.  The distinction between the
0024     two is necessary because option values might come from the outside
0025     world (command line, config file, ...), and any options dependent on
0026     other options must be computed *after* these outside influences have
0027     been processed -- hence 'finalize_options()'.  The "body" of the
0028     subroutine, where it does all its work based on the values of its
0029     options, is the 'run()' method, which must also be implemented by every
0030     command class.
0031     """
0032 
0033     # 'sub_commands' formalizes the notion of a "family" of commands,
0034     # eg. "install" as the parent with sub-commands "install_lib",
0035     # "install_headers", etc.  The parent of a family of commands
0036     # defines 'sub_commands' as a class attribute; it's a list of
0037     #    (command_name : string, predicate : unbound_method | string | None)
0038     # tuples, where 'predicate' is a method of the parent command that
0039     # determines whether the corresponding command is applicable in the
0040     # current situation.  (Eg. we "install_headers" is only applicable if
0041     # we have any C header files to install.)  If 'predicate' is None,
0042     # that command is always applicable.
0043     #
0044     # 'sub_commands' is usually defined at the *end* of a class, because
0045     # predicates can be unbound methods, so they must already have been
0046     # defined.  The canonical example is the "install" command.
0047     sub_commands = []
0048 
0049 
0050     # -- Creation/initialization methods -------------------------------
0051 
0052     def __init__ (self, dist):
0053         """Create and initialize a new Command object.  Most importantly,
0054         invokes the 'initialize_options()' method, which is the real
0055         initializer and depends on the actual command being
0056         instantiated.
0057         """
0058         # late import because of mutual dependence between these classes
0059         from distutils.dist import Distribution
0060 
0061         if not isinstance(dist, Distribution):
0062             raise TypeError, "dist must be a Distribution instance"
0063         if self.__class__ is Command:
0064             raise RuntimeError, "Command is an abstract class"
0065 
0066         self.distribution = dist
0067         self.initialize_options()
0068 
0069         # Per-command versions of the global flags, so that the user can
0070         # customize Distutils' behaviour command-by-command and let some
0071         # commands fall back on the Distribution's behaviour.  None means
0072         # "not defined, check self.distribution's copy", while 0 or 1 mean
0073         # false and true (duh).  Note that this means figuring out the real
0074         # value of each flag is a touch complicated -- hence "self._dry_run"
0075         # will be handled by __getattr__, below.
0076         # XXX This needs to be fixed.
0077         self._dry_run = None
0078 
0079         # verbose is largely ignored, but needs to be set for
0080         # backwards compatibility (I think)?
0081         self.verbose = dist.verbose
0082 
0083         # Some commands define a 'self.force' option to ignore file
0084         # timestamps, but methods defined *here* assume that
0085         # 'self.force' exists for all commands.  So define it here
0086         # just to be safe.
0087         self.force = None
0088 
0089         # The 'help' flag is just used for command-line parsing, so
0090         # none of that complicated bureaucracy is needed.
0091         self.help = 0
0092 
0093         # 'finalized' records whether or not 'finalize_options()' has been
0094         # called.  'finalize_options()' itself should not pay attention to
0095         # this flag: it is the business of 'ensure_finalized()', which
0096         # always calls 'finalize_options()', to respect/update it.
0097         self.finalized = 0
0098 
0099     # __init__ ()
0100 
0101 
0102     # XXX A more explicit way to customize dry_run would be better.
0103 
0104     def __getattr__ (self, attr):
0105         if attr == 'dry_run':
0106             myval = getattr(self, "_" + attr)
0107             if myval is None:
0108                 return getattr(self.distribution, attr)
0109             else:
0110                 return myval
0111         else:
0112             raise AttributeError, attr
0113 
0114 
0115     def ensure_finalized (self):
0116         if not self.finalized:
0117             self.finalize_options()
0118         self.finalized = 1
0119 
0120 
0121     # Subclasses must define:
0122     #   initialize_options()
0123     #     provide default values for all options; may be customized by
0124     #     setup script, by options from config file(s), or by command-line
0125     #     options
0126     #   finalize_options()
0127     #     decide on the final values for all options; this is called
0128     #     after all possible intervention from the outside world
0129     #     (command-line, option file, etc.) has been processed
0130     #   run()
0131     #     run the command: do whatever it is we're here to do,
0132     #     controlled by the command's various option values
0133 
0134     def initialize_options (self):
0135         """Set default values for all the options that this command
0136         supports.  Note that these defaults may be overridden by other
0137         commands, by the setup script, by config files, or by the
0138         command-line.  Thus, this is not the place to code dependencies
0139         between options; generally, 'initialize_options()' implementations
0140         are just a bunch of "self.foo = None" assignments.
0141 
0142         This method must be implemented by all command classes.
0143         """
0144         raise RuntimeError, \
0145               "abstract method -- subclass %s must override" % self.__class__
0146 
0147     def finalize_options (self):
0148         """Set final values for all the options that this command supports.
0149         This is always called as late as possible, ie.  after any option
0150         assignments from the command-line or from other commands have been
0151         done.  Thus, this is the place to code option dependencies: if
0152         'foo' depends on 'bar', then it is safe to set 'foo' from 'bar' as
0153         long as 'foo' still has the same value it was assigned in
0154         'initialize_options()'.
0155 
0156         This method must be implemented by all command classes.
0157         """
0158         raise RuntimeError, \
0159               "abstract method -- subclass %s must override" % self.__class__
0160 
0161 
0162     def dump_options (self, header=None, indent=""):
0163         from distutils.fancy_getopt import longopt_xlate
0164         if header is None:
0165             header = "command options for '%s':" % self.get_command_name()
0166         print indent + header
0167         indent = indent + "  "
0168         for (option, _, _) in self.user_options:
0169             option = string.translate(option, longopt_xlate)
0170             if option[-1] == "=":
0171                 option = option[:-1]
0172             value = getattr(self, option)
0173             print indent + "%s = %s" % (option, value)
0174 
0175 
0176     def run (self):
0177         """A command's raison d'etre: carry out the action it exists to
0178         perform, controlled by the options initialized in
0179         'initialize_options()', customized by other commands, the setup
0180         script, the command-line, and config files, and finalized in
0181         'finalize_options()'.  All terminal output and filesystem
0182         interaction should be done by 'run()'.
0183 
0184         This method must be implemented by all command classes.
0185         """
0186 
0187         raise RuntimeError, \
0188               "abstract method -- subclass %s must override" % self.__class__
0189 
0190     def announce (self, msg, level=1):
0191         """If the current verbosity level is of greater than or equal to
0192         'level' print 'msg' to stdout.
0193         """
0194         log.log(level, msg)
0195 
0196     def debug_print (self, msg):
0197         """Print 'msg' to stdout if the global DEBUG (taken from the
0198         DISTUTILS_DEBUG environment variable) flag is true.
0199         """
0200         from distutils.debug import DEBUG
0201         if DEBUG:
0202             print msg
0203             sys.stdout.flush()
0204 
0205 
0206 
0207     # -- Option validation methods -------------------------------------
0208     # (these are very handy in writing the 'finalize_options()' method)
0209     #
0210     # NB. the general philosophy here is to ensure that a particular option
0211     # value meets certain type and value constraints.  If not, we try to
0212     # force it into conformance (eg. if we expect a list but have a string,
0213     # split the string on comma and/or whitespace).  If we can't force the
0214     # option into conformance, raise DistutilsOptionError.  Thus, command
0215     # classes need do nothing more than (eg.)
0216     #   self.ensure_string_list('foo')
0217     # and they can be guaranteed that thereafter, self.foo will be
0218     # a list of strings.
0219 
0220     def _ensure_stringlike (self, option, what, default=None):
0221         val = getattr(self, option)
0222         if val is None:
0223             setattr(self, option, default)
0224             return default
0225         elif type(val) is not StringType:
0226             raise DistutilsOptionError, \
0227                   "'%s' must be a %s (got `%s`)" % (option, what, val)
0228         return val
0229 
0230     def ensure_string (self, option, default=None):
0231         """Ensure that 'option' is a string; if not defined, set it to
0232         'default'.
0233         """
0234         self._ensure_stringlike(option, "string", default)
0235 
0236     def ensure_string_list (self, option):
0237         """Ensure that 'option' is a list of strings.  If 'option' is
0238         currently a string, we split it either on /,\s*/ or /\s+/, so
0239         "foo bar baz", "foo,bar,baz", and "foo,   bar baz" all become
0240         ["foo", "bar", "baz"].
0241         """
0242         val = getattr(self, option)
0243         if val is None:
0244             return
0245         elif type(val) is StringType:
0246             setattr(self, option, re.split(r',\s*|\s+', val))
0247         else:
0248             if type(val) is ListType:
0249                 types = map(type, val)
0250                 ok = (types == [StringType] * len(val))
0251             else:
0252                 ok = 0
0253 
0254             if not ok:
0255                 raise DistutilsOptionError, \
0256                       "'%s' must be a list of strings (got %r)" % \
0257                       (option, val)
0258 
0259     def _ensure_tested_string (self, option, tester,
0260                                what, error_fmt, default=None):
0261         val = self._ensure_stringlike(option, what, default)
0262         if val is not None and not tester(val):
0263             raise DistutilsOptionError, \
0264                   ("error in '%s' option: " + error_fmt) % (option, val)
0265 
0266     def ensure_filename (self, option):
0267         """Ensure that 'option' is the name of an existing file."""
0268         self._ensure_tested_string(option, os.path.isfile,
0269                                    "filename",
0270                                    "'%s' does not exist or is not a file")
0271 
0272     def ensure_dirname (self, option):
0273         self._ensure_tested_string(option, os.path.isdir,
0274                                    "directory name",
0275                                    "'%s' does not exist or is not a directory")
0276 
0277 
0278     # -- Convenience methods for commands ------------------------------
0279 
0280     def get_command_name (self):
0281         if hasattr(self, 'command_name'):
0282             return self.command_name
0283         else:
0284             return self.__class__.__name__
0285 
0286 
0287     def set_undefined_options (self, src_cmd, *option_pairs):
0288         """Set the values of any "undefined" options from corresponding
0289         option values in some other command object.  "Undefined" here means
0290         "is None", which is the convention used to indicate that an option
0291         has not been changed between 'initialize_options()' and
0292         'finalize_options()'.  Usually called from 'finalize_options()' for
0293         options that depend on some other command rather than another
0294         option of the same command.  'src_cmd' is the other command from
0295         which option values will be taken (a command object will be created
0296         for it if necessary); the remaining arguments are
0297         '(src_option,dst_option)' tuples which mean "take the value of
0298         'src_option' in the 'src_cmd' command object, and copy it to
0299         'dst_option' in the current command object".
0300         """
0301 
0302         # Option_pairs: list of (src_option, dst_option) tuples
0303 
0304         src_cmd_obj = self.distribution.get_command_obj(src_cmd)
0305         src_cmd_obj.ensure_finalized()
0306         for (src_option, dst_option) in option_pairs:
0307             if getattr(self, dst_option) is None:
0308                 setattr(self, dst_option,
0309                         getattr(src_cmd_obj, src_option))
0310 
0311 
0312     def get_finalized_command (self, command, create=1):
0313         """Wrapper around Distribution's 'get_command_obj()' method: find
0314         (create if necessary and 'create' is true) the command object for
0315         'command', call its 'ensure_finalized()' method, and return the
0316         finalized command object.
0317         """
0318         cmd_obj = self.distribution.get_command_obj(command, create)
0319         cmd_obj.ensure_finalized()
0320         return cmd_obj
0321 
0322     # XXX rename to 'get_reinitialized_command()'? (should do the
0323     # same in dist.py, if so)
0324     def reinitialize_command (self, command, reinit_subcommands=0):
0325         return self.distribution.reinitialize_command(
0326             command, reinit_subcommands)
0327 
0328     def run_command (self, command):
0329         """Run some other command: uses the 'run_command()' method of
0330         Distribution, which creates and finalizes the command object if
0331         necessary and then invokes its 'run()' method.
0332         """
0333         self.distribution.run_command(command)
0334 
0335 
0336     def get_sub_commands (self):
0337         """Determine the sub-commands that are relevant in the current
0338         distribution (ie., that need to be run).  This is based on the
0339         'sub_commands' class attribute: each tuple in that list may include
0340         a method that we call to determine if the subcommand needs to be
0341         run for the current distribution.  Return a list of command names.
0342         """
0343         commands = []
0344         for (cmd_name, method) in self.sub_commands:
0345             if method is None or method(self):
0346                 commands.append(cmd_name)
0347         return commands
0348 
0349 
0350     # -- External world manipulation -----------------------------------
0351 
0352     def warn (self, msg):
0353         sys.stderr.write("warning: %s: %s\n" %
0354                          (self.get_command_name(), msg))
0355 
0356 
0357     def execute (self, func, args, msg=None, level=1):
0358         util.execute(func, args, msg, dry_run=self.dry_run)
0359 
0360 
0361     def mkpath (self, name, mode=0777):
0362         dir_util.mkpath(name, mode, dry_run=self.dry_run)
0363 
0364 
0365     def copy_file (self, infile, outfile,
0366                    preserve_mode=1, preserve_times=1, link=None, level=1):
0367         """Copy a file respecting verbose, dry-run and force flags.  (The
0368         former two default to whatever is in the Distribution object, and
0369         the latter defaults to false for commands that don't define it.)"""
0370 
0371         return file_util.copy_file(
0372             infile, outfile,
0373             preserve_mode, preserve_times,
0374             not self.force,
0375             link,
0376             dry_run=self.dry_run)
0377 
0378 
0379     def copy_tree (self, infile, outfile,
0380                    preserve_mode=1, preserve_times=1, preserve_symlinks=0,
0381                    level=1):
0382         """Copy an entire directory tree respecting verbose, dry-run,
0383         and force flags.
0384         """
0385         return dir_util.copy_tree(
0386             infile, outfile,
0387             preserve_mode,preserve_times,preserve_symlinks,
0388             not self.force,
0389             dry_run=self.dry_run)
0390 
0391     def move_file (self, src, dst, level=1):
0392         """Move a file respectin dry-run flag."""
0393         return file_util.move_file(src, dst, dry_run = self.dry_run)
0394 
0395     def spawn (self, cmd, search_path=1, level=1):
0396         """Spawn an external command respecting dry-run flag."""
0397         from distutils.spawn import spawn
0398         spawn(cmd, search_path, dry_run= self.dry_run)
0399 
0400     def make_archive (self, base_name, format,
0401                       root_dir=None, base_dir=None):
0402         return archive_util.make_archive(
0403             base_name, format, root_dir, base_dir, dry_run=self.dry_run)
0404 
0405 
0406     def make_file (self, infiles, outfile, func, args,
0407                    exec_msg=None, skip_msg=None, level=1):
0408         """Special case of 'execute()' for operations that process one or
0409         more input files and generate one output file.  Works just like
0410         'execute()', except the operation is skipped and a different
0411         message printed if 'outfile' already exists and is newer than all
0412         files listed in 'infiles'.  If the command defined 'self.force',
0413         and it is true, then the command is unconditionally run -- does no
0414         timestamp checks.
0415         """
0416         if exec_msg is None:
0417             exec_msg = "generating %s from %s" % \
0418                        (outfile, string.join(infiles, ', '))
0419         if skip_msg is None:
0420             skip_msg = "skipping %s (inputs unchanged)" % outfile
0421 
0422 
0423         # Allow 'infiles' to be a single string
0424         if type(infiles) is StringType:
0425             infiles = (infiles,)
0426         elif type(infiles) not in (ListType, TupleType):
0427             raise TypeError, \
0428                   "'infiles' must be a string, or a list or tuple of strings"
0429 
0430         # If 'outfile' must be regenerated (either because it doesn't
0431         # exist, is out-of-date, or the 'force' flag is true) then
0432         # perform the action that presumably regenerates it
0433         if self.force or dep_util.newer_group (infiles, outfile):
0434             self.execute(func, args, exec_msg, level)
0435 
0436         # Otherwise, print the "skip" message
0437         else:
0438             log.debug(skip_msg)
0439 
0440     # make_file ()
0441 
0442 # class Command
0443 
0444 
0445 # XXX 'install_misc' class not currently used -- it was the base class for
0446 # both 'install_scripts' and 'install_data', but they outgrew it.  It might
0447 # still be useful for 'install_headers', though, so I'm keeping it around
0448 # for the time being.
0449 
0450 class install_misc (Command):
0451     """Common base class for installing some files in a subdirectory.
0452     Currently used by install_data and install_scripts.
0453     """
0454 
0455     user_options = [('install-dir=', 'd', "directory to install the files to")]
0456 
0457     def initialize_options (self):
0458         self.install_dir = None
0459         self.outfiles = []
0460 
0461     def _install_dir_from (self, dirname):
0462         self.set_undefined_options('install', (dirname, 'install_dir'))
0463 
0464     def _copy_files (self, filelist):
0465         self.outfiles = []
0466         if not filelist:
0467             return
0468         self.mkpath(self.install_dir)
0469         for f in filelist:
0470             self.copy_file(f, self.install_dir)
0471             self.outfiles.append(os.path.join(self.install_dir, f))
0472 
0473     def get_outputs (self):
0474         return self.outfiles
0475 
0476 
0477 if __name__ == "__main__":
0478     print "ok"
0479 

Generated by PyXR 0.9.4
SourceForge.net Logo