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
15 from distutils
.errors
import *
16 from distutils
.fancy_getopt
import fancy_getopt
17 from distutils
import util
19 # This is not *quite* the same as a Python NAME; I don't allow leading
20 # underscores. The fact that they're very similar is no coincidence...
21 command_re
= re
.compile (r
'^[a-zA-Z]([a-zA-Z0-9_]*)$')
23 # Defining this as a global is probably inadequate -- what about
24 # listing the available options (or even commands, which can vary
26 usage
= '%s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]' % sys
.argv
[0]
31 """The gateway to the Distutils: do everything your setup script
32 needs to do, in a highly flexible and user-driven way. Briefly:
33 create a Distribution instance; parse the command-line, creating
34 and customizing instances of the command class for each command
35 found on the command-line; run each of those commands.
37 The Distribution instance might be an instance of a class
38 supplied via the 'distclass' keyword argument to 'setup'; if no
39 such class is supplied, then the 'Distribution' class (also in
40 this module) is instantiated. All other arguments to 'setup'
41 (except for 'cmdclass') are used to set attributes of the
42 Distribution instance.
44 The 'cmdclass' argument, if supplied, is a dictionary mapping
45 command names to command classes. Each command encountered on the
46 command line will be turned into a command class, which is in turn
47 instantiated; any class found in 'cmdclass' is used in place of the
48 default, which is (for command 'foo_bar') class 'FooBar' in module
49 'distutils.command.foo_bar'. The command object must provide an
50 'options' attribute which is a list of option specifiers for
51 'distutils.fancy_getopt'. Any command-line options between the
52 current and the next command are used to set attributes in the
53 current command object.
55 When the entire command-line has been successfully parsed, calls the
56 'run' method on each command object in turn. This method will be
57 driven entirely by the Distribution object (which each command
58 object has a reference to, thanks to its constructor), and the
59 command-specific options that became attributes of each command
62 # Determine the distribution class -- either caller-supplied or
63 # our Distribution (see below).
64 klass
= attrs
.get ('distclass')
66 del attrs
['distclass']
70 # Create the Distribution instance, using the remaining arguments
71 # (ie. everything except distclass) to initialize it
74 # Get it to parse the command line; any command-line errors are
75 # the end-users fault, so turn them into SystemExit to suppress
78 dist
.parse_command_line (sys
.argv
[1:])
79 except DistutilsArgError
, msg
:
82 # And finally, run all the commands found on the command line.
89 """The core of the Distutils. Most of the work hiding behind
90 'setup' is really done within a Distribution instance, which
91 farms the work out to the Distutils commands specified on the
94 Clients will almost never instantiate Distribution directly,
95 unless the 'setup' function is totally inadequate to their needs.
96 However, it is conceivable that a client might wish to subclass
97 Distribution for some specialized purpose, and then pass the
98 subclass to 'setup' as the 'distclass' keyword argument. If so,
99 it is necessary to respect the expectations that 'setup' has of
100 Distribution: it must have a constructor and methods
101 'parse_command_line()' and 'run_commands()' with signatures like
102 those described below."""
105 # 'global_options' describes the command-line options that may
106 # be supplied to the client (setup.py) prior to any actual
107 # commands. Eg. "./setup.py -nv" or "./setup.py --verbose"
108 # both take advantage of these global options.
109 global_options
= [('verbose', 'v', "run verbosely"),
110 ('dry-run', 'n', "don't actually do anything"),
114 # -- Creation/initialization methods -------------------------------
116 def __init__ (self
, attrs
=None):
117 """Construct a new Distribution instance: initialize all the
118 attributes of a Distribution, and then uses 'attrs' (a
119 dictionary mapping attribute names to values) to assign
120 some of those attributes their "real" values. (Any attributes
121 not mentioned in 'attrs' will be assigned to some null
122 value: 0, None, an empty list or dictionary, etc.) Most
123 importantly, initialize the 'command_obj' attribute
124 to the empty dictionary; this will be filled in with real
125 command objects by 'parse_command_line()'."""
127 # Default values for our command-line options
131 # And for all other attributes (stuff that might be passed in
132 # from setup.py, rather than from the end-user)
137 self
.description
= None
141 # The rest of these are really the business of various commands,
142 # rather than of the Distribution itself. However, they have
143 # to be here as a conduit to the relevant command class.
144 self
.py_modules
= None
145 self
.ext_modules
= None
148 # Now we'll use the attrs dictionary to possibly override
149 # any or all of these distribution options
151 for k
in attrs
.keys():
152 setattr (self
, k
, attrs
[k
])
154 # And now initialize bookkeeping stuff that can't be supplied by
156 self
.command_obj
= {}
161 def parse_command_line (self
, args
):
162 """Parse the client's command line: set any Distribution
163 attributes tied to command-line options, create all command
164 objects, and set their options from the command-line. 'args'
165 must be a list of command-line arguments, most likely
166 'sys.argv[1:]' (see the 'setup()' function). This list is
167 first processed for "global options" -- options that set
168 attributes of the Distribution instance. Then, it is
169 alternately scanned for Distutils command and options for
170 that command. Each new command terminates the options for
171 the previous command. The allowed options for a command are
172 determined by the 'options' attribute of the command object
173 -- thus, we instantiate (and cache) every command object
174 here, in order to access its 'options' attribute. Any error
175 in that 'options' attribute raises DistutilsGetoptError; any
176 error on the command-line raises DistutilsArgError. If no
177 Distutils commands were found on the command line, raises
178 DistutilsArgError."""
180 # We have to parse the command line a bit at a time -- global
181 # options, then the first command, then its options, and so on --
182 # because each command will be handled by a different class, and
183 # the options that are valid for a particular class aren't
184 # known until we instantiate the command class, which doesn't
185 # happen until we know what the command is.
188 args
= fancy_getopt (self
.global_options
, self
, sys
.argv
[1:])
191 # Pull the current command from the head of the command line
193 if not command_re
.match (command
):
194 raise SystemExit, "invalid command name '%s'" % command
195 self
.commands
.append (command
)
197 # Have to instantiate the command class now, so we have a
198 # way to get its valid options and somewhere to put the
199 # results of parsing its share of the command-line
200 cmd_obj
= self
.create_command_obj (command
)
202 # Require that the command class be derived from Command --
203 # that way, we can be sure that we at least have the 'run'
204 # and 'get_option' methods.
205 if not isinstance (cmd_obj
, Command
):
206 raise DistutilsClassError
, \
207 "command class %s must subclass Command" % \
210 # XXX this assumes that cmd_obj provides an 'options'
211 # attribute, but we're not enforcing that anywhere!
212 args
= fancy_getopt (cmd_obj
.options
, cmd_obj
, args
[1:])
213 self
.command_obj
[command
] = cmd_obj
217 # Oops, no commands found -- an end-user error
218 if not self
.commands
:
219 sys
.stderr
.write (usage
+ "\n")
220 raise DistutilsArgError
, "no commands supplied"
222 # parse_command_line()
225 # -- Command class/object methods ----------------------------------
227 # This is a method just so it can be overridden if desired; it doesn't
228 # actually use or change any attributes of the Distribution instance.
229 def find_command_class (self
, command
):
230 """Given a command, derives the names of the module and class
231 expected to implement the command: eg. 'foo_bar' becomes
232 'distutils.command.foo_bar' (the module) and 'FooBar' (the
233 class within that module). Loads the module, extracts the
234 class from it, and returns the class object.
236 Raises DistutilsModuleError with a semi-user-targeted error
237 message if the expected module could not be loaded, or the
238 expected class was not found in it."""
240 module_name
= 'distutils.command.' + command
241 klass_name
= string
.join \
242 (map (string
.capitalize
, string
.split (command
, '_')), '')
245 __import__ (module_name
)
246 module
= sys
.modules
[module_name
]
248 raise DistutilsModuleError
, \
249 "invalid command '%s' (no module named %s)" % \
250 (command
, module_name
)
253 klass
= vars(module
)[klass_name
]
255 raise DistutilsModuleError
, \
256 "invalid command '%s' (no class '%s' in module '%s')" \
257 % (command
, klass_name
, module_name
)
261 # find_command_class ()
264 def create_command_obj (self
, command
):
265 """Figure out the class that should implement a command,
266 instantiate it, cache and return the new "command object".
267 The "command class" is determined either by looking it up in
268 the 'cmdclass' attribute (this is the mechanism whereby
269 clients may override default Distutils commands or add their
270 own), or by calling the 'find_command_class()' method (if the
271 command name is not in 'cmdclass'."""
273 # Determine the command class -- either it's in the command_class
274 # dictionary, or we have to divine the module and class name
275 klass
= self
.cmdclass
.get(command
)
277 klass
= self
.find_command_class (command
)
278 self
.cmdclass
[command
] = klass
280 # Found the class OK -- instantiate it
281 cmd_obj
= klass (self
)
285 def find_command_obj (self
, command
, create
=1):
286 """Look up and return a command object in the cache maintained by
287 'create_command_obj()'. If none found, the action taken
288 depends on 'create': if true (the default), create a new
289 command object by calling 'create_command_obj()' and return
290 it; otherwise, return None."""
292 cmd_obj
= self
.command_obj
.get (command
)
293 if not cmd_obj
and create
:
294 cmd_obj
= self
.create_command_obj (command
)
295 self
.command_obj
[command
] = cmd_obj
300 # -- Methods that operate on the Distribution ----------------------
302 def announce (self
, msg
, level
=1):
303 """Print 'msg' if 'level' is greater than or equal to the verbosity
304 level recorded in the 'verbose' attribute (which, currently,
305 can be only 0 or 1)."""
307 if self
.verbose
>= level
:
311 def run_commands (self
):
312 """Run each command that was seen on the client command line.
313 Uses the list of commands found and cache of command objects
314 created by 'create_command_obj()'."""
316 for cmd
in self
.commands
:
317 self
.run_command (cmd
)
320 def get_option (self
, option
):
321 """Return the value of a distribution option. Raise
322 DistutilsOptionError if 'option' is not known."""
325 return getattr (self
, opt
)
326 except AttributeError:
327 raise DistutilsOptionError
, \
328 "unknown distribution option %s" % option
331 def get_options (self
, *options
):
332 """Return (as a tuple) the values of several distribution
333 options. Raise DistutilsOptionError if any element of
334 'options' is not known."""
339 values
.append (getattr (self
, opt
))
340 except AttributeError, name
:
341 raise DistutilsOptionError
, \
342 "unknown distribution option %s" % name
344 return tuple (values
)
347 # -- Methods that operate on its Commands --------------------------
349 def run_command (self
, command
):
350 """Create a command object for 'command' if necessary, and
351 run the command by invoking its 'run()' method."""
353 self
.announce ("running " + command
)
354 cmd_obj
= self
.find_command_obj (command
)
358 def get_command_option (self
, command
, option
):
359 """Create a command object for 'command' if necessary, finalize
360 its option values by invoking its 'set_final_options()'
361 method, and return the value of its 'option' option. Raise
362 DistutilsOptionError if 'option' is not known for
365 cmd_obj
= self
.find_command_obj (command
)
366 cmd_obj
.set_final_options ()
367 return cmd_obj
.get_option (option
)
369 return getattr (cmd_obj
, option
)
370 except AttributeError:
371 raise DistutilsOptionError
, \
372 "command %s: no such option %s" % (command
, option
)
375 def get_command_options (self
, command
, *options
):
376 """Create a command object for 'command' if necessary, finalize
377 its option values by invoking its 'set_final_options()'
378 method, and return the values of all the options listed in
379 'options' for that command. Raise DistutilsOptionError if
380 'option' is not known for that 'command'."""
382 cmd_obj
= self
.find_command_obj (command
)
383 cmd_obj
.set_final_options ()
387 values
.append (getattr (cmd_obj
, option
))
388 except AttributeError, name
:
389 raise DistutilsOptionError
, \
390 "command %s: no such option %s" % (command
, name
)
392 return tuple (values
)
394 # end class Distribution
398 """Abstract base class for defining command classes, the "worker bees"
399 of the Distutils. A useful analogy for command classes is to
400 think of them as subroutines with local variables called
401 "options". The options are "declared" in 'set_initial_options()'
402 and "initialized" (given their real values) in
403 'set_final_options()', both of which must be defined by every
404 command class. The distinction between the two is necessary
405 because option values might come from the outside world (command
406 line, option file, ...), and any options dependent on other
407 options must be computed *after* these outside influences have
408 been processed -- hence 'set_final_values()'. The "body" of the
409 subroutine, where it does all its work based on the values of its
410 options, is the 'run()' method, which must also be implemented by
411 every command class."""
413 # -- Creation/initialization methods -------------------------------
415 def __init__ (self
, dist
):
416 """Create and initialize a new Command object. Most importantly,
417 invokes the 'set_default_options()' method, which is the
418 real initializer and depends on the actual command being
421 if not isinstance (dist
, Distribution
):
422 raise TypeError, "dist must be a Distribution instance"
423 if self
.__class
__ is Command
:
424 raise RuntimeError, "Command is an abstract class"
426 self
.distribution
= dist
427 self
.set_default_options ()
431 # Subclasses must define:
432 # set_default_options()
433 # provide default values for all options; may be overridden
434 # by Distutils client, by command-line options, or by options
436 # set_final_options()
437 # decide on the final values for all options; this is called
438 # after all possible intervention from the outside world
439 # (command-line, option file, etc.) has been processed
441 # run the command: do whatever it is we're here to do,
442 # controlled by the command's various option values
444 def set_default_options (self
):
445 """Set default values for all the options that this command
446 supports. Note that these defaults may be overridden
447 by the command-line supplied by the user; thus, this is
448 not the place to code dependencies between options; generally,
449 'set_default_options()' implementations are just a bunch
450 of "self.foo = None" assignments.
452 This method must be implemented by all command classes."""
454 raise RuntimeError, \
455 "abstract method -- subclass %s must override" % self
.__class
__
457 def set_final_options (self
):
458 """Set final values for all the options that this command
459 supports. This is always called as late as possible, ie.
460 after any option assignments from the command-line or from
461 other commands have been done. Thus, this is the place to to
462 code option dependencies: if 'foo' depends on 'bar', then it
463 is safe to set 'foo' from 'bar' as long as 'foo' still has
464 the same value it was assigned in 'set_default_options()'.
466 This method must be implemented by all command classes."""
468 raise RuntimeError, \
469 "abstract method -- subclass %s must override" % self
.__class
__
472 """A command's raison d'etre: carry out the action it exists
473 to perform, controlled by the options initialized in
474 'set_initial_options()', customized by the user and other
475 commands, and finalized in 'set_final_options()'. All
476 terminal output and filesystem interaction should be done by
479 This method must be implemented by all command classes."""
481 raise RuntimeError, \
482 "abstract method -- subclass %s must override" % self
.__class
__
484 def announce (self
, msg
, level
=1):
485 """If the Distribution instance to which this command belongs
486 has a verbosity level of greater than or equal to 'level'
487 print 'msg' to stdout."""
488 if self
.distribution
.verbose
>= level
:
492 # -- Option query/set methods --------------------------------------
494 def get_option (self
, option
):
495 """Return the value of a single option for this command. Raise
496 DistutilsOptionError if 'option' is not known."""
498 return getattr (self
, option
)
499 except AttributeError:
500 raise DistutilsOptionError
, \
501 "command %s: no such option %s" % \
502 (self
.command_name(), option
)
505 def get_options (self
, *options
):
506 """Return (as a tuple) the values of several options for this
507 command. Raise DistutilsOptionError if any of the options in
508 'options' are not known."""
513 values
.append (getattr (self
, opt
))
514 except AttributeError, name
:
515 raise DistutilsOptionError
, \
516 "command %s: no such option %s" % \
517 (self
.command_name(), name
)
519 return tuple (values
)
522 def set_option (self
, option
, value
):
523 """Set the value of a single option for this command. Raise
524 DistutilsOptionError if 'option' is not known."""
526 if not hasattr (self
, option
):
527 raise DistutilsOptionError
, \
528 "command %s: no such option %s" % \
529 (self
.command_name(), option
)
530 if value
is not None:
531 setattr (self
, option
, value
)
533 def set_options (self
, **optval
):
534 """Set the values of several options for this command. Raise
535 DistutilsOptionError if any of the options specified as
536 keyword arguments are not known."""
538 for k
in optval
.keys():
539 if optval
[k
] is not None:
540 self
.set_option (k
, optval
[k
])
543 # -- Convenience methods for commands ------------------------------
545 def set_undefined_options (self
, src_cmd
, *option_pairs
):
546 """Set the values of any "undefined" options from corresponding
547 option values in some other command object. "Undefined" here
548 means "is None", which is the convention used to indicate
549 that an option has not been changed between
550 'set_initial_values()' and 'set_final_values()'. Usually
551 called from 'set_final_values()' for options that depend on
552 some other command rather than another option of the same
553 command. 'src_cmd' is the other command from which option
554 values will be taken (a command object will be created for it
555 if necessary); the remaining arguments are
556 '(src_option,dst_option)' tuples which mean "take the value
557 of 'src_option' in the 'src_cmd' command object, and copy it
558 to 'dst_option' in the current command object"."""
560 # Option_pairs: list of (src_option, dst_option) tuples
562 src_cmd_obj
= self
.distribution
.find_command_obj (src_cmd
)
563 src_cmd_obj
.set_final_options ()
565 for (src_option
, dst_option
) in option_pairs
:
566 if getattr (self
, dst_option
) is None:
567 self
.set_option (dst_option
,
568 src_cmd_obj
.get_option (src_option
))
569 except AttributeError, name
:
570 # duh, which command?
571 raise DistutilsOptionError
, "unknown option %s" % name
574 def set_peer_option (self
, command
, option
, value
):
575 """Attempt to simulate a command-line override of some option
576 value in another command. Creates a command object for
577 'command' if necessary, sets 'option' to 'value', and invokes
578 'set_final_options()' on that command object. This will only
579 have the desired effect if the command object for 'command'
580 has not previously been created. Generally this is used to
581 ensure that the options in 'command' dependent on 'option'
582 are computed, hopefully (but not necessarily) deriving from
583 'value'. It might be more accurate to call this method
584 'influence_dependent_peer_options()'."""
586 cmd_obj
= self
.distribution
.find_command_obj (command
)
587 cmd_obj
.set_option (option
, value
)
588 cmd_obj
.set_final_options ()
591 def run_peer (self
, command
):
592 """Run some other command: uses the 'run_command()' method of
593 Distribution, which creates the command object if necessary
594 and then invokes its 'run()' method."""
596 self
.distribution
.run_command (command
)
599 # -- External world manipulation -----------------------------------
601 def execute (self
, func
, args
, msg
=None, level
=1):
602 """Perform some action that affects the outside world (eg.
603 by writing to the filesystem). Such actions are special because
604 they should be disabled by the "dry run" flag (carried around by
605 the Command's Distribution), and should announce themselves if
606 the current verbosity level is high enough. This method takes
607 care of all that bureaucracy for you; all you have to do is
608 supply the funtion to call and an argument tuple for it (to
609 embody the "external action" being performed), a message to
610 print if the verbosity level is high enough, and an optional
611 verbosity threshold."""
614 # Generate a message if we weren't passed one
616 msg
= "%s %s" % (func
.__name
__, `args`
)
617 if msg
[-2:] == ',)': # correct for singleton tuple
618 msg
= msg
[0:-2] + ')'
620 # Print it if verbosity level is high enough
621 self
.announce (msg
, level
)
623 # And do it, as long as we're not in dry-run mode
624 if not self
.distribution
.dry_run
:
630 def mkpath (self
, name
, mode
=0777):
631 util
.mkpath (name
, mode
,
632 self
.distribution
.verbose
, self
.distribution
.dry_run
)
635 def copy_file (self
, infile
, outfile
,
636 preserve_mode
=1, preserve_times
=1, update
=1, level
=1):
637 """Copy a file respecting verbose and dry-run flags."""
639 util
.copy_file (infile
, outfile
,
640 preserve_mode
, preserve_times
,
641 update
, self
.distribution
.verbose
>= level
,
642 self
.distribution
.dry_run
)
645 def copy_tree (self
, infile
, outfile
,
646 preserve_mode
=1, preserve_times
=1, preserve_symlinks
=0,
648 """Copy an entire directory tree respecting verbose and dry-run
651 util
.copy_tree (infile
, outfile
,
652 preserve_mode
, preserve_times
, preserve_symlinks
,
653 update
, self
.distribution
.verbose
>= level
,
654 self
.distribution
.dry_run
)
657 def make_file (self
, infiles
, outfile
, func
, args
,
658 exec_msg
=None, skip_msg
=None, level
=1):
660 """Special case of 'execute()' for operations that process one or
661 more input files and generate one output file. Works just like
662 'execute()', except the operation is skipped and a different
663 message printed if 'outfile' already exists and is newer than
664 all files listed in 'infiles'."""
668 exec_msg
= "generating %s from %s" % \
669 (outfile
, string
.join (infiles
, ', '))
671 skip_msg
= "skipping %s (inputs unchanged)" % outfile
674 # Allow 'infiles' to be a single string
675 if type (infiles
) is StringType
:
677 elif type (infiles
) not in (ListType
, TupleType
):
679 "'infiles' must be a string, or a list or tuple of strings"
681 # XXX this stuff should probably be moved off to a function
682 # in 'distutils.util'
685 if os
.path
.exists (outfile
):
686 out_mtime
= os
.stat (outfile
)[ST_MTIME
]
688 # Loop over all infiles. If any infile is newer than outfile,
689 # then we'll have to regenerate outfile
691 in_mtime
= os
.stat (f
)[ST_MTIME
]
692 if in_mtime
> out_mtime
:
701 # If we determined that 'outfile' must be regenerated, then
702 # perform the action that presumably regenerates it
704 self
.execute (func
, args
, exec_msg
, level
)
706 # Otherwise, print the "skip" message
708 self
.announce (skip_msg
, level
)
713 # def make_files (self, infiles, outfiles, func, args,
714 # exec_msg=None, skip_msg=None, level=1):
716 # """Special case of 'execute()' for operations that process one or
717 # more input files and generate one or more output files. Works
718 # just like 'execute()', except the operation is skipped and a
719 # different message printed if all files listed in 'outfiles'
720 # already exist and are newer than all files listed in