blob: 9eb2aa424c154997422cbb8e1daeb436cc48d218 [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
Martin v. Löwis5a6601c2004-11-10 22:23:15 +00007# This module should be kept compatible with Python 2.1.
Andrew M. Kuchlingd448f662002-11-19 13:12:28 +00008
Greg Wardfe6462c2000-04-04 01:40:52 +00009__revision__ = "$Id$"
10
Gregory P. Smith14263542000-05-12 00:41:33 +000011import sys, os, string, re
Greg Wardfe6462c2000-04-04 01:40:52 +000012from types import *
13from copy import copy
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +000014
15try:
16 import warnings
Andrew M. Kuchlingccf4e422002-10-31 13:39:33 +000017except ImportError:
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +000018 warnings = None
19
Greg Wardfe6462c2000-04-04 01:40:52 +000020from distutils.errors import *
Greg Ward2f2b6c62000-09-25 01:58:07 +000021from distutils.fancy_getopt import FancyGetopt, translate_longopt
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +000022from distutils.util import check_environ, strtobool, rfc822_escape
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000023from distutils import log
Jeremy Hyltonfcd73532002-09-11 16:31:53 +000024from distutils.debug import DEBUG
Greg Wardfe6462c2000-04-04 01:40:52 +000025
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:
Greg Ward8ff5a3f2000-06-02 00:44:53 +000034 """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.
Greg Wardfe6462c2000-04-04 01:40:52 +000037
Greg Ward8ff5a3f2000-06-02 00:44:53 +000038 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 """
Greg Wardfe6462c2000-04-04 01:40:52 +000046
47
48 # 'global_options' describes the command-line options that may be
Greg Ward82715e12000-04-21 02:28:14 +000049 # supplied to the setup script prior to any actual commands.
50 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
Greg Wardfe6462c2000-04-04 01:40:52 +000051 # 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.
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000055 # The fourth entry for verbose means that it can be repeated.
56 global_options = [('verbose', 'v', "run verbosely (default)", 1),
Greg Wardd5d8a992000-05-23 01:42:17 +000057 ('quiet', 'q', "run quietly (turns verbosity off)"),
58 ('dry-run', 'n', "don't actually do anything"),
59 ('help', 'h', "show detailed help message"),
Greg Wardfe6462c2000-04-04 01:40:52 +000060 ]
Greg Ward82715e12000-04-21 02:28:14 +000061
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,
Greg Wardd5d8a992000-05-23 01:42:17 +000081 "print the maintainer's name if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000082 ('contact-email', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000083 "print the maintainer's email address if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000084 ('url', None,
85 "print the URL for this package"),
Greg Ward82715e12000-04-21 02:28:14 +000086 ('license', None,
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +000087 "print the license of the package"),
88 ('licence', None,
89 "alias for --license"),
Greg Ward82715e12000-04-21 02:28:14 +000090 ('description', None,
91 "print the package description"),
Greg Warde5a584e2000-04-26 02:26:55 +000092 ('long-description', None,
93 "print the long package description"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +000094 ('platforms', None,
95 "print the list of platforms"),
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +000096 ('classifiers', None,
97 "print the list of classifiers"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +000098 ('keywords', None,
99 "print the list of keywords"),
Greg Ward82715e12000-04-21 02:28:14 +0000100 ]
Greg Ward2f2b6c62000-09-25 01:58:07 +0000101 display_option_names = map(lambda x: translate_longopt(x[0]),
102 display_options)
Greg Ward82715e12000-04-21 02:28:14 +0000103
104 # negative options are options that exclude other options
Greg Wardfe6462c2000-04-04 01:40:52 +0000105 negative_opt = {'quiet': 'verbose'}
106
107
108 # -- Creation/initialization methods -------------------------------
Fred Drakeb94b8492001-12-06 20:51:35 +0000109
Greg Wardfe6462c2000-04-04 01:40:52 +0000110 def __init__ (self, attrs=None):
111 """Construct a new Distribution instance: initialize all the
Greg Ward8ff5a3f2000-06-02 00:44:53 +0000112 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 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000120
121 # Default values for our command-line options
122 self.verbose = 1
123 self.dry_run = 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000124 self.help = 0
Greg Ward82715e12000-04-21 02:28:14 +0000125 for attr in self.display_option_names:
126 setattr(self, attr, 0)
Greg Wardfe6462c2000-04-04 01:40:52 +0000127
Greg Ward82715e12000-04-21 02:28:14 +0000128 # 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.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000133 self.metadata = DistributionMetadata()
Neil Schemenauera8aefe52001-09-03 15:47:21 +0000134 for basename in self.metadata._METHOD_BASENAMES:
Greg Ward4982f982000-04-22 02:52:44 +0000135 method_name = "get_" + basename
136 setattr(self, method_name, getattr(self.metadata, method_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000137
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
Greg Ward82715e12000-04-21 02:28:14 +0000141 # for the setup script to override command classes
Greg Wardfe6462c2000-04-04 01:40:52 +0000142 self.cmdclass = {}
143
Fred Draked04573f2004-08-03 16:37:40 +0000144 # '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
Greg Ward9821bf42000-08-29 01:15:18 +0000152 # '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
Greg Wardd5d8a992000-05-23 01:42:17 +0000158 # '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) } }
Gregory P. Smith14263542000-05-12 00:41:33 +0000163 self.command_options = {}
164
Greg Wardfe6462c2000-04-04 01:40:52 +0000165 # 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.
Greg Wardfe6462c2000-04-04 01:40:52 +0000168 self.packages = None
Fred Drake0eb32a62004-06-11 21:50:33 +0000169 self.package_data = {}
Greg Wardfe6462c2000-04-04 01:40:52 +0000170 self.package_dir = None
171 self.py_modules = None
172 self.libraries = None
Greg Ward51def7d2000-05-27 01:36:14 +0000173 self.headers = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000174 self.ext_modules = None
175 self.ext_package = None
176 self.include_dirs = None
177 self.extra_path = None
Gregory P. Smithb2e3bb32000-05-12 00:52:23 +0000178 self.scripts = None
Gregory P. Smith6a901dd2000-05-13 03:09:50 +0000179 self.data_files = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000180
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
Greg Ward612eb9f2000-07-27 02:13:20 +0000195 # the command is successfully run. Thus it's probably best to use
Greg Wardfe6462c2000-04-04 01:40:52 +0000196 # '.get()' rather than a straight lookup.
197 self.have_run = {}
198
199 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000200 # the setup script) to possibly override any or all of these
201 # distribution options.
202
Greg Wardfe6462c2000-04-04 01:40:52 +0000203 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.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000209 options = attrs.get('options')
Greg Wardfe6462c2000-04-04 01:40:52 +0000210 if options:
211 del attrs['options']
212 for (command, cmd_options) in options.items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000213 opt_dict = self.get_option_dict(command)
214 for (opt, val) in cmd_options.items():
215 opt_dict[opt] = ("setup script", val)
Greg Wardfe6462c2000-04-04 01:40:52 +0000216
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +0000217 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
Greg Wardfe6462c2000-04-04 01:40:52 +0000226 # 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():
Greg Wardfd7b91e2000-09-26 01:52:25 +0000229 if hasattr(self.metadata, key):
230 setattr(self.metadata, key, val)
231 elif hasattr(self, key):
232 setattr(self, key, val)
Anthony Baxter73cc8472004-10-13 13:22:34 +0000233 else:
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +0000234 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")
Greg Wardfe6462c2000-04-04 01:40:52 +0000239
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000240 self.finalize_options()
Fred Drakeb94b8492001-12-06 20:51:35 +0000241
Greg Wardfe6462c2000-04-04 01:40:52 +0000242 # __init__ ()
243
244
Greg Ward0e48cfd2000-05-26 01:00:15 +0000245 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
Greg Wardc32d9a62000-05-28 23:53:06 +0000258 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 ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000284
Greg Wardc32d9a62000-05-28 23:53:06 +0000285
286
Greg Wardd5d8a992000-05-23 01:42:17 +0000287 # -- Config file finding/parsing methods ---------------------------
288
Gregory P. Smith14263542000-05-12 00:41:33 +0000289 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
Andrew M. Kuchlingd303b612001-12-06 16:32:05 +0000295 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.
Greg Wardd5d8a992000-05-23 01:42:17 +0000300 """
Gregory P. Smith14263542000-05-12 00:41:33 +0000301 files = []
Greg Wardacf3f6a2000-06-07 02:26:19 +0000302 check_environ()
Gregory P. Smith14263542000-05-12 00:41:33 +0000303
Greg Ward11696872000-06-07 02:29:03 +0000304 # 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")
Greg Wardacf3f6a2000-06-07 02:26:19 +0000309 if os.path.isfile(sys_file):
310 files.append(sys_file)
Gregory P. Smith14263542000-05-12 00:41:33 +0000311
Greg Ward11696872000-06-07 02:29:03 +0000312 # What to call the per-user config file
313 if os.name == 'posix':
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000314 user_filename = ".pydistutils.cfg"
315 else:
316 user_filename = "pydistutils.cfg"
Greg Wardfa9ff762000-10-14 04:06:40 +0000317
Greg Ward11696872000-06-07 02:29:03 +0000318 # And look for the user config file
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000319 if os.environ.has_key('HOME'):
320 user_file = os.path.join(os.environ.get('HOME'), user_filename)
Gregory P. Smith14263542000-05-12 00:41:33 +0000321 if os.path.isfile(user_file):
322 files.append(user_file)
323
Gregory P. Smith14263542000-05-12 00:41:33 +0000324 # 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
Greg Ward2bd3f422000-06-02 01:59:33 +0000341 if DEBUG: print "Distribution.parse_config_files():"
Greg Ward47460772000-05-23 03:47:35 +0000342
Gregory P. Smith14263542000-05-12 00:41:33 +0000343 parser = ConfigParser()
Greg Wardd5d8a992000-05-23 01:42:17 +0000344 for filename in filenames:
Greg Ward2bd3f422000-06-02 01:59:33 +0000345 if DEBUG: print " reading", filename
Greg Wardd5d8a992000-05-23 01:42:17 +0000346 parser.read(filename)
347 for section in parser.sections():
348 options = parser.options(section)
Greg Ward0e48cfd2000-05-26 01:00:15 +0000349 opt_dict = self.get_option_dict(section)
Gregory P. Smith14263542000-05-12 00:41:33 +0000350
Greg Wardd5d8a992000-05-23 01:42:17 +0000351 for opt in options:
352 if opt != '__name__':
Greg Wardceb9e222000-09-25 01:23:52 +0000353 val = parser.get(section,opt)
354 opt = string.replace(opt, '-', '_')
355 opt_dict[opt] = (filename, val)
Gregory P. Smith14263542000-05-12 00:41:33 +0000356
Greg Ward47460772000-05-23 03:47:35 +0000357 # Make the ConfigParser forget everything (so we retain
Fred Drakef06116d2004-02-17 22:35:19 +0000358 # the original filenames that options come from)
Greg Ward47460772000-05-23 03:47:35 +0000359 parser.__init__()
Gregory P. Smith14263542000-05-12 00:41:33 +0000360
Greg Wardceb9e222000-09-25 01:23:52 +0000361 # 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))
Fred Draked04573f2004-08-03 16:37:40 +0000372 else:
373 setattr(self, opt, val)
Greg Wardceb9e222000-09-25 01:23:52 +0000374 except ValueError, msg:
375 raise DistutilsOptionError, msg
376
377 # parse_config_files ()
378
Gregory P. Smith14263542000-05-12 00:41:33 +0000379
Greg Wardd5d8a992000-05-23 01:42:17 +0000380 # -- Command-line parsing methods ----------------------------------
381
Greg Ward9821bf42000-08-29 01:15:18 +0000382 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
Greg Wardceb9e222000-09-25 01:23:52 +0000396 true if command-line was successfully parsed and we should carry
Greg Ward9821bf42000-08-29 01:15:18 +0000397 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).
Greg Wardd5d8a992000-05-23 01:42:17 +0000400 """
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000401 #
Fred Drake981a1782001-08-10 18:59:30 +0000402 # We now have enough information to show the Macintosh dialog
403 # that allows the user to interactively specify the "command line".
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000404 #
Fred Draked04573f2004-08-03 16:37:40 +0000405 toplevel_options = self._get_toplevel_options()
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000406 if sys.platform == 'mac':
407 import EasyDialogs
408 cmdlist = self.get_command_list()
409 self.script_args = EasyDialogs.GetArgv(
Fred Draked04573f2004-08-03 16:37:40 +0000410 toplevel_options + self.display_options, cmdlist)
Fred Drakeb94b8492001-12-06 20:51:35 +0000411
Greg Wardfe6462c2000-04-04 01:40:52 +0000412 # 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
Greg Wardd5d8a992000-05-23 01:42:17 +0000415 # 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.
Greg Wardfe6462c2000-04-04 01:40:52 +0000418
419 self.commands = []
Fred Draked04573f2004-08-03 16:37:40 +0000420 parser = FancyGetopt(toplevel_options + self.display_options)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000421 parser.set_negative_aliases(self.negative_opt)
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +0000422 parser.set_aliases({'licence': 'license'})
Greg Wardfd7b91e2000-09-26 01:52:25 +0000423 args = parser.getopt(args=self.script_args, object=self)
Greg Ward82715e12000-04-21 02:28:14 +0000424 option_order = parser.get_option_order()
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000425 log.set_verbosity(self.verbose)
Greg Wardfe6462c2000-04-04 01:40:52 +0000426
Greg Ward82715e12000-04-21 02:28:14 +0000427 # for display options we return immediately
428 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000429 return
Fred Drakeb94b8492001-12-06 20:51:35 +0000430
Greg Wardfe6462c2000-04-04 01:40:52 +0000431 while args:
Greg Wardd5d8a992000-05-23 01:42:17 +0000432 args = self._parse_command_opts(parser, args)
433 if args is None: # user asked for help (and got it)
Greg Wardfe6462c2000-04-04 01:40:52 +0000434 return
Greg Wardfe6462c2000-04-04 01:40:52 +0000435
Greg Wardd5d8a992000-05-23 01:42:17 +0000436 # 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.
Greg Wardfe6462c2000-04-04 01:40:52 +0000442 if self.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000443 self._show_help(parser,
444 display_options=len(self.commands) == 0,
445 commands=self.commands)
Greg Wardfe6462c2000-04-04 01:40:52 +0000446 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
Fred Draked04573f2004-08-03 16:37:40 +0000457 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
Greg Wardd5d8a992000-05-23 01:42:17 +0000468 def _parse_command_opts (self, parser, args):
Greg Wardd5d8a992000-05-23 01:42:17 +0000469 """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]
Greg Wardfd7b91e2000-09-26 01:52:25 +0000482 if not command_re.match(command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000483 raise SystemExit, "invalid command name '%s'" % command
Greg Wardfd7b91e2000-09-26 01:52:25 +0000484 self.commands.append(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000485
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:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000490 cmd_class = self.get_command_class(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000491 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.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000496 if not issubclass(cmd_class, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000497 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.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000502 if not (hasattr(cmd_class, 'user_options') and
503 type(cmd_class.user_options) is ListType):
Greg Wardd5d8a992000-05-23 01:42:17 +0000504 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
Greg Wardfd7b91e2000-09-26 01:52:25 +0000512 if hasattr(cmd_class, 'negative_opt'):
513 negative_opt = copy(negative_opt)
514 negative_opt.update(cmd_class.negative_opt)
Greg Wardd5d8a992000-05-23 01:42:17 +0000515
Greg Wardfa9ff762000-10-14 04:06:40 +0000516 # Check for help_options in command class. They have a different
517 # format (tuple of four) so we need to preprocess them here.
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000518 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000519 type(cmd_class.help_options) is ListType):
Greg Ward2ff78872000-06-24 00:23:20 +0000520 help_options = fix_help_options(cmd_class.help_options)
521 else:
Greg Ward55fced32000-06-24 01:22:41 +0000522 help_options = []
Greg Ward2ff78872000-06-24 00:23:20 +0000523
Greg Ward9d17a7a2000-06-07 03:00:06 +0000524
Greg Wardd5d8a992000-05-23 01:42:17 +0000525 # All commands support the global options too, just by adding
526 # in 'global_options'.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000527 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:])
Greg Ward47460772000-05-23 03:47:35 +0000532 if hasattr(opts, 'help') and opts.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000533 self._show_help(parser, display_options=0, commands=[cmd_class])
534 return
535
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000536 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000537 type(cmd_class.help_options) is ListType):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000538 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
Greg Wardfa9ff762000-10-14 04:06:40 +0000542 #print "showing help for option %s of command %s" % \
Greg Ward2ff78872000-06-24 00:23:20 +0000543 # (help_option[0],cmd_class)
Greg Ward55fced32000-06-24 01:22:41 +0000544
545 if callable(func):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000546 func()
Greg Ward55fced32000-06-24 01:22:41 +0000547 else:
Fred Drake981a1782001-08-10 18:59:30 +0000548 raise DistutilsClassError(
Walter Dörwald70a6b492004-02-12 17:35:32 +0000549 "invalid help function %r for help option '%s': "
Fred Drake981a1782001-08-10 18:59:30 +0000550 "must be a callable object (function, etc.)"
Walter Dörwald70a6b492004-02-12 17:35:32 +0000551 % (func, help_option))
Greg Ward55fced32000-06-24 01:22:41 +0000552
Fred Drakeb94b8492001-12-06 20:51:35 +0000553 if help_option_found:
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000554 return
Greg Ward9d17a7a2000-06-07 03:00:06 +0000555
Greg Wardd5d8a992000-05-23 01:42:17 +0000556 # Put the options from the command-line into their official
557 # holding pen, the 'command_options' dictionary.
Greg Ward0e48cfd2000-05-26 01:00:15 +0000558 opt_dict = self.get_option_dict(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000559 for (name, value) in vars(opts).items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000560 opt_dict[name] = ("command line", value)
Greg Wardd5d8a992000-05-23 01:42:17 +0000561
562 return args
563
564 # _parse_command_opts ()
565
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000566 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
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000572 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
Greg Wardd5d8a992000-05-23 01:42:17 +0000584 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
Greg Ward9821bf42000-08-29 01:15:18 +0000602 from distutils.core import gen_usage
Greg Wardd5d8a992000-05-23 01:42:17 +0000603 from distutils.cmd import Command
604
605 if global_options:
Fred Draked04573f2004-08-03 16:37:40 +0000606 if display_options:
607 options = self._get_toplevel_options()
608 else:
609 options = self.global_options
610 parser.set_option_table(options)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000611 parser.print_help("Global options:")
Greg Wardd5d8a992000-05-23 01:42:17 +0000612 print
613
614 if display_options:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000615 parser.set_option_table(self.display_options)
616 parser.print_help(
Greg Wardd5d8a992000-05-23 01:42:17 +0000617 "Information display options (just display " +
618 "information, ignore any commands)")
619 print
620
621 for command in self.commands:
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +0000622 if type(command) is ClassType and issubclass(command, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000623 klass = command
624 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000625 klass = self.get_command_class(command)
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000626 if (hasattr(klass, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000627 type(klass.help_options) is ListType):
628 parser.set_option_table(klass.user_options +
629 fix_help_options(klass.help_options))
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000630 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000631 parser.set_option_table(klass.user_options)
632 parser.print_help("Options for '%s' command:" % klass.__name__)
Greg Wardd5d8a992000-05-23 01:42:17 +0000633 print
634
Greg Ward9821bf42000-08-29 01:15:18 +0000635 print gen_usage(self.script_name)
Greg Wardd5d8a992000-05-23 01:42:17 +0000636 return
637
638 # _show_help ()
Greg Wardfa9ff762000-10-14 04:06:40 +0000639
Greg Wardd5d8a992000-05-23 01:42:17 +0000640
Greg Ward82715e12000-04-21 02:28:14 +0000641 def handle_display_options (self, option_order):
642 """If there were any non-global "display-only" options
Greg Wardd5d8a992000-05-23 01:42:17 +0000643 (--help-commands or the metadata display options) on the command
644 line, display the requested info and return true; else return
645 false.
646 """
Greg Ward9821bf42000-08-29 01:15:18 +0000647 from distutils.core import gen_usage
Greg Ward82715e12000-04-21 02:28:14 +0000648
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:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000653 self.print_commands()
Greg Ward82715e12000-04-21 02:28:14 +0000654 print
Greg Ward9821bf42000-08-29 01:15:18 +0000655 print gen_usage(self.script_name)
Greg Ward82715e12000-04-21 02:28:14 +0000656 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):
Greg Ward2f2b6c62000-09-25 01:58:07 +0000668 opt = translate_longopt(opt)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000669 value = getattr(self.metadata, "get_"+opt)()
670 if opt in ['keywords', 'platforms']:
671 print string.join(value, ',')
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +0000672 elif opt == 'classifiers':
673 print string.join(value, '\n')
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000674 else:
675 print value
Greg Ward82715e12000-04-21 02:28:14 +0000676 any_display_options = 1
677
678 return any_display_options
679
680 # handle_display_options()
Greg Wardfe6462c2000-04-04 01:40:52 +0000681
682 def print_command_list (self, commands, header, max_length):
683 """Print a subset of the list of all commands -- used by
Greg Wardd5d8a992000-05-23 01:42:17 +0000684 'print_commands()'.
685 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000686
687 print header + ":"
688
689 for cmd in commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000690 klass = self.cmdclass.get(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000691 if not klass:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000692 klass = self.get_command_class(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000693 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):
Greg Wardd5d8a992000-05-23 01:42:17 +0000704 """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 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000711
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):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000721 extra_commands.append(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000722
723 max_length = 0
724 for cmd in (std_commands + extra_commands):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000725 if len(cmd) > max_length:
726 max_length = len(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000727
Greg Wardfd7b91e2000-09-26 01:52:25 +0000728 self.print_command_list(std_commands,
729 "Standard commands",
730 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000731 if extra_commands:
732 print
Greg Wardfd7b91e2000-09-26 01:52:25 +0000733 self.print_command_list(extra_commands,
734 "Extra commands",
735 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000736
737 # print_commands ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000738
Greg Wardf6fc8752000-11-11 02:47:11 +0000739 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
Greg Wardfe6462c2000-04-04 01:40:52 +0000771
772 # -- Command class/object methods ----------------------------------
773
Fred Draked04573f2004-08-03 16:37:40 +0000774 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
Greg Wardd5d8a992000-05-23 01:42:17 +0000787 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()'.
Greg Wardfe6462c2000-04-04 01:40:52 +0000795
Gregory P. Smith14263542000-05-12 00:41:33 +0000796 Raises DistutilsModuleError if the expected module could not be
Greg Wardd5d8a992000-05-23 01:42:17 +0000797 found, or if that module does not define the expected class.
798 """
799 klass = self.cmdclass.get(command)
800 if klass:
801 return klass
Greg Wardfe6462c2000-04-04 01:40:52 +0000802
Fred Draked04573f2004-08-03 16:37:40 +0000803 for pkgname in self.get_command_packages():
804 module_name = "%s.%s" % (pkgname, command)
805 klass_name = command
Greg Wardfe6462c2000-04-04 01:40:52 +0000806
Fred Draked04573f2004-08-03 16:37:40 +0000807 try:
808 __import__ (module_name)
809 module = sys.modules[module_name]
810 except ImportError:
811 continue
Greg Wardfe6462c2000-04-04 01:40:52 +0000812
Fred Draked04573f2004-08-03 16:37:40 +0000813 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)
Greg Wardfe6462c2000-04-04 01:40:52 +0000819
Fred Draked04573f2004-08-03 16:37:40 +0000820 self.cmdclass[command] = klass
821 return klass
822
823 raise DistutilsModuleError("invalid command '%s'" % command)
824
Greg Wardfe6462c2000-04-04 01:40:52 +0000825
Greg Wardd5d8a992000-05-23 01:42:17 +0000826 # get_command_class ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000827
Greg Wardd5d8a992000-05-23 01:42:17 +0000828 def get_command_obj (self, command, create=1):
829 """Return the command object for 'command'. Normally this object
Greg Ward612eb9f2000-07-27 02:13:20 +0000830 is cached on a previous call to 'get_command_obj()'; if no command
Greg Wardd5d8a992000-05-23 01:42:17 +0000831 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)
Greg Wardfe6462c2000-04-04 01:40:52 +0000835 if not cmd_obj and create:
Greg Ward2bd3f422000-06-02 01:59:33 +0000836 if DEBUG:
837 print "Distribution.get_command_obj(): " \
838 "creating '%s' command object" % command
Greg Ward47460772000-05-23 03:47:35 +0000839
Greg Wardd5d8a992000-05-23 01:42:17 +0000840 klass = self.get_command_class(command)
Greg Ward47460772000-05-23 03:47:35 +0000841 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:
Greg Wardc32d9a62000-05-28 23:53:06 +0000851 self._set_command_options(cmd_obj, options)
Greg Wardfe6462c2000-04-04 01:40:52 +0000852
853 return cmd_obj
854
Greg Wardc32d9a62000-05-28 23:53:06 +0000855 def _set_command_options (self, command_obj, option_dict=None):
Greg Wardc32d9a62000-05-28 23:53:06 +0000856 """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
Greg Wardceb9e222000-09-25 01:23:52 +0000860 'command_obj' must be a Command instance. If 'option_dict' is not
Greg Wardc32d9a62000-05-28 23:53:06 +0000861 supplied, uses the standard option dictionary for this command
862 (from 'self.command_options').
863 """
Greg Wardc32d9a62000-05-28 23:53:06 +0000864 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)
Greg Wardceb9e222000-09-25 01:23:52 +0000871 try:
Greg Ward2f2b6c62000-09-25 01:58:07 +0000872 bool_opts = map(translate_longopt, command_obj.boolean_options)
Greg Wardceb9e222000-09-25 01:23:52 +0000873 except AttributeError:
874 bool_opts = []
875 try:
876 neg_opt = command_obj.negative_opt
877 except AttributeError:
878 neg_opt = {}
879
880 try:
Greg Ward2c08cf02000-09-27 00:15:37 +0000881 is_string = type(value) is StringType
882 if neg_opt.has_key(option) and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000883 setattr(command_obj, neg_opt[option], not strtobool(value))
Greg Ward2c08cf02000-09-27 00:15:37 +0000884 elif option in bool_opts and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000885 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
Greg Wardc32d9a62000-05-28 23:53:06 +0000894
Greg Wardf449ea52000-09-16 15:23:28 +0000895 def reinitialize_command (self, command, reinit_subcommands=0):
Greg Wardc32d9a62000-05-28 23:53:06 +0000896 """Reinitializes a command to the state it was in when first
897 returned by 'get_command_obj()': ie., initialized but not yet
Greg Ward7d9c7052000-06-28 01:25:27 +0000898 finalized. This provides the opportunity to sneak option
Greg Wardc32d9a62000-05-28 23:53:06 +0000899 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
Fred Drakeb94b8492001-12-06 20:51:35 +0000903 real.
Greg Wardc32d9a62000-05-28 23:53:06 +0000904
Greg Wardf449ea52000-09-16 15:23:28 +0000905 '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
Greg Wardc32d9a62000-05-28 23:53:06 +0000912 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:
Greg Ward282c7a02000-06-01 01:09:47 +0000922 return command
Greg Wardc32d9a62000-05-28 23:53:06 +0000923 command.initialize_options()
924 command.finalized = 0
Greg Ward43955c92000-06-06 02:52:36 +0000925 self.have_run[command_name] = 0
Greg Wardc32d9a62000-05-28 23:53:06 +0000926 self._set_command_options(command)
Greg Wardf449ea52000-09-16 15:23:28 +0000927
Greg Wardf449ea52000-09-16 15:23:28 +0000928 if reinit_subcommands:
Greg Wardf449ea52000-09-16 15:23:28 +0000929 for sub in command.get_sub_commands():
Fred Drakeb94b8492001-12-06 20:51:35 +0000930 self.reinitialize_command(sub, reinit_subcommands)
Greg Wardf449ea52000-09-16 15:23:28 +0000931
Greg Wardc32d9a62000-05-28 23:53:06 +0000932 return command
933
Fred Drakeb94b8492001-12-06 20:51:35 +0000934
Greg Wardfe6462c2000-04-04 01:40:52 +0000935 # -- Methods that operate on the Distribution ----------------------
936
937 def announce (self, msg, level=1):
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000938 log.debug(msg)
Greg Wardfe6462c2000-04-04 01:40:52 +0000939
940 def run_commands (self):
Greg Ward82715e12000-04-21 02:28:14 +0000941 """Run each command that was seen on the setup script command line.
Greg Wardd5d8a992000-05-23 01:42:17 +0000942 Uses the list of commands found and cache of command objects
Greg Wardfd7b91e2000-09-26 01:52:25 +0000943 created by 'get_command_obj()'.
944 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000945 for cmd in self.commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000946 self.run_command(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000947
948
Greg Wardfe6462c2000-04-04 01:40:52 +0000949 # -- Methods that operate on its Commands --------------------------
950
951 def run_command (self, command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000952 """Do whatever it takes to run a command (including nothing at all,
Greg Wardd5d8a992000-05-23 01:42:17 +0000953 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 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000959 # Already been here, done that? then return silently.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000960 if self.have_run.get(command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000961 return
962
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000963 log.info("running %s", command)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000964 cmd_obj = self.get_command_obj(command)
965 cmd_obj.ensure_finalized()
966 cmd_obj.run()
Greg Wardfe6462c2000-04-04 01:40:52 +0000967 self.have_run[command] = 1
968
969
Greg Wardfe6462c2000-04-04 01:40:52 +0000970 # -- Distribution query methods ------------------------------------
971
972 def has_pure_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000973 return len(self.packages or self.py_modules or []) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000974
975 def has_ext_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000976 return self.ext_modules and len(self.ext_modules) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000977
978 def has_c_libraries (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000979 return self.libraries and len(self.libraries) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000980
981 def has_modules (self):
982 return self.has_pure_modules() or self.has_ext_modules()
983
Greg Ward51def7d2000-05-27 01:36:14 +0000984 def has_headers (self):
985 return self.headers and len(self.headers) > 0
986
Greg Ward44a61bb2000-05-20 15:06:48 +0000987 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
Greg Wardfe6462c2000-04-04 01:40:52 +0000993 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
Greg Ward82715e12000-04-21 02:28:14 +0000998 # -- 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,
Greg Wardfd7b91e2000-09-26 01:52:25 +00001010 author, and so forth.
1011 """
Greg Ward82715e12000-04-21 02:28:14 +00001012
Neil Schemenauera8aefe52001-09-03 15:47:21 +00001013 _METHOD_BASENAMES = ("name", "version", "author", "author_email",
1014 "maintainer", "maintainer_email", "url",
1015 "license", "description", "long_description",
1016 "keywords", "platforms", "fullname", "contact",
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +00001017 "contact_email", "license", "classifiers",
Anthony Baxterf2113f02004-10-13 12:35:28 +00001018 "download_url")
Neil Schemenauera8aefe52001-09-03 15:47:21 +00001019
Greg Ward82715e12000-04-21 02:28:14 +00001020 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
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001028 self.license = None
Greg Ward82715e12000-04-21 02:28:14 +00001029 self.description = None
Greg Warde5a584e2000-04-26 02:26:55 +00001030 self.long_description = None
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001031 self.keywords = None
1032 self.platforms = None
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001033 self.classifiers = None
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001034 self.download_url = None
Fred Drakeb94b8492001-12-06 20:51:35 +00001035
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001036 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() )
Andrew M. Kuchlingffb963c2001-03-22 15:32:23 +00001047 pkg_info.write('Author: %s\n' % self.get_contact() )
1048 pkg_info.write('Author-email: %s\n' % self.get_contact_email() )
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001049 pkg_info.write('License: %s\n' % self.get_license() )
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001050 if self.download_url:
1051 pkg_info.write('Download-URL: %s\n' % self.download_url)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001052
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
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001063 for classifier in self.get_classifiers():
1064 pkg_info.write('Classifier: %s\n' % classifier )
1065
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001066 pkg_info.close()
Fred Drakeb94b8492001-12-06 20:51:35 +00001067
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001068 # write_pkg_info ()
Fred Drakeb94b8492001-12-06 20:51:35 +00001069
Greg Ward82715e12000-04-21 02:28:14 +00001070 # -- Metadata query methods ----------------------------------------
1071
Greg Wardfe6462c2000-04-04 01:40:52 +00001072 def get_name (self):
1073 return self.name or "UNKNOWN"
1074
Greg Ward82715e12000-04-21 02:28:14 +00001075 def get_version(self):
Thomas Hellerbcd89752001-12-06 20:44:19 +00001076 return self.version or "0.0.0"
Greg Wardfe6462c2000-04-04 01:40:52 +00001077
Greg Ward82715e12000-04-21 02:28:14 +00001078 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
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001106 def get_license(self):
1107 return self.license or "UNKNOWN"
1108 get_licence = get_license
Fred Drakeb94b8492001-12-06 20:51:35 +00001109
Greg Ward82715e12000-04-21 02:28:14 +00001110 def get_description(self):
1111 return self.description or "UNKNOWN"
Greg Warde5a584e2000-04-26 02:26:55 +00001112
1113 def get_long_description(self):
1114 return self.long_description or "UNKNOWN"
1115
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001116 def get_keywords(self):
1117 return self.keywords or []
1118
1119 def get_platforms(self):
1120 return self.platforms or ["UNKNOWN"]
1121
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001122 def get_classifiers(self):
1123 return self.classifiers or []
1124
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001125 def get_download_url(self):
1126 return self.download_url or "UNKNOWN"
1127
Greg Ward82715e12000-04-21 02:28:14 +00001128# class DistributionMetadata
Greg Wardfe6462c2000-04-04 01:40:52 +00001129
Greg Ward2ff78872000-06-24 00:23:20 +00001130
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
Greg Wardfe6462c2000-04-04 01:40:52 +00001141if __name__ == "__main__":
Greg Wardfd7b91e2000-09-26 01:52:25 +00001142 dist = Distribution()
Greg Wardfe6462c2000-04-04 01:40:52 +00001143 print "ok"