blob: 4f4bae5218d7b6b487210c4cd5c2e96b9d71b014 [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
Martin v. Löwis8ed338a2005-03-03 08:12:27 +000062 # 'common_usage' is a short (2-3 line) string describing the common
63 # usage of the setup script.
64 common_usage = """\
65Common commands: (see '--help-commands' for more)
66
67 setup.py build will build the package underneath 'build/'
68 setup.py install will install the package
69"""
70
Greg Ward82715e12000-04-21 02:28:14 +000071 # options that are not propagated to the commands
72 display_options = [
73 ('help-commands', None,
74 "list all available commands"),
75 ('name', None,
76 "print package name"),
77 ('version', 'V',
78 "print package version"),
79 ('fullname', None,
80 "print <package name>-<version>"),
81 ('author', None,
82 "print the author's name"),
83 ('author-email', None,
84 "print the author's email address"),
85 ('maintainer', None,
86 "print the maintainer's name"),
87 ('maintainer-email', None,
88 "print the maintainer's email address"),
89 ('contact', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000090 "print the maintainer's name if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000091 ('contact-email', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000092 "print the maintainer's email address if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000093 ('url', None,
94 "print the URL for this package"),
Greg Ward82715e12000-04-21 02:28:14 +000095 ('license', None,
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +000096 "print the license of the package"),
97 ('licence', None,
98 "alias for --license"),
Greg Ward82715e12000-04-21 02:28:14 +000099 ('description', None,
100 "print the package description"),
Greg Warde5a584e2000-04-26 02:26:55 +0000101 ('long-description', None,
102 "print the long package description"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000103 ('platforms', None,
104 "print the list of platforms"),
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +0000105 ('classifiers', None,
106 "print the list of classifiers"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000107 ('keywords', None,
108 "print the list of keywords"),
Greg Ward82715e12000-04-21 02:28:14 +0000109 ]
Greg Ward2f2b6c62000-09-25 01:58:07 +0000110 display_option_names = map(lambda x: translate_longopt(x[0]),
111 display_options)
Greg Ward82715e12000-04-21 02:28:14 +0000112
113 # negative options are options that exclude other options
Greg Wardfe6462c2000-04-04 01:40:52 +0000114 negative_opt = {'quiet': 'verbose'}
115
116
117 # -- Creation/initialization methods -------------------------------
Fred Drakeb94b8492001-12-06 20:51:35 +0000118
Greg Wardfe6462c2000-04-04 01:40:52 +0000119 def __init__ (self, attrs=None):
120 """Construct a new Distribution instance: initialize all the
Greg Ward8ff5a3f2000-06-02 00:44:53 +0000121 attributes of a Distribution, and then use 'attrs' (a dictionary
122 mapping attribute names to values) to assign some of those
123 attributes their "real" values. (Any attributes not mentioned in
124 'attrs' will be assigned to some null value: 0, None, an empty list
125 or dictionary, etc.) Most importantly, initialize the
126 'command_obj' attribute to the empty dictionary; this will be
127 filled in with real command objects by 'parse_command_line()'.
128 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000129
130 # Default values for our command-line options
131 self.verbose = 1
132 self.dry_run = 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000133 self.help = 0
Greg Ward82715e12000-04-21 02:28:14 +0000134 for attr in self.display_option_names:
135 setattr(self, attr, 0)
Greg Wardfe6462c2000-04-04 01:40:52 +0000136
Greg Ward82715e12000-04-21 02:28:14 +0000137 # Store the distribution meta-data (name, version, author, and so
138 # forth) in a separate object -- we're getting to have enough
139 # information here (and enough command-line options) that it's
140 # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
141 # object in a sneaky and underhanded (but efficient!) way.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000142 self.metadata = DistributionMetadata()
Neil Schemenauera8aefe52001-09-03 15:47:21 +0000143 for basename in self.metadata._METHOD_BASENAMES:
Greg Ward4982f982000-04-22 02:52:44 +0000144 method_name = "get_" + basename
145 setattr(self, method_name, getattr(self.metadata, method_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000146
147 # 'cmdclass' maps command names to class objects, so we
148 # can 1) quickly figure out which class to instantiate when
149 # we need to create a new command object, and 2) have a way
Greg Ward82715e12000-04-21 02:28:14 +0000150 # for the setup script to override command classes
Greg Wardfe6462c2000-04-04 01:40:52 +0000151 self.cmdclass = {}
152
Fred Draked04573f2004-08-03 16:37:40 +0000153 # 'command_packages' is a list of packages in which commands
154 # are searched for. The factory for command 'foo' is expected
155 # to be named 'foo' in the module 'foo' in one of the packages
156 # named here. This list is searched from the left; an error
157 # is raised if no named package provides the command being
158 # searched for. (Always access using get_command_packages().)
159 self.command_packages = None
160
Greg Ward9821bf42000-08-29 01:15:18 +0000161 # 'script_name' and 'script_args' are usually set to sys.argv[0]
162 # and sys.argv[1:], but they can be overridden when the caller is
163 # not necessarily a setup script run from the command-line.
164 self.script_name = None
165 self.script_args = None
166
Greg Wardd5d8a992000-05-23 01:42:17 +0000167 # 'command_options' is where we store command options between
168 # parsing them (from config files, the command-line, etc.) and when
169 # they are actually needed -- ie. when the command in question is
170 # instantiated. It is a dictionary of dictionaries of 2-tuples:
171 # command_options = { command_name : { option : (source, value) } }
Gregory P. Smith14263542000-05-12 00:41:33 +0000172 self.command_options = {}
173
Greg Wardfe6462c2000-04-04 01:40:52 +0000174 # These options are really the business of various commands, rather
175 # than of the Distribution itself. We provide aliases for them in
176 # Distribution as a convenience to the developer.
Greg Wardfe6462c2000-04-04 01:40:52 +0000177 self.packages = None
Fred Drake0eb32a62004-06-11 21:50:33 +0000178 self.package_data = {}
Greg Wardfe6462c2000-04-04 01:40:52 +0000179 self.package_dir = None
180 self.py_modules = None
181 self.libraries = None
Greg Ward51def7d2000-05-27 01:36:14 +0000182 self.headers = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000183 self.ext_modules = None
184 self.ext_package = None
185 self.include_dirs = None
186 self.extra_path = None
Gregory P. Smithb2e3bb32000-05-12 00:52:23 +0000187 self.scripts = None
Gregory P. Smith6a901dd2000-05-13 03:09:50 +0000188 self.data_files = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000189
190 # And now initialize bookkeeping stuff that can't be supplied by
191 # the caller at all. 'command_obj' maps command names to
192 # Command instances -- that's how we enforce that every command
193 # class is a singleton.
194 self.command_obj = {}
195
196 # 'have_run' maps command names to boolean values; it keeps track
197 # of whether we have actually run a particular command, to make it
198 # cheap to "run" a command whenever we think we might need to -- if
199 # it's already been done, no need for expensive filesystem
200 # operations, we just check the 'have_run' dictionary and carry on.
201 # It's only safe to query 'have_run' for a command class that has
202 # been instantiated -- a false value will be inserted when the
203 # command object is created, and replaced with a true value when
Greg Ward612eb9f2000-07-27 02:13:20 +0000204 # the command is successfully run. Thus it's probably best to use
Greg Wardfe6462c2000-04-04 01:40:52 +0000205 # '.get()' rather than a straight lookup.
206 self.have_run = {}
207
208 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000209 # the setup script) to possibly override any or all of these
210 # distribution options.
211
Greg Wardfe6462c2000-04-04 01:40:52 +0000212 if attrs:
213
214 # Pull out the set of command options and work on them
215 # specifically. Note that this order guarantees that aliased
216 # command options will override any supplied redundantly
217 # through the general options dictionary.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000218 options = attrs.get('options')
Greg Wardfe6462c2000-04-04 01:40:52 +0000219 if options:
220 del attrs['options']
221 for (command, cmd_options) in options.items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000222 opt_dict = self.get_option_dict(command)
223 for (opt, val) in cmd_options.items():
224 opt_dict[opt] = ("setup script", val)
Greg Wardfe6462c2000-04-04 01:40:52 +0000225
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +0000226 if attrs.has_key('licence'):
227 attrs['license'] = attrs['licence']
228 del attrs['licence']
229 msg = "'licence' distribution option is deprecated; use 'license'"
230 if warnings is not None:
231 warnings.warn(msg)
232 else:
233 sys.stderr.write(msg + "\n")
234
Greg Wardfe6462c2000-04-04 01:40:52 +0000235 # Now work on the rest of the attributes. Any attribute that's
236 # not already defined is invalid!
237 for (key,val) in attrs.items():
Greg Wardfd7b91e2000-09-26 01:52:25 +0000238 if hasattr(self.metadata, key):
239 setattr(self.metadata, key, val)
240 elif hasattr(self, key):
241 setattr(self, key, val)
Anthony Baxter73cc8472004-10-13 13:22:34 +0000242 else:
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +0000243 msg = "Unknown distribution option: %s" % repr(key)
244 if warnings is not None:
245 warnings.warn(msg)
246 else:
247 sys.stderr.write(msg + "\n")
Greg Wardfe6462c2000-04-04 01:40:52 +0000248
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000249 self.finalize_options()
Fred Drakeb94b8492001-12-06 20:51:35 +0000250
Greg Wardfe6462c2000-04-04 01:40:52 +0000251 # __init__ ()
252
253
Greg Ward0e48cfd2000-05-26 01:00:15 +0000254 def get_option_dict (self, command):
255 """Get the option dictionary for a given command. If that
256 command's option dictionary hasn't been created yet, then create it
257 and return the new dictionary; otherwise, return the existing
258 option dictionary.
259 """
260
261 dict = self.command_options.get(command)
262 if dict is None:
263 dict = self.command_options[command] = {}
264 return dict
265
266
Greg Wardc32d9a62000-05-28 23:53:06 +0000267 def dump_option_dicts (self, header=None, commands=None, indent=""):
268 from pprint import pformat
269
270 if commands is None: # dump all command option dicts
271 commands = self.command_options.keys()
272 commands.sort()
273
274 if header is not None:
275 print indent + header
276 indent = indent + " "
277
278 if not commands:
279 print indent + "no commands known yet"
280 return
281
282 for cmd_name in commands:
283 opt_dict = self.command_options.get(cmd_name)
284 if opt_dict is None:
285 print indent + "no option dict for '%s' command" % cmd_name
286 else:
287 print indent + "option dict for '%s' command:" % cmd_name
288 out = pformat(opt_dict)
289 for line in string.split(out, "\n"):
290 print indent + " " + line
291
292 # dump_option_dicts ()
Fred Drakeb94b8492001-12-06 20:51:35 +0000293
Greg Wardc32d9a62000-05-28 23:53:06 +0000294
295
Greg Wardd5d8a992000-05-23 01:42:17 +0000296 # -- Config file finding/parsing methods ---------------------------
297
Gregory P. Smith14263542000-05-12 00:41:33 +0000298 def find_config_files (self):
299 """Find as many configuration files as should be processed for this
300 platform, and return a list of filenames in the order in which they
301 should be parsed. The filenames returned are guaranteed to exist
302 (modulo nasty race conditions).
303
Andrew M. Kuchlingd303b612001-12-06 16:32:05 +0000304 There are three possible config files: distutils.cfg in the
305 Distutils installation directory (ie. where the top-level
306 Distutils __inst__.py file lives), a file in the user's home
307 directory named .pydistutils.cfg on Unix and pydistutils.cfg
308 on Windows/Mac, and setup.cfg in the current directory.
Greg Wardd5d8a992000-05-23 01:42:17 +0000309 """
Gregory P. Smith14263542000-05-12 00:41:33 +0000310 files = []
Greg Wardacf3f6a2000-06-07 02:26:19 +0000311 check_environ()
Gregory P. Smith14263542000-05-12 00:41:33 +0000312
Greg Ward11696872000-06-07 02:29:03 +0000313 # Where to look for the system-wide Distutils config file
314 sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
315
316 # Look for the system config file
317 sys_file = os.path.join(sys_dir, "distutils.cfg")
Greg Wardacf3f6a2000-06-07 02:26:19 +0000318 if os.path.isfile(sys_file):
319 files.append(sys_file)
Gregory P. Smith14263542000-05-12 00:41:33 +0000320
Greg Ward11696872000-06-07 02:29:03 +0000321 # What to call the per-user config file
322 if os.name == 'posix':
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000323 user_filename = ".pydistutils.cfg"
324 else:
325 user_filename = "pydistutils.cfg"
Greg Wardfa9ff762000-10-14 04:06:40 +0000326
Greg Ward11696872000-06-07 02:29:03 +0000327 # And look for the user config file
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000328 if os.environ.has_key('HOME'):
329 user_file = os.path.join(os.environ.get('HOME'), user_filename)
Gregory P. Smith14263542000-05-12 00:41:33 +0000330 if os.path.isfile(user_file):
331 files.append(user_file)
332
Gregory P. Smith14263542000-05-12 00:41:33 +0000333 # All platforms support local setup.cfg
334 local_file = "setup.cfg"
335 if os.path.isfile(local_file):
336 files.append(local_file)
337
338 return files
339
340 # find_config_files ()
341
342
343 def parse_config_files (self, filenames=None):
344
345 from ConfigParser import ConfigParser
346
347 if filenames is None:
348 filenames = self.find_config_files()
349
Greg Ward2bd3f422000-06-02 01:59:33 +0000350 if DEBUG: print "Distribution.parse_config_files():"
Greg Ward47460772000-05-23 03:47:35 +0000351
Gregory P. Smith14263542000-05-12 00:41:33 +0000352 parser = ConfigParser()
Greg Wardd5d8a992000-05-23 01:42:17 +0000353 for filename in filenames:
Greg Ward2bd3f422000-06-02 01:59:33 +0000354 if DEBUG: print " reading", filename
Greg Wardd5d8a992000-05-23 01:42:17 +0000355 parser.read(filename)
356 for section in parser.sections():
357 options = parser.options(section)
Greg Ward0e48cfd2000-05-26 01:00:15 +0000358 opt_dict = self.get_option_dict(section)
Gregory P. Smith14263542000-05-12 00:41:33 +0000359
Greg Wardd5d8a992000-05-23 01:42:17 +0000360 for opt in options:
361 if opt != '__name__':
Greg Wardceb9e222000-09-25 01:23:52 +0000362 val = parser.get(section,opt)
363 opt = string.replace(opt, '-', '_')
364 opt_dict[opt] = (filename, val)
Gregory P. Smith14263542000-05-12 00:41:33 +0000365
Greg Ward47460772000-05-23 03:47:35 +0000366 # Make the ConfigParser forget everything (so we retain
Fred Drakef06116d2004-02-17 22:35:19 +0000367 # the original filenames that options come from)
Greg Ward47460772000-05-23 03:47:35 +0000368 parser.__init__()
Gregory P. Smith14263542000-05-12 00:41:33 +0000369
Greg Wardceb9e222000-09-25 01:23:52 +0000370 # If there was a "global" section in the config file, use it
371 # to set Distribution options.
372
373 if self.command_options.has_key('global'):
374 for (opt, (src, val)) in self.command_options['global'].items():
375 alias = self.negative_opt.get(opt)
376 try:
377 if alias:
378 setattr(self, alias, not strtobool(val))
379 elif opt in ('verbose', 'dry_run'): # ugh!
380 setattr(self, opt, strtobool(val))
Fred Draked04573f2004-08-03 16:37:40 +0000381 else:
382 setattr(self, opt, val)
Greg Wardceb9e222000-09-25 01:23:52 +0000383 except ValueError, msg:
384 raise DistutilsOptionError, msg
385
386 # parse_config_files ()
387
Gregory P. Smith14263542000-05-12 00:41:33 +0000388
Greg Wardd5d8a992000-05-23 01:42:17 +0000389 # -- Command-line parsing methods ----------------------------------
390
Greg Ward9821bf42000-08-29 01:15:18 +0000391 def parse_command_line (self):
392 """Parse the setup script's command line, taken from the
393 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
394 -- see 'setup()' in core.py). This list is first processed for
395 "global options" -- options that set attributes of the Distribution
396 instance. Then, it is alternately scanned for Distutils commands
397 and options for that command. Each new command terminates the
398 options for the previous command. The allowed options for a
399 command are determined by the 'user_options' attribute of the
400 command class -- thus, we have to be able to load command classes
401 in order to parse the command line. Any error in that 'options'
402 attribute raises DistutilsGetoptError; any error on the
403 command-line raises DistutilsArgError. If no Distutils commands
404 were found on the command line, raises DistutilsArgError. Return
Greg Wardceb9e222000-09-25 01:23:52 +0000405 true if command-line was successfully parsed and we should carry
Greg Ward9821bf42000-08-29 01:15:18 +0000406 on with executing commands; false if no errors but we shouldn't
407 execute commands (currently, this only happens if user asks for
408 help).
Greg Wardd5d8a992000-05-23 01:42:17 +0000409 """
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000410 #
Fred Drake981a1782001-08-10 18:59:30 +0000411 # We now have enough information to show the Macintosh dialog
412 # that allows the user to interactively specify the "command line".
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000413 #
Fred Draked04573f2004-08-03 16:37:40 +0000414 toplevel_options = self._get_toplevel_options()
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000415 if sys.platform == 'mac':
416 import EasyDialogs
417 cmdlist = self.get_command_list()
418 self.script_args = EasyDialogs.GetArgv(
Fred Draked04573f2004-08-03 16:37:40 +0000419 toplevel_options + self.display_options, cmdlist)
Fred Drakeb94b8492001-12-06 20:51:35 +0000420
Greg Wardfe6462c2000-04-04 01:40:52 +0000421 # We have to parse the command line a bit at a time -- global
422 # options, then the first command, then its options, and so on --
423 # because each command will be handled by a different class, and
Greg Wardd5d8a992000-05-23 01:42:17 +0000424 # the options that are valid for a particular class aren't known
425 # until we have loaded the command class, which doesn't happen
426 # until we know what the command is.
Greg Wardfe6462c2000-04-04 01:40:52 +0000427
428 self.commands = []
Fred Draked04573f2004-08-03 16:37:40 +0000429 parser = FancyGetopt(toplevel_options + self.display_options)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000430 parser.set_negative_aliases(self.negative_opt)
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +0000431 parser.set_aliases({'licence': 'license'})
Greg Wardfd7b91e2000-09-26 01:52:25 +0000432 args = parser.getopt(args=self.script_args, object=self)
Greg Ward82715e12000-04-21 02:28:14 +0000433 option_order = parser.get_option_order()
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000434 log.set_verbosity(self.verbose)
Greg Wardfe6462c2000-04-04 01:40:52 +0000435
Greg Ward82715e12000-04-21 02:28:14 +0000436 # for display options we return immediately
437 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000438 return
Fred Drakeb94b8492001-12-06 20:51:35 +0000439
Greg Wardfe6462c2000-04-04 01:40:52 +0000440 while args:
Greg Wardd5d8a992000-05-23 01:42:17 +0000441 args = self._parse_command_opts(parser, args)
442 if args is None: # user asked for help (and got it)
Greg Wardfe6462c2000-04-04 01:40:52 +0000443 return
Greg Wardfe6462c2000-04-04 01:40:52 +0000444
Greg Wardd5d8a992000-05-23 01:42:17 +0000445 # Handle the cases of --help as a "global" option, ie.
446 # "setup.py --help" and "setup.py --help command ...". For the
447 # former, we show global options (--verbose, --dry-run, etc.)
448 # and display-only options (--name, --version, etc.); for the
449 # latter, we omit the display-only options and show help for
450 # each command listed on the command line.
Greg Wardfe6462c2000-04-04 01:40:52 +0000451 if self.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000452 self._show_help(parser,
453 display_options=len(self.commands) == 0,
454 commands=self.commands)
Greg Wardfe6462c2000-04-04 01:40:52 +0000455 return
456
457 # Oops, no commands found -- an end-user error
458 if not self.commands:
459 raise DistutilsArgError, "no commands supplied"
460
461 # All is well: return true
462 return 1
463
464 # parse_command_line()
465
Fred Draked04573f2004-08-03 16:37:40 +0000466 def _get_toplevel_options (self):
467 """Return the non-display options recognized at the top level.
468
469 This includes options that are recognized *only* at the top
470 level as well as options recognized for commands.
471 """
472 return self.global_options + [
473 ("command-packages=", None,
474 "list of packages that provide distutils commands"),
475 ]
476
Greg Wardd5d8a992000-05-23 01:42:17 +0000477 def _parse_command_opts (self, parser, args):
Greg Wardd5d8a992000-05-23 01:42:17 +0000478 """Parse the command-line options for a single command.
479 'parser' must be a FancyGetopt instance; 'args' must be the list
480 of arguments, starting with the current command (whose options
481 we are about to parse). Returns a new version of 'args' with
482 the next command at the front of the list; will be the empty
483 list if there are no more commands on the command line. Returns
484 None if the user asked for help on this command.
485 """
486 # late import because of mutual dependence between these modules
487 from distutils.cmd import Command
488
489 # Pull the current command from the head of the command line
490 command = args[0]
Greg Wardfd7b91e2000-09-26 01:52:25 +0000491 if not command_re.match(command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000492 raise SystemExit, "invalid command name '%s'" % command
Greg Wardfd7b91e2000-09-26 01:52:25 +0000493 self.commands.append(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000494
495 # Dig up the command class that implements this command, so we
496 # 1) know that it's a valid command, and 2) know which options
497 # it takes.
498 try:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000499 cmd_class = self.get_command_class(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000500 except DistutilsModuleError, msg:
501 raise DistutilsArgError, msg
502
503 # Require that the command class be derived from Command -- want
504 # to be sure that the basic "command" interface is implemented.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000505 if not issubclass(cmd_class, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000506 raise DistutilsClassError, \
507 "command class %s must subclass Command" % cmd_class
508
509 # Also make sure that the command object provides a list of its
510 # known options.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000511 if not (hasattr(cmd_class, 'user_options') and
512 type(cmd_class.user_options) is ListType):
Greg Wardd5d8a992000-05-23 01:42:17 +0000513 raise DistutilsClassError, \
514 ("command class %s must provide " +
515 "'user_options' attribute (a list of tuples)") % \
516 cmd_class
517
518 # If the command class has a list of negative alias options,
519 # merge it in with the global negative aliases.
520 negative_opt = self.negative_opt
Greg Wardfd7b91e2000-09-26 01:52:25 +0000521 if hasattr(cmd_class, 'negative_opt'):
522 negative_opt = copy(negative_opt)
523 negative_opt.update(cmd_class.negative_opt)
Greg Wardd5d8a992000-05-23 01:42:17 +0000524
Greg Wardfa9ff762000-10-14 04:06:40 +0000525 # Check for help_options in command class. They have a different
526 # format (tuple of four) so we need to preprocess them here.
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000527 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000528 type(cmd_class.help_options) is ListType):
Greg Ward2ff78872000-06-24 00:23:20 +0000529 help_options = fix_help_options(cmd_class.help_options)
530 else:
Greg Ward55fced32000-06-24 01:22:41 +0000531 help_options = []
Greg Ward2ff78872000-06-24 00:23:20 +0000532
Greg Ward9d17a7a2000-06-07 03:00:06 +0000533
Greg Wardd5d8a992000-05-23 01:42:17 +0000534 # All commands support the global options too, just by adding
535 # in 'global_options'.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000536 parser.set_option_table(self.global_options +
537 cmd_class.user_options +
538 help_options)
539 parser.set_negative_aliases(negative_opt)
540 (args, opts) = parser.getopt(args[1:])
Greg Ward47460772000-05-23 03:47:35 +0000541 if hasattr(opts, 'help') and opts.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000542 self._show_help(parser, display_options=0, commands=[cmd_class])
543 return
544
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000545 if (hasattr(cmd_class, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000546 type(cmd_class.help_options) is ListType):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000547 help_option_found=0
548 for (help_option, short, desc, func) in cmd_class.help_options:
549 if hasattr(opts, parser.get_attr_name(help_option)):
550 help_option_found=1
Greg Wardfa9ff762000-10-14 04:06:40 +0000551 #print "showing help for option %s of command %s" % \
Greg Ward2ff78872000-06-24 00:23:20 +0000552 # (help_option[0],cmd_class)
Greg Ward55fced32000-06-24 01:22:41 +0000553
554 if callable(func):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000555 func()
Greg Ward55fced32000-06-24 01:22:41 +0000556 else:
Fred Drake981a1782001-08-10 18:59:30 +0000557 raise DistutilsClassError(
Walter Dörwald70a6b492004-02-12 17:35:32 +0000558 "invalid help function %r for help option '%s': "
Fred Drake981a1782001-08-10 18:59:30 +0000559 "must be a callable object (function, etc.)"
Walter Dörwald70a6b492004-02-12 17:35:32 +0000560 % (func, help_option))
Greg Ward55fced32000-06-24 01:22:41 +0000561
Fred Drakeb94b8492001-12-06 20:51:35 +0000562 if help_option_found:
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000563 return
Greg Ward9d17a7a2000-06-07 03:00:06 +0000564
Greg Wardd5d8a992000-05-23 01:42:17 +0000565 # Put the options from the command-line into their official
566 # holding pen, the 'command_options' dictionary.
Greg Ward0e48cfd2000-05-26 01:00:15 +0000567 opt_dict = self.get_option_dict(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000568 for (name, value) in vars(opts).items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000569 opt_dict[name] = ("command line", value)
Greg Wardd5d8a992000-05-23 01:42:17 +0000570
571 return args
572
573 # _parse_command_opts ()
574
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000575 def finalize_options (self):
576 """Set final values for all the options on the Distribution
577 instance, analogous to the .finalize_options() method of Command
578 objects.
579 """
580
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000581 keywords = self.metadata.keywords
582 if keywords is not None:
583 if type(keywords) is StringType:
584 keywordlist = string.split(keywords, ',')
585 self.metadata.keywords = map(string.strip, keywordlist)
586
587 platforms = self.metadata.platforms
588 if platforms is not None:
589 if type(platforms) is StringType:
590 platformlist = string.split(platforms, ',')
591 self.metadata.platforms = map(string.strip, platformlist)
592
Greg Wardd5d8a992000-05-23 01:42:17 +0000593 def _show_help (self,
594 parser,
595 global_options=1,
596 display_options=1,
597 commands=[]):
598 """Show help for the setup script command-line in the form of
599 several lists of command-line options. 'parser' should be a
600 FancyGetopt instance; do not expect it to be returned in the
601 same state, as its option table will be reset to make it
602 generate the correct help text.
603
604 If 'global_options' is true, lists the global options:
605 --verbose, --dry-run, etc. If 'display_options' is true, lists
606 the "display-only" options: --name, --version, etc. Finally,
607 lists per-command help for every command name or command class
608 in 'commands'.
609 """
610 # late import because of mutual dependence between these modules
Greg Ward9821bf42000-08-29 01:15:18 +0000611 from distutils.core import gen_usage
Greg Wardd5d8a992000-05-23 01:42:17 +0000612 from distutils.cmd import Command
613
614 if global_options:
Fred Draked04573f2004-08-03 16:37:40 +0000615 if display_options:
616 options = self._get_toplevel_options()
617 else:
618 options = self.global_options
619 parser.set_option_table(options)
Martin v. Löwis8ed338a2005-03-03 08:12:27 +0000620 parser.print_help(self.common_usage + "\nGlobal options:")
Greg Wardd5d8a992000-05-23 01:42:17 +0000621 print
622
623 if display_options:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000624 parser.set_option_table(self.display_options)
625 parser.print_help(
Greg Wardd5d8a992000-05-23 01:42:17 +0000626 "Information display options (just display " +
627 "information, ignore any commands)")
628 print
629
630 for command in self.commands:
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +0000631 if type(command) is ClassType and issubclass(command, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000632 klass = command
633 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000634 klass = self.get_command_class(command)
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000635 if (hasattr(klass, 'help_options') and
Greg Wardfd7b91e2000-09-26 01:52:25 +0000636 type(klass.help_options) is ListType):
637 parser.set_option_table(klass.user_options +
638 fix_help_options(klass.help_options))
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000639 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000640 parser.set_option_table(klass.user_options)
641 parser.print_help("Options for '%s' command:" % klass.__name__)
Greg Wardd5d8a992000-05-23 01:42:17 +0000642 print
643
Greg Ward9821bf42000-08-29 01:15:18 +0000644 print gen_usage(self.script_name)
Greg Wardd5d8a992000-05-23 01:42:17 +0000645 return
646
647 # _show_help ()
Greg Wardfa9ff762000-10-14 04:06:40 +0000648
Greg Wardd5d8a992000-05-23 01:42:17 +0000649
Greg Ward82715e12000-04-21 02:28:14 +0000650 def handle_display_options (self, option_order):
651 """If there were any non-global "display-only" options
Greg Wardd5d8a992000-05-23 01:42:17 +0000652 (--help-commands or the metadata display options) on the command
653 line, display the requested info and return true; else return
654 false.
655 """
Greg Ward9821bf42000-08-29 01:15:18 +0000656 from distutils.core import gen_usage
Greg Ward82715e12000-04-21 02:28:14 +0000657
658 # User just wants a list of commands -- we'll print it out and stop
659 # processing now (ie. if they ran "setup --help-commands foo bar",
660 # we ignore "foo bar").
661 if self.help_commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000662 self.print_commands()
Greg Ward82715e12000-04-21 02:28:14 +0000663 print
Greg Ward9821bf42000-08-29 01:15:18 +0000664 print gen_usage(self.script_name)
Greg Ward82715e12000-04-21 02:28:14 +0000665 return 1
666
667 # If user supplied any of the "display metadata" options, then
668 # display that metadata in the order in which the user supplied the
669 # metadata options.
670 any_display_options = 0
671 is_display_option = {}
672 for option in self.display_options:
673 is_display_option[option[0]] = 1
674
675 for (opt, val) in option_order:
676 if val and is_display_option.get(opt):
Greg Ward2f2b6c62000-09-25 01:58:07 +0000677 opt = translate_longopt(opt)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000678 value = getattr(self.metadata, "get_"+opt)()
679 if opt in ['keywords', 'platforms']:
680 print string.join(value, ',')
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +0000681 elif opt == 'classifiers':
682 print string.join(value, '\n')
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000683 else:
684 print value
Greg Ward82715e12000-04-21 02:28:14 +0000685 any_display_options = 1
686
687 return any_display_options
688
689 # handle_display_options()
Greg Wardfe6462c2000-04-04 01:40:52 +0000690
691 def print_command_list (self, commands, header, max_length):
692 """Print a subset of the list of all commands -- used by
Greg Wardd5d8a992000-05-23 01:42:17 +0000693 'print_commands()'.
694 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000695
696 print header + ":"
697
698 for cmd in commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000699 klass = self.cmdclass.get(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000700 if not klass:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000701 klass = self.get_command_class(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000702 try:
703 description = klass.description
704 except AttributeError:
705 description = "(no description available)"
706
707 print " %-*s %s" % (max_length, cmd, description)
708
709 # print_command_list ()
710
711
712 def print_commands (self):
Greg Wardd5d8a992000-05-23 01:42:17 +0000713 """Print out a help message listing all available commands with a
714 description of each. The list is divided into "standard commands"
715 (listed in distutils.command.__all__) and "extra commands"
716 (mentioned in self.cmdclass, but not a standard command). The
717 descriptions come from the command class attribute
718 'description'.
719 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000720
721 import distutils.command
722 std_commands = distutils.command.__all__
723 is_std = {}
724 for cmd in std_commands:
725 is_std[cmd] = 1
726
727 extra_commands = []
728 for cmd in self.cmdclass.keys():
729 if not is_std.get(cmd):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000730 extra_commands.append(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000731
732 max_length = 0
733 for cmd in (std_commands + extra_commands):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000734 if len(cmd) > max_length:
735 max_length = len(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000736
Greg Wardfd7b91e2000-09-26 01:52:25 +0000737 self.print_command_list(std_commands,
738 "Standard commands",
739 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000740 if extra_commands:
741 print
Greg Wardfd7b91e2000-09-26 01:52:25 +0000742 self.print_command_list(extra_commands,
743 "Extra commands",
744 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000745
746 # print_commands ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000747
Greg Wardf6fc8752000-11-11 02:47:11 +0000748 def get_command_list (self):
749 """Get a list of (command, description) tuples.
750 The list is divided into "standard commands" (listed in
751 distutils.command.__all__) and "extra commands" (mentioned in
752 self.cmdclass, but not a standard command). The descriptions come
753 from the command class attribute 'description'.
754 """
755 # Currently this is only used on Mac OS, for the Mac-only GUI
756 # Distutils interface (by Jack Jansen)
757
758 import distutils.command
759 std_commands = distutils.command.__all__
760 is_std = {}
761 for cmd in std_commands:
762 is_std[cmd] = 1
763
764 extra_commands = []
765 for cmd in self.cmdclass.keys():
766 if not is_std.get(cmd):
767 extra_commands.append(cmd)
768
769 rv = []
770 for cmd in (std_commands + extra_commands):
771 klass = self.cmdclass.get(cmd)
772 if not klass:
773 klass = self.get_command_class(cmd)
774 try:
775 description = klass.description
776 except AttributeError:
777 description = "(no description available)"
778 rv.append((cmd, description))
779 return rv
Greg Wardfe6462c2000-04-04 01:40:52 +0000780
781 # -- Command class/object methods ----------------------------------
782
Fred Draked04573f2004-08-03 16:37:40 +0000783 def get_command_packages (self):
784 """Return a list of packages from which commands are loaded."""
785 pkgs = self.command_packages
786 if not isinstance(pkgs, type([])):
787 pkgs = string.split(pkgs or "", ",")
788 for i in range(len(pkgs)):
789 pkgs[i] = string.strip(pkgs[i])
790 pkgs = filter(None, pkgs)
791 if "distutils.command" not in pkgs:
792 pkgs.insert(0, "distutils.command")
793 self.command_packages = pkgs
794 return pkgs
795
Greg Wardd5d8a992000-05-23 01:42:17 +0000796 def get_command_class (self, command):
797 """Return the class that implements the Distutils command named by
798 'command'. First we check the 'cmdclass' dictionary; if the
799 command is mentioned there, we fetch the class object from the
800 dictionary and return it. Otherwise we load the command module
801 ("distutils.command." + command) and fetch the command class from
802 the module. The loaded class is also stored in 'cmdclass'
803 to speed future calls to 'get_command_class()'.
Greg Wardfe6462c2000-04-04 01:40:52 +0000804
Gregory P. Smith14263542000-05-12 00:41:33 +0000805 Raises DistutilsModuleError if the expected module could not be
Greg Wardd5d8a992000-05-23 01:42:17 +0000806 found, or if that module does not define the expected class.
807 """
808 klass = self.cmdclass.get(command)
809 if klass:
810 return klass
Greg Wardfe6462c2000-04-04 01:40:52 +0000811
Fred Draked04573f2004-08-03 16:37:40 +0000812 for pkgname in self.get_command_packages():
813 module_name = "%s.%s" % (pkgname, command)
814 klass_name = command
Greg Wardfe6462c2000-04-04 01:40:52 +0000815
Fred Draked04573f2004-08-03 16:37:40 +0000816 try:
817 __import__ (module_name)
818 module = sys.modules[module_name]
819 except ImportError:
820 continue
Greg Wardfe6462c2000-04-04 01:40:52 +0000821
Fred Draked04573f2004-08-03 16:37:40 +0000822 try:
823 klass = getattr(module, klass_name)
824 except AttributeError:
825 raise DistutilsModuleError, \
826 "invalid command '%s' (no class '%s' in module '%s')" \
827 % (command, klass_name, module_name)
Greg Wardfe6462c2000-04-04 01:40:52 +0000828
Fred Draked04573f2004-08-03 16:37:40 +0000829 self.cmdclass[command] = klass
830 return klass
831
832 raise DistutilsModuleError("invalid command '%s'" % command)
833
Greg Wardfe6462c2000-04-04 01:40:52 +0000834
Greg Wardd5d8a992000-05-23 01:42:17 +0000835 # get_command_class ()
Greg Wardfe6462c2000-04-04 01:40:52 +0000836
Greg Wardd5d8a992000-05-23 01:42:17 +0000837 def get_command_obj (self, command, create=1):
838 """Return the command object for 'command'. Normally this object
Greg Ward612eb9f2000-07-27 02:13:20 +0000839 is cached on a previous call to 'get_command_obj()'; if no command
Greg Wardd5d8a992000-05-23 01:42:17 +0000840 object for 'command' is in the cache, then we either create and
841 return it (if 'create' is true) or return None.
842 """
843 cmd_obj = self.command_obj.get(command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000844 if not cmd_obj and create:
Greg Ward2bd3f422000-06-02 01:59:33 +0000845 if DEBUG:
846 print "Distribution.get_command_obj(): " \
847 "creating '%s' command object" % command
Greg Ward47460772000-05-23 03:47:35 +0000848
Greg Wardd5d8a992000-05-23 01:42:17 +0000849 klass = self.get_command_class(command)
Greg Ward47460772000-05-23 03:47:35 +0000850 cmd_obj = self.command_obj[command] = klass(self)
851 self.have_run[command] = 0
852
853 # Set any options that were supplied in config files
854 # or on the command line. (NB. support for error
855 # reporting is lame here: any errors aren't reported
856 # until 'finalize_options()' is called, which means
857 # we won't report the source of the error.)
858 options = self.command_options.get(command)
859 if options:
Greg Wardc32d9a62000-05-28 23:53:06 +0000860 self._set_command_options(cmd_obj, options)
Greg Wardfe6462c2000-04-04 01:40:52 +0000861
862 return cmd_obj
863
Greg Wardc32d9a62000-05-28 23:53:06 +0000864 def _set_command_options (self, command_obj, option_dict=None):
Greg Wardc32d9a62000-05-28 23:53:06 +0000865 """Set the options for 'command_obj' from 'option_dict'. Basically
866 this means copying elements of a dictionary ('option_dict') to
867 attributes of an instance ('command').
868
Greg Wardceb9e222000-09-25 01:23:52 +0000869 'command_obj' must be a Command instance. If 'option_dict' is not
Greg Wardc32d9a62000-05-28 23:53:06 +0000870 supplied, uses the standard option dictionary for this command
871 (from 'self.command_options').
872 """
Greg Wardc32d9a62000-05-28 23:53:06 +0000873 command_name = command_obj.get_command_name()
874 if option_dict is None:
875 option_dict = self.get_option_dict(command_name)
876
877 if DEBUG: print " setting options for '%s' command:" % command_name
878 for (option, (source, value)) in option_dict.items():
879 if DEBUG: print " %s = %s (from %s)" % (option, value, source)
Greg Wardceb9e222000-09-25 01:23:52 +0000880 try:
Greg Ward2f2b6c62000-09-25 01:58:07 +0000881 bool_opts = map(translate_longopt, command_obj.boolean_options)
Greg Wardceb9e222000-09-25 01:23:52 +0000882 except AttributeError:
883 bool_opts = []
884 try:
885 neg_opt = command_obj.negative_opt
886 except AttributeError:
887 neg_opt = {}
888
889 try:
Greg Ward2c08cf02000-09-27 00:15:37 +0000890 is_string = type(value) is StringType
891 if neg_opt.has_key(option) and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000892 setattr(command_obj, neg_opt[option], not strtobool(value))
Greg Ward2c08cf02000-09-27 00:15:37 +0000893 elif option in bool_opts and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000894 setattr(command_obj, option, strtobool(value))
895 elif hasattr(command_obj, option):
896 setattr(command_obj, option, value)
897 else:
898 raise DistutilsOptionError, \
899 ("error in %s: command '%s' has no such option '%s'"
900 % (source, command_name, option))
901 except ValueError, msg:
902 raise DistutilsOptionError, msg
Greg Wardc32d9a62000-05-28 23:53:06 +0000903
Greg Wardf449ea52000-09-16 15:23:28 +0000904 def reinitialize_command (self, command, reinit_subcommands=0):
Greg Wardc32d9a62000-05-28 23:53:06 +0000905 """Reinitializes a command to the state it was in when first
906 returned by 'get_command_obj()': ie., initialized but not yet
Greg Ward7d9c7052000-06-28 01:25:27 +0000907 finalized. This provides the opportunity to sneak option
Greg Wardc32d9a62000-05-28 23:53:06 +0000908 values in programmatically, overriding or supplementing
909 user-supplied values from the config files and command line.
910 You'll have to re-finalize the command object (by calling
911 'finalize_options()' or 'ensure_finalized()') before using it for
Fred Drakeb94b8492001-12-06 20:51:35 +0000912 real.
Greg Wardc32d9a62000-05-28 23:53:06 +0000913
Greg Wardf449ea52000-09-16 15:23:28 +0000914 'command' should be a command name (string) or command object. If
915 'reinit_subcommands' is true, also reinitializes the command's
916 sub-commands, as declared by the 'sub_commands' class attribute (if
917 it has one). See the "install" command for an example. Only
918 reinitializes the sub-commands that actually matter, ie. those
919 whose test predicates return true.
920
Greg Wardc32d9a62000-05-28 23:53:06 +0000921 Returns the reinitialized command object.
922 """
923 from distutils.cmd import Command
924 if not isinstance(command, Command):
925 command_name = command
926 command = self.get_command_obj(command_name)
927 else:
928 command_name = command.get_command_name()
929
930 if not command.finalized:
Greg Ward282c7a02000-06-01 01:09:47 +0000931 return command
Greg Wardc32d9a62000-05-28 23:53:06 +0000932 command.initialize_options()
933 command.finalized = 0
Greg Ward43955c92000-06-06 02:52:36 +0000934 self.have_run[command_name] = 0
Greg Wardc32d9a62000-05-28 23:53:06 +0000935 self._set_command_options(command)
Greg Wardf449ea52000-09-16 15:23:28 +0000936
Greg Wardf449ea52000-09-16 15:23:28 +0000937 if reinit_subcommands:
Greg Wardf449ea52000-09-16 15:23:28 +0000938 for sub in command.get_sub_commands():
Fred Drakeb94b8492001-12-06 20:51:35 +0000939 self.reinitialize_command(sub, reinit_subcommands)
Greg Wardf449ea52000-09-16 15:23:28 +0000940
Greg Wardc32d9a62000-05-28 23:53:06 +0000941 return command
942
Fred Drakeb94b8492001-12-06 20:51:35 +0000943
Greg Wardfe6462c2000-04-04 01:40:52 +0000944 # -- Methods that operate on the Distribution ----------------------
945
946 def announce (self, msg, level=1):
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000947 log.debug(msg)
Greg Wardfe6462c2000-04-04 01:40:52 +0000948
949 def run_commands (self):
Greg Ward82715e12000-04-21 02:28:14 +0000950 """Run each command that was seen on the setup script command line.
Greg Wardd5d8a992000-05-23 01:42:17 +0000951 Uses the list of commands found and cache of command objects
Greg Wardfd7b91e2000-09-26 01:52:25 +0000952 created by 'get_command_obj()'.
953 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000954 for cmd in self.commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000955 self.run_command(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000956
957
Greg Wardfe6462c2000-04-04 01:40:52 +0000958 # -- Methods that operate on its Commands --------------------------
959
960 def run_command (self, command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000961 """Do whatever it takes to run a command (including nothing at all,
Greg Wardd5d8a992000-05-23 01:42:17 +0000962 if the command has already been run). Specifically: if we have
963 already created and run the command named by 'command', return
964 silently without doing anything. If the command named by 'command'
965 doesn't even have a command object yet, create one. Then invoke
966 'run()' on that command object (or an existing one).
967 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000968 # Already been here, done that? then return silently.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000969 if self.have_run.get(command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000970 return
971
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000972 log.info("running %s", command)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000973 cmd_obj = self.get_command_obj(command)
974 cmd_obj.ensure_finalized()
975 cmd_obj.run()
Greg Wardfe6462c2000-04-04 01:40:52 +0000976 self.have_run[command] = 1
977
978
Greg Wardfe6462c2000-04-04 01:40:52 +0000979 # -- Distribution query methods ------------------------------------
980
981 def has_pure_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000982 return len(self.packages or self.py_modules or []) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000983
984 def has_ext_modules (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000985 return self.ext_modules and len(self.ext_modules) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000986
987 def has_c_libraries (self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000988 return self.libraries and len(self.libraries) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000989
990 def has_modules (self):
991 return self.has_pure_modules() or self.has_ext_modules()
992
Greg Ward51def7d2000-05-27 01:36:14 +0000993 def has_headers (self):
994 return self.headers and len(self.headers) > 0
995
Greg Ward44a61bb2000-05-20 15:06:48 +0000996 def has_scripts (self):
997 return self.scripts and len(self.scripts) > 0
998
999 def has_data_files (self):
1000 return self.data_files and len(self.data_files) > 0
1001
Greg Wardfe6462c2000-04-04 01:40:52 +00001002 def is_pure (self):
1003 return (self.has_pure_modules() and
1004 not self.has_ext_modules() and
1005 not self.has_c_libraries())
1006
Greg Ward82715e12000-04-21 02:28:14 +00001007 # -- Metadata query methods ----------------------------------------
1008
1009 # If you're looking for 'get_name()', 'get_version()', and so forth,
1010 # they are defined in a sneaky way: the constructor binds self.get_XXX
1011 # to self.metadata.get_XXX. The actual code is in the
1012 # DistributionMetadata class, below.
1013
1014# class Distribution
1015
1016
1017class DistributionMetadata:
1018 """Dummy class to hold the distribution meta-data: name, version,
Greg Wardfd7b91e2000-09-26 01:52:25 +00001019 author, and so forth.
1020 """
Greg Ward82715e12000-04-21 02:28:14 +00001021
Neil Schemenauera8aefe52001-09-03 15:47:21 +00001022 _METHOD_BASENAMES = ("name", "version", "author", "author_email",
1023 "maintainer", "maintainer_email", "url",
1024 "license", "description", "long_description",
1025 "keywords", "platforms", "fullname", "contact",
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +00001026 "contact_email", "license", "classifiers",
Anthony Baxterf2113f02004-10-13 12:35:28 +00001027 "download_url")
Neil Schemenauera8aefe52001-09-03 15:47:21 +00001028
Greg Ward82715e12000-04-21 02:28:14 +00001029 def __init__ (self):
1030 self.name = None
1031 self.version = None
1032 self.author = None
1033 self.author_email = None
1034 self.maintainer = None
1035 self.maintainer_email = None
1036 self.url = None
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001037 self.license = None
Greg Ward82715e12000-04-21 02:28:14 +00001038 self.description = None
Greg Warde5a584e2000-04-26 02:26:55 +00001039 self.long_description = None
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001040 self.keywords = None
1041 self.platforms = None
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001042 self.classifiers = None
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001043 self.download_url = None
Fred Drakeb94b8492001-12-06 20:51:35 +00001044
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001045 def write_pkg_info (self, base_dir):
1046 """Write the PKG-INFO file into the release tree.
1047 """
1048
1049 pkg_info = open( os.path.join(base_dir, 'PKG-INFO'), 'w')
1050
1051 pkg_info.write('Metadata-Version: 1.0\n')
1052 pkg_info.write('Name: %s\n' % self.get_name() )
1053 pkg_info.write('Version: %s\n' % self.get_version() )
1054 pkg_info.write('Summary: %s\n' % self.get_description() )
1055 pkg_info.write('Home-page: %s\n' % self.get_url() )
Andrew M. Kuchlingffb963c2001-03-22 15:32:23 +00001056 pkg_info.write('Author: %s\n' % self.get_contact() )
1057 pkg_info.write('Author-email: %s\n' % self.get_contact_email() )
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001058 pkg_info.write('License: %s\n' % self.get_license() )
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001059 if self.download_url:
1060 pkg_info.write('Download-URL: %s\n' % self.download_url)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001061
1062 long_desc = rfc822_escape( self.get_long_description() )
1063 pkg_info.write('Description: %s\n' % long_desc)
1064
1065 keywords = string.join( self.get_keywords(), ',')
1066 if keywords:
1067 pkg_info.write('Keywords: %s\n' % keywords )
1068
1069 for platform in self.get_platforms():
1070 pkg_info.write('Platform: %s\n' % platform )
1071
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001072 for classifier in self.get_classifiers():
1073 pkg_info.write('Classifier: %s\n' % classifier )
1074
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001075 pkg_info.close()
Fred Drakeb94b8492001-12-06 20:51:35 +00001076
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001077 # write_pkg_info ()
Fred Drakeb94b8492001-12-06 20:51:35 +00001078
Greg Ward82715e12000-04-21 02:28:14 +00001079 # -- Metadata query methods ----------------------------------------
1080
Greg Wardfe6462c2000-04-04 01:40:52 +00001081 def get_name (self):
1082 return self.name or "UNKNOWN"
1083
Greg Ward82715e12000-04-21 02:28:14 +00001084 def get_version(self):
Thomas Hellerbcd89752001-12-06 20:44:19 +00001085 return self.version or "0.0.0"
Greg Wardfe6462c2000-04-04 01:40:52 +00001086
Greg Ward82715e12000-04-21 02:28:14 +00001087 def get_fullname (self):
1088 return "%s-%s" % (self.get_name(), self.get_version())
1089
1090 def get_author(self):
1091 return self.author or "UNKNOWN"
1092
1093 def get_author_email(self):
1094 return self.author_email or "UNKNOWN"
1095
1096 def get_maintainer(self):
1097 return self.maintainer or "UNKNOWN"
1098
1099 def get_maintainer_email(self):
1100 return self.maintainer_email or "UNKNOWN"
1101
1102 def get_contact(self):
1103 return (self.maintainer or
1104 self.author or
1105 "UNKNOWN")
1106
1107 def get_contact_email(self):
1108 return (self.maintainer_email or
1109 self.author_email or
1110 "UNKNOWN")
1111
1112 def get_url(self):
1113 return self.url or "UNKNOWN"
1114
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001115 def get_license(self):
1116 return self.license or "UNKNOWN"
1117 get_licence = get_license
Fred Drakeb94b8492001-12-06 20:51:35 +00001118
Greg Ward82715e12000-04-21 02:28:14 +00001119 def get_description(self):
1120 return self.description or "UNKNOWN"
Greg Warde5a584e2000-04-26 02:26:55 +00001121
1122 def get_long_description(self):
1123 return self.long_description or "UNKNOWN"
1124
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001125 def get_keywords(self):
1126 return self.keywords or []
1127
1128 def get_platforms(self):
1129 return self.platforms or ["UNKNOWN"]
1130
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001131 def get_classifiers(self):
1132 return self.classifiers or []
1133
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001134 def get_download_url(self):
1135 return self.download_url or "UNKNOWN"
1136
Greg Ward82715e12000-04-21 02:28:14 +00001137# class DistributionMetadata
Greg Wardfe6462c2000-04-04 01:40:52 +00001138
Greg Ward2ff78872000-06-24 00:23:20 +00001139
1140def fix_help_options (options):
1141 """Convert a 4-tuple 'help_options' list as found in various command
1142 classes to the 3-tuple form required by FancyGetopt.
1143 """
1144 new_options = []
1145 for help_tuple in options:
1146 new_options.append(help_tuple[0:3])
1147 return new_options
1148
1149
Greg Wardfe6462c2000-04-04 01:40:52 +00001150if __name__ == "__main__":
Greg Wardfd7b91e2000-09-26 01:52:25 +00001151 dist = Distribution()
Greg Wardfe6462c2000-04-04 01:40:52 +00001152 print "ok"