blob: fe728c3b60edbba83cd14c3bff691b7c30154a4f [file] [log] [blame]
Greg Wardfe6462c2000-04-04 01:40:52 +00001"""distutils.dist
2
3Provides the Distribution class, which represents the module distribution
Greg Ward8ff5a3f2000-06-02 00:44:53 +00004being built/installed/distributed.
5"""
Greg Wardfe6462c2000-04-04 01:40:52 +00006
7# created 2000/04/03, Greg Ward
8# (extricated from core.py; actually dates back to the beginning)
9
10__revision__ = "$Id$"
11
Gregory P. Smith14263542000-05-12 00:41:33 +000012import sys, os, string, re
Greg Wardfe6462c2000-04-04 01:40:52 +000013from types import *
14from copy import copy
15from distutils.errors import *
Greg Ward36c36fe2000-05-20 14:07:59 +000016from distutils import sysconfig
Greg Ward2f2b6c62000-09-25 01:58:07 +000017from distutils.fancy_getopt import FancyGetopt, translate_longopt
Greg Wardceb9e222000-09-25 01:23:52 +000018from distutils.util import check_environ, strtobool
Greg Wardfe6462c2000-04-04 01:40:52 +000019
20
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.
25command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
26
27
28class Distribution:
Greg Ward8ff5a3f2000-06-02 00:44:53 +000029 """The core of the Distutils. Most of the work hiding behind 'setup'
30 is really done within a Distribution instance, which farms the work out
31 to the Distutils commands specified on the command line.
Greg Wardfe6462c2000-04-04 01:40:52 +000032
Greg Ward8ff5a3f2000-06-02 00:44:53 +000033 Setup scripts will almost never instantiate Distribution directly,
34 unless the 'setup()' function is totally inadequate to their needs.
35 However, it is conceivable that a setup script might wish to subclass
36 Distribution for some specialized purpose, and then pass the subclass
37 to 'setup()' as the 'distclass' keyword argument. If so, it is
38 necessary to respect the expectations that 'setup' has of Distribution.
39 See the code for 'setup()', in core.py, for details.
40 """
Greg Wardfe6462c2000-04-04 01:40:52 +000041
42
43 # 'global_options' describes the command-line options that may be
Greg Ward82715e12000-04-21 02:28:14 +000044 # supplied to the setup script prior to any actual commands.
45 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
Greg Wardfe6462c2000-04-04 01:40:52 +000046 # these global options. This list should be kept to a bare minimum,
47 # since every global option is also valid as a command option -- and we
48 # don't want to pollute the commands with too many options that they
49 # have minimal control over.
Greg Wardd5d8a992000-05-23 01:42:17 +000050 global_options = [('verbose', 'v', "run verbosely (default)"),
51 ('quiet', 'q', "run quietly (turns verbosity off)"),
52 ('dry-run', 'n', "don't actually do anything"),
53 ('help', 'h', "show detailed help message"),
Greg Wardfe6462c2000-04-04 01:40:52 +000054 ]
Greg Ward82715e12000-04-21 02:28:14 +000055
56 # options that are not propagated to the commands
57 display_options = [
58 ('help-commands', None,
59 "list all available commands"),
60 ('name', None,
61 "print package name"),
62 ('version', 'V',
63 "print package version"),
64 ('fullname', None,
65 "print <package name>-<version>"),
66 ('author', None,
67 "print the author's name"),
68 ('author-email', None,
69 "print the author's email address"),
70 ('maintainer', None,
71 "print the maintainer's name"),
72 ('maintainer-email', None,
73 "print the maintainer's email address"),
74 ('contact', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000075 "print the maintainer's name if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000076 ('contact-email', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000077 "print the maintainer's email address if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000078 ('url', None,
79 "print the URL for this package"),
80 ('licence', None,
81 "print the licence of the package"),
82 ('license', None,
83 "alias for --licence"),
84 ('description', None,
85 "print the package description"),
Greg Warde5a584e2000-04-26 02:26:55 +000086 ('long-description', None,
87 "print the long package description"),
Greg Ward82715e12000-04-21 02:28:14 +000088 ]
Greg Ward2f2b6c62000-09-25 01:58:07 +000089 display_option_names = map(lambda x: translate_longopt(x[0]),
90 display_options)
Greg Ward82715e12000-04-21 02:28:14 +000091
92 # negative options are options that exclude other options
Greg Wardfe6462c2000-04-04 01:40:52 +000093 negative_opt = {'quiet': 'verbose'}
94
95
96 # -- Creation/initialization methods -------------------------------
97
98 def __init__ (self, attrs=None):
99 """Construct a new Distribution instance: initialize all the
Greg Ward8ff5a3f2000-06-02 00:44:53 +0000100 attributes of a Distribution, and then use 'attrs' (a dictionary
101 mapping attribute names to values) to assign some of those
102 attributes their "real" values. (Any attributes not mentioned in
103 'attrs' will be assigned to some null value: 0, None, an empty list
104 or dictionary, etc.) Most importantly, initialize the
105 'command_obj' attribute to the empty dictionary; this will be
106 filled in with real command objects by 'parse_command_line()'.
107 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000108
109 # Default values for our command-line options
110 self.verbose = 1
111 self.dry_run = 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000112 self.help = 0
Greg Ward82715e12000-04-21 02:28:14 +0000113 for attr in self.display_option_names:
114 setattr(self, attr, 0)
Greg Wardfe6462c2000-04-04 01:40:52 +0000115
Greg Ward82715e12000-04-21 02:28:14 +0000116 # Store the distribution meta-data (name, version, author, and so
117 # forth) in a separate object -- we're getting to have enough
118 # information here (and enough command-line options) that it's
119 # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
120 # object in a sneaky and underhanded (but efficient!) way.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000121 self.metadata = DistributionMetadata()
Greg Ward4982f982000-04-22 02:52:44 +0000122 method_basenames = dir(self.metadata) + \
123 ['fullname', 'contact', 'contact_email']
124 for basename in method_basenames:
125 method_name = "get_" + basename
126 setattr(self, method_name, getattr(self.metadata, method_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000127
128 # 'cmdclass' maps command names to class objects, so we
129 # can 1) quickly figure out which class to instantiate when
130 # we need to create a new command object, and 2) have a way
Greg Ward82715e12000-04-21 02:28:14 +0000131 # for the setup script to override command classes
Greg Wardfe6462c2000-04-04 01:40:52 +0000132 self.cmdclass = {}
133
Greg Ward9821bf42000-08-29 01:15:18 +0000134 # 'script_name' and 'script_args' are usually set to sys.argv[0]
135 # and sys.argv[1:], but they can be overridden when the caller is
136 # not necessarily a setup script run from the command-line.
137 self.script_name = None
138 self.script_args = None
139
Greg Wardd5d8a992000-05-23 01:42:17 +0000140 # 'command_options' is where we store command options between
141 # parsing them (from config files, the command-line, etc.) and when
142 # they are actually needed -- ie. when the command in question is
143 # instantiated. It is a dictionary of dictionaries of 2-tuples:
144 # command_options = { command_name : { option : (source, value) } }
Gregory P. Smith14263542000-05-12 00:41:33 +0000145 self.command_options = {}
146
Greg Wardfe6462c2000-04-04 01:40:52 +0000147 # These options are really the business of various commands, rather
148 # than of the Distribution itself. We provide aliases for them in
149 # Distribution as a convenience to the developer.
Greg Wardfe6462c2000-04-04 01:40:52 +0000150 self.packages = None
151 self.package_dir = None
152 self.py_modules = None
153 self.libraries = None
Greg Ward51def7d2000-05-27 01:36:14 +0000154 self.headers = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000155 self.ext_modules = None
156 self.ext_package = None
157 self.include_dirs = None
158 self.extra_path = None
Gregory P. Smithb2e3bb32000-05-12 00:52:23 +0000159 self.scripts = None
Gregory P. Smith6a901dd2000-05-13 03:09:50 +0000160 self.data_files = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000161
162 # And now initialize bookkeeping stuff that can't be supplied by
163 # the caller at all. 'command_obj' maps command names to
164 # Command instances -- that's how we enforce that every command
165 # class is a singleton.
166 self.command_obj = {}
167
168 # 'have_run' maps command names to boolean values; it keeps track
169 # of whether we have actually run a particular command, to make it
170 # cheap to "run" a command whenever we think we might need to -- if
171 # it's already been done, no need for expensive filesystem
172 # operations, we just check the 'have_run' dictionary and carry on.
173 # It's only safe to query 'have_run' for a command class that has
174 # been instantiated -- a false value will be inserted when the
Greg Wardf6fc8752000-11-11 02:47:11 +0000175 if sys.platform == 'mac':
176 import EasyDialogs
177 cmdlist = self.get_command_list()
178 self.script_args = EasyDialogs.GetArgv(
179 self.global_options + self.display_options, cmdlist)
180
Greg Wardfe6462c2000-04-04 01:40:52 +0000181 # command object is created, and replaced with a true value when
Greg Ward612eb9f2000-07-27 02:13:20 +0000182 # the command is successfully run. Thus it's probably best to use
Greg Wardfe6462c2000-04-04 01:40:52 +0000183 # '.get()' rather than a straight lookup.
184 self.have_run = {}
185
186 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000187 # the setup script) to possibly override any or all of these
188 # distribution options.
189
Greg Wardfe6462c2000-04-04 01:40:52 +0000190 if attrs:
191
192 # Pull out the set of command options and work on them
193 # specifically. Note that this order guarantees that aliased
194 # command options will override any supplied redundantly
195 # through the general options dictionary.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000196 options = attrs.get('options')
Greg Wardfe6462c2000-04-04 01:40:52 +0000197 if options:
198 del attrs['options']
199 for (command, cmd_options) in options.items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000200 opt_dict = self.get_option_dict(command)
201 for (opt, val) in cmd_options.items():
202 opt_dict[opt] = ("setup script", val)
Greg Wardfe6462c2000-04-04 01:40:52 +0000203
204 # Now work on the rest of the attributes. Any attribute that's
205 # not already defined is invalid!
206 for (key,val) in attrs.items():
Greg Wardfd7b91e2000-09-26 01:52:25 +0000207 if hasattr(self.metadata, key):
208 setattr(self.metadata, key, val)
209 elif hasattr(self, key):
210 setattr(self, key, val)
Greg Wardfe6462c2000-04-04 01:40:52 +0000211 else:
Greg Ward02a1a2b2000-04-15 22:15:07 +0000212 raise DistutilsSetupError, \
Greg Wardfe6462c2000-04-04 01:40:52 +0000213 "invalid distribution option '%s'" % key
214
215 # __init__ ()
216
217
Greg Ward0e48cfd2000-05-26 01:00:15 +0000218 def get_option_dict (self, command):
219 """Get the option dictionary for a given command. If that
220 command's option dictionary hasn't been created yet, then create it
221 and return the new dictionary; otherwise, return the existing
222 option dictionary.
223 """
224
225 dict = self.command_options.get(command)
226 if dict is None:
227 dict = self.command_options[command] = {}
228 return dict
229
230
Greg Wardc32d9a62000-05-28 23:53:06 +0000231 def dump_option_dicts (self, header=None, commands=None, indent=""):
232 from pprint import pformat
233
234 if commands is None: # dump all command option dicts
235 commands = self.command_options.keys()
236 commands.sort()
237
238 if header is not None:
239 print indent + header
240 indent = indent + " "
241
242 if not commands:
243 print indent + "no commands known yet"
244 return
245
246 for cmd_name in commands:
247 opt_dict = self.command_options.get(cmd_name)
248 if opt_dict is None:
249 print indent + "no option dict for '%s' command" % cmd_name
250 else:
251 print indent + "option dict for '%s' command:" % cmd_name
252 out = pformat(opt_dict)
253 for line in string.split(out, "\n"):
254 print indent + " " + line
255
256 # dump_option_dicts ()
257
258
259
Greg Wardd5d8a992000-05-23 01:42:17 +0000260 # -- Config file finding/parsing methods ---------------------------
261
Gregory P. Smith14263542000-05-12 00:41:33 +0000262 def find_config_files (self):
263 """Find as many configuration files as should be processed for this
264 platform, and return a list of filenames in the order in which they
265 should be parsed. The filenames returned are guaranteed to exist
266 (modulo nasty race conditions).
267
268 On Unix, there are three possible config files: pydistutils.cfg in
269 the Distutils installation directory (ie. where the top-level
270 Distutils __inst__.py file lives), .pydistutils.cfg in the user's
271 home directory, and setup.cfg in the current directory.
272
273 On Windows and Mac OS, there are two possible config files:
274 pydistutils.cfg in the Python installation directory (sys.prefix)
Greg Wardd5d8a992000-05-23 01:42:17 +0000275 and setup.cfg in the current directory.
276 """
Gregory P. Smith14263542000-05-12 00:41:33 +0000277 files = []
Greg Wardacf3f6a2000-06-07 02:26:19 +0000278 check_environ()
Gregory P. Smith14263542000-05-12 00:41:33 +0000279
Greg Ward11696872000-06-07 02:29:03 +0000280 # Where to look for the system-wide Distutils config file
281 sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
282
283 # Look for the system config file
284 sys_file = os.path.join(sys_dir, "distutils.cfg")
Greg Wardacf3f6a2000-06-07 02:26:19 +0000285 if os.path.isfile(sys_file):
286 files.append(sys_file)
Gregory P. Smith14263542000-05-12 00:41:33 +0000287
Greg Ward11696872000-06-07 02:29:03 +0000288 # What to call the per-user config file
289 if os.name == 'posix':
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000290 user_filename = ".pydistutils.cfg"
291 else:
292 user_filename = "pydistutils.cfg"
Greg Wardfa9ff762000-10-14 04:06:40 +0000293
Greg Ward11696872000-06-07 02:29:03 +0000294 # And look for the user config file
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000295 if os.environ.has_key('HOME'):
296 user_file = os.path.join(os.environ.get('HOME'), user_filename)
Gregory P. Smith14263542000-05-12 00:41:33 +0000297 if os.path.isfile(user_file):
298 files.append(user_file)
299
Gregory P. Smith14263542000-05-12 00:41:33 +0000300 # All platforms support local setup.cfg
301 local_file = "setup.cfg"
302 if os.path.isfile(local_file):
303 files.append(local_file)
304
305 return files
306
307 # find_config_files ()
308
309
310 def parse_config_files (self, filenames=None):
311
312 from ConfigParser import ConfigParser
Greg Ward2bd3f422000-06-02 01:59:33 +0000313 from distutils.core import DEBUG
Gregory P. Smith14263542000-05-12 00:41:33 +0000314
315 if filenames is None:
316 filenames = self.find_config_files()
317
Greg Ward2bd3f422000-06-02 01:59:33 +0000318 if DEBUG: print "Distribution.parse_config_files():"
Greg Ward47460772000-05-23 03:47:35 +0000319
Gregory P. Smith14263542000-05-12 00:41:33 +0000320 parser = ConfigParser()
Greg Wardd5d8a992000-05-23 01:42:17 +0000321 for filename in filenames:
Greg Ward2bd3f422000-06-02 01:59:33 +0000322 if DEBUG: print " reading", filename
Greg Wardd5d8a992000-05-23 01:42:17 +0000323 parser.read(filename)
324 for section in parser.sections():
325 options = parser.options(section)
Greg Ward0e48cfd2000-05-26 01:00:15 +0000326 opt_dict = self.get_option_dict(section)
Gregory P. Smith14263542000-05-12 00:41:33 +0000327
Greg Wardd5d8a992000-05-23 01:42:17 +0000328 for opt in options:
329 if opt != '__name__':
Greg Wardceb9e222000-09-25 01:23:52 +0000330 val = parser.get(section,opt)
331 opt = string.replace(opt, '-', '_')
332 opt_dict[opt] = (filename, val)
Gregory P. Smith14263542000-05-12 00:41:33 +0000333
Greg Ward47460772000-05-23 03:47:35 +0000334 # Make the ConfigParser forget everything (so we retain
335 # the original filenames that options come from) -- gag,
336 # retch, puke -- another good reason for a distutils-
337 # specific config parser (sigh...)
338 parser.__init__()
Gregory P. Smith14263542000-05-12 00:41:33 +0000339
Greg Wardceb9e222000-09-25 01:23:52 +0000340 # If there was a "global" section in the config file, use it
341 # to set Distribution options.
342
343 if self.command_options.has_key('global'):
344 for (opt, (src, val)) in self.command_options['global'].items():
345 alias = self.negative_opt.get(opt)
346 try:
347 if alias:
348 setattr(self, alias, not strtobool(val))
349 elif opt in ('verbose', 'dry_run'): # ugh!
350 setattr(self, opt, strtobool(val))
351 except ValueError, msg:
352 raise DistutilsOptionError, msg
353
354 # parse_config_files ()
355
Gregory P. Smith14263542000-05-12 00:41:33 +0000356
Greg Wardd5d8a992000-05-23 01:42:17 +0000357 # -- Command-line parsing methods ----------------------------------
358
Greg Ward9821bf42000-08-29 01:15:18 +0000359 def parse_command_line (self):
360 """Parse the setup script's command line, taken from the
361 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
362 -- see 'setup()' in core.py). This list is first processed for
363 "global options" -- options that set attributes of the Distribution
364 instance. Then, it is alternately scanned for Distutils commands
365 and options for that command. Each new command terminates the
366 options for the previous command. The allowed options for a
367 command are determined by the 'user_options' attribute of the
368 command class -- thus, we have to be able to load command classes
369 in order to parse the command line. Any error in that 'options'
370 attribute raises DistutilsGetoptError; any error on the
371 command-line raises DistutilsArgError. If no Distutils commands
372 were found on the command line, raises DistutilsArgError. Return
Greg Wardceb9e222000-09-25 01:23:52 +0000373 true if command-line was successfully parsed and we should carry
Greg Ward9821bf42000-08-29 01:15:18 +0000374 on with executing commands; false if no errors but we shouldn't
375 execute commands (currently, this only happens if user asks for
376 help).
Greg Wardd5d8a992000-05-23 01:42:17 +0000377 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000378 # We have to parse the command line a bit at a time -- global
379 # options, then the first command, then its options, and so on --
380 # because each command will be handled by a different class, and
Greg Wardd5d8a992000-05-23 01:42:17 +0000381 # the options that are valid for a particular class aren't known
382 # until we have loaded the command class, which doesn't happen
383 # until we know what the command is.
Greg Wardfe6462c2000-04-04 01:40:52 +0000384
385 self.commands = []
Greg Wardfd7b91e2000-09-26 01:52:25 +0000386 parser = FancyGetopt(self.global_options + self.display_options)
387 parser.set_negative_aliases(self.negative_opt)
388 parser.set_aliases({'license': 'licence'})
389 args = parser.getopt(args=self.script_args, object=self)
Greg Ward82715e12000-04-21 02:28:14 +0000390 option_order = parser.get_option_order()
Greg Wardfe6462c2000-04-04 01:40:52 +0000391
Greg Ward82715e12000-04-21 02:28:14 +0000392 # for display options we return immediately
393 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000394 return
395
396 while args:
Greg Wardd5d8a992000-05-23 01:42:17 +0000397 args = self._parse_command_opts(parser, args)
398 if args is None: # user asked for help (and got it)
Greg Wardfe6462c2000-04-04 01:40:52 +0000399 return
Greg Wardfe6462c2000-04-04 01:40:52 +0000400
Greg Wardd5d8a992000-05-23 01:42:17 +0000401 # Handle the cases of --help as a "global" option, ie.
402 # "setup.py --help" and "setup.py --help command ...". For the
403 # former, we show global options (--verbose, --dry-run, etc.)
404 # and display-only options (--name, --version, etc.); for the
405 # latter, we omit the display-only options and show help for
406 # each command listed on the command line.
Greg Wardfe6462c2000-04-04 01:40:52 +0000407 if self.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000408 self._show_help(parser,
409 display_options=len(self.commands) == 0,
410 commands=self.commands)
Greg Wardfe6462c2000-04-04 01:40:52 +0000411 return
412
413 # Oops, no commands found -- an end-user error
414 if not self.commands:
415 raise DistutilsArgError, "no commands supplied"
416
417 # All is well: return true
418 return 1
419
420 # parse_command_line()
421
Greg Wardd5d8a992000-05-23 01:42:17 +0000422 def _parse_command_opts (self, parser, args):
Greg Wardd5d8a992000-05-23 01:42:17 +0000423 """Parse the command-line options for a single command.
424 'parser' must be a FancyGetopt instance; 'args' must be the list
425 of arguments, starting with the current command (whose options
426 we are about to parse). Returns a new version of 'args' with
427 the next command at the front of the list; will be the empty
428 list if there are no more commands on the command line. Returns
429 None if the user asked for help on this command.
430 """
431 # late import because of mutual dependence between these modules
432 from distutils.cmd import Command
433
434 # Pull the current command from the head of the command line
435 command = args[0]
Greg Wardfd7b91e2000-09-26 01:52:25 +0000436 if not command_re.match(command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000437 raise SystemExit, "invalid command name '%s'" % command
Greg Wardfd7b91e2000-09-26 01:52:25 +0000438 self.commands.append(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000439
440 # Dig up the command class that implements this command, so we
441 # 1) know that it's a valid command, and 2) know which options
442 # it takes.
443 try:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000444 cmd_class = self.get_command_class(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000445 except DistutilsModuleError, msg:
446 raise DistutilsArgError, msg
447
448 # Require that the command class be derived from Command -- want
449 # to be sure that the basic "command" interface is implemented.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000450 if not issubclass(cmd_class, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000451 raise DistutilsClassError, \
452 "command class %s must subclass Command" % cmd_class
453
454 # Also make sure that the command object provides a list of its
455 # known options.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000456 if not (hasattr(cmd_class, 'user_options') and
457 type(cmd_class.user_options) is ListType):
Greg Wardd5d8a992000-05-23 01:42:17 +0000458 raise DistutilsClassError, \
459 ("command class %s must provide " +
460 "'user_options' attribute (a list of tuples)") % \
461 cmd_class
462
463 # If the command class has a list of negative alias options,
464 # merge it in with the global negative aliases.
465 negative_opt = self.negative_opt
Greg Wardfd7b91e2000-09-26 01:52:25 +0000466 if hasattr(cmd_class, 'negative_opt'):
467 negative_opt = copy(negative_opt)
468 negative_opt.update(cmd_class.negative_opt)
Greg Wardd5d8a992000-05-23 01:42:17 +0000469
Greg Wardfa9ff762000-10-14 04:06:40 +0000470 # Check for help_options in command class. They have a different
471 # format (tuple of four) so we need to preprocess them here.
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000472 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000473 type(cmd_class.help_options) is ListType):
Greg Ward2ff78872000-06-24 00:23:20 +0000474 help_options = fix_help_options(cmd_class.help_options)
475 else:
Greg Ward55fced32000-06-24 01:22:41 +0000476 help_options = []
Greg Ward2ff78872000-06-24 00:23:20 +0000477
Greg Ward9d17a7a2000-06-07 03:00:06 +0000478
Greg Wardd5d8a992000-05-23 01:42:17 +0000479 # All commands support the global options too, just by adding
480 # in 'global_options'.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000481 parser.set_option_table(self.global_options +
482 cmd_class.user_options +
483 help_options)
484 parser.set_negative_aliases(negative_opt)
485 (args, opts) = parser.getopt(args[1:])
Greg Ward47460772000-05-23 03:47:35 +0000486 if hasattr(opts, 'help') and opts.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000487 self._show_help(parser, display_options=0, commands=[cmd_class])
488 return
489
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000490 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000491 type(cmd_class.help_options) is ListType):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000492 help_option_found=0
493 for (help_option, short, desc, func) in cmd_class.help_options:
494 if hasattr(opts, parser.get_attr_name(help_option)):
495 help_option_found=1
Greg Wardfa9ff762000-10-14 04:06:40 +0000496 #print "showing help for option %s of command %s" % \
Greg Ward2ff78872000-06-24 00:23:20 +0000497 # (help_option[0],cmd_class)
Greg Ward55fced32000-06-24 01:22:41 +0000498
499 if callable(func):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000500 func()
Greg Ward55fced32000-06-24 01:22:41 +0000501 else:
502 raise DistutilsClassError, \
503 ("invalid help function %s for help option '%s': "
504 "must be a callable object (function, etc.)") % \
505 (`func`, help_option)
506
507 if help_option_found:
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000508 return
Greg Ward9d17a7a2000-06-07 03:00:06 +0000509
Greg Wardd5d8a992000-05-23 01:42:17 +0000510 # Put the options from the command-line into their official
511 # holding pen, the 'command_options' dictionary.
Greg Ward0e48cfd2000-05-26 01:00:15 +0000512 opt_dict = self.get_option_dict(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000513 for (name, value) in vars(opts).items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000514 opt_dict[name] = ("command line", value)
Greg Wardd5d8a992000-05-23 01:42:17 +0000515
516 return args
517
518 # _parse_command_opts ()
519
520
521 def _show_help (self,
522 parser,
523 global_options=1,
524 display_options=1,
525 commands=[]):
526 """Show help for the setup script command-line in the form of
527 several lists of command-line options. 'parser' should be a
528 FancyGetopt instance; do not expect it to be returned in the
529 same state, as its option table will be reset to make it
530 generate the correct help text.
531
532 If 'global_options' is true, lists the global options:
533 --verbose, --dry-run, etc. If 'display_options' is true, lists
534 the "display-only" options: --name, --version, etc. Finally,
535 lists per-command help for every command name or command class
536 in 'commands'.
537 """
538 # late import because of mutual dependence between these modules
Greg Ward9821bf42000-08-29 01:15:18 +0000539 from distutils.core import gen_usage
Greg Wardd5d8a992000-05-23 01:42:17 +0000540 from distutils.cmd import Command
541
542 if global_options:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000543 parser.set_option_table(self.global_options)
544 parser.print_help("Global options:")
Greg Wardd5d8a992000-05-23 01:42:17 +0000545 print
546
547 if display_options:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000548 parser.set_option_table(self.display_options)
549 parser.print_help(
Greg Wardd5d8a992000-05-23 01:42:17 +0000550 "Information display options (just display " +
551 "information, ignore any commands)")
552 print
553
554 for command in self.commands:
555 if type(command) is ClassType and issubclass(klass, Command):
556 klass = command
557 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000558 klass = self.get_command_class(command)
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000559 if (hasattr(klass, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000560 type(klass.help_options) is ListType):
561 parser.set_option_table(klass.user_options +
562 fix_help_options(klass.help_options))
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000563 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000564 parser.set_option_table(klass.user_options)
565 parser.print_help("Options for '%s' command:" % klass.__name__)
Greg Wardd5d8a992000-05-23 01:42:17 +0000566 print
567
Greg Ward9821bf42000-08-29 01:15:18 +0000568 print gen_usage(self.script_name)
Greg Wardd5d8a992000-05-23 01:42:17 +0000569 return
570
571 # _show_help ()
Greg Wardfa9ff762000-10-14 04:06:40 +0000572
Greg Wardd5d8a992000-05-23 01:42:17 +0000573
Greg Ward82715e12000-04-21 02:28:14 +0000574 def handle_display_options (self, option_order):
575 """If there were any non-global "display-only" options
Greg Wardd5d8a992000-05-23 01:42:17 +0000576 (--help-commands or the metadata display options) on the command
577 line, display the requested info and return true; else return
578 false.
579 """
Greg Ward9821bf42000-08-29 01:15:18 +0000580 from distutils.core import gen_usage
Greg Ward82715e12000-04-21 02:28:14 +0000581
582 # User just wants a list of commands -- we'll print it out and stop
583 # processing now (ie. if they ran "setup --help-commands foo bar",
584 # we ignore "foo bar").
585 if self.help_commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000586 self.print_commands()
Greg Ward82715e12000-04-21 02:28:14 +0000587 print
Greg Ward9821bf42000-08-29 01:15:18 +0000588 print gen_usage(self.script_name)
Greg Ward82715e12000-04-21 02:28:14 +0000589 return 1
590
591 # If user supplied any of the "display metadata" options, then
592 # display that metadata in the order in which the user supplied the
593 # metadata options.
594 any_display_options = 0
595 is_display_option = {}
596 for option in self.display_options:
597 is_display_option[option[0]] = 1
598
599 for (opt, val) in option_order:
600 if val and is_display_option.get(opt):
Greg Ward2f2b6c62000-09-25 01:58:07 +0000601 opt = translate_longopt(opt)
Greg Ward82715e12000-04-21 02:28:14 +0000602 print getattr(self.metadata, "get_"+opt)()
603 any_display_options = 1
604
605 return any_display_options
606
607 # handle_display_options()
Greg Wardfe6462c2000-04-04 01:40:52 +0000608
609 def print_command_list (self, commands, header, max_length):
610 """Print a subset of the list of all commands -- used by
Greg Wardd5d8a992000-05-23 01:42:17 +0000611 'print_commands()'.
612 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000613
614 print header + ":"
615
616 for cmd in commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000617 klass = self.cmdclass.get(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000618 if not klass:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000619 klass = self.get_command_class(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000620 try:
621 description = klass.description
622 except AttributeError:
623 description = "(no description available)"
624
625 print " %-*s %s" % (max_length, cmd, description)
626
627 # print_command_list ()
628
629
630 def print_commands (self):
Greg Wardd5d8a992000-05-23 01:42:17 +0000631 """Print out a help message listing all available commands with a
632 description of each. The list is divided into "standard commands"
633 (listed in distutils.command.__all__) and "extra commands"
634 (mentioned in self.cmdclass, but not a standard command). The
635 descriptions come from the command class attribute
636 'description'.
637 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000638
639 import distutils.command
640 std_commands = distutils.command.__all__
641 is_std = {}
642 for cmd in std_commands:
643 is_std[cmd] = 1
644
645 extra_commands = []
646 for cmd in self.cmdclass.keys():
647 if not is_std.get(cmd):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000648 extra_commands.append(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000649
650 max_length = 0
651 for cmd in (std_commands + extra_commands):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000652 if len(cmd) > max_length:
653 max_length = len(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000654
Greg Wardfd7b91e2000-09-26 01:52:25 +0000655 self.print_command_list(std_commands,
656 "Standard commands",
657 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000658 if extra_commands:
659 print
Greg Wardfd7b91e2000-09-26 01:52:25 +0000660 self.print_command_list(extra_commands,
661 "Extra commands",
662 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000663
664 # print_commands ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000665
Greg Wardf6fc8752000-11-11 02:47:11 +0000666 def get_command_list (self):
667 """Get a list of (command, description) tuples.
668 The list is divided into "standard commands" (listed in
669 distutils.command.__all__) and "extra commands" (mentioned in
670 self.cmdclass, but not a standard command). The descriptions come
671 from the command class attribute 'description'.
672 """
673 # Currently this is only used on Mac OS, for the Mac-only GUI
674 # Distutils interface (by Jack Jansen)
675
676 import distutils.command
677 std_commands = distutils.command.__all__
678 is_std = {}
679 for cmd in std_commands:
680 is_std[cmd] = 1
681
682 extra_commands = []
683 for cmd in self.cmdclass.keys():
684 if not is_std.get(cmd):
685 extra_commands.append(cmd)
686
687 rv = []
688 for cmd in (std_commands + extra_commands):
689 klass = self.cmdclass.get(cmd)
690 if not klass:
691 klass = self.get_command_class(cmd)
692 try:
693 description = klass.description
694 except AttributeError:
695 description = "(no description available)"
696 rv.append((cmd, description))
697 return rv
Greg Wardfe6462c2000-04-04 01:40:52 +0000698
699 # -- Command class/object methods ----------------------------------
700
Greg Wardd5d8a992000-05-23 01:42:17 +0000701 def get_command_class (self, command):
702 """Return the class that implements the Distutils command named by
703 'command'. First we check the 'cmdclass' dictionary; if the
704 command is mentioned there, we fetch the class object from the
705 dictionary and return it. Otherwise we load the command module
706 ("distutils.command." + command) and fetch the command class from
707 the module. The loaded class is also stored in 'cmdclass'
708 to speed future calls to 'get_command_class()'.
Greg Wardfe6462c2000-04-04 01:40:52 +0000709
Gregory P. Smith14263542000-05-12 00:41:33 +0000710 Raises DistutilsModuleError if the expected module could not be
Greg Wardd5d8a992000-05-23 01:42:17 +0000711 found, or if that module does not define the expected class.
712 """
713 klass = self.cmdclass.get(command)
714 if klass:
715 return klass
Greg Wardfe6462c2000-04-04 01:40:52 +0000716
717 module_name = 'distutils.command.' + command
718 klass_name = command
719
720 try:
721 __import__ (module_name)
722 module = sys.modules[module_name]
723 except ImportError:
724 raise DistutilsModuleError, \
725 "invalid command '%s' (no module named '%s')" % \
726 (command, module_name)
727
728 try:
Greg Wardd5d8a992000-05-23 01:42:17 +0000729 klass = getattr(module, klass_name)
730 except AttributeError:
Greg Wardfe6462c2000-04-04 01:40:52 +0000731 raise DistutilsModuleError, \
732 "invalid command '%s' (no class '%s' in module '%s')" \
733 % (command, klass_name, module_name)
734
Greg Wardd5d8a992000-05-23 01:42:17 +0000735 self.cmdclass[command] = klass
Greg Wardfe6462c2000-04-04 01:40:52 +0000736 return klass
737
Greg Wardd5d8a992000-05-23 01:42:17 +0000738 # get_command_class ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000739
Greg Wardd5d8a992000-05-23 01:42:17 +0000740 def get_command_obj (self, command, create=1):
741 """Return the command object for 'command'. Normally this object
Greg Ward612eb9f2000-07-27 02:13:20 +0000742 is cached on a previous call to 'get_command_obj()'; if no command
Greg Wardd5d8a992000-05-23 01:42:17 +0000743 object for 'command' is in the cache, then we either create and
744 return it (if 'create' is true) or return None.
745 """
Greg Ward2bd3f422000-06-02 01:59:33 +0000746 from distutils.core import DEBUG
Greg Wardd5d8a992000-05-23 01:42:17 +0000747 cmd_obj = self.command_obj.get(command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000748 if not cmd_obj and create:
Greg Ward2bd3f422000-06-02 01:59:33 +0000749 if DEBUG:
750 print "Distribution.get_command_obj(): " \
751 "creating '%s' command object" % command
Greg Ward47460772000-05-23 03:47:35 +0000752
Greg Wardd5d8a992000-05-23 01:42:17 +0000753 klass = self.get_command_class(command)
Greg Ward47460772000-05-23 03:47:35 +0000754 cmd_obj = self.command_obj[command] = klass(self)
755 self.have_run[command] = 0
756
757 # Set any options that were supplied in config files
758 # or on the command line. (NB. support for error
759 # reporting is lame here: any errors aren't reported
760 # until 'finalize_options()' is called, which means
761 # we won't report the source of the error.)
762 options = self.command_options.get(command)
763 if options:
Greg Wardc32d9a62000-05-28 23:53:06 +0000764 self._set_command_options(cmd_obj, options)
Greg Wardfe6462c2000-04-04 01:40:52 +0000765
766 return cmd_obj
767
Greg Wardc32d9a62000-05-28 23:53:06 +0000768 def _set_command_options (self, command_obj, option_dict=None):
Greg Wardc32d9a62000-05-28 23:53:06 +0000769 """Set the options for 'command_obj' from 'option_dict'. Basically
770 this means copying elements of a dictionary ('option_dict') to
771 attributes of an instance ('command').
772
Greg Wardceb9e222000-09-25 01:23:52 +0000773 'command_obj' must be a Command instance. If 'option_dict' is not
Greg Wardc32d9a62000-05-28 23:53:06 +0000774 supplied, uses the standard option dictionary for this command
775 (from 'self.command_options').
776 """
777 from distutils.core import DEBUG
778
779 command_name = command_obj.get_command_name()
780 if option_dict is None:
781 option_dict = self.get_option_dict(command_name)
782
783 if DEBUG: print " setting options for '%s' command:" % command_name
784 for (option, (source, value)) in option_dict.items():
785 if DEBUG: print " %s = %s (from %s)" % (option, value, source)
Greg Wardceb9e222000-09-25 01:23:52 +0000786 try:
Greg Ward2f2b6c62000-09-25 01:58:07 +0000787 bool_opts = map(translate_longopt, command_obj.boolean_options)
Greg Wardceb9e222000-09-25 01:23:52 +0000788 except AttributeError:
789 bool_opts = []
790 try:
791 neg_opt = command_obj.negative_opt
792 except AttributeError:
793 neg_opt = {}
794
795 try:
Greg Ward2c08cf02000-09-27 00:15:37 +0000796 is_string = type(value) is StringType
797 if neg_opt.has_key(option) and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000798 setattr(command_obj, neg_opt[option], not strtobool(value))
Greg Ward2c08cf02000-09-27 00:15:37 +0000799 elif option in bool_opts and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000800 setattr(command_obj, option, strtobool(value))
801 elif hasattr(command_obj, option):
802 setattr(command_obj, option, value)
803 else:
804 raise DistutilsOptionError, \
805 ("error in %s: command '%s' has no such option '%s'"
806 % (source, command_name, option))
807 except ValueError, msg:
808 raise DistutilsOptionError, msg
Greg Wardc32d9a62000-05-28 23:53:06 +0000809
Greg Wardf449ea52000-09-16 15:23:28 +0000810 def reinitialize_command (self, command, reinit_subcommands=0):
Greg Wardc32d9a62000-05-28 23:53:06 +0000811 """Reinitializes a command to the state it was in when first
812 returned by 'get_command_obj()': ie., initialized but not yet
Greg Ward7d9c7052000-06-28 01:25:27 +0000813 finalized. This provides the opportunity to sneak option
Greg Wardc32d9a62000-05-28 23:53:06 +0000814 values in programmatically, overriding or supplementing
815 user-supplied values from the config files and command line.
816 You'll have to re-finalize the command object (by calling
817 'finalize_options()' or 'ensure_finalized()') before using it for
818 real.
819
Greg Wardf449ea52000-09-16 15:23:28 +0000820 'command' should be a command name (string) or command object. If
821 'reinit_subcommands' is true, also reinitializes the command's
822 sub-commands, as declared by the 'sub_commands' class attribute (if
823 it has one). See the "install" command for an example. Only
824 reinitializes the sub-commands that actually matter, ie. those
825 whose test predicates return true.
826
Greg Wardc32d9a62000-05-28 23:53:06 +0000827 Returns the reinitialized command object.
828 """
829 from distutils.cmd import Command
830 if not isinstance(command, Command):
831 command_name = command
832 command = self.get_command_obj(command_name)
833 else:
834 command_name = command.get_command_name()
835
836 if not command.finalized:
Greg Ward282c7a02000-06-01 01:09:47 +0000837 return command
Greg Wardc32d9a62000-05-28 23:53:06 +0000838 command.initialize_options()
839 command.finalized = 0
Greg Ward43955c92000-06-06 02:52:36 +0000840 self.have_run[command_name] = 0
Greg Wardc32d9a62000-05-28 23:53:06 +0000841 self._set_command_options(command)
Greg Wardf449ea52000-09-16 15:23:28 +0000842
Greg Wardf449ea52000-09-16 15:23:28 +0000843 if reinit_subcommands:
Greg Wardf449ea52000-09-16 15:23:28 +0000844 for sub in command.get_sub_commands():
845 self.reinitialize_command(sub, reinit_subcommands)
846
Greg Wardc32d9a62000-05-28 23:53:06 +0000847 return command
848
Greg Wardfe6462c2000-04-04 01:40:52 +0000849
850 # -- Methods that operate on the Distribution ----------------------
851
852 def announce (self, msg, level=1):
853 """Print 'msg' if 'level' is greater than or equal to the verbosity
Greg Wardd5d8a992000-05-23 01:42:17 +0000854 level recorded in the 'verbose' attribute (which, currently, can be
855 only 0 or 1).
856 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000857 if self.verbose >= level:
858 print msg
859
860
861 def run_commands (self):
Greg Ward82715e12000-04-21 02:28:14 +0000862 """Run each command that was seen on the setup script command line.
Greg Wardd5d8a992000-05-23 01:42:17 +0000863 Uses the list of commands found and cache of command objects
Greg Wardfd7b91e2000-09-26 01:52:25 +0000864 created by 'get_command_obj()'.
865 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000866 for cmd in self.commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000867 self.run_command(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000868
869
Greg Wardfe6462c2000-04-04 01:40:52 +0000870 # -- Methods that operate on its Commands --------------------------
871
872 def run_command (self, command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000873 """Do whatever it takes to run a command (including nothing at all,
Greg Wardd5d8a992000-05-23 01:42:17 +0000874 if the command has already been run). Specifically: if we have
875 already created and run the command named by 'command', return
876 silently without doing anything. If the command named by 'command'
877 doesn't even have a command object yet, create one. Then invoke
878 'run()' on that command object (or an existing one).
879 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000880 # Already been here, done that? then return silently.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000881 if self.have_run.get(command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000882 return
883
Greg Wardfd7b91e2000-09-26 01:52:25 +0000884 self.announce("running " + command)
885 cmd_obj = self.get_command_obj(command)
886 cmd_obj.ensure_finalized()
887 cmd_obj.run()
Greg Wardfe6462c2000-04-04 01:40:52 +0000888 self.have_run[command] = 1
889
890
Greg Wardfe6462c2000-04-04 01:40:52 +0000891 # -- Distribution query methods ------------------------------------
892
893 def has_pure_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000894 return len(self.packages or self.py_modules or []) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000895
896 def has_ext_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000897 return self.ext_modules and len(self.ext_modules) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000898
899 def has_c_libraries (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000900 return self.libraries and len(self.libraries) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000901
902 def has_modules (self):
903 return self.has_pure_modules() or self.has_ext_modules()
904
Greg Ward51def7d2000-05-27 01:36:14 +0000905 def has_headers (self):
906 return self.headers and len(self.headers) > 0
907
Greg Ward44a61bb2000-05-20 15:06:48 +0000908 def has_scripts (self):
909 return self.scripts and len(self.scripts) > 0
910
911 def has_data_files (self):
912 return self.data_files and len(self.data_files) > 0
913
Greg Wardfe6462c2000-04-04 01:40:52 +0000914 def is_pure (self):
915 return (self.has_pure_modules() and
916 not self.has_ext_modules() and
917 not self.has_c_libraries())
918
Greg Ward82715e12000-04-21 02:28:14 +0000919 # -- Metadata query methods ----------------------------------------
920
921 # If you're looking for 'get_name()', 'get_version()', and so forth,
922 # they are defined in a sneaky way: the constructor binds self.get_XXX
923 # to self.metadata.get_XXX. The actual code is in the
924 # DistributionMetadata class, below.
925
926# class Distribution
927
928
929class DistributionMetadata:
930 """Dummy class to hold the distribution meta-data: name, version,
Greg Wardfd7b91e2000-09-26 01:52:25 +0000931 author, and so forth.
932 """
Greg Ward82715e12000-04-21 02:28:14 +0000933
934 def __init__ (self):
935 self.name = None
936 self.version = None
937 self.author = None
938 self.author_email = None
939 self.maintainer = None
940 self.maintainer_email = None
941 self.url = None
942 self.licence = None
943 self.description = None
Greg Warde5a584e2000-04-26 02:26:55 +0000944 self.long_description = None
Greg Ward82715e12000-04-21 02:28:14 +0000945
946 # -- Metadata query methods ----------------------------------------
947
Greg Wardfe6462c2000-04-04 01:40:52 +0000948 def get_name (self):
949 return self.name or "UNKNOWN"
950
Greg Ward82715e12000-04-21 02:28:14 +0000951 def get_version(self):
952 return self.version or "???"
Greg Wardfe6462c2000-04-04 01:40:52 +0000953
Greg Ward82715e12000-04-21 02:28:14 +0000954 def get_fullname (self):
955 return "%s-%s" % (self.get_name(), self.get_version())
956
957 def get_author(self):
958 return self.author or "UNKNOWN"
959
960 def get_author_email(self):
961 return self.author_email or "UNKNOWN"
962
963 def get_maintainer(self):
964 return self.maintainer or "UNKNOWN"
965
966 def get_maintainer_email(self):
967 return self.maintainer_email or "UNKNOWN"
968
969 def get_contact(self):
970 return (self.maintainer or
971 self.author or
972 "UNKNOWN")
973
974 def get_contact_email(self):
975 return (self.maintainer_email or
976 self.author_email or
977 "UNKNOWN")
978
979 def get_url(self):
980 return self.url or "UNKNOWN"
981
982 def get_licence(self):
983 return self.licence or "UNKNOWN"
984
985 def get_description(self):
986 return self.description or "UNKNOWN"
Greg Warde5a584e2000-04-26 02:26:55 +0000987
988 def get_long_description(self):
989 return self.long_description or "UNKNOWN"
990
Greg Ward82715e12000-04-21 02:28:14 +0000991# class DistributionMetadata
Greg Wardfe6462c2000-04-04 01:40:52 +0000992
Greg Ward2ff78872000-06-24 00:23:20 +0000993
994def fix_help_options (options):
995 """Convert a 4-tuple 'help_options' list as found in various command
996 classes to the 3-tuple form required by FancyGetopt.
997 """
998 new_options = []
999 for help_tuple in options:
1000 new_options.append(help_tuple[0:3])
1001 return new_options
1002
1003
Greg Wardfe6462c2000-04-04 01:40:52 +00001004if __name__ == "__main__":
Greg Wardfd7b91e2000-09-26 01:52:25 +00001005 dist = Distribution()
Greg Wardfe6462c2000-04-04 01:40:52 +00001006 print "ok"