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