The 0.5 release happened on 2/15, not on 2/14. :-)
[python/dscho.git] / Lib / distutils / core.py
blob88e889b22fe43efd0930e978f3ba66c348daf308
1 """distutils.core
3 The only module that needs to be imported to use the Distutils; provides
4 the 'setup' function (which must be called); the 'Distribution' class
5 (which may be subclassed if additional functionality is desired), and
6 the 'Command' class (which is used both internally by Distutils, and
7 may be subclassed by clients for still more flexibility)."""
9 # created 1999/03/01, Greg Ward
11 __rcsid__ = "$Id$"
13 import sys, os
14 import string, re
15 from types import *
16 from copy import copy
17 from distutils.errors import *
18 from distutils.fancy_getopt import fancy_getopt, print_help
19 from distutils import util
21 # Regex to define acceptable Distutils command names. This is not *quite*
22 # the same as a Python NAME -- I don't allow leading underscores. The fact
23 # that they're very similar is no coincidence; the default naming scheme is
24 # to look for a Python module named after the command.
25 command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
27 # Defining this as a global is probably inadequate -- what about
28 # listing the available options (or even commands, which can vary
29 # quite late as well)
30 usage = """\
31 usage: %s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
32 or: %s --help
33 or: %s --help-commands
34 or: %s cmd --help
35 """ % ((sys.argv[0],) * 4)
38 def setup (**attrs):
39 """The gateway to the Distutils: do everything your setup script
40 needs to do, in a highly flexible and user-driven way. Briefly:
41 create a Distribution instance; parse the command-line, creating
42 and customizing instances of the command class for each command
43 found on the command-line; run each of those commands.
45 The Distribution instance might be an instance of a class
46 supplied via the 'distclass' keyword argument to 'setup'; if no
47 such class is supplied, then the 'Distribution' class (also in
48 this module) is instantiated. All other arguments to 'setup'
49 (except for 'cmdclass') are used to set attributes of the
50 Distribution instance.
52 The 'cmdclass' argument, if supplied, is a dictionary mapping
53 command names to command classes. Each command encountered on the
54 command line will be turned into a command class, which is in turn
55 instantiated; any class found in 'cmdclass' is used in place of the
56 default, which is (for command 'foo_bar') class 'FooBar' in module
57 'distutils.command.foo_bar'. The command object must provide an
58 'options' attribute which is a list of option specifiers for
59 'distutils.fancy_getopt'. Any command-line options between the
60 current and the next command are used to set attributes in the
61 current command object.
63 When the entire command-line has been successfully parsed, calls the
64 'run' method on each command object in turn. This method will be
65 driven entirely by the Distribution object (which each command
66 object has a reference to, thanks to its constructor), and the
67 command-specific options that became attributes of each command
68 object."""
70 # Determine the distribution class -- either caller-supplied or
71 # our Distribution (see below).
72 klass = attrs.get ('distclass')
73 if klass:
74 del attrs['distclass']
75 else:
76 klass = Distribution
78 # Create the Distribution instance, using the remaining arguments
79 # (ie. everything except distclass) to initialize it
80 dist = klass (attrs)
82 # If we had a config file, this is where we would parse it: override
83 # the client-supplied command options, but be overridden by the
84 # command line.
86 # Parse the command line; any command-line errors are the end-users
87 # fault, so turn them into SystemExit to suppress tracebacks.
88 try:
89 ok = dist.parse_command_line (sys.argv[1:])
90 except DistutilsArgError, msg:
91 sys.stderr.write (usage + "\n")
92 raise SystemExit, "error: %s" % msg
94 # And finally, run all the commands found on the command line.
95 if ok:
96 try:
97 dist.run_commands ()
98 except KeyboardInterrupt:
99 raise SystemExit, "interrupted"
100 except IOError, exc:
101 # is this 1.5.2-specific? 1.5-specific?
102 raise SystemExit, "error: %s: %s" % (exc.filename, exc.strerror)
104 # setup ()
107 class Distribution:
108 """The core of the Distutils. Most of the work hiding behind
109 'setup' is really done within a Distribution instance, which
110 farms the work out to the Distutils commands specified on the
111 command line.
113 Clients will almost never instantiate Distribution directly,
114 unless the 'setup' function is totally inadequate to their needs.
115 However, it is conceivable that a client might wish to subclass
116 Distribution for some specialized purpose, and then pass the
117 subclass to 'setup' as the 'distclass' keyword argument. If so,
118 it is necessary to respect the expectations that 'setup' has of
119 Distribution: it must have a constructor and methods
120 'parse_command_line()' and 'run_commands()' with signatures like
121 those described below."""
124 # 'global_options' describes the command-line options that may be
125 # supplied to the client (setup.py) prior to any actual commands.
126 # Eg. "./setup.py -nv" or "./setup.py --verbose" both take advantage of
127 # these global options. This list should be kept to a bare minimum,
128 # since every global option is also valid as a command option -- and we
129 # don't want to pollute the commands with too many options that they
130 # have minimal control over.
131 global_options = [('verbose', 'v',
132 "run verbosely (default)"),
133 ('quiet', 'q',
134 "run quietly (turns verbosity off)"),
135 ('dry-run', 'n',
136 "don't actually do anything"),
137 ('force', 'f',
138 "skip dependency checking between files"),
139 ('help', 'h',
140 "show this help message"),
142 negative_opt = {'quiet': 'verbose'}
145 # -- Creation/initialization methods -------------------------------
147 def __init__ (self, attrs=None):
148 """Construct a new Distribution instance: initialize all the
149 attributes of a Distribution, and then uses 'attrs' (a
150 dictionary mapping attribute names to values) to assign
151 some of those attributes their "real" values. (Any attributes
152 not mentioned in 'attrs' will be assigned to some null
153 value: 0, None, an empty list or dictionary, etc.) Most
154 importantly, initialize the 'command_obj' attribute
155 to the empty dictionary; this will be filled in with real
156 command objects by 'parse_command_line()'."""
158 # Default values for our command-line options
159 self.verbose = 1
160 self.dry_run = 0
161 self.force = 0
162 self.help = 0
163 self.help_commands = 0
165 # And the "distribution meta-data" options -- these can only
166 # come from setup.py (the caller), not the command line
167 # (or a hypothetical config file).
168 self.name = None
169 self.version = None
170 self.author = None
171 self.author_email = None
172 self.maintainer = None
173 self.maintainer_email = None
174 self.url = None
175 self.licence = None
176 self.description = None
178 # 'cmdclass' maps command names to class objects, so we
179 # can 1) quickly figure out which class to instantiate when
180 # we need to create a new command object, and 2) have a way
181 # for the client to override command classes
182 self.cmdclass = {}
184 # These options are really the business of various commands, rather
185 # than of the Distribution itself. We provide aliases for them in
186 # Distribution as a convenience to the developer.
187 # dictionary.
188 self.packages = None
189 self.package_dir = None
190 self.py_modules = None
191 self.libraries = None
192 self.ext_modules = None
193 self.ext_package = None
194 self.include_dirs = None
195 self.install_path = None
197 # And now initialize bookkeeping stuff that can't be supplied by
198 # the caller at all. 'command_obj' maps command names to
199 # Command instances -- that's how we enforce that every command
200 # class is a singleton.
201 self.command_obj = {}
203 # 'have_run' maps command names to boolean values; it keeps track
204 # of whether we have actually run a particular command, to make it
205 # cheap to "run" a command whenever we think we might need to -- if
206 # it's already been done, no need for expensive filesystem
207 # operations, we just check the 'have_run' dictionary and carry on.
208 # It's only safe to query 'have_run' for a command class that has
209 # been instantiated -- a false value will be inserted when the
210 # command object is created, and replaced with a true value when
211 # the command is succesfully run. Thus it's probably best to use
212 # '.get()' rather than a straight lookup.
213 self.have_run = {}
215 # Now we'll use the attrs dictionary (ultimately, keyword args from
216 # the client) to possibly override any or all of these distribution
217 # options.
218 if attrs:
220 # Pull out the set of command options and work on them
221 # specifically. Note that this order guarantees that aliased
222 # command options will override any supplied redundantly
223 # through the general options dictionary.
224 options = attrs.get ('options')
225 if options:
226 del attrs['options']
227 for (command, cmd_options) in options.items():
228 cmd_obj = self.find_command_obj (command)
229 for (key, val) in cmd_options.items():
230 cmd_obj.set_option (key, val)
231 # loop over commands
232 # if any command options
234 # Now work on the rest of the attributes. Any attribute that's
235 # not already defined is invalid!
236 for (key,val) in attrs.items():
237 if hasattr (self, key):
238 setattr (self, key, val)
239 else:
240 raise DistutilsOptionError, \
241 "invalid distribution option '%s'" % key
243 # __init__ ()
246 def parse_command_line (self, args):
247 """Parse the setup script's command line: set any Distribution
248 attributes tied to command-line options, create all command
249 objects, and set their options from the command-line. 'args'
250 must be a list of command-line arguments, most likely
251 'sys.argv[1:]' (see the 'setup()' function). This list is first
252 processed for "global options" -- options that set attributes of
253 the Distribution instance. Then, it is alternately scanned for
254 Distutils command and options for that command. Each new
255 command terminates the options for the previous command. The
256 allowed options for a command are determined by the 'options'
257 attribute of the command object -- thus, we instantiate (and
258 cache) every command object here, in order to access its
259 'options' attribute. Any error in that 'options' attribute
260 raises DistutilsGetoptError; any error on the command-line
261 raises DistutilsArgError. If no Distutils commands were found
262 on the command line, raises DistutilsArgError. Return true if
263 command-line successfully parsed and we should carry on with
264 executing commands; false if no errors but we shouldn't execute
265 commands (currently, this only happens if user asks for
266 help)."""
268 # We have to parse the command line a bit at a time -- global
269 # options, then the first command, then its options, and so on --
270 # because each command will be handled by a different class, and
271 # the options that are valid for a particular class aren't
272 # known until we instantiate the command class, which doesn't
273 # happen until we know what the command is.
275 self.commands = []
276 options = self.global_options + \
277 [('help-commands', None,
278 "list all available commands")]
279 args = fancy_getopt (options, self.negative_opt,
280 self, sys.argv[1:])
282 # User just wants a list of commands -- we'll print it out and stop
283 # processing now (ie. if they ran "setup --help-commands foo bar",
284 # we ignore "foo bar").
285 if self.help_commands:
286 self.print_commands ()
287 print
288 print usage
289 return
291 while args:
292 # Pull the current command from the head of the command line
293 command = args[0]
294 if not command_re.match (command):
295 raise SystemExit, "invalid command name '%s'" % command
296 self.commands.append (command)
298 # Make sure we have a command object to put the options into
299 # (this either pulls it out of a cache of command objects,
300 # or finds and instantiates the command class).
301 try:
302 cmd_obj = self.find_command_obj (command)
303 except DistutilsModuleError, msg:
304 raise DistutilsArgError, msg
306 # Require that the command class be derived from Command --
307 # that way, we can be sure that we at least have the 'run'
308 # and 'get_option' methods.
309 if not isinstance (cmd_obj, Command):
310 raise DistutilsClassError, \
311 "command class %s must subclass Command" % \
312 cmd_obj.__class__
314 # Also make sure that the command object provides a list of its
315 # known options
316 if not (hasattr (cmd_obj, 'options') and
317 type (cmd_obj.options) is ListType):
318 raise DistutilsClassError, \
319 ("command class %s must provide an 'options' attribute "+
320 "(a list of tuples)") % \
321 cmd_obj.__class__
323 # Poof! like magic, all commands support the global
324 # options too, just by adding in 'global_options'.
325 negative_opt = self.negative_opt
326 if hasattr (cmd_obj, 'negative_opt'):
327 negative_opt = copy (negative_opt)
328 negative_opt.update (cmd_obj.negative_opt)
330 options = self.global_options + cmd_obj.options
331 args = fancy_getopt (options, negative_opt,
332 cmd_obj, args[1:])
333 if cmd_obj.help:
334 print_help (self.global_options,
335 header="Global options:")
336 print
337 print_help (cmd_obj.options,
338 header="Options for '%s' command:" % command)
339 print
340 print usage
341 return
343 self.command_obj[command] = cmd_obj
344 self.have_run[command] = 0
346 # while args
348 # If the user wants help -- ie. they gave the "--help" option --
349 # give it to 'em. We do this *after* processing the commands in
350 # case they want help on any particular command, eg.
351 # "setup.py --help foo". (This isn't the documented way to
352 # get help on a command, but I support it because that's how
353 # CVS does it -- might as well be consistent.)
354 if self.help:
355 print_help (self.global_options, header="Global options:")
356 print
358 for command in self.commands:
359 klass = self.find_command_class (command)
360 print_help (klass.options,
361 header="Options for '%s' command:" % command)
362 print
364 print usage
365 return
367 # Oops, no commands found -- an end-user error
368 if not self.commands:
369 raise DistutilsArgError, "no commands supplied"
371 # All is well: return true
372 return 1
374 # parse_command_line()
377 def print_command_list (self, commands, header, max_length):
378 """Print a subset of the list of all commands -- used by
379 'print_commands()'."""
381 print header + ":"
383 for cmd in commands:
384 klass = self.cmdclass.get (cmd)
385 if not klass:
386 klass = self.find_command_class (cmd)
387 try:
388 description = klass.description
389 except AttributeError:
390 description = "(no description available)"
392 print " %-*s %s" % (max_length, cmd, description)
394 # print_command_list ()
397 def print_commands (self):
398 """Print out a help message listing all available commands with
399 a description of each. The list is divided into "standard
400 commands" (listed in distutils.command.__all__) and "extra
401 commands" (mentioned in self.cmdclass, but not a standard
402 command). The descriptions come from the command class
403 attribute 'description'."""
405 import distutils.command
406 std_commands = distutils.command.__all__
407 is_std = {}
408 for cmd in std_commands:
409 is_std[cmd] = 1
411 extra_commands = []
412 for cmd in self.cmdclass.keys():
413 if not is_std.get(cmd):
414 extra_commands.append (cmd)
416 max_length = 0
417 for cmd in (std_commands + extra_commands):
418 if len (cmd) > max_length:
419 max_length = len (cmd)
421 self.print_command_list (std_commands,
422 "Standard commands",
423 max_length)
424 if extra_commands:
425 print
426 self.print_command_list (extra_commands,
427 "Extra commands",
428 max_length)
430 # print_commands ()
434 # -- Command class/object methods ----------------------------------
436 # This is a method just so it can be overridden if desired; it doesn't
437 # actually use or change any attributes of the Distribution instance.
438 def find_command_class (self, command):
439 """Given a command, derives the names of the module and class
440 expected to implement the command: eg. 'foo_bar' becomes
441 'distutils.command.foo_bar' (the module) and 'FooBar' (the
442 class within that module). Loads the module, extracts the
443 class from it, and returns the class object.
445 Raises DistutilsModuleError with a semi-user-targeted error
446 message if the expected module could not be loaded, or the
447 expected class was not found in it."""
449 module_name = 'distutils.command.' + command
450 klass_name = string.join \
451 (map (string.capitalize, string.split (command, '_')), '')
453 try:
454 __import__ (module_name)
455 module = sys.modules[module_name]
456 except ImportError:
457 raise DistutilsModuleError, \
458 "invalid command '%s' (no module named '%s')" % \
459 (command, module_name)
461 try:
462 klass = vars(module)[klass_name]
463 except KeyError:
464 raise DistutilsModuleError, \
465 "invalid command '%s' (no class '%s' in module '%s')" \
466 % (command, klass_name, module_name)
468 return klass
470 # find_command_class ()
473 def create_command_obj (self, command):
474 """Figure out the class that should implement a command,
475 instantiate it, cache and return the new "command object".
476 The "command class" is determined either by looking it up in
477 the 'cmdclass' attribute (this is the mechanism whereby
478 clients may override default Distutils commands or add their
479 own), or by calling the 'find_command_class()' method (if the
480 command name is not in 'cmdclass'."""
482 # Determine the command class -- either it's in the command_class
483 # dictionary, or we have to divine the module and class name
484 klass = self.cmdclass.get(command)
485 if not klass:
486 klass = self.find_command_class (command)
487 self.cmdclass[command] = klass
489 # Found the class OK -- instantiate it
490 cmd_obj = klass (self)
491 return cmd_obj
494 def find_command_obj (self, command, create=1):
495 """Look up and return a command object in the cache maintained by
496 'create_command_obj()'. If none found, the action taken
497 depends on 'create': if true (the default), create a new
498 command object by calling 'create_command_obj()' and return
499 it; otherwise, return None. If 'command' is an invalid
500 command name, then DistutilsModuleError will be raised."""
502 cmd_obj = self.command_obj.get (command)
503 if not cmd_obj and create:
504 cmd_obj = self.create_command_obj (command)
505 self.command_obj[command] = cmd_obj
507 return cmd_obj
510 # -- Methods that operate on the Distribution ----------------------
512 def announce (self, msg, level=1):
513 """Print 'msg' if 'level' is greater than or equal to the verbosity
514 level recorded in the 'verbose' attribute (which, currently,
515 can be only 0 or 1)."""
517 if self.verbose >= level:
518 print msg
521 def run_commands (self):
522 """Run each command that was seen on the client command line.
523 Uses the list of commands found and cache of command objects
524 created by 'create_command_obj()'."""
526 for cmd in self.commands:
527 self.run_command (cmd)
530 def get_option (self, option):
531 """Return the value of a distribution option. Raise
532 DistutilsOptionError if 'option' is not known."""
534 try:
535 return getattr (self, opt)
536 except AttributeError:
537 raise DistutilsOptionError, \
538 "unknown distribution option %s" % option
541 def get_options (self, *options):
542 """Return (as a tuple) the values of several distribution
543 options. Raise DistutilsOptionError if any element of
544 'options' is not known."""
546 values = []
547 try:
548 for opt in options:
549 values.append (getattr (self, opt))
550 except AttributeError, name:
551 raise DistutilsOptionError, \
552 "unknown distribution option %s" % name
554 return tuple (values)
557 # -- Methods that operate on its Commands --------------------------
559 def run_command (self, command):
561 """Do whatever it takes to run a command (including nothing at all,
562 if the command has already been run). Specifically: if we have
563 already created and run the command named by 'command', return
564 silently without doing anything. If the command named by
565 'command' doesn't even have a command object yet, create one.
566 Then invoke 'run()' on that command object (or an existing
567 one)."""
569 # Already been here, done that? then return silently.
570 if self.have_run.get (command):
571 return
573 self.announce ("running " + command)
574 cmd_obj = self.find_command_obj (command)
575 cmd_obj.ensure_ready ()
576 cmd_obj.run ()
577 self.have_run[command] = 1
580 def get_command_option (self, command, option):
581 """Create a command object for 'command' if necessary, ensure that
582 its option values are all set to their final values, and return
583 the value of its 'option' option. Raise DistutilsOptionError if
584 'option' is not known for that 'command'."""
586 cmd_obj = self.find_command_obj (command)
587 cmd_obj.ensure_ready ()
588 return cmd_obj.get_option (option)
589 try:
590 return getattr (cmd_obj, option)
591 except AttributeError:
592 raise DistutilsOptionError, \
593 "command %s: no such option %s" % (command, option)
596 def get_command_options (self, command, *options):
597 """Create a command object for 'command' if necessary, ensure that
598 its option values are all set to their final values, and return
599 a tuple containing the values of all the options listed in
600 'options' for that command. Raise DistutilsOptionError if any
601 invalid option is supplied in 'options'."""
603 cmd_obj = self.find_command_obj (command)
604 cmd_obj.ensure_ready ()
605 values = []
606 try:
607 for opt in options:
608 values.append (getattr (cmd_obj, option))
609 except AttributeError, name:
610 raise DistutilsOptionError, \
611 "command %s: no such option %s" % (command, name)
613 return tuple (values)
615 # end class Distribution
618 class Command:
619 """Abstract base class for defining command classes, the "worker bees"
620 of the Distutils. A useful analogy for command classes is to
621 think of them as subroutines with local variables called
622 "options". The options are "declared" in 'set_default_options()'
623 and "initialized" (given their real values) in
624 'set_final_options()', both of which must be defined by every
625 command class. The distinction between the two is necessary
626 because option values might come from the outside world (command
627 line, option file, ...), and any options dependent on other
628 options must be computed *after* these outside influences have
629 been processed -- hence 'set_final_options()'. The "body" of the
630 subroutine, where it does all its work based on the values of its
631 options, is the 'run()' method, which must also be implemented by
632 every command class."""
634 # -- Creation/initialization methods -------------------------------
636 def __init__ (self, dist):
637 """Create and initialize a new Command object. Most importantly,
638 invokes the 'set_default_options()' method, which is the
639 real initializer and depends on the actual command being
640 instantiated."""
642 if not isinstance (dist, Distribution):
643 raise TypeError, "dist must be a Distribution instance"
644 if self.__class__ is Command:
645 raise RuntimeError, "Command is an abstract class"
647 self.distribution = dist
648 self.set_default_options ()
650 # Per-command versions of the global flags, so that the user can
651 # customize Distutils' behaviour command-by-command and let some
652 # commands fallback on the Distribution's behaviour. None means
653 # "not defined, check self.distribution's copy", while 0 or 1 mean
654 # false and true (duh). Note that this means figuring out the real
655 # value of each flag is a touch complicatd -- hence "self.verbose"
656 # (etc.) will be handled by __getattr__, below.
657 self._verbose = None
658 self._dry_run = None
659 self._force = None
661 # The 'help' flag is just used for command-line parsing, so
662 # none of that complicated bureaucracy is needed.
663 self.help = 0
665 # 'ready' records whether or not 'set_final_options()' has been
666 # called. 'set_final_options()' itself should not pay attention to
667 # this flag: it is the business of 'ensure_ready()', which always
668 # calls 'set_final_options()', to respect/update it.
669 self.ready = 0
671 # end __init__ ()
674 def __getattr__ (self, attr):
675 if attr in ('verbose', 'dry_run', 'force'):
676 myval = getattr (self, "_" + attr)
677 if myval is None:
678 return getattr (self.distribution, attr)
679 else:
680 return myval
681 else:
682 raise AttributeError, attr
685 def ensure_ready (self):
686 if not self.ready:
687 self.set_final_options ()
688 self.ready = 1
691 # Subclasses must define:
692 # set_default_options()
693 # provide default values for all options; may be overridden
694 # by Distutils client, by command-line options, or by options
695 # from option file
696 # set_final_options()
697 # decide on the final values for all options; this is called
698 # after all possible intervention from the outside world
699 # (command-line, option file, etc.) has been processed
700 # run()
701 # run the command: do whatever it is we're here to do,
702 # controlled by the command's various option values
704 def set_default_options (self):
705 """Set default values for all the options that this command
706 supports. Note that these defaults may be overridden
707 by the command-line supplied by the user; thus, this is
708 not the place to code dependencies between options; generally,
709 'set_default_options()' implementations are just a bunch
710 of "self.foo = None" assignments.
712 This method must be implemented by all command classes."""
714 raise RuntimeError, \
715 "abstract method -- subclass %s must override" % self.__class__
717 def set_final_options (self):
718 """Set final values for all the options that this command
719 supports. This is always called as late as possible, ie.
720 after any option assignments from the command-line or from
721 other commands have been done. Thus, this is the place to to
722 code option dependencies: if 'foo' depends on 'bar', then it
723 is safe to set 'foo' from 'bar' as long as 'foo' still has
724 the same value it was assigned in 'set_default_options()'.
726 This method must be implemented by all command classes."""
728 raise RuntimeError, \
729 "abstract method -- subclass %s must override" % self.__class__
731 def run (self):
732 """A command's raison d'etre: carry out the action it exists
733 to perform, controlled by the options initialized in
734 'set_initial_options()', customized by the user and other
735 commands, and finalized in 'set_final_options()'. All
736 terminal output and filesystem interaction should be done by
737 'run()'.
739 This method must be implemented by all command classes."""
741 raise RuntimeError, \
742 "abstract method -- subclass %s must override" % self.__class__
744 def announce (self, msg, level=1):
745 """If the Distribution instance to which this command belongs
746 has a verbosity level of greater than or equal to 'level'
747 print 'msg' to stdout."""
749 if self.verbose >= level:
750 print msg
753 # -- Option query/set methods --------------------------------------
755 def get_option (self, option):
756 """Return the value of a single option for this command. Raise
757 DistutilsOptionError if 'option' is not known."""
758 try:
759 return getattr (self, option)
760 except AttributeError:
761 raise DistutilsOptionError, \
762 "command %s: no such option %s" % \
763 (self.get_command_name(), option)
766 def get_options (self, *options):
767 """Return (as a tuple) the values of several options for this
768 command. Raise DistutilsOptionError if any of the options in
769 'options' are not known."""
771 values = []
772 try:
773 for opt in options:
774 values.append (getattr (self, opt))
775 except AttributeError, name:
776 raise DistutilsOptionError, \
777 "command %s: no such option %s" % \
778 (self.get_command_name(), name)
780 return tuple (values)
783 def set_option (self, option, value):
784 """Set the value of a single option for this command. Raise
785 DistutilsOptionError if 'option' is not known."""
787 if not hasattr (self, option):
788 raise DistutilsOptionError, \
789 "command '%s': no such option '%s'" % \
790 (self.get_command_name(), option)
791 if value is not None:
792 setattr (self, option, value)
794 def set_options (self, **optval):
795 """Set the values of several options for this command. Raise
796 DistutilsOptionError if any of the options specified as
797 keyword arguments are not known."""
799 for k in optval.keys():
800 if optval[k] is not None:
801 self.set_option (k, optval[k])
804 # -- Convenience methods for commands ------------------------------
806 def get_command_name (self):
807 if hasattr (self, 'command_name'):
808 return self.command_name
809 else:
810 class_name = self.__class__.__name__
812 # The re.split here returs empty strings delimited by the
813 # words we're actually interested in -- e.g. "FooBarBaz"
814 # splits to ['', 'Foo', '', 'Bar', '', 'Baz', '']. Hence
815 # the 'filter' to strip out the empties.
816 words = filter (None, re.split (r'([A-Z][a-z]+)', class_name))
817 self.command_name = string.join (map (string.lower, words), "_")
818 return self.command_name
821 def set_undefined_options (self, src_cmd, *option_pairs):
822 """Set the values of any "undefined" options from corresponding
823 option values in some other command object. "Undefined" here
824 means "is None", which is the convention used to indicate
825 that an option has not been changed between
826 'set_initial_values()' and 'set_final_values()'. Usually
827 called from 'set_final_values()' for options that depend on
828 some other command rather than another option of the same
829 command. 'src_cmd' is the other command from which option
830 values will be taken (a command object will be created for it
831 if necessary); the remaining arguments are
832 '(src_option,dst_option)' tuples which mean "take the value
833 of 'src_option' in the 'src_cmd' command object, and copy it
834 to 'dst_option' in the current command object"."""
836 # Option_pairs: list of (src_option, dst_option) tuples
838 src_cmd_obj = self.distribution.find_command_obj (src_cmd)
839 src_cmd_obj.set_final_options ()
840 try:
841 for (src_option, dst_option) in option_pairs:
842 if getattr (self, dst_option) is None:
843 self.set_option (dst_option,
844 src_cmd_obj.get_option (src_option))
845 except AttributeError, name:
846 # duh, which command?
847 raise DistutilsOptionError, "unknown option %s" % name
850 def set_peer_option (self, command, option, value):
851 """Attempt to simulate a command-line override of some option
852 value in another command. Finds the command object for
853 'command', sets its 'option' to 'value', and unconditionally
854 calls 'set_final_options()' on it: this means that some command
855 objects may have 'set_final_options()' invoked more than once.
856 Even so, this is not entirely reliable: the other command may
857 already be initialized to its satisfaction, in which case the
858 second 'set_final_options()' invocation will have little or no
859 effect."""
861 cmd_obj = self.distribution.find_command_obj (command)
862 cmd_obj.set_option (option, value)
863 cmd_obj.set_final_options ()
866 def find_peer (self, command, create=1):
867 """Wrapper around Distribution's 'find_command_obj()' method:
868 find (create if necessary and 'create' is true) the command
869 object for 'command'.."""
871 return self.distribution.find_command_obj (command, create)
874 def get_peer_option (self, command, option):
875 """Find or create the command object for 'command', and return
876 its 'option' option."""
878 cmd_obj = self.distribution.find_command_obj (command)
879 return cmd_obj.get_option (option)
882 def run_peer (self, command):
883 """Run some other command: uses the 'run_command()' method of
884 Distribution, which creates the command object if necessary
885 and then invokes its 'run()' method."""
887 self.distribution.run_command (command)
890 # -- External world manipulation -----------------------------------
892 def warn (self, msg):
893 sys.stderr.write ("warning: %s: %s\n" %
894 (self.get_command_name(), msg))
897 def execute (self, func, args, msg=None, level=1):
898 """Perform some action that affects the outside world (eg.
899 by writing to the filesystem). Such actions are special because
900 they should be disabled by the "dry run" flag, and should
901 announce themselves if the current verbosity level is high
902 enough. This method takes care of all that bureaucracy for you;
903 all you have to do is supply the funtion to call and an argument
904 tuple for it (to embody the "external action" being performed),
905 a message to print if the verbosity level is high enough, and an
906 optional verbosity threshold."""
908 # Generate a message if we weren't passed one
909 if msg is None:
910 msg = "%s %s" % (func.__name__, `args`)
911 if msg[-2:] == ',)': # correct for singleton tuple
912 msg = msg[0:-2] + ')'
914 # Print it if verbosity level is high enough
915 self.announce (msg, level)
917 # And do it, as long as we're not in dry-run mode
918 if not self.dry_run:
919 apply (func, args)
921 # execute()
924 def mkpath (self, name, mode=0777):
925 util.mkpath (name, mode,
926 self.verbose, self.dry_run)
929 def copy_file (self, infile, outfile,
930 preserve_mode=1, preserve_times=1, level=1):
931 """Copy a file respecting verbose, dry-run and force flags."""
933 return util.copy_file (infile, outfile,
934 preserve_mode, preserve_times,
935 not self.force,
936 self.verbose >= level,
937 self.dry_run)
940 def copy_tree (self, infile, outfile,
941 preserve_mode=1, preserve_times=1, preserve_symlinks=0,
942 level=1):
943 """Copy an entire directory tree respecting verbose, dry-run,
944 and force flags."""
946 return util.copy_tree (infile, outfile,
947 preserve_mode,preserve_times,preserve_symlinks,
948 not self.force,
949 self.verbose >= level,
950 self.dry_run)
953 def move_file (self, src, dst, level=1):
954 """Move a file respecting verbose and dry-run flags."""
955 return util.move_file (src, dst,
956 self.verbose >= level,
957 self.dry_run)
960 def spawn (self, cmd, search_path=1, level=1):
961 from distutils.spawn import spawn
962 spawn (cmd, search_path,
963 self.verbose >= level,
964 self.dry_run)
967 def make_file (self, infiles, outfile, func, args,
968 exec_msg=None, skip_msg=None, level=1):
970 """Special case of 'execute()' for operations that process one or
971 more input files and generate one output file. Works just like
972 'execute()', except the operation is skipped and a different
973 message printed if 'outfile' already exists and is newer than
974 all files listed in 'infiles'."""
977 if exec_msg is None:
978 exec_msg = "generating %s from %s" % \
979 (outfile, string.join (infiles, ', '))
980 if skip_msg is None:
981 skip_msg = "skipping %s (inputs unchanged)" % outfile
984 # Allow 'infiles' to be a single string
985 if type (infiles) is StringType:
986 infiles = (infiles,)
987 elif type (infiles) not in (ListType, TupleType):
988 raise TypeError, \
989 "'infiles' must be a string, or a list or tuple of strings"
991 # If 'outfile' must be regenerated (either because it doesn't
992 # exist, is out-of-date, or the 'force' flag is true) then
993 # perform the action that presumably regenerates it
994 if self.force or util.newer_group (infiles, outfile):
995 self.execute (func, args, exec_msg, level)
997 # Otherwise, print the "skip" message
998 else:
999 self.announce (skip_msg, level)
1001 # make_file ()
1003 # end class Command