blob: 4a83c794ffc6da4fac4f253f0c1afa62e3075bd7 [file] [log] [blame]
Greg Wardfe6462c2000-04-04 01:40:52 +00001"""distutils.dist
2
3Provides the Distribution class, which represents the module distribution
4being built/installed/distributed."""
5
6# created 2000/04/03, Greg Ward
7# (extricated from core.py; actually dates back to the beginning)
8
9__revision__ = "$Id$"
10
11import sys, string, re
12from types import *
13from copy import copy
14from distutils.errors import *
Greg Ward82715e12000-04-21 02:28:14 +000015from distutils.fancy_getopt import FancyGetopt, longopt_xlate
Greg Wardfe6462c2000-04-04 01:40:52 +000016
17
18# Regex to define acceptable Distutils command names. This is not *quite*
19# the same as a Python NAME -- I don't allow leading underscores. The fact
20# that they're very similar is no coincidence; the default naming scheme is
21# to look for a Python module named after the command.
22command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
23
24
25class Distribution:
26 """The core of the Distutils. Most of the work hiding behind
27 'setup' is really done within a Distribution instance, which
28 farms the work out to the Distutils commands specified on the
29 command line.
30
31 Clients will almost never instantiate Distribution directly,
32 unless the 'setup' function is totally inadequate to their needs.
33 However, it is conceivable that a client might wish to subclass
34 Distribution for some specialized purpose, and then pass the
35 subclass to 'setup' as the 'distclass' keyword argument. If so,
36 it is necessary to respect the expectations that 'setup' has of
37 Distribution: it must have a constructor and methods
38 'parse_command_line()' and 'run_commands()' with signatures like
39 those described below."""
40
41
42 # 'global_options' describes the command-line options that may be
Greg Ward82715e12000-04-21 02:28:14 +000043 # supplied to the setup script prior to any actual commands.
44 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
Greg Wardfe6462c2000-04-04 01:40:52 +000045 # these global options. This list should be kept to a bare minimum,
46 # since every global option is also valid as a command option -- and we
47 # don't want to pollute the commands with too many options that they
48 # have minimal control over.
49 global_options = [('verbose', 'v',
50 "run verbosely (default)"),
51 ('quiet', 'q',
52 "run quietly (turns verbosity off)"),
53 ('dry-run', 'n',
54 "don't actually do anything"),
Greg Wardfe6462c2000-04-04 01:40:52 +000055 ('help', 'h',
Greg Ward82715e12000-04-21 02:28:14 +000056 "show this help message, plus help for any commands " +
57 "given on the command-line"),
Greg Wardfe6462c2000-04-04 01:40:52 +000058 ]
Greg Ward82715e12000-04-21 02:28:14 +000059
60 # options that are not propagated to the commands
61 display_options = [
62 ('help-commands', None,
63 "list all available commands"),
64 ('name', None,
65 "print package name"),
66 ('version', 'V',
67 "print package version"),
68 ('fullname', None,
69 "print <package name>-<version>"),
70 ('author', None,
71 "print the author's name"),
72 ('author-email', None,
73 "print the author's email address"),
74 ('maintainer', None,
75 "print the maintainer's name"),
76 ('maintainer-email', None,
77 "print the maintainer's email address"),
78 ('contact', None,
79 "print the name of the maintainer if present, "
80 "else author"),
81 ('contact-email', None,
82 "print the email of the maintainer if present, "
83 "else author"),
84 ('url', None,
85 "print the URL for this package"),
86 ('licence', None,
87 "print the licence of the package"),
88 ('license', None,
89 "alias for --licence"),
90 ('description', None,
91 "print the package description"),
92 ]
93 display_option_names = map(lambda x: string.translate(x[0], longopt_xlate),
94 display_options)
95
96 # negative options are options that exclude other options
Greg Wardfe6462c2000-04-04 01:40:52 +000097 negative_opt = {'quiet': 'verbose'}
98
99
100 # -- Creation/initialization methods -------------------------------
101
102 def __init__ (self, attrs=None):
103 """Construct a new Distribution instance: initialize all the
104 attributes of a Distribution, and then uses 'attrs' (a
105 dictionary mapping attribute names to values) to assign
106 some of those attributes their "real" values. (Any attributes
107 not mentioned in 'attrs' will be assigned to some null
108 value: 0, None, an empty list or dictionary, etc.) Most
109 importantly, initialize the 'command_obj' attribute
110 to the empty dictionary; this will be filled in with real
111 command objects by 'parse_command_line()'."""
112
113 # Default values for our command-line options
114 self.verbose = 1
115 self.dry_run = 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000116 self.help = 0
Greg Ward82715e12000-04-21 02:28:14 +0000117 for attr in self.display_option_names:
118 setattr(self, attr, 0)
Greg Wardfe6462c2000-04-04 01:40:52 +0000119
Greg Ward82715e12000-04-21 02:28:14 +0000120 # Store the distribution meta-data (name, version, author, and so
121 # forth) in a separate object -- we're getting to have enough
122 # information here (and enough command-line options) that it's
123 # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
124 # object in a sneaky and underhanded (but efficient!) way.
125 self.metadata = DistributionMetadata ()
Greg Ward4982f982000-04-22 02:52:44 +0000126 method_basenames = dir(self.metadata) + \
127 ['fullname', 'contact', 'contact_email']
128 for basename in method_basenames:
129 method_name = "get_" + basename
130 setattr(self, method_name, getattr(self.metadata, method_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000131
132 # 'cmdclass' maps command names to class objects, so we
133 # can 1) quickly figure out which class to instantiate when
134 # we need to create a new command object, and 2) have a way
Greg Ward82715e12000-04-21 02:28:14 +0000135 # for the setup script to override command classes
Greg Wardfe6462c2000-04-04 01:40:52 +0000136 self.cmdclass = {}
137
138 # These options are really the business of various commands, rather
139 # than of the Distribution itself. We provide aliases for them in
140 # Distribution as a convenience to the developer.
Greg Wardfe6462c2000-04-04 01:40:52 +0000141 self.packages = None
142 self.package_dir = None
143 self.py_modules = None
144 self.libraries = None
145 self.ext_modules = None
146 self.ext_package = None
147 self.include_dirs = None
148 self.extra_path = None
149
150 # And now initialize bookkeeping stuff that can't be supplied by
151 # the caller at all. 'command_obj' maps command names to
152 # Command instances -- that's how we enforce that every command
153 # class is a singleton.
154 self.command_obj = {}
155
156 # 'have_run' maps command names to boolean values; it keeps track
157 # of whether we have actually run a particular command, to make it
158 # cheap to "run" a command whenever we think we might need to -- if
159 # it's already been done, no need for expensive filesystem
160 # operations, we just check the 'have_run' dictionary and carry on.
161 # It's only safe to query 'have_run' for a command class that has
162 # been instantiated -- a false value will be inserted when the
163 # command object is created, and replaced with a true value when
164 # the command is succesfully run. Thus it's probably best to use
165 # '.get()' rather than a straight lookup.
166 self.have_run = {}
167
168 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000169 # the setup script) to possibly override any or all of these
170 # distribution options.
171
Greg Wardfe6462c2000-04-04 01:40:52 +0000172 if attrs:
173
174 # Pull out the set of command options and work on them
175 # specifically. Note that this order guarantees that aliased
176 # command options will override any supplied redundantly
177 # through the general options dictionary.
178 options = attrs.get ('options')
179 if options:
180 del attrs['options']
181 for (command, cmd_options) in options.items():
182 cmd_obj = self.find_command_obj (command)
183 for (key, val) in cmd_options.items():
184 cmd_obj.set_option (key, val)
185 # loop over commands
186 # if any command options
187
188 # Now work on the rest of the attributes. Any attribute that's
189 # not already defined is invalid!
190 for (key,val) in attrs.items():
Greg Ward82715e12000-04-21 02:28:14 +0000191 if hasattr (self.metadata, key):
192 setattr (self.metadata, key, val)
193 elif hasattr (self, key):
Greg Wardfe6462c2000-04-04 01:40:52 +0000194 setattr (self, key, val)
195 else:
Greg Ward02a1a2b2000-04-15 22:15:07 +0000196 raise DistutilsSetupError, \
Greg Wardfe6462c2000-04-04 01:40:52 +0000197 "invalid distribution option '%s'" % key
198
199 # __init__ ()
200
201
202 def parse_command_line (self, args):
203 """Parse the setup script's command line: set any Distribution
204 attributes tied to command-line options, create all command
205 objects, and set their options from the command-line. 'args'
206 must be a list of command-line arguments, most likely
207 'sys.argv[1:]' (see the 'setup()' function). This list is first
208 processed for "global options" -- options that set attributes of
209 the Distribution instance. Then, it is alternately scanned for
210 Distutils command and options for that command. Each new
211 command terminates the options for the previous command. The
212 allowed options for a command are determined by the 'options'
213 attribute of the command object -- thus, we instantiate (and
214 cache) every command object here, in order to access its
215 'options' attribute. Any error in that 'options' attribute
216 raises DistutilsGetoptError; any error on the command-line
217 raises DistutilsArgError. If no Distutils commands were found
218 on the command line, raises DistutilsArgError. Return true if
219 command-line successfully parsed and we should carry on with
220 executing commands; false if no errors but we shouldn't execute
221 commands (currently, this only happens if user asks for
222 help)."""
223
Greg Ward7d508fe2000-04-06 02:07:41 +0000224 # late import because of mutual dependence between these modules
Greg Wardfe6462c2000-04-04 01:40:52 +0000225 from distutils.cmd import Command
Greg Ward7d508fe2000-04-06 02:07:41 +0000226 from distutils.core import usage
Greg Wardfe6462c2000-04-04 01:40:52 +0000227
228 # We have to parse the command line a bit at a time -- global
229 # options, then the first command, then its options, and so on --
230 # because each command will be handled by a different class, and
231 # the options that are valid for a particular class aren't
232 # known until we instantiate the command class, which doesn't
233 # happen until we know what the command is.
234
235 self.commands = []
Greg Ward82715e12000-04-21 02:28:14 +0000236 parser = FancyGetopt (self.global_options + self.display_options)
237 parser.set_negative_aliases (self.negative_opt)
Greg Ward58ec6ed2000-04-21 04:22:49 +0000238 parser.set_aliases ({'license': 'licence'})
Greg Ward82715e12000-04-21 02:28:14 +0000239 args = parser.getopt (object=self)
240 option_order = parser.get_option_order()
Greg Wardfe6462c2000-04-04 01:40:52 +0000241
Greg Ward82715e12000-04-21 02:28:14 +0000242 # for display options we return immediately
243 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000244 return
245
246 while args:
247 # Pull the current command from the head of the command line
248 command = args[0]
249 if not command_re.match (command):
250 raise SystemExit, "invalid command name '%s'" % command
251 self.commands.append (command)
252
253 # Make sure we have a command object to put the options into
254 # (this either pulls it out of a cache of command objects,
255 # or finds and instantiates the command class).
256 try:
257 cmd_obj = self.find_command_obj (command)
258 except DistutilsModuleError, msg:
259 raise DistutilsArgError, msg
260
261 # Require that the command class be derived from Command --
262 # that way, we can be sure that we at least have the 'run'
263 # and 'get_option' methods.
264 if not isinstance (cmd_obj, Command):
265 raise DistutilsClassError, \
266 "command class %s must subclass Command" % \
267 cmd_obj.__class__
268
269 # Also make sure that the command object provides a list of its
270 # known options
271 if not (hasattr (cmd_obj, 'user_options') and
272 type (cmd_obj.user_options) is ListType):
273 raise DistutilsClassError, \
274 ("command class %s must provide " +
275 "'user_options' attribute (a list of tuples)") % \
276 cmd_obj.__class__
277
278 # Poof! like magic, all commands support the global
279 # options too, just by adding in 'global_options'.
280 negative_opt = self.negative_opt
281 if hasattr (cmd_obj, 'negative_opt'):
282 negative_opt = copy (negative_opt)
283 negative_opt.update (cmd_obj.negative_opt)
284
Greg Ward82715e12000-04-21 02:28:14 +0000285 parser.set_option_table (self.global_options +
286 cmd_obj.user_options)
287 parser.set_negative_aliases (negative_opt)
288 args = parser.getopt (args[1:], cmd_obj)
Greg Wardfe6462c2000-04-04 01:40:52 +0000289 if cmd_obj.help:
Greg Ward82715e12000-04-21 02:28:14 +0000290 parser.set_option_table (self.global_options)
291 parser.print_help ("Global options:")
Greg Wardfe6462c2000-04-04 01:40:52 +0000292 print
Greg Ward82715e12000-04-21 02:28:14 +0000293
294 parser.set_option_table (cmd_obj.user_options)
295 parser.print_help ("Options for '%s' command:" % command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000296 print
297 print usage
298 return
299
300 self.command_obj[command] = cmd_obj
301 self.have_run[command] = 0
302
303 # while args
304
305 # If the user wants help -- ie. they gave the "--help" option --
306 # give it to 'em. We do this *after* processing the commands in
307 # case they want help on any particular command, eg.
308 # "setup.py --help foo". (This isn't the documented way to
309 # get help on a command, but I support it because that's how
310 # CVS does it -- might as well be consistent.)
311 if self.help:
Greg Ward82715e12000-04-21 02:28:14 +0000312 parser.set_option_table (self.global_options)
313 parser.print_help (
314 "Global options (apply to all commands, " +
315 "or can be used per command):")
Greg Wardfe6462c2000-04-04 01:40:52 +0000316 print
317
Greg Ward82715e12000-04-21 02:28:14 +0000318 if not self.commands:
319 parser.set_option_table (self.display_options)
320 parser.print_help (
321 "Information display options (just display " +
322 "information, ignore any commands)")
323 print
324
Greg Wardfe6462c2000-04-04 01:40:52 +0000325 for command in self.commands:
326 klass = self.find_command_class (command)
Greg Ward82715e12000-04-21 02:28:14 +0000327 parser.set_option_table (klass.user_options)
328 parser.print_help ("Options for '%s' command:" % command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000329 print
330
331 print usage
332 return
333
334 # Oops, no commands found -- an end-user error
335 if not self.commands:
336 raise DistutilsArgError, "no commands supplied"
337
338 # All is well: return true
339 return 1
340
341 # parse_command_line()
342
Greg Ward82715e12000-04-21 02:28:14 +0000343 def handle_display_options (self, option_order):
344 """If there were any non-global "display-only" options
345 (--help-commands or the metadata display options) on the command
346 line, display the requested info and return true; else return
347 false."""
348
349 from distutils.core import usage
350
351 # User just wants a list of commands -- we'll print it out and stop
352 # processing now (ie. if they ran "setup --help-commands foo bar",
353 # we ignore "foo bar").
354 if self.help_commands:
355 self.print_commands ()
356 print
357 print usage
358 return 1
359
360 # If user supplied any of the "display metadata" options, then
361 # display that metadata in the order in which the user supplied the
362 # metadata options.
363 any_display_options = 0
364 is_display_option = {}
365 for option in self.display_options:
366 is_display_option[option[0]] = 1
367
368 for (opt, val) in option_order:
369 if val and is_display_option.get(opt):
370 opt = string.translate (opt, longopt_xlate)
371 print getattr(self.metadata, "get_"+opt)()
372 any_display_options = 1
373
374 return any_display_options
375
376 # handle_display_options()
Greg Wardfe6462c2000-04-04 01:40:52 +0000377
378 def print_command_list (self, commands, header, max_length):
379 """Print a subset of the list of all commands -- used by
380 'print_commands()'."""
381
382 print header + ":"
383
384 for cmd in commands:
385 klass = self.cmdclass.get (cmd)
386 if not klass:
387 klass = self.find_command_class (cmd)
388 try:
389 description = klass.description
390 except AttributeError:
391 description = "(no description available)"
392
393 print " %-*s %s" % (max_length, cmd, description)
394
395 # print_command_list ()
396
397
398 def print_commands (self):
399 """Print out a help message listing all available commands with
400 a description of each. The list is divided into "standard
401 commands" (listed in distutils.command.__all__) and "extra
402 commands" (mentioned in self.cmdclass, but not a standard
403 command). The descriptions come from the command class
404 attribute 'description'."""
405
406 import distutils.command
407 std_commands = distutils.command.__all__
408 is_std = {}
409 for cmd in std_commands:
410 is_std[cmd] = 1
411
412 extra_commands = []
413 for cmd in self.cmdclass.keys():
414 if not is_std.get(cmd):
415 extra_commands.append (cmd)
416
417 max_length = 0
418 for cmd in (std_commands + extra_commands):
419 if len (cmd) > max_length:
420 max_length = len (cmd)
421
422 self.print_command_list (std_commands,
423 "Standard commands",
424 max_length)
425 if extra_commands:
426 print
427 self.print_command_list (extra_commands,
428 "Extra commands",
429 max_length)
430
431 # print_commands ()
432
433
434
435 # -- Command class/object methods ----------------------------------
436
437 # This is a method just so it can be overridden if desired; it doesn't
438 # actually use or change any attributes of the Distribution instance.
439 def find_command_class (self, command):
440 """Given a command, derives the names of the module and class
441 expected to implement the command: eg. 'foo_bar' becomes
442 'distutils.command.foo_bar' (the module) and 'FooBar' (the
443 class within that module). Loads the module, extracts the
444 class from it, and returns the class object.
445
446 Raises DistutilsModuleError with a semi-user-targeted error
447 message if the expected module could not be loaded, or the
448 expected class was not found in it."""
449
450 module_name = 'distutils.command.' + command
451 klass_name = command
452
453 try:
454 __import__ (module_name)
455 module = sys.modules[module_name]
456 except ImportError:
457 raise DistutilsModuleError, \
458 "invalid command '%s' (no module named '%s')" % \
459 (command, module_name)
460
461 try:
462 klass = vars(module)[klass_name]
463 except KeyError:
464 raise DistutilsModuleError, \
465 "invalid command '%s' (no class '%s' in module '%s')" \
466 % (command, klass_name, module_name)
467
468 return klass
469
470 # find_command_class ()
471
472
473 def create_command_obj (self, command):
474 """Figure out the class that should implement a command,
475 instantiate it, cache and return the new "command object".
476 The "command class" is determined either by looking it up in
477 the 'cmdclass' attribute (this is the mechanism whereby
478 clients may override default Distutils commands or add their
479 own), or by calling the 'find_command_class()' method (if the
480 command name is not in 'cmdclass'."""
481
482 # Determine the command class -- either it's in the command_class
483 # dictionary, or we have to divine the module and class name
484 klass = self.cmdclass.get(command)
485 if not klass:
486 klass = self.find_command_class (command)
487 self.cmdclass[command] = klass
488
489 # Found the class OK -- instantiate it
490 cmd_obj = klass (self)
491 return cmd_obj
492
493
494 def find_command_obj (self, command, create=1):
495 """Look up and return a command object in the cache maintained by
496 'create_command_obj()'. If none found, the action taken
497 depends on 'create': if true (the default), create a new
498 command object by calling 'create_command_obj()' and return
499 it; otherwise, return None. If 'command' is an invalid
500 command name, then DistutilsModuleError will be raised."""
501
502 cmd_obj = self.command_obj.get (command)
503 if not cmd_obj and create:
504 cmd_obj = self.create_command_obj (command)
505 self.command_obj[command] = cmd_obj
506
507 return cmd_obj
508
509
510 # -- Methods that operate on the Distribution ----------------------
511
512 def announce (self, msg, level=1):
513 """Print 'msg' if 'level' is greater than or equal to the verbosity
514 level recorded in the 'verbose' attribute (which, currently,
515 can be only 0 or 1)."""
516
517 if self.verbose >= level:
518 print msg
519
520
521 def run_commands (self):
Greg Ward82715e12000-04-21 02:28:14 +0000522 """Run each command that was seen on the setup script command line.
Greg Wardfe6462c2000-04-04 01:40:52 +0000523 Uses the list of commands found and cache of command objects
524 created by 'create_command_obj()'."""
525
526 for cmd in self.commands:
527 self.run_command (cmd)
528
529
530 def get_option (self, option):
531 """Return the value of a distribution option. Raise
Greg Ward02a1a2b2000-04-15 22:15:07 +0000532 AttributeError if 'option' is not known."""
533 return getattr (self, opt)
Greg Wardfe6462c2000-04-04 01:40:52 +0000534
535
536 def get_options (self, *options):
537 """Return (as a tuple) the values of several distribution
Greg Ward02a1a2b2000-04-15 22:15:07 +0000538 options. Raise AttributeError if any element of
Greg Wardfe6462c2000-04-04 01:40:52 +0000539 'options' is not known."""
540
541 values = []
Greg Ward02a1a2b2000-04-15 22:15:07 +0000542 for opt in options:
543 values.append (getattr (self, opt))
Greg Wardfe6462c2000-04-04 01:40:52 +0000544
545 return tuple (values)
546
547
548 # -- Methods that operate on its Commands --------------------------
549
550 def run_command (self, command):
551
552 """Do whatever it takes to run a command (including nothing at all,
553 if the command has already been run). Specifically: if we have
554 already created and run the command named by 'command', return
555 silently without doing anything. If the command named by
556 'command' doesn't even have a command object yet, create one.
557 Then invoke 'run()' on that command object (or an existing
558 one)."""
559
560 # Already been here, done that? then return silently.
561 if self.have_run.get (command):
562 return
563
564 self.announce ("running " + command)
565 cmd_obj = self.find_command_obj (command)
566 cmd_obj.ensure_ready ()
567 cmd_obj.run ()
568 self.have_run[command] = 1
569
570
571 def get_command_option (self, command, option):
572 """Create a command object for 'command' if necessary, ensure that
573 its option values are all set to their final values, and return
Greg Ward02a1a2b2000-04-15 22:15:07 +0000574 the value of its 'option' option. Raise AttributeError if
Greg Wardfe6462c2000-04-04 01:40:52 +0000575 'option' is not known for that 'command'."""
576
577 cmd_obj = self.find_command_obj (command)
578 cmd_obj.ensure_ready ()
579 return cmd_obj.get_option (option)
Greg Wardfe6462c2000-04-04 01:40:52 +0000580
581
582 def get_command_options (self, command, *options):
583 """Create a command object for 'command' if necessary, ensure that
584 its option values are all set to their final values, and return
585 a tuple containing the values of all the options listed in
586 'options' for that command. Raise DistutilsOptionError if any
587 invalid option is supplied in 'options'."""
588
589 cmd_obj = self.find_command_obj (command)
590 cmd_obj.ensure_ready ()
591 values = []
Greg Ward02a1a2b2000-04-15 22:15:07 +0000592 for opt in options:
593 values.append (getattr (cmd_obj, option))
Greg Wardfe6462c2000-04-04 01:40:52 +0000594
595 return tuple (values)
596
597
598 # -- Distribution query methods ------------------------------------
599
600 def has_pure_modules (self):
601 return len (self.packages or self.py_modules or []) > 0
602
603 def has_ext_modules (self):
604 return self.ext_modules and len (self.ext_modules) > 0
605
606 def has_c_libraries (self):
607 return self.libraries and len (self.libraries) > 0
608
609 def has_modules (self):
610 return self.has_pure_modules() or self.has_ext_modules()
611
612 def is_pure (self):
613 return (self.has_pure_modules() and
614 not self.has_ext_modules() and
615 not self.has_c_libraries())
616
Greg Ward82715e12000-04-21 02:28:14 +0000617 # -- Metadata query methods ----------------------------------------
618
619 # If you're looking for 'get_name()', 'get_version()', and so forth,
620 # they are defined in a sneaky way: the constructor binds self.get_XXX
621 # to self.metadata.get_XXX. The actual code is in the
622 # DistributionMetadata class, below.
623
624# class Distribution
625
626
627class DistributionMetadata:
628 """Dummy class to hold the distribution meta-data: name, version,
629 author, and so forth."""
630
631 def __init__ (self):
632 self.name = None
633 self.version = None
634 self.author = None
635 self.author_email = None
636 self.maintainer = None
637 self.maintainer_email = None
638 self.url = None
639 self.licence = None
640 self.description = None
641
642 # -- Metadata query methods ----------------------------------------
643
Greg Wardfe6462c2000-04-04 01:40:52 +0000644 def get_name (self):
645 return self.name or "UNKNOWN"
646
Greg Ward82715e12000-04-21 02:28:14 +0000647 def get_version(self):
648 return self.version or "???"
Greg Wardfe6462c2000-04-04 01:40:52 +0000649
Greg Ward82715e12000-04-21 02:28:14 +0000650 def get_fullname (self):
651 return "%s-%s" % (self.get_name(), self.get_version())
652
653 def get_author(self):
654 return self.author or "UNKNOWN"
655
656 def get_author_email(self):
657 return self.author_email or "UNKNOWN"
658
659 def get_maintainer(self):
660 return self.maintainer or "UNKNOWN"
661
662 def get_maintainer_email(self):
663 return self.maintainer_email or "UNKNOWN"
664
665 def get_contact(self):
666 return (self.maintainer or
667 self.author or
668 "UNKNOWN")
669
670 def get_contact_email(self):
671 return (self.maintainer_email or
672 self.author_email or
673 "UNKNOWN")
674
675 def get_url(self):
676 return self.url or "UNKNOWN"
677
678 def get_licence(self):
679 return self.licence or "UNKNOWN"
680
681 def get_description(self):
682 return self.description or "UNKNOWN"
683
684# class DistributionMetadata
Greg Wardfe6462c2000-04-04 01:40:52 +0000685
686if __name__ == "__main__":
687 dist = Distribution ()
688 print "ok"