Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / distutils / dist.py
CommitLineData
86530b38
AT
1"""distutils.dist
2
3Provides the Distribution class, which represents the module distribution
4being built/installed/distributed.
5"""
6
7# This module should be kept compatible with Python 2.1.
8
9__revision__ = "$Id: dist.py,v 1.72 2004/11/10 22:23:14 loewis Exp $"
10
11import sys, os, string, re
12from types import *
13from copy import copy
14
15try:
16 import warnings
17except ImportError:
18 warnings = None
19
20from distutils.errors import *
21from distutils.fancy_getopt import FancyGetopt, translate_longopt
22from distutils.util import check_environ, strtobool, rfc822_escape
23from distutils import log
24from distutils.debug import DEBUG
25
26# Regex to define acceptable Distutils command names. This is not *quite*
27# the same as a Python NAME -- I don't allow leading underscores. The fact
28# that they're very similar is no coincidence; the default naming scheme is
29# to look for a Python module named after the command.
30command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
31
32
33class Distribution:
34 """The core of the Distutils. Most of the work hiding behind 'setup'
35 is really done within a Distribution instance, which farms the work out
36 to the Distutils commands specified on the command line.
37
38 Setup scripts will almost never instantiate Distribution directly,
39 unless the 'setup()' function is totally inadequate to their needs.
40 However, it is conceivable that a setup script might wish to subclass
41 Distribution for some specialized purpose, and then pass the subclass
42 to 'setup()' as the 'distclass' keyword argument. If so, it is
43 necessary to respect the expectations that 'setup' has of Distribution.
44 See the code for 'setup()', in core.py, for details.
45 """
46
47
48 # 'global_options' describes the command-line options that may be
49 # supplied to the setup script prior to any actual commands.
50 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
51 # these global options. This list should be kept to a bare minimum,
52 # since every global option is also valid as a command option -- and we
53 # don't want to pollute the commands with too many options that they
54 # have minimal control over.
55 # The fourth entry for verbose means that it can be repeated.
56 global_options = [('verbose', 'v', "run verbosely (default)", 1),
57 ('quiet', 'q', "run quietly (turns verbosity off)"),
58 ('dry-run', 'n', "don't actually do anything"),
59 ('help', 'h', "show detailed help message"),
60 ]
61
62 # options that are not propagated to the commands
63 display_options = [
64 ('help-commands', None,
65 "list all available commands"),
66 ('name', None,
67 "print package name"),
68 ('version', 'V',
69 "print package version"),
70 ('fullname', None,
71 "print <package name>-<version>"),
72 ('author', None,
73 "print the author's name"),
74 ('author-email', None,
75 "print the author's email address"),
76 ('maintainer', None,
77 "print the maintainer's name"),
78 ('maintainer-email', None,
79 "print the maintainer's email address"),
80 ('contact', None,
81 "print the maintainer's name if known, else the author's"),
82 ('contact-email', None,
83 "print the maintainer's email address if known, else the author's"),
84 ('url', None,
85 "print the URL for this package"),
86 ('license', None,
87 "print the license of the package"),
88 ('licence', None,
89 "alias for --license"),
90 ('description', None,
91 "print the package description"),
92 ('long-description', None,
93 "print the long package description"),
94 ('platforms', None,
95 "print the list of platforms"),
96 ('classifiers', None,
97 "print the list of classifiers"),
98 ('keywords', None,
99 "print the list of keywords"),
100 ]
101 display_option_names = map(lambda x: translate_longopt(x[0]),
102 display_options)
103
104 # negative options are options that exclude other options
105 negative_opt = {'quiet': 'verbose'}
106
107
108 # -- Creation/initialization methods -------------------------------
109
110 def __init__ (self, attrs=None):
111 """Construct a new Distribution instance: initialize all the
112 attributes of a Distribution, and then use 'attrs' (a dictionary
113 mapping attribute names to values) to assign some of those
114 attributes their "real" values. (Any attributes not mentioned in
115 'attrs' will be assigned to some null value: 0, None, an empty list
116 or dictionary, etc.) Most importantly, initialize the
117 'command_obj' attribute to the empty dictionary; this will be
118 filled in with real command objects by 'parse_command_line()'.
119 """
120
121 # Default values for our command-line options
122 self.verbose = 1
123 self.dry_run = 0
124 self.help = 0
125 for attr in self.display_option_names:
126 setattr(self, attr, 0)
127
128 # Store the distribution meta-data (name, version, author, and so
129 # forth) in a separate object -- we're getting to have enough
130 # information here (and enough command-line options) that it's
131 # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
132 # object in a sneaky and underhanded (but efficient!) way.
133 self.metadata = DistributionMetadata()
134 for basename in self.metadata._METHOD_BASENAMES:
135 method_name = "get_" + basename
136 setattr(self, method_name, getattr(self.metadata, method_name))
137
138 # 'cmdclass' maps command names to class objects, so we
139 # can 1) quickly figure out which class to instantiate when
140 # we need to create a new command object, and 2) have a way
141 # for the setup script to override command classes
142 self.cmdclass = {}
143
144 # 'command_packages' is a list of packages in which commands
145 # are searched for. The factory for command 'foo' is expected
146 # to be named 'foo' in the module 'foo' in one of the packages
147 # named here. This list is searched from the left; an error
148 # is raised if no named package provides the command being
149 # searched for. (Always access using get_command_packages().)
150 self.command_packages = None
151
152 # 'script_name' and 'script_args' are usually set to sys.argv[0]
153 # and sys.argv[1:], but they can be overridden when the caller is
154 # not necessarily a setup script run from the command-line.
155 self.script_name = None
156 self.script_args = None
157
158 # 'command_options' is where we store command options between
159 # parsing them (from config files, the command-line, etc.) and when
160 # they are actually needed -- ie. when the command in question is
161 # instantiated. It is a dictionary of dictionaries of 2-tuples:
162 # command_options = { command_name : { option : (source, value) } }
163 self.command_options = {}
164
165 # These options are really the business of various commands, rather
166 # than of the Distribution itself. We provide aliases for them in
167 # Distribution as a convenience to the developer.
168 self.packages = None
169 self.package_data = {}
170 self.package_dir = None
171 self.py_modules = None
172 self.libraries = None
173 self.headers = None
174 self.ext_modules = None
175 self.ext_package = None
176 self.include_dirs = None
177 self.extra_path = None
178 self.scripts = None
179 self.data_files = None
180
181 # And now initialize bookkeeping stuff that can't be supplied by
182 # the caller at all. 'command_obj' maps command names to
183 # Command instances -- that's how we enforce that every command
184 # class is a singleton.
185 self.command_obj = {}
186
187 # 'have_run' maps command names to boolean values; it keeps track
188 # of whether we have actually run a particular command, to make it
189 # cheap to "run" a command whenever we think we might need to -- if
190 # it's already been done, no need for expensive filesystem
191 # operations, we just check the 'have_run' dictionary and carry on.
192 # It's only safe to query 'have_run' for a command class that has
193 # been instantiated -- a false value will be inserted when the
194 # command object is created, and replaced with a true value when
195 # the command is successfully run. Thus it's probably best to use
196 # '.get()' rather than a straight lookup.
197 self.have_run = {}
198
199 # Now we'll use the attrs dictionary (ultimately, keyword args from
200 # the setup script) to possibly override any or all of these
201 # distribution options.
202
203 if attrs:
204
205 # Pull out the set of command options and work on them
206 # specifically. Note that this order guarantees that aliased
207 # command options will override any supplied redundantly
208 # through the general options dictionary.
209 options = attrs.get('options')
210 if options:
211 del attrs['options']
212 for (command, cmd_options) in options.items():
213 opt_dict = self.get_option_dict(command)
214 for (opt, val) in cmd_options.items():
215 opt_dict[opt] = ("setup script", val)
216
217 if attrs.has_key('licence'):
218 attrs['license'] = attrs['licence']
219 del attrs['licence']
220 msg = "'licence' distribution option is deprecated; use 'license'"
221 if warnings is not None:
222 warnings.warn(msg)
223 else:
224 sys.stderr.write(msg + "\n")
225
226 # Now work on the rest of the attributes. Any attribute that's
227 # not already defined is invalid!
228 for (key,val) in attrs.items():
229 if hasattr(self.metadata, key):
230 setattr(self.metadata, key, val)
231 elif hasattr(self, key):
232 setattr(self, key, val)
233 else:
234 msg = "Unknown distribution option: %s" % repr(key)
235 if warnings is not None:
236 warnings.warn(msg)
237 else:
238 sys.stderr.write(msg + "\n")
239
240 self.finalize_options()
241
242 # __init__ ()
243
244
245 def get_option_dict (self, command):
246 """Get the option dictionary for a given command. If that
247 command's option dictionary hasn't been created yet, then create it
248 and return the new dictionary; otherwise, return the existing
249 option dictionary.
250 """
251
252 dict = self.command_options.get(command)
253 if dict is None:
254 dict = self.command_options[command] = {}
255 return dict
256
257
258 def dump_option_dicts (self, header=None, commands=None, indent=""):
259 from pprint import pformat
260
261 if commands is None: # dump all command option dicts
262 commands = self.command_options.keys()
263 commands.sort()
264
265 if header is not None:
266 print indent + header
267 indent = indent + " "
268
269 if not commands:
270 print indent + "no commands known yet"
271 return
272
273 for cmd_name in commands:
274 opt_dict = self.command_options.get(cmd_name)
275 if opt_dict is None:
276 print indent + "no option dict for '%s' command" % cmd_name
277 else:
278 print indent + "option dict for '%s' command:" % cmd_name
279 out = pformat(opt_dict)
280 for line in string.split(out, "\n"):
281 print indent + " " + line
282
283 # dump_option_dicts ()
284
285
286
287 # -- Config file finding/parsing methods ---------------------------
288
289 def find_config_files (self):
290 """Find as many configuration files as should be processed for this
291 platform, and return a list of filenames in the order in which they
292 should be parsed. The filenames returned are guaranteed to exist
293 (modulo nasty race conditions).
294
295 There are three possible config files: distutils.cfg in the
296 Distutils installation directory (ie. where the top-level
297 Distutils __inst__.py file lives), a file in the user's home
298 directory named .pydistutils.cfg on Unix and pydistutils.cfg
299 on Windows/Mac, and setup.cfg in the current directory.
300 """
301 files = []
302 check_environ()
303
304 # Where to look for the system-wide Distutils config file
305 sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
306
307 # Look for the system config file
308 sys_file = os.path.join(sys_dir, "distutils.cfg")
309 if os.path.isfile(sys_file):
310 files.append(sys_file)
311
312 # What to call the per-user config file
313 if os.name == 'posix':
314 user_filename = ".pydistutils.cfg"
315 else:
316 user_filename = "pydistutils.cfg"
317
318 # And look for the user config file
319 if os.environ.has_key('HOME'):
320 user_file = os.path.join(os.environ.get('HOME'), user_filename)
321 if os.path.isfile(user_file):
322 files.append(user_file)
323
324 # All platforms support local setup.cfg
325 local_file = "setup.cfg"
326 if os.path.isfile(local_file):
327 files.append(local_file)
328
329 return files
330
331 # find_config_files ()
332
333
334 def parse_config_files (self, filenames=None):
335
336 from ConfigParser import ConfigParser
337
338 if filenames is None:
339 filenames = self.find_config_files()
340
341 if DEBUG: print "Distribution.parse_config_files():"
342
343 parser = ConfigParser()
344 for filename in filenames:
345 if DEBUG: print " reading", filename
346 parser.read(filename)
347 for section in parser.sections():
348 options = parser.options(section)
349 opt_dict = self.get_option_dict(section)
350
351 for opt in options:
352 if opt != '__name__':
353 val = parser.get(section,opt)
354 opt = string.replace(opt, '-', '_')
355 opt_dict[opt] = (filename, val)
356
357 # Make the ConfigParser forget everything (so we retain
358 # the original filenames that options come from)
359 parser.__init__()
360
361 # If there was a "global" section in the config file, use it
362 # to set Distribution options.
363
364 if self.command_options.has_key('global'):
365 for (opt, (src, val)) in self.command_options['global'].items():
366 alias = self.negative_opt.get(opt)
367 try:
368 if alias:
369 setattr(self, alias, not strtobool(val))
370 elif opt in ('verbose', 'dry_run'): # ugh!
371 setattr(self, opt, strtobool(val))
372 else:
373 setattr(self, opt, val)
374 except ValueError, msg:
375 raise DistutilsOptionError, msg
376
377 # parse_config_files ()
378
379
380 # -- Command-line parsing methods ----------------------------------
381
382 def parse_command_line (self):
383 """Parse the setup script's command line, taken from the
384 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
385 -- see 'setup()' in core.py). This list is first processed for
386 "global options" -- options that set attributes of the Distribution
387 instance. Then, it is alternately scanned for Distutils commands
388 and options for that command. Each new command terminates the
389 options for the previous command. The allowed options for a
390 command are determined by the 'user_options' attribute of the
391 command class -- thus, we have to be able to load command classes
392 in order to parse the command line. Any error in that 'options'
393 attribute raises DistutilsGetoptError; any error on the
394 command-line raises DistutilsArgError. If no Distutils commands
395 were found on the command line, raises DistutilsArgError. Return
396 true if command-line was successfully parsed and we should carry
397 on with executing commands; false if no errors but we shouldn't
398 execute commands (currently, this only happens if user asks for
399 help).
400 """
401 #
402 # We now have enough information to show the Macintosh dialog
403 # that allows the user to interactively specify the "command line".
404 #
405 toplevel_options = self._get_toplevel_options()
406 if sys.platform == 'mac':
407 import EasyDialogs
408 cmdlist = self.get_command_list()
409 self.script_args = EasyDialogs.GetArgv(
410 toplevel_options + self.display_options, cmdlist)
411
412 # We have to parse the command line a bit at a time -- global
413 # options, then the first command, then its options, and so on --
414 # because each command will be handled by a different class, and
415 # the options that are valid for a particular class aren't known
416 # until we have loaded the command class, which doesn't happen
417 # until we know what the command is.
418
419 self.commands = []
420 parser = FancyGetopt(toplevel_options + self.display_options)
421 parser.set_negative_aliases(self.negative_opt)
422 parser.set_aliases({'licence': 'license'})
423 args = parser.getopt(args=self.script_args, object=self)
424 option_order = parser.get_option_order()
425 log.set_verbosity(self.verbose)
426
427 # for display options we return immediately
428 if self.handle_display_options(option_order):
429 return
430
431 while args:
432 args = self._parse_command_opts(parser, args)
433 if args is None: # user asked for help (and got it)
434 return
435
436 # Handle the cases of --help as a "global" option, ie.
437 # "setup.py --help" and "setup.py --help command ...". For the
438 # former, we show global options (--verbose, --dry-run, etc.)
439 # and display-only options (--name, --version, etc.); for the
440 # latter, we omit the display-only options and show help for
441 # each command listed on the command line.
442 if self.help:
443 self._show_help(parser,
444 display_options=len(self.commands) == 0,
445 commands=self.commands)
446 return
447
448 # Oops, no commands found -- an end-user error
449 if not self.commands:
450 raise DistutilsArgError, "no commands supplied"
451
452 # All is well: return true
453 return 1
454
455 # parse_command_line()
456
457 def _get_toplevel_options (self):
458 """Return the non-display options recognized at the top level.
459
460 This includes options that are recognized *only* at the top
461 level as well as options recognized for commands.
462 """
463 return self.global_options + [
464 ("command-packages=", None,
465 "list of packages that provide distutils commands"),
466 ]
467
468 def _parse_command_opts (self, parser, args):
469 """Parse the command-line options for a single command.
470 'parser' must be a FancyGetopt instance; 'args' must be the list
471 of arguments, starting with the current command (whose options
472 we are about to parse). Returns a new version of 'args' with
473 the next command at the front of the list; will be the empty
474 list if there are no more commands on the command line. Returns
475 None if the user asked for help on this command.
476 """
477 # late import because of mutual dependence between these modules
478 from distutils.cmd import Command
479
480 # Pull the current command from the head of the command line
481 command = args[0]
482 if not command_re.match(command):
483 raise SystemExit, "invalid command name '%s'" % command
484 self.commands.append(command)
485
486 # Dig up the command class that implements this command, so we
487 # 1) know that it's a valid command, and 2) know which options
488 # it takes.
489 try:
490 cmd_class = self.get_command_class(command)
491 except DistutilsModuleError, msg:
492 raise DistutilsArgError, msg
493
494 # Require that the command class be derived from Command -- want
495 # to be sure that the basic "command" interface is implemented.
496 if not issubclass(cmd_class, Command):
497 raise DistutilsClassError, \
498 "command class %s must subclass Command" % cmd_class
499
500 # Also make sure that the command object provides a list of its
501 # known options.
502 if not (hasattr(cmd_class, 'user_options') and
503 type(cmd_class.user_options) is ListType):
504 raise DistutilsClassError, \
505 ("command class %s must provide " +
506 "'user_options' attribute (a list of tuples)") % \
507 cmd_class
508
509 # If the command class has a list of negative alias options,
510 # merge it in with the global negative aliases.
511 negative_opt = self.negative_opt
512 if hasattr(cmd_class, 'negative_opt'):
513 negative_opt = copy(negative_opt)
514 negative_opt.update(cmd_class.negative_opt)
515
516 # Check for help_options in command class. They have a different
517 # format (tuple of four) so we need to preprocess them here.
518 if (hasattr(cmd_class, 'help_options') and
519 type(cmd_class.help_options) is ListType):
520 help_options = fix_help_options(cmd_class.help_options)
521 else:
522 help_options = []
523
524
525 # All commands support the global options too, just by adding
526 # in 'global_options'.
527 parser.set_option_table(self.global_options +
528 cmd_class.user_options +
529 help_options)
530 parser.set_negative_aliases(negative_opt)
531 (args, opts) = parser.getopt(args[1:])
532 if hasattr(opts, 'help') and opts.help:
533 self._show_help(parser, display_options=0, commands=[cmd_class])
534 return
535
536 if (hasattr(cmd_class, 'help_options') and
537 type(cmd_class.help_options) is ListType):
538 help_option_found=0
539 for (help_option, short, desc, func) in cmd_class.help_options:
540 if hasattr(opts, parser.get_attr_name(help_option)):
541 help_option_found=1
542 #print "showing help for option %s of command %s" % \
543 # (help_option[0],cmd_class)
544
545 if callable(func):
546 func()
547 else:
548 raise DistutilsClassError(
549 "invalid help function %r for help option '%s': "
550 "must be a callable object (function, etc.)"
551 % (func, help_option))
552
553 if help_option_found:
554 return
555
556 # Put the options from the command-line into their official
557 # holding pen, the 'command_options' dictionary.
558 opt_dict = self.get_option_dict(command)
559 for (name, value) in vars(opts).items():
560 opt_dict[name] = ("command line", value)
561
562 return args
563
564 # _parse_command_opts ()
565
566 def finalize_options (self):
567 """Set final values for all the options on the Distribution
568 instance, analogous to the .finalize_options() method of Command
569 objects.
570 """
571
572 keywords = self.metadata.keywords
573 if keywords is not None:
574 if type(keywords) is StringType:
575 keywordlist = string.split(keywords, ',')
576 self.metadata.keywords = map(string.strip, keywordlist)
577
578 platforms = self.metadata.platforms
579 if platforms is not None:
580 if type(platforms) is StringType:
581 platformlist = string.split(platforms, ',')
582 self.metadata.platforms = map(string.strip, platformlist)
583
584 def _show_help (self,
585 parser,
586 global_options=1,
587 display_options=1,
588 commands=[]):
589 """Show help for the setup script command-line in the form of
590 several lists of command-line options. 'parser' should be a
591 FancyGetopt instance; do not expect it to be returned in the
592 same state, as its option table will be reset to make it
593 generate the correct help text.
594
595 If 'global_options' is true, lists the global options:
596 --verbose, --dry-run, etc. If 'display_options' is true, lists
597 the "display-only" options: --name, --version, etc. Finally,
598 lists per-command help for every command name or command class
599 in 'commands'.
600 """
601 # late import because of mutual dependence between these modules
602 from distutils.core import gen_usage
603 from distutils.cmd import Command
604
605 if global_options:
606 if display_options:
607 options = self._get_toplevel_options()
608 else:
609 options = self.global_options
610 parser.set_option_table(options)
611 parser.print_help("Global options:")
612 print
613
614 if display_options:
615 parser.set_option_table(self.display_options)
616 parser.print_help(
617 "Information display options (just display " +
618 "information, ignore any commands)")
619 print
620
621 for command in self.commands:
622 if type(command) is ClassType and issubclass(command, Command):
623 klass = command
624 else:
625 klass = self.get_command_class(command)
626 if (hasattr(klass, 'help_options') and
627 type(klass.help_options) is ListType):
628 parser.set_option_table(klass.user_options +
629 fix_help_options(klass.help_options))
630 else:
631 parser.set_option_table(klass.user_options)
632 parser.print_help("Options for '%s' command:" % klass.__name__)
633 print
634
635 print gen_usage(self.script_name)
636 return
637
638 # _show_help ()
639
640
641 def handle_display_options (self, option_order):
642 """If there were any non-global "display-only" options
643 (--help-commands or the metadata display options) on the command
644 line, display the requested info and return true; else return
645 false.
646 """
647 from distutils.core import gen_usage
648
649 # User just wants a list of commands -- we'll print it out and stop
650 # processing now (ie. if they ran "setup --help-commands foo bar",
651 # we ignore "foo bar").
652 if self.help_commands:
653 self.print_commands()
654 print
655 print gen_usage(self.script_name)
656 return 1
657
658 # If user supplied any of the "display metadata" options, then
659 # display that metadata in the order in which the user supplied the
660 # metadata options.
661 any_display_options = 0
662 is_display_option = {}
663 for option in self.display_options:
664 is_display_option[option[0]] = 1
665
666 for (opt, val) in option_order:
667 if val and is_display_option.get(opt):
668 opt = translate_longopt(opt)
669 value = getattr(self.metadata, "get_"+opt)()
670 if opt in ['keywords', 'platforms']:
671 print string.join(value, ',')
672 elif opt == 'classifiers':
673 print string.join(value, '\n')
674 else:
675 print value
676 any_display_options = 1
677
678 return any_display_options
679
680 # handle_display_options()
681
682 def print_command_list (self, commands, header, max_length):
683 """Print a subset of the list of all commands -- used by
684 'print_commands()'.
685 """
686
687 print header + ":"
688
689 for cmd in commands:
690 klass = self.cmdclass.get(cmd)
691 if not klass:
692 klass = self.get_command_class(cmd)
693 try:
694 description = klass.description
695 except AttributeError:
696 description = "(no description available)"
697
698 print " %-*s %s" % (max_length, cmd, description)
699
700 # print_command_list ()
701
702
703 def print_commands (self):
704 """Print out a help message listing all available commands with a
705 description of each. The list is divided into "standard commands"
706 (listed in distutils.command.__all__) and "extra commands"
707 (mentioned in self.cmdclass, but not a standard command). The
708 descriptions come from the command class attribute
709 'description'.
710 """
711
712 import distutils.command
713 std_commands = distutils.command.__all__
714 is_std = {}
715 for cmd in std_commands:
716 is_std[cmd] = 1
717
718 extra_commands = []
719 for cmd in self.cmdclass.keys():
720 if not is_std.get(cmd):
721 extra_commands.append(cmd)
722
723 max_length = 0
724 for cmd in (std_commands + extra_commands):
725 if len(cmd) > max_length:
726 max_length = len(cmd)
727
728 self.print_command_list(std_commands,
729 "Standard commands",
730 max_length)
731 if extra_commands:
732 print
733 self.print_command_list(extra_commands,
734 "Extra commands",
735 max_length)
736
737 # print_commands ()
738
739 def get_command_list (self):
740 """Get a list of (command, description) tuples.
741 The list is divided into "standard commands" (listed in
742 distutils.command.__all__) and "extra commands" (mentioned in
743 self.cmdclass, but not a standard command). The descriptions come
744 from the command class attribute 'description'.
745 """
746 # Currently this is only used on Mac OS, for the Mac-only GUI
747 # Distutils interface (by Jack Jansen)
748
749 import distutils.command
750 std_commands = distutils.command.__all__
751 is_std = {}
752 for cmd in std_commands:
753 is_std[cmd] = 1
754
755 extra_commands = []
756 for cmd in self.cmdclass.keys():
757 if not is_std.get(cmd):
758 extra_commands.append(cmd)
759
760 rv = []
761 for cmd in (std_commands + extra_commands):
762 klass = self.cmdclass.get(cmd)
763 if not klass:
764 klass = self.get_command_class(cmd)
765 try:
766 description = klass.description
767 except AttributeError:
768 description = "(no description available)"
769 rv.append((cmd, description))
770 return rv
771
772 # -- Command class/object methods ----------------------------------
773
774 def get_command_packages (self):
775 """Return a list of packages from which commands are loaded."""
776 pkgs = self.command_packages
777 if not isinstance(pkgs, type([])):
778 pkgs = string.split(pkgs or "", ",")
779 for i in range(len(pkgs)):
780 pkgs[i] = string.strip(pkgs[i])
781 pkgs = filter(None, pkgs)
782 if "distutils.command" not in pkgs:
783 pkgs.insert(0, "distutils.command")
784 self.command_packages = pkgs
785 return pkgs
786
787 def get_command_class (self, command):
788 """Return the class that implements the Distutils command named by
789 'command'. First we check the 'cmdclass' dictionary; if the
790 command is mentioned there, we fetch the class object from the
791 dictionary and return it. Otherwise we load the command module
792 ("distutils.command." + command) and fetch the command class from
793 the module. The loaded class is also stored in 'cmdclass'
794 to speed future calls to 'get_command_class()'.
795
796 Raises DistutilsModuleError if the expected module could not be
797 found, or if that module does not define the expected class.
798 """
799 klass = self.cmdclass.get(command)
800 if klass:
801 return klass
802
803 for pkgname in self.get_command_packages():
804 module_name = "%s.%s" % (pkgname, command)
805 klass_name = command
806
807 try:
808 __import__ (module_name)
809 module = sys.modules[module_name]
810 except ImportError:
811 continue
812
813 try:
814 klass = getattr(module, klass_name)
815 except AttributeError:
816 raise DistutilsModuleError, \
817 "invalid command '%s' (no class '%s' in module '%s')" \
818 % (command, klass_name, module_name)
819
820 self.cmdclass[command] = klass
821 return klass
822
823 raise DistutilsModuleError("invalid command '%s'" % command)
824
825
826 # get_command_class ()
827
828 def get_command_obj (self, command, create=1):
829 """Return the command object for 'command'. Normally this object
830 is cached on a previous call to 'get_command_obj()'; if no command
831 object for 'command' is in the cache, then we either create and
832 return it (if 'create' is true) or return None.
833 """
834 cmd_obj = self.command_obj.get(command)
835 if not cmd_obj and create:
836 if DEBUG:
837 print "Distribution.get_command_obj(): " \
838 "creating '%s' command object" % command
839
840 klass = self.get_command_class(command)
841 cmd_obj = self.command_obj[command] = klass(self)
842 self.have_run[command] = 0
843
844 # Set any options that were supplied in config files
845 # or on the command line. (NB. support for error
846 # reporting is lame here: any errors aren't reported
847 # until 'finalize_options()' is called, which means
848 # we won't report the source of the error.)
849 options = self.command_options.get(command)
850 if options:
851 self._set_command_options(cmd_obj, options)
852
853 return cmd_obj
854
855 def _set_command_options (self, command_obj, option_dict=None):
856 """Set the options for 'command_obj' from 'option_dict'. Basically
857 this means copying elements of a dictionary ('option_dict') to
858 attributes of an instance ('command').
859
860 'command_obj' must be a Command instance. If 'option_dict' is not
861 supplied, uses the standard option dictionary for this command
862 (from 'self.command_options').
863 """
864 command_name = command_obj.get_command_name()
865 if option_dict is None:
866 option_dict = self.get_option_dict(command_name)
867
868 if DEBUG: print " setting options for '%s' command:" % command_name
869 for (option, (source, value)) in option_dict.items():
870 if DEBUG: print " %s = %s (from %s)" % (option, value, source)
871 try:
872 bool_opts = map(translate_longopt, command_obj.boolean_options)
873 except AttributeError:
874 bool_opts = []
875 try:
876 neg_opt = command_obj.negative_opt
877 except AttributeError:
878 neg_opt = {}
879
880 try:
881 is_string = type(value) is StringType
882 if neg_opt.has_key(option) and is_string:
883 setattr(command_obj, neg_opt[option], not strtobool(value))
884 elif option in bool_opts and is_string:
885 setattr(command_obj, option, strtobool(value))
886 elif hasattr(command_obj, option):
887 setattr(command_obj, option, value)
888 else:
889 raise DistutilsOptionError, \
890 ("error in %s: command '%s' has no such option '%s'"
891 % (source, command_name, option))
892 except ValueError, msg:
893 raise DistutilsOptionError, msg
894
895 def reinitialize_command (self, command, reinit_subcommands=0):
896 """Reinitializes a command to the state it was in when first
897 returned by 'get_command_obj()': ie., initialized but not yet
898 finalized. This provides the opportunity to sneak option
899 values in programmatically, overriding or supplementing
900 user-supplied values from the config files and command line.
901 You'll have to re-finalize the command object (by calling
902 'finalize_options()' or 'ensure_finalized()') before using it for
903 real.
904
905 'command' should be a command name (string) or command object. If
906 'reinit_subcommands' is true, also reinitializes the command's
907 sub-commands, as declared by the 'sub_commands' class attribute (if
908 it has one). See the "install" command for an example. Only
909 reinitializes the sub-commands that actually matter, ie. those
910 whose test predicates return true.
911
912 Returns the reinitialized command object.
913 """
914 from distutils.cmd import Command
915 if not isinstance(command, Command):
916 command_name = command
917 command = self.get_command_obj(command_name)
918 else:
919 command_name = command.get_command_name()
920
921 if not command.finalized:
922 return command
923 command.initialize_options()
924 command.finalized = 0
925 self.have_run[command_name] = 0
926 self._set_command_options(command)
927
928 if reinit_subcommands:
929 for sub in command.get_sub_commands():
930 self.reinitialize_command(sub, reinit_subcommands)
931
932 return command
933
934
935 # -- Methods that operate on the Distribution ----------------------
936
937 def announce (self, msg, level=1):
938 log.debug(msg)
939
940 def run_commands (self):
941 """Run each command that was seen on the setup script command line.
942 Uses the list of commands found and cache of command objects
943 created by 'get_command_obj()'.
944 """
945 for cmd in self.commands:
946 self.run_command(cmd)
947
948
949 # -- Methods that operate on its Commands --------------------------
950
951 def run_command (self, command):
952 """Do whatever it takes to run a command (including nothing at all,
953 if the command has already been run). Specifically: if we have
954 already created and run the command named by 'command', return
955 silently without doing anything. If the command named by 'command'
956 doesn't even have a command object yet, create one. Then invoke
957 'run()' on that command object (or an existing one).
958 """
959 # Already been here, done that? then return silently.
960 if self.have_run.get(command):
961 return
962
963 log.info("running %s", command)
964 cmd_obj = self.get_command_obj(command)
965 cmd_obj.ensure_finalized()
966 cmd_obj.run()
967 self.have_run[command] = 1
968
969
970 # -- Distribution query methods ------------------------------------
971
972 def has_pure_modules (self):
973 return len(self.packages or self.py_modules or []) > 0
974
975 def has_ext_modules (self):
976 return self.ext_modules and len(self.ext_modules) > 0
977
978 def has_c_libraries (self):
979 return self.libraries and len(self.libraries) > 0
980
981 def has_modules (self):
982 return self.has_pure_modules() or self.has_ext_modules()
983
984 def has_headers (self):
985 return self.headers and len(self.headers) > 0
986
987 def has_scripts (self):
988 return self.scripts and len(self.scripts) > 0
989
990 def has_data_files (self):
991 return self.data_files and len(self.data_files) > 0
992
993 def is_pure (self):
994 return (self.has_pure_modules() and
995 not self.has_ext_modules() and
996 not self.has_c_libraries())
997
998 # -- Metadata query methods ----------------------------------------
999
1000 # If you're looking for 'get_name()', 'get_version()', and so forth,
1001 # they are defined in a sneaky way: the constructor binds self.get_XXX
1002 # to self.metadata.get_XXX. The actual code is in the
1003 # DistributionMetadata class, below.
1004
1005# class Distribution
1006
1007
1008class DistributionMetadata:
1009 """Dummy class to hold the distribution meta-data: name, version,
1010 author, and so forth.
1011 """
1012
1013 _METHOD_BASENAMES = ("name", "version", "author", "author_email",
1014 "maintainer", "maintainer_email", "url",
1015 "license", "description", "long_description",
1016 "keywords", "platforms", "fullname", "contact",
1017 "contact_email", "license", "classifiers",
1018 "download_url")
1019
1020 def __init__ (self):
1021 self.name = None
1022 self.version = None
1023 self.author = None
1024 self.author_email = None
1025 self.maintainer = None
1026 self.maintainer_email = None
1027 self.url = None
1028 self.license = None
1029 self.description = None
1030 self.long_description = None
1031 self.keywords = None
1032 self.platforms = None
1033 self.classifiers = None
1034 self.download_url = None
1035
1036 def write_pkg_info (self, base_dir):
1037 """Write the PKG-INFO file into the release tree.
1038 """
1039
1040 pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w')
1041
1042 pkg_info.write('Metadata-Version: 1.0\n')
1043 pkg_info.write('Name: %s\n' % self.get_name() )
1044 pkg_info.write('Version: %s\n' % self.get_version() )
1045 pkg_info.write('Summary: %s\n' % self.get_description() )
1046 pkg_info.write('Home-page: %s\n' % self.get_url() )
1047 pkg_info.write('Author: %s\n' % self.get_contact() )
1048 pkg_info.write('Author-email: %s\n' % self.get_contact_email() )
1049 pkg_info.write('License: %s\n' % self.get_license() )
1050 if self.download_url:
1051 pkg_info.write('Download-URL: %s\n' % self.download_url)
1052
1053 long_desc = rfc822_escape( self.get_long_description() )
1054 pkg_info.write('Description: %s\n' % long_desc)
1055
1056 keywords = string.join( self.get_keywords(), ',')
1057 if keywords:
1058 pkg_info.write('Keywords: %s\n' % keywords )
1059
1060 for platform in self.get_platforms():
1061 pkg_info.write('Platform: %s\n' % platform )
1062
1063 for classifier in self.get_classifiers():
1064 pkg_info.write('Classifier: %s\n' % classifier )
1065
1066 pkg_info.close()
1067
1068 # write_pkg_info ()
1069
1070 # -- Metadata query methods ----------------------------------------
1071
1072 def get_name (self):
1073 return self.name or "UNKNOWN"
1074
1075 def get_version(self):
1076 return self.version or "0.0.0"
1077
1078 def get_fullname (self):
1079 return "%s-%s" % (self.get_name(), self.get_version())
1080
1081 def get_author(self):
1082 return self.author or "UNKNOWN"
1083
1084 def get_author_email(self):
1085 return self.author_email or "UNKNOWN"
1086
1087 def get_maintainer(self):
1088 return self.maintainer or "UNKNOWN"
1089
1090 def get_maintainer_email(self):
1091 return self.maintainer_email or "UNKNOWN"
1092
1093 def get_contact(self):
1094 return (self.maintainer or
1095 self.author or
1096 "UNKNOWN")
1097
1098 def get_contact_email(self):
1099 return (self.maintainer_email or
1100 self.author_email or
1101 "UNKNOWN")
1102
1103 def get_url(self):
1104 return self.url or "UNKNOWN"
1105
1106 def get_license(self):
1107 return self.license or "UNKNOWN"
1108 get_licence = get_license
1109
1110 def get_description(self):
1111 return self.description or "UNKNOWN"
1112
1113 def get_long_description(self):
1114 return self.long_description or "UNKNOWN"
1115
1116 def get_keywords(self):
1117 return self.keywords or []
1118
1119 def get_platforms(self):
1120 return self.platforms or ["UNKNOWN"]
1121
1122 def get_classifiers(self):
1123 return self.classifiers or []
1124
1125 def get_download_url(self):
1126 return self.download_url or "UNKNOWN"
1127
1128# class DistributionMetadata
1129
1130
1131def fix_help_options (options):
1132 """Convert a 4-tuple 'help_options' list as found in various command
1133 classes to the 3-tuple form required by FancyGetopt.
1134 """
1135 new_options = []
1136 for help_tuple in options:
1137 new_options.append(help_tuple[0:3])
1138 return new_options
1139
1140
1141if __name__ == "__main__":
1142 dist = Distribution()
1143 print "ok"