blob: 11a210279e96e36964d46e0c78449c3c749a9bfc [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
Neal Norwitz9d72bb42007-04-17 08:48:32 +00007import sys, os, re
Jason R. Coombs3492e392013-11-10 18:15:03 -05008from email import message_from_file
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +00009
10try:
11 import warnings
Andrew M. Kuchlingccf4e422002-10-31 13:39:33 +000012except ImportError:
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +000013 warnings = None
14
Tarek Ziadé36797272010-07-22 12:50:05 +000015from distutils.errors import *
Greg Ward2f2b6c62000-09-25 01:58:07 +000016from distutils.fancy_getopt import FancyGetopt, translate_longopt
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +000017from distutils.util import check_environ, strtobool, rfc822_escape
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000018from distutils import log
Jeremy Hyltonfcd73532002-09-11 16:31:53 +000019from distutils.debug import DEBUG
Greg Wardfe6462c2000-04-04 01:40:52 +000020
21# Regex to define acceptable Distutils command names. This is not *quite*
22# the same as a Python NAME -- I don't allow leading underscores. The fact
23# that they're very similar is no coincidence; the default naming scheme is
24# to look for a Python module named after the command.
25command_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$')
26
27
28class Distribution:
Greg Ward8ff5a3f2000-06-02 00:44:53 +000029 """The core of the Distutils. Most of the work hiding behind 'setup'
30 is really done within a Distribution instance, which farms the work out
31 to the Distutils commands specified on the command line.
Greg Wardfe6462c2000-04-04 01:40:52 +000032
Greg Ward8ff5a3f2000-06-02 00:44:53 +000033 Setup scripts will almost never instantiate Distribution directly,
34 unless the 'setup()' function is totally inadequate to their needs.
35 However, it is conceivable that a setup script might wish to subclass
36 Distribution for some specialized purpose, and then pass the subclass
37 to 'setup()' as the 'distclass' keyword argument. If so, it is
38 necessary to respect the expectations that 'setup' has of Distribution.
39 See the code for 'setup()', in core.py, for details.
40 """
Greg Wardfe6462c2000-04-04 01:40:52 +000041
42
43 # 'global_options' describes the command-line options that may be
Greg Ward82715e12000-04-21 02:28:14 +000044 # supplied to the setup script prior to any actual commands.
45 # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
Greg Wardfe6462c2000-04-04 01:40:52 +000046 # these global options. This list should be kept to a bare minimum,
47 # since every global option is also valid as a command option -- and we
48 # don't want to pollute the commands with too many options that they
49 # have minimal control over.
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +000050 # The fourth entry for verbose means that it can be repeated.
51 global_options = [('verbose', 'v', "run verbosely (default)", 1),
Greg Wardd5d8a992000-05-23 01:42:17 +000052 ('quiet', 'q', "run quietly (turns verbosity off)"),
53 ('dry-run', 'n', "don't actually do anything"),
54 ('help', 'h', "show detailed help message"),
Tarek Ziadé36797272010-07-22 12:50:05 +000055 ]
Greg Ward82715e12000-04-21 02:28:14 +000056
Martin v. Löwis8ed338a2005-03-03 08:12:27 +000057 # 'common_usage' is a short (2-3 line) string describing the common
58 # usage of the setup script.
59 common_usage = """\
60Common commands: (see '--help-commands' for more)
61
62 setup.py build will build the package underneath 'build/'
63 setup.py install will install the package
64"""
65
Greg Ward82715e12000-04-21 02:28:14 +000066 # options that are not propagated to the commands
67 display_options = [
68 ('help-commands', None,
69 "list all available commands"),
70 ('name', None,
71 "print package name"),
72 ('version', 'V',
73 "print package version"),
74 ('fullname', None,
75 "print <package name>-<version>"),
76 ('author', None,
77 "print the author's name"),
78 ('author-email', None,
79 "print the author's email address"),
80 ('maintainer', None,
81 "print the maintainer's name"),
82 ('maintainer-email', None,
83 "print the maintainer's email address"),
84 ('contact', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000085 "print the maintainer's name if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000086 ('contact-email', None,
Greg Wardd5d8a992000-05-23 01:42:17 +000087 "print the maintainer's email address if known, else the author's"),
Greg Ward82715e12000-04-21 02:28:14 +000088 ('url', None,
89 "print the URL for this package"),
Greg Ward82715e12000-04-21 02:28:14 +000090 ('license', None,
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +000091 "print the license of the package"),
92 ('licence', None,
93 "alias for --license"),
Greg Ward82715e12000-04-21 02:28:14 +000094 ('description', None,
95 "print the package description"),
Greg Warde5a584e2000-04-26 02:26:55 +000096 ('long-description', None,
97 "print the long package description"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +000098 ('platforms', None,
99 "print the list of platforms"),
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +0000100 ('classifiers', None,
101 "print the list of classifiers"),
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000102 ('keywords', None,
103 "print the list of keywords"),
Fred Drakedb7b0022005-03-20 22:19:47 +0000104 ('provides', None,
105 "print the list of packages/modules provided"),
106 ('requires', None,
107 "print the list of packages/modules required"),
108 ('obsoletes', None,
109 "print the list of packages/modules made obsolete")
Greg Ward82715e12000-04-21 02:28:14 +0000110 ]
Guido van Rossumc1f779c2007-07-03 08:25:58 +0000111 display_option_names = [translate_longopt(x[0]) for x in 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
Martin v. Löwis98da5622005-03-23 18:54:36 +0000174 # 'dist_files' is the list of (command, pyversion, file) that
175 # have been created by any dist commands run so far. This is
176 # filled regardless of whether the run is dry or not. pyversion
177 # gives sysconfig.get_python_version() if the dist file is
178 # specific to a Python version, 'any' if it is good for all
179 # Python versions on the target platform, and '' for a source
180 # file. pyversion should not be used to specify minimum or
181 # maximum required Python versions; use the metainfo for that
182 # instead.
Martin v. Löwis55f1bb82005-03-21 20:56:35 +0000183 self.dist_files = []
184
Greg Wardfe6462c2000-04-04 01:40:52 +0000185 # These options are really the business of various commands, rather
186 # than of the Distribution itself. We provide aliases for them in
187 # Distribution as a convenience to the developer.
Greg Wardfe6462c2000-04-04 01:40:52 +0000188 self.packages = None
Fred Drake0eb32a62004-06-11 21:50:33 +0000189 self.package_data = {}
Greg Wardfe6462c2000-04-04 01:40:52 +0000190 self.package_dir = None
191 self.py_modules = None
192 self.libraries = None
Greg Ward51def7d2000-05-27 01:36:14 +0000193 self.headers = None
Greg Wardfe6462c2000-04-04 01:40:52 +0000194 self.ext_modules = None
195 self.ext_package = None
196 self.include_dirs = None
197 self.extra_path = None
Gregory P. Smithb2e3bb32000-05-12 00:52:23 +0000198 self.scripts = None
Gregory P. Smith6a901dd2000-05-13 03:09:50 +0000199 self.data_files = None
Tarek Ziadé13f7c3b2009-01-09 00:15:45 +0000200 self.password = ''
Greg Wardfe6462c2000-04-04 01:40:52 +0000201
202 # And now initialize bookkeeping stuff that can't be supplied by
203 # the caller at all. 'command_obj' maps command names to
204 # Command instances -- that's how we enforce that every command
205 # class is a singleton.
206 self.command_obj = {}
207
208 # 'have_run' maps command names to boolean values; it keeps track
209 # of whether we have actually run a particular command, to make it
210 # cheap to "run" a command whenever we think we might need to -- if
211 # it's already been done, no need for expensive filesystem
212 # operations, we just check the 'have_run' dictionary and carry on.
213 # It's only safe to query 'have_run' for a command class that has
214 # been instantiated -- a false value will be inserted when the
215 # command object is created, and replaced with a true value when
Greg Ward612eb9f2000-07-27 02:13:20 +0000216 # the command is successfully run. Thus it's probably best to use
Greg Wardfe6462c2000-04-04 01:40:52 +0000217 # '.get()' rather than a straight lookup.
218 self.have_run = {}
219
220 # Now we'll use the attrs dictionary (ultimately, keyword args from
Greg Ward82715e12000-04-21 02:28:14 +0000221 # the setup script) to possibly override any or all of these
222 # distribution options.
223
Greg Wardfe6462c2000-04-04 01:40:52 +0000224 if attrs:
Greg Wardfe6462c2000-04-04 01:40:52 +0000225 # Pull out the set of command options and work on them
226 # specifically. Note that this order guarantees that aliased
227 # command options will override any supplied redundantly
228 # through the general options dictionary.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000229 options = attrs.get('options')
Tarek Ziadé4450dcf2008-12-29 22:38:38 +0000230 if options is not None:
Greg Wardfe6462c2000-04-04 01:40:52 +0000231 del attrs['options']
232 for (command, cmd_options) in options.items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000233 opt_dict = self.get_option_dict(command)
234 for (opt, val) in cmd_options.items():
235 opt_dict[opt] = ("setup script", val)
Greg Wardfe6462c2000-04-04 01:40:52 +0000236
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000237 if 'licence' in attrs:
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +0000238 attrs['license'] = attrs['licence']
239 del attrs['licence']
240 msg = "'licence' distribution option is deprecated; use 'license'"
241 if warnings is not None:
242 warnings.warn(msg)
243 else:
244 sys.stderr.write(msg + "\n")
245
Greg Wardfe6462c2000-04-04 01:40:52 +0000246 # Now work on the rest of the attributes. Any attribute that's
247 # not already defined is invalid!
Tarek Ziadéf11be752009-06-01 22:36:26 +0000248 for (key, val) in attrs.items():
Fred Drakedb7b0022005-03-20 22:19:47 +0000249 if hasattr(self.metadata, "set_" + key):
250 getattr(self.metadata, "set_" + key)(val)
251 elif hasattr(self.metadata, key):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000252 setattr(self.metadata, key, val)
253 elif hasattr(self, key):
254 setattr(self, key, val)
Anthony Baxter73cc8472004-10-13 13:22:34 +0000255 else:
Andrew M. Kuchlingff4ad9a2002-10-31 13:22:41 +0000256 msg = "Unknown distribution option: %s" % repr(key)
257 if warnings is not None:
258 warnings.warn(msg)
259 else:
260 sys.stderr.write(msg + "\n")
Greg Wardfe6462c2000-04-04 01:40:52 +0000261
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000262 self.finalize_options()
Fred Drakeb94b8492001-12-06 20:51:35 +0000263
Tarek Ziadé188789d2009-05-16 18:37:32 +0000264 def get_option_dict(self, command):
Greg Ward0e48cfd2000-05-26 01:00:15 +0000265 """Get the option dictionary for a given command. If that
266 command's option dictionary hasn't been created yet, then create it
267 and return the new dictionary; otherwise, return the existing
268 option dictionary.
269 """
Greg Ward0e48cfd2000-05-26 01:00:15 +0000270 dict = self.command_options.get(command)
271 if dict is None:
272 dict = self.command_options[command] = {}
273 return dict
274
Tarek Ziadé188789d2009-05-16 18:37:32 +0000275 def dump_option_dicts(self, header=None, commands=None, indent=""):
Greg Wardc32d9a62000-05-28 23:53:06 +0000276 from pprint import pformat
277
278 if commands is None: # dump all command option dicts
Guido van Rossumd4ee1672007-10-15 01:27:53 +0000279 commands = sorted(self.command_options.keys())
Greg Wardc32d9a62000-05-28 23:53:06 +0000280
281 if header is not None:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000282 self.announce(indent + header)
Greg Wardc32d9a62000-05-28 23:53:06 +0000283 indent = indent + " "
284
285 if not commands:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000286 self.announce(indent + "no commands known yet")
Greg Wardc32d9a62000-05-28 23:53:06 +0000287 return
288
289 for cmd_name in commands:
290 opt_dict = self.command_options.get(cmd_name)
291 if opt_dict is None:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000292 self.announce(indent +
293 "no option dict for '%s' command" % cmd_name)
Greg Wardc32d9a62000-05-28 23:53:06 +0000294 else:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000295 self.announce(indent +
296 "option dict for '%s' command:" % cmd_name)
Greg Wardc32d9a62000-05-28 23:53:06 +0000297 out = pformat(opt_dict)
Tarek Ziadéf11be752009-06-01 22:36:26 +0000298 for line in out.split('\n'):
299 self.announce(indent + " " + line)
Greg Wardc32d9a62000-05-28 23:53:06 +0000300
Greg Wardd5d8a992000-05-23 01:42:17 +0000301 # -- Config file finding/parsing methods ---------------------------
302
Tarek Ziadé188789d2009-05-16 18:37:32 +0000303 def find_config_files(self):
Gregory P. Smith14263542000-05-12 00:41:33 +0000304 """Find as many configuration files as should be processed for this
305 platform, and return a list of filenames in the order in which they
306 should be parsed. The filenames returned are guaranteed to exist
307 (modulo nasty race conditions).
308
Andrew M. Kuchlingd303b612001-12-06 16:32:05 +0000309 There are three possible config files: distutils.cfg in the
310 Distutils installation directory (ie. where the top-level
311 Distutils __inst__.py file lives), a file in the user's home
312 directory named .pydistutils.cfg on Unix and pydistutils.cfg
Tarek Ziadé36797272010-07-22 12:50:05 +0000313 on Windows/Mac, and setup.cfg in the current directory.
Greg Wardd5d8a992000-05-23 01:42:17 +0000314 """
Gregory P. Smith14263542000-05-12 00:41:33 +0000315 files = []
Greg Wardacf3f6a2000-06-07 02:26:19 +0000316 check_environ()
Gregory P. Smith14263542000-05-12 00:41:33 +0000317
Greg Ward11696872000-06-07 02:29:03 +0000318 # Where to look for the system-wide Distutils config file
319 sys_dir = os.path.dirname(sys.modules['distutils'].__file__)
320
321 # Look for the system config file
322 sys_file = os.path.join(sys_dir, "distutils.cfg")
Greg Wardacf3f6a2000-06-07 02:26:19 +0000323 if os.path.isfile(sys_file):
324 files.append(sys_file)
Gregory P. Smith14263542000-05-12 00:41:33 +0000325
Greg Ward11696872000-06-07 02:29:03 +0000326 # What to call the per-user config file
327 if os.name == 'posix':
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000328 user_filename = ".pydistutils.cfg"
329 else:
330 user_filename = "pydistutils.cfg"
Greg Wardfa9ff762000-10-14 04:06:40 +0000331
Greg Ward11696872000-06-07 02:29:03 +0000332 # And look for the user config file
Tarek Ziadé36797272010-07-22 12:50:05 +0000333 user_file = os.path.join(os.path.expanduser('~'), user_filename)
334 if os.path.isfile(user_file):
335 files.append(user_file)
Gregory P. Smith14263542000-05-12 00:41:33 +0000336
Gregory P. Smith14263542000-05-12 00:41:33 +0000337 # All platforms support local setup.cfg
338 local_file = "setup.cfg"
339 if os.path.isfile(local_file):
340 files.append(local_file)
341
342 return files
343
Tarek Ziadé188789d2009-05-16 18:37:32 +0000344 def parse_config_files(self, filenames=None):
Alexandre Vassalotti1d1eaa42008-05-14 22:59:42 +0000345 from configparser import ConfigParser
Gregory P. Smith14263542000-05-12 00:41:33 +0000346
Georg Brandl521ed522013-05-12 12:36:07 +0200347 # Ignore install directory options if we have a venv
348 if sys.prefix != sys.base_prefix:
349 ignore_options = [
350 'install-base', 'install-platbase', 'install-lib',
351 'install-platlib', 'install-purelib', 'install-headers',
352 'install-scripts', 'install-data', 'prefix', 'exec-prefix',
353 'home', 'user', 'root']
354 else:
355 ignore_options = []
356
357 ignore_options = frozenset(ignore_options)
358
Gregory P. Smith14263542000-05-12 00:41:33 +0000359 if filenames is None:
360 filenames = self.find_config_files()
361
Tarek Ziadéf11be752009-06-01 22:36:26 +0000362 if DEBUG:
363 self.announce("Distribution.parse_config_files():")
Greg Ward47460772000-05-23 03:47:35 +0000364
Gregory P. Smith14263542000-05-12 00:41:33 +0000365 parser = ConfigParser()
Greg Wardd5d8a992000-05-23 01:42:17 +0000366 for filename in filenames:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000367 if DEBUG:
Tarek Ziadé31d46072009-09-21 13:55:19 +0000368 self.announce(" reading %s" % filename)
Greg Wardd5d8a992000-05-23 01:42:17 +0000369 parser.read(filename)
370 for section in parser.sections():
371 options = parser.options(section)
Greg Ward0e48cfd2000-05-26 01:00:15 +0000372 opt_dict = self.get_option_dict(section)
Gregory P. Smith14263542000-05-12 00:41:33 +0000373
Greg Wardd5d8a992000-05-23 01:42:17 +0000374 for opt in options:
Georg Brandl521ed522013-05-12 12:36:07 +0200375 if opt != '__name__' and opt not in ignore_options:
Greg Wardceb9e222000-09-25 01:23:52 +0000376 val = parser.get(section,opt)
Neal Norwitz9d72bb42007-04-17 08:48:32 +0000377 opt = opt.replace('-', '_')
Greg Wardceb9e222000-09-25 01:23:52 +0000378 opt_dict[opt] = (filename, val)
Gregory P. Smith14263542000-05-12 00:41:33 +0000379
Greg Ward47460772000-05-23 03:47:35 +0000380 # Make the ConfigParser forget everything (so we retain
Fred Drakef06116d2004-02-17 22:35:19 +0000381 # the original filenames that options come from)
Greg Ward47460772000-05-23 03:47:35 +0000382 parser.__init__()
Gregory P. Smith14263542000-05-12 00:41:33 +0000383
Greg Wardceb9e222000-09-25 01:23:52 +0000384 # If there was a "global" section in the config file, use it
385 # to set Distribution options.
386
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000387 if 'global' in self.command_options:
Greg Wardceb9e222000-09-25 01:23:52 +0000388 for (opt, (src, val)) in self.command_options['global'].items():
389 alias = self.negative_opt.get(opt)
390 try:
391 if alias:
392 setattr(self, alias, not strtobool(val))
393 elif opt in ('verbose', 'dry_run'): # ugh!
394 setattr(self, opt, strtobool(val))
Fred Draked04573f2004-08-03 16:37:40 +0000395 else:
396 setattr(self, opt, val)
Guido van Rossumb940e112007-01-10 16:19:56 +0000397 except ValueError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000398 raise DistutilsOptionError(msg)
Greg Wardceb9e222000-09-25 01:23:52 +0000399
Greg Wardd5d8a992000-05-23 01:42:17 +0000400 # -- Command-line parsing methods ----------------------------------
401
Tarek Ziadé188789d2009-05-16 18:37:32 +0000402 def parse_command_line(self):
Greg Ward9821bf42000-08-29 01:15:18 +0000403 """Parse the setup script's command line, taken from the
404 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
405 -- see 'setup()' in core.py). This list is first processed for
406 "global options" -- options that set attributes of the Distribution
407 instance. Then, it is alternately scanned for Distutils commands
408 and options for that command. Each new command terminates the
409 options for the previous command. The allowed options for a
410 command are determined by the 'user_options' attribute of the
411 command class -- thus, we have to be able to load command classes
412 in order to parse the command line. Any error in that 'options'
413 attribute raises DistutilsGetoptError; any error on the
414 command-line raises DistutilsArgError. If no Distutils commands
415 were found on the command line, raises DistutilsArgError. Return
Greg Wardceb9e222000-09-25 01:23:52 +0000416 true if command-line was successfully parsed and we should carry
Greg Ward9821bf42000-08-29 01:15:18 +0000417 on with executing commands; false if no errors but we shouldn't
418 execute commands (currently, this only happens if user asks for
419 help).
Greg Wardd5d8a992000-05-23 01:42:17 +0000420 """
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000421 #
Fred Drake981a1782001-08-10 18:59:30 +0000422 # We now have enough information to show the Macintosh dialog
423 # that allows the user to interactively specify the "command line".
Andrew M. Kuchling3f819ec2001-01-15 16:09:35 +0000424 #
Fred Draked04573f2004-08-03 16:37:40 +0000425 toplevel_options = self._get_toplevel_options()
Fred Drakeb94b8492001-12-06 20:51:35 +0000426
Greg Wardfe6462c2000-04-04 01:40:52 +0000427 # We have to parse the command line a bit at a time -- global
428 # options, then the first command, then its options, and so on --
429 # because each command will be handled by a different class, and
Greg Wardd5d8a992000-05-23 01:42:17 +0000430 # the options that are valid for a particular class aren't known
431 # until we have loaded the command class, which doesn't happen
432 # until we know what the command is.
Greg Wardfe6462c2000-04-04 01:40:52 +0000433
434 self.commands = []
Fred Draked04573f2004-08-03 16:37:40 +0000435 parser = FancyGetopt(toplevel_options + self.display_options)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000436 parser.set_negative_aliases(self.negative_opt)
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +0000437 parser.set_aliases({'licence': 'license'})
Greg Wardfd7b91e2000-09-26 01:52:25 +0000438 args = parser.getopt(args=self.script_args, object=self)
Greg Ward82715e12000-04-21 02:28:14 +0000439 option_order = parser.get_option_order()
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000440 log.set_verbosity(self.verbose)
Greg Wardfe6462c2000-04-04 01:40:52 +0000441
Greg Ward82715e12000-04-21 02:28:14 +0000442 # for display options we return immediately
443 if self.handle_display_options(option_order):
Greg Wardfe6462c2000-04-04 01:40:52 +0000444 return
Greg Wardfe6462c2000-04-04 01:40:52 +0000445 while args:
Greg Wardd5d8a992000-05-23 01:42:17 +0000446 args = self._parse_command_opts(parser, args)
447 if args is None: # user asked for help (and got it)
Greg Wardfe6462c2000-04-04 01:40:52 +0000448 return
Greg Wardfe6462c2000-04-04 01:40:52 +0000449
Greg Wardd5d8a992000-05-23 01:42:17 +0000450 # Handle the cases of --help as a "global" option, ie.
451 # "setup.py --help" and "setup.py --help command ...". For the
452 # former, we show global options (--verbose, --dry-run, etc.)
453 # and display-only options (--name, --version, etc.); for the
454 # latter, we omit the display-only options and show help for
455 # each command listed on the command line.
Greg Wardfe6462c2000-04-04 01:40:52 +0000456 if self.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000457 self._show_help(parser,
458 display_options=len(self.commands) == 0,
459 commands=self.commands)
Greg Wardfe6462c2000-04-04 01:40:52 +0000460 return
461
462 # Oops, no commands found -- an end-user error
463 if not self.commands:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000464 raise DistutilsArgError("no commands supplied")
Greg Wardfe6462c2000-04-04 01:40:52 +0000465
466 # All is well: return true
Collin Winter5b7e9d72007-08-30 03:52:21 +0000467 return True
Greg Wardfe6462c2000-04-04 01:40:52 +0000468
Tarek Ziadé188789d2009-05-16 18:37:32 +0000469 def _get_toplevel_options(self):
Fred Draked04573f2004-08-03 16:37:40 +0000470 """Return the non-display options recognized at the top level.
471
472 This includes options that are recognized *only* at the top
473 level as well as options recognized for commands.
474 """
475 return self.global_options + [
476 ("command-packages=", None,
477 "list of packages that provide distutils commands"),
478 ]
479
Tarek Ziadé188789d2009-05-16 18:37:32 +0000480 def _parse_command_opts(self, parser, args):
Greg Wardd5d8a992000-05-23 01:42:17 +0000481 """Parse the command-line options for a single command.
482 'parser' must be a FancyGetopt instance; 'args' must be the list
483 of arguments, starting with the current command (whose options
484 we are about to parse). Returns a new version of 'args' with
485 the next command at the front of the list; will be the empty
486 list if there are no more commands on the command line. Returns
487 None if the user asked for help on this command.
488 """
489 # late import because of mutual dependence between these modules
490 from distutils.cmd import Command
491
492 # Pull the current command from the head of the command line
493 command = args[0]
Greg Wardfd7b91e2000-09-26 01:52:25 +0000494 if not command_re.match(command):
Collin Winter5b7e9d72007-08-30 03:52:21 +0000495 raise SystemExit("invalid command name '%s'" % command)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000496 self.commands.append(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000497
498 # Dig up the command class that implements this command, so we
499 # 1) know that it's a valid command, and 2) know which options
500 # it takes.
501 try:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000502 cmd_class = self.get_command_class(command)
Guido van Rossumb940e112007-01-10 16:19:56 +0000503 except DistutilsModuleError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000504 raise DistutilsArgError(msg)
Greg Wardd5d8a992000-05-23 01:42:17 +0000505
506 # Require that the command class be derived from Command -- want
507 # to be sure that the basic "command" interface is implemented.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000508 if not issubclass(cmd_class, Command):
Collin Winter5b7e9d72007-08-30 03:52:21 +0000509 raise DistutilsClassError(
510 "command class %s must subclass Command" % cmd_class)
Greg Wardd5d8a992000-05-23 01:42:17 +0000511
512 # Also make sure that the command object provides a list of its
513 # known options.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000514 if not (hasattr(cmd_class, 'user_options') and
Guido van Rossum13257902007-06-07 23:15:56 +0000515 isinstance(cmd_class.user_options, list)):
Collin Winter5b7e9d72007-08-30 03:52:21 +0000516 raise DistutilsClassError(("command class %s must provide " +
Greg Wardd5d8a992000-05-23 01:42:17 +0000517 "'user_options' attribute (a list of tuples)") % \
Collin Winter5b7e9d72007-08-30 03:52:21 +0000518 cmd_class)
Greg Wardd5d8a992000-05-23 01:42:17 +0000519
520 # If the command class has a list of negative alias options,
521 # merge it in with the global negative aliases.
522 negative_opt = self.negative_opt
Greg Wardfd7b91e2000-09-26 01:52:25 +0000523 if hasattr(cmd_class, 'negative_opt'):
Antoine Pitrou56a00de2009-05-15 17:34:21 +0000524 negative_opt = negative_opt.copy()
Greg Wardfd7b91e2000-09-26 01:52:25 +0000525 negative_opt.update(cmd_class.negative_opt)
Greg Wardd5d8a992000-05-23 01:42:17 +0000526
Greg Wardfa9ff762000-10-14 04:06:40 +0000527 # Check for help_options in command class. They have a different
528 # format (tuple of four) so we need to preprocess them here.
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000529 if (hasattr(cmd_class, 'help_options') and
Guido van Rossum13257902007-06-07 23:15:56 +0000530 isinstance(cmd_class.help_options, list)):
Greg Ward2ff78872000-06-24 00:23:20 +0000531 help_options = fix_help_options(cmd_class.help_options)
532 else:
Greg Ward55fced32000-06-24 01:22:41 +0000533 help_options = []
Greg Ward2ff78872000-06-24 00:23:20 +0000534
Greg Ward9d17a7a2000-06-07 03:00:06 +0000535
Greg Wardd5d8a992000-05-23 01:42:17 +0000536 # All commands support the global options too, just by adding
537 # in 'global_options'.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000538 parser.set_option_table(self.global_options +
539 cmd_class.user_options +
540 help_options)
541 parser.set_negative_aliases(negative_opt)
542 (args, opts) = parser.getopt(args[1:])
Greg Ward47460772000-05-23 03:47:35 +0000543 if hasattr(opts, 'help') and opts.help:
Greg Wardd5d8a992000-05-23 01:42:17 +0000544 self._show_help(parser, display_options=0, commands=[cmd_class])
545 return
546
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000547 if (hasattr(cmd_class, 'help_options') and
Guido van Rossum13257902007-06-07 23:15:56 +0000548 isinstance(cmd_class.help_options, list)):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000549 help_option_found=0
550 for (help_option, short, desc, func) in cmd_class.help_options:
551 if hasattr(opts, parser.get_attr_name(help_option)):
552 help_option_found=1
Florent Xicluna5d1155c2011-10-28 14:45:05 +0200553 if callable(func):
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000554 func()
Greg Ward55fced32000-06-24 01:22:41 +0000555 else:
Fred Drake981a1782001-08-10 18:59:30 +0000556 raise DistutilsClassError(
Walter Dörwald70a6b492004-02-12 17:35:32 +0000557 "invalid help function %r for help option '%s': "
Fred Drake981a1782001-08-10 18:59:30 +0000558 "must be a callable object (function, etc.)"
Walter Dörwald70a6b492004-02-12 17:35:32 +0000559 % (func, help_option))
Greg Ward55fced32000-06-24 01:22:41 +0000560
Fred Drakeb94b8492001-12-06 20:51:35 +0000561 if help_option_found:
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000562 return
Greg Ward9d17a7a2000-06-07 03:00:06 +0000563
Greg Wardd5d8a992000-05-23 01:42:17 +0000564 # Put the options from the command-line into their official
565 # holding pen, the 'command_options' dictionary.
Greg Ward0e48cfd2000-05-26 01:00:15 +0000566 opt_dict = self.get_option_dict(command)
Greg Wardd5d8a992000-05-23 01:42:17 +0000567 for (name, value) in vars(opts).items():
Greg Ward0e48cfd2000-05-26 01:00:15 +0000568 opt_dict[name] = ("command line", value)
Greg Wardd5d8a992000-05-23 01:42:17 +0000569
570 return args
571
Tarek Ziadé188789d2009-05-16 18:37:32 +0000572 def finalize_options(self):
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000573 """Set final values for all the options on the Distribution
574 instance, analogous to the .finalize_options() method of Command
575 objects.
576 """
Tarek Ziadéf11be752009-06-01 22:36:26 +0000577 for attr in ('keywords', 'platforms'):
578 value = getattr(self.metadata, attr)
579 if value is None:
580 continue
581 if isinstance(value, str):
582 value = [elm.strip() for elm in value.split(',')]
583 setattr(self.metadata, attr, value)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000584
Tarek Ziadé188789d2009-05-16 18:37:32 +0000585 def _show_help(self, parser, global_options=1, display_options=1,
586 commands=[]):
Greg Wardd5d8a992000-05-23 01:42:17 +0000587 """Show help for the setup script command-line in the form of
588 several lists of command-line options. 'parser' should be a
589 FancyGetopt instance; do not expect it to be returned in the
590 same state, as its option table will be reset to make it
591 generate the correct help text.
592
593 If 'global_options' is true, lists the global options:
594 --verbose, --dry-run, etc. If 'display_options' is true, lists
595 the "display-only" options: --name, --version, etc. Finally,
596 lists per-command help for every command name or command class
597 in 'commands'.
598 """
599 # late import because of mutual dependence between these modules
Greg Ward9821bf42000-08-29 01:15:18 +0000600 from distutils.core import gen_usage
Greg Wardd5d8a992000-05-23 01:42:17 +0000601 from distutils.cmd import Command
602
603 if global_options:
Fred Draked04573f2004-08-03 16:37:40 +0000604 if display_options:
605 options = self._get_toplevel_options()
606 else:
607 options = self.global_options
608 parser.set_option_table(options)
Martin v. Löwis8ed338a2005-03-03 08:12:27 +0000609 parser.print_help(self.common_usage + "\nGlobal options:")
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000610 print('')
Greg Wardd5d8a992000-05-23 01:42:17 +0000611
612 if display_options:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000613 parser.set_option_table(self.display_options)
614 parser.print_help(
Greg Wardd5d8a992000-05-23 01:42:17 +0000615 "Information display options (just display " +
616 "information, ignore any commands)")
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000617 print('')
Greg Wardd5d8a992000-05-23 01:42:17 +0000618
619 for command in self.commands:
Guido van Rossum13257902007-06-07 23:15:56 +0000620 if isinstance(command, type) and issubclass(command, Command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000621 klass = command
622 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000623 klass = self.get_command_class(command)
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000624 if (hasattr(klass, 'help_options') and
Guido van Rossum13257902007-06-07 23:15:56 +0000625 isinstance(klass.help_options, list)):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000626 parser.set_option_table(klass.user_options +
627 fix_help_options(klass.help_options))
Jeremy Hylton65d6edb2000-07-07 20:45:21 +0000628 else:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000629 parser.set_option_table(klass.user_options)
630 parser.print_help("Options for '%s' command:" % klass.__name__)
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000631 print('')
Greg Wardd5d8a992000-05-23 01:42:17 +0000632
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000633 print(gen_usage(self.script_name))
Greg Wardd5d8a992000-05-23 01:42:17 +0000634
Tarek Ziadé188789d2009-05-16 18:37:32 +0000635 def handle_display_options(self, option_order):
Greg Ward82715e12000-04-21 02:28:14 +0000636 """If there were any non-global "display-only" options
Greg Wardd5d8a992000-05-23 01:42:17 +0000637 (--help-commands or the metadata display options) on the command
638 line, display the requested info and return true; else return
639 false.
640 """
Greg Ward9821bf42000-08-29 01:15:18 +0000641 from distutils.core import gen_usage
Greg Ward82715e12000-04-21 02:28:14 +0000642
643 # User just wants a list of commands -- we'll print it out and stop
644 # processing now (ie. if they ran "setup --help-commands foo bar",
645 # we ignore "foo bar").
646 if self.help_commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000647 self.print_commands()
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000648 print('')
649 print(gen_usage(self.script_name))
Greg Ward82715e12000-04-21 02:28:14 +0000650 return 1
651
652 # If user supplied any of the "display metadata" options, then
653 # display that metadata in the order in which the user supplied the
654 # metadata options.
655 any_display_options = 0
656 is_display_option = {}
657 for option in self.display_options:
658 is_display_option[option[0]] = 1
659
660 for (opt, val) in option_order:
661 if val and is_display_option.get(opt):
Greg Ward2f2b6c62000-09-25 01:58:07 +0000662 opt = translate_longopt(opt)
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000663 value = getattr(self.metadata, "get_"+opt)()
664 if opt in ['keywords', 'platforms']:
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000665 print(','.join(value))
Fred Drakedb7b0022005-03-20 22:19:47 +0000666 elif opt in ('classifiers', 'provides', 'requires',
667 'obsoletes'):
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000668 print('\n'.join(value))
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +0000669 else:
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000670 print(value)
Greg Ward82715e12000-04-21 02:28:14 +0000671 any_display_options = 1
672
673 return any_display_options
674
Tarek Ziadé188789d2009-05-16 18:37:32 +0000675 def print_command_list(self, commands, header, max_length):
Greg Wardfe6462c2000-04-04 01:40:52 +0000676 """Print a subset of the list of all commands -- used by
Greg Wardd5d8a992000-05-23 01:42:17 +0000677 'print_commands()'.
678 """
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000679 print(header + ":")
Greg Wardfe6462c2000-04-04 01:40:52 +0000680
681 for cmd in commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000682 klass = self.cmdclass.get(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000683 if not klass:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000684 klass = self.get_command_class(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000685 try:
686 description = klass.description
687 except AttributeError:
688 description = "(no description available)"
689
Tarek Ziadé0d3fa832009-07-04 03:00:50 +0000690 print(" %-*s %s" % (max_length, cmd, description))
Greg Wardfe6462c2000-04-04 01:40:52 +0000691
Tarek Ziadé188789d2009-05-16 18:37:32 +0000692 def print_commands(self):
Greg Wardd5d8a992000-05-23 01:42:17 +0000693 """Print out a help message listing all available commands with a
694 description of each. The list is divided into "standard commands"
695 (listed in distutils.command.__all__) and "extra commands"
696 (mentioned in self.cmdclass, but not a standard command). The
697 descriptions come from the command class attribute
698 'description'.
699 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000700 import distutils.command
701 std_commands = distutils.command.__all__
702 is_std = {}
703 for cmd in std_commands:
704 is_std[cmd] = 1
705
706 extra_commands = []
707 for cmd in self.cmdclass.keys():
708 if not is_std.get(cmd):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000709 extra_commands.append(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000710
711 max_length = 0
712 for cmd in (std_commands + extra_commands):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000713 if len(cmd) > max_length:
714 max_length = len(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000715
Greg Wardfd7b91e2000-09-26 01:52:25 +0000716 self.print_command_list(std_commands,
717 "Standard commands",
718 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000719 if extra_commands:
Guido van Rossumbe19ed72007-02-09 05:37:30 +0000720 print()
Greg Wardfd7b91e2000-09-26 01:52:25 +0000721 self.print_command_list(extra_commands,
722 "Extra commands",
723 max_length)
Greg Wardfe6462c2000-04-04 01:40:52 +0000724
Tarek Ziadé188789d2009-05-16 18:37:32 +0000725 def get_command_list(self):
Greg Wardf6fc8752000-11-11 02:47:11 +0000726 """Get a list of (command, description) tuples.
727 The list is divided into "standard commands" (listed in
728 distutils.command.__all__) and "extra commands" (mentioned in
729 self.cmdclass, but not a standard command). The descriptions come
730 from the command class attribute 'description'.
731 """
732 # Currently this is only used on Mac OS, for the Mac-only GUI
733 # Distutils interface (by Jack Jansen)
Greg Wardf6fc8752000-11-11 02:47:11 +0000734 import distutils.command
735 std_commands = distutils.command.__all__
736 is_std = {}
737 for cmd in std_commands:
738 is_std[cmd] = 1
739
740 extra_commands = []
741 for cmd in self.cmdclass.keys():
742 if not is_std.get(cmd):
743 extra_commands.append(cmd)
744
745 rv = []
746 for cmd in (std_commands + extra_commands):
747 klass = self.cmdclass.get(cmd)
748 if not klass:
749 klass = self.get_command_class(cmd)
750 try:
751 description = klass.description
752 except AttributeError:
753 description = "(no description available)"
754 rv.append((cmd, description))
755 return rv
Greg Wardfe6462c2000-04-04 01:40:52 +0000756
757 # -- Command class/object methods ----------------------------------
758
Tarek Ziadé188789d2009-05-16 18:37:32 +0000759 def get_command_packages(self):
Fred Draked04573f2004-08-03 16:37:40 +0000760 """Return a list of packages from which commands are loaded."""
761 pkgs = self.command_packages
Tarek Ziadéf11be752009-06-01 22:36:26 +0000762 if not isinstance(pkgs, list):
763 if pkgs is None:
764 pkgs = ''
765 pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != '']
Fred Draked04573f2004-08-03 16:37:40 +0000766 if "distutils.command" not in pkgs:
767 pkgs.insert(0, "distutils.command")
768 self.command_packages = pkgs
769 return pkgs
770
Tarek Ziadé188789d2009-05-16 18:37:32 +0000771 def get_command_class(self, command):
Greg Wardd5d8a992000-05-23 01:42:17 +0000772 """Return the class that implements the Distutils command named by
773 'command'. First we check the 'cmdclass' dictionary; if the
774 command is mentioned there, we fetch the class object from the
775 dictionary and return it. Otherwise we load the command module
776 ("distutils.command." + command) and fetch the command class from
777 the module. The loaded class is also stored in 'cmdclass'
778 to speed future calls to 'get_command_class()'.
Greg Wardfe6462c2000-04-04 01:40:52 +0000779
Gregory P. Smith14263542000-05-12 00:41:33 +0000780 Raises DistutilsModuleError if the expected module could not be
Greg Wardd5d8a992000-05-23 01:42:17 +0000781 found, or if that module does not define the expected class.
782 """
783 klass = self.cmdclass.get(command)
784 if klass:
785 return klass
Greg Wardfe6462c2000-04-04 01:40:52 +0000786
Fred Draked04573f2004-08-03 16:37:40 +0000787 for pkgname in self.get_command_packages():
788 module_name = "%s.%s" % (pkgname, command)
789 klass_name = command
Greg Wardfe6462c2000-04-04 01:40:52 +0000790
Fred Draked04573f2004-08-03 16:37:40 +0000791 try:
792 __import__ (module_name)
793 module = sys.modules[module_name]
794 except ImportError:
795 continue
Greg Wardfe6462c2000-04-04 01:40:52 +0000796
Fred Draked04573f2004-08-03 16:37:40 +0000797 try:
798 klass = getattr(module, klass_name)
799 except AttributeError:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000800 raise DistutilsModuleError(
801 "invalid command '%s' (no class '%s' in module '%s')"
802 % (command, klass_name, module_name))
Greg Wardfe6462c2000-04-04 01:40:52 +0000803
Fred Draked04573f2004-08-03 16:37:40 +0000804 self.cmdclass[command] = klass
805 return klass
806
807 raise DistutilsModuleError("invalid command '%s'" % command)
808
Tarek Ziadé188789d2009-05-16 18:37:32 +0000809 def get_command_obj(self, command, create=1):
Greg Wardd5d8a992000-05-23 01:42:17 +0000810 """Return the command object for 'command'. Normally this object
Greg Ward612eb9f2000-07-27 02:13:20 +0000811 is cached on a previous call to 'get_command_obj()'; if no command
Greg Wardd5d8a992000-05-23 01:42:17 +0000812 object for 'command' is in the cache, then we either create and
813 return it (if 'create' is true) or return None.
814 """
815 cmd_obj = self.command_obj.get(command)
Greg Wardfe6462c2000-04-04 01:40:52 +0000816 if not cmd_obj and create:
Greg Ward2bd3f422000-06-02 01:59:33 +0000817 if DEBUG:
Tarek Ziadéf11be752009-06-01 22:36:26 +0000818 self.announce("Distribution.get_command_obj(): " \
819 "creating '%s' command object" % command)
Greg Ward47460772000-05-23 03:47:35 +0000820
Greg Wardd5d8a992000-05-23 01:42:17 +0000821 klass = self.get_command_class(command)
Greg Ward47460772000-05-23 03:47:35 +0000822 cmd_obj = self.command_obj[command] = klass(self)
823 self.have_run[command] = 0
824
825 # Set any options that were supplied in config files
826 # or on the command line. (NB. support for error
827 # reporting is lame here: any errors aren't reported
828 # until 'finalize_options()' is called, which means
829 # we won't report the source of the error.)
830 options = self.command_options.get(command)
831 if options:
Greg Wardc32d9a62000-05-28 23:53:06 +0000832 self._set_command_options(cmd_obj, options)
Greg Wardfe6462c2000-04-04 01:40:52 +0000833
834 return cmd_obj
835
Tarek Ziadé188789d2009-05-16 18:37:32 +0000836 def _set_command_options(self, command_obj, option_dict=None):
Greg Wardc32d9a62000-05-28 23:53:06 +0000837 """Set the options for 'command_obj' from 'option_dict'. Basically
838 this means copying elements of a dictionary ('option_dict') to
839 attributes of an instance ('command').
840
Greg Wardceb9e222000-09-25 01:23:52 +0000841 'command_obj' must be a Command instance. If 'option_dict' is not
Greg Wardc32d9a62000-05-28 23:53:06 +0000842 supplied, uses the standard option dictionary for this command
843 (from 'self.command_options').
844 """
Greg Wardc32d9a62000-05-28 23:53:06 +0000845 command_name = command_obj.get_command_name()
846 if option_dict is None:
847 option_dict = self.get_option_dict(command_name)
848
Tarek Ziadéf11be752009-06-01 22:36:26 +0000849 if DEBUG:
850 self.announce(" setting options for '%s' command:" % command_name)
Greg Wardc32d9a62000-05-28 23:53:06 +0000851 for (option, (source, value)) in option_dict.items():
Tarek Ziadéf11be752009-06-01 22:36:26 +0000852 if DEBUG:
853 self.announce(" %s = %s (from %s)" % (option, value,
854 source))
Greg Wardceb9e222000-09-25 01:23:52 +0000855 try:
Amaury Forgeot d'Arc61cb0872008-07-26 20:09:45 +0000856 bool_opts = [translate_longopt(o)
857 for o in command_obj.boolean_options]
Greg Wardceb9e222000-09-25 01:23:52 +0000858 except AttributeError:
859 bool_opts = []
860 try:
861 neg_opt = command_obj.negative_opt
862 except AttributeError:
863 neg_opt = {}
864
865 try:
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000866 is_string = isinstance(value, str)
Guido van Rossume2b70bc2006-08-18 22:13:04 +0000867 if option in neg_opt and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000868 setattr(command_obj, neg_opt[option], not strtobool(value))
Greg Ward2c08cf02000-09-27 00:15:37 +0000869 elif option in bool_opts and is_string:
Greg Wardceb9e222000-09-25 01:23:52 +0000870 setattr(command_obj, option, strtobool(value))
871 elif hasattr(command_obj, option):
872 setattr(command_obj, option, value)
873 else:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000874 raise DistutilsOptionError(
875 "error in %s: command '%s' has no such option '%s'"
876 % (source, command_name, option))
Guido van Rossumb940e112007-01-10 16:19:56 +0000877 except ValueError as msg:
Collin Winter5b7e9d72007-08-30 03:52:21 +0000878 raise DistutilsOptionError(msg)
Greg Wardc32d9a62000-05-28 23:53:06 +0000879
Tarek Ziadé188789d2009-05-16 18:37:32 +0000880 def reinitialize_command(self, command, reinit_subcommands=0):
Greg Wardc32d9a62000-05-28 23:53:06 +0000881 """Reinitializes a command to the state it was in when first
882 returned by 'get_command_obj()': ie., initialized but not yet
Greg Ward7d9c7052000-06-28 01:25:27 +0000883 finalized. This provides the opportunity to sneak option
Greg Wardc32d9a62000-05-28 23:53:06 +0000884 values in programmatically, overriding or supplementing
885 user-supplied values from the config files and command line.
886 You'll have to re-finalize the command object (by calling
887 'finalize_options()' or 'ensure_finalized()') before using it for
Fred Drakeb94b8492001-12-06 20:51:35 +0000888 real.
Greg Wardc32d9a62000-05-28 23:53:06 +0000889
Greg Wardf449ea52000-09-16 15:23:28 +0000890 'command' should be a command name (string) or command object. If
891 'reinit_subcommands' is true, also reinitializes the command's
892 sub-commands, as declared by the 'sub_commands' class attribute (if
893 it has one). See the "install" command for an example. Only
894 reinitializes the sub-commands that actually matter, ie. those
895 whose test predicates return true.
896
Greg Wardc32d9a62000-05-28 23:53:06 +0000897 Returns the reinitialized command object.
898 """
899 from distutils.cmd import Command
900 if not isinstance(command, Command):
901 command_name = command
902 command = self.get_command_obj(command_name)
903 else:
904 command_name = command.get_command_name()
905
906 if not command.finalized:
Greg Ward282c7a02000-06-01 01:09:47 +0000907 return command
Greg Wardc32d9a62000-05-28 23:53:06 +0000908 command.initialize_options()
909 command.finalized = 0
Greg Ward43955c92000-06-06 02:52:36 +0000910 self.have_run[command_name] = 0
Greg Wardc32d9a62000-05-28 23:53:06 +0000911 self._set_command_options(command)
Greg Wardf449ea52000-09-16 15:23:28 +0000912
Greg Wardf449ea52000-09-16 15:23:28 +0000913 if reinit_subcommands:
Greg Wardf449ea52000-09-16 15:23:28 +0000914 for sub in command.get_sub_commands():
Fred Drakeb94b8492001-12-06 20:51:35 +0000915 self.reinitialize_command(sub, reinit_subcommands)
Greg Wardf449ea52000-09-16 15:23:28 +0000916
Greg Wardc32d9a62000-05-28 23:53:06 +0000917 return command
918
Greg Wardfe6462c2000-04-04 01:40:52 +0000919 # -- Methods that operate on the Distribution ----------------------
920
Tarek Ziadé05bf01a2009-07-04 02:04:21 +0000921 def announce(self, msg, level=log.INFO):
922 log.log(level, msg)
Greg Wardfe6462c2000-04-04 01:40:52 +0000923
Tarek Ziadé188789d2009-05-16 18:37:32 +0000924 def run_commands(self):
Greg Ward82715e12000-04-21 02:28:14 +0000925 """Run each command that was seen on the setup script command line.
Greg Wardd5d8a992000-05-23 01:42:17 +0000926 Uses the list of commands found and cache of command objects
Greg Wardfd7b91e2000-09-26 01:52:25 +0000927 created by 'get_command_obj()'.
928 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000929 for cmd in self.commands:
Greg Wardfd7b91e2000-09-26 01:52:25 +0000930 self.run_command(cmd)
Greg Wardfe6462c2000-04-04 01:40:52 +0000931
Greg Wardfe6462c2000-04-04 01:40:52 +0000932 # -- Methods that operate on its Commands --------------------------
933
Tarek Ziadé188789d2009-05-16 18:37:32 +0000934 def run_command(self, command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000935 """Do whatever it takes to run a command (including nothing at all,
Greg Wardd5d8a992000-05-23 01:42:17 +0000936 if the command has already been run). Specifically: if we have
937 already created and run the command named by 'command', return
938 silently without doing anything. If the command named by 'command'
939 doesn't even have a command object yet, create one. Then invoke
940 'run()' on that command object (or an existing one).
941 """
Greg Wardfe6462c2000-04-04 01:40:52 +0000942 # Already been here, done that? then return silently.
Greg Wardfd7b91e2000-09-26 01:52:25 +0000943 if self.have_run.get(command):
Greg Wardfe6462c2000-04-04 01:40:52 +0000944 return
945
Jeremy Hyltoncd8a1142002-06-04 20:14:43 +0000946 log.info("running %s", command)
Greg Wardfd7b91e2000-09-26 01:52:25 +0000947 cmd_obj = self.get_command_obj(command)
948 cmd_obj.ensure_finalized()
949 cmd_obj.run()
Greg Wardfe6462c2000-04-04 01:40:52 +0000950 self.have_run[command] = 1
951
952
Greg Wardfe6462c2000-04-04 01:40:52 +0000953 # -- Distribution query methods ------------------------------------
954
Tarek Ziadé188789d2009-05-16 18:37:32 +0000955 def has_pure_modules(self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000956 return len(self.packages or self.py_modules or []) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000957
Tarek Ziadé188789d2009-05-16 18:37:32 +0000958 def has_ext_modules(self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000959 return self.ext_modules and len(self.ext_modules) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000960
Tarek Ziadé188789d2009-05-16 18:37:32 +0000961 def has_c_libraries(self):
Greg Wardfd7b91e2000-09-26 01:52:25 +0000962 return self.libraries and len(self.libraries) > 0
Greg Wardfe6462c2000-04-04 01:40:52 +0000963
Tarek Ziadé188789d2009-05-16 18:37:32 +0000964 def has_modules(self):
Greg Wardfe6462c2000-04-04 01:40:52 +0000965 return self.has_pure_modules() or self.has_ext_modules()
966
Tarek Ziadé188789d2009-05-16 18:37:32 +0000967 def has_headers(self):
Greg Ward51def7d2000-05-27 01:36:14 +0000968 return self.headers and len(self.headers) > 0
969
Tarek Ziadé188789d2009-05-16 18:37:32 +0000970 def has_scripts(self):
Greg Ward44a61bb2000-05-20 15:06:48 +0000971 return self.scripts and len(self.scripts) > 0
972
Tarek Ziadé188789d2009-05-16 18:37:32 +0000973 def has_data_files(self):
Greg Ward44a61bb2000-05-20 15:06:48 +0000974 return self.data_files and len(self.data_files) > 0
975
Tarek Ziadé188789d2009-05-16 18:37:32 +0000976 def is_pure(self):
Greg Wardfe6462c2000-04-04 01:40:52 +0000977 return (self.has_pure_modules() and
978 not self.has_ext_modules() and
979 not self.has_c_libraries())
980
Greg Ward82715e12000-04-21 02:28:14 +0000981 # -- Metadata query methods ----------------------------------------
982
983 # If you're looking for 'get_name()', 'get_version()', and so forth,
984 # they are defined in a sneaky way: the constructor binds self.get_XXX
985 # to self.metadata.get_XXX. The actual code is in the
986 # DistributionMetadata class, below.
987
Greg Ward82715e12000-04-21 02:28:14 +0000988class DistributionMetadata:
989 """Dummy class to hold the distribution meta-data: name, version,
Greg Wardfd7b91e2000-09-26 01:52:25 +0000990 author, and so forth.
991 """
Greg Ward82715e12000-04-21 02:28:14 +0000992
Neil Schemenauera8aefe52001-09-03 15:47:21 +0000993 _METHOD_BASENAMES = ("name", "version", "author", "author_email",
994 "maintainer", "maintainer_email", "url",
995 "license", "description", "long_description",
996 "keywords", "platforms", "fullname", "contact",
Andrew M. Kuchlinga52b8522003-03-03 20:07:27 +0000997 "contact_email", "license", "classifiers",
Fred Drakedb7b0022005-03-20 22:19:47 +0000998 "download_url",
999 # PEP 314
1000 "provides", "requires", "obsoletes",
1001 )
Neil Schemenauera8aefe52001-09-03 15:47:21 +00001002
Jason R. Coombs3492e392013-11-10 18:15:03 -05001003 def __init__(self, path=None):
1004 if path is not None:
1005 self.read_pkg_file(open(path))
1006 else:
1007 self.name = None
1008 self.version = None
1009 self.author = None
1010 self.author_email = None
1011 self.maintainer = None
1012 self.maintainer_email = None
1013 self.url = None
1014 self.license = None
1015 self.description = None
1016 self.long_description = None
1017 self.keywords = None
1018 self.platforms = None
1019 self.classifiers = None
1020 self.download_url = None
1021 # PEP 314
1022 self.provides = None
1023 self.requires = None
1024 self.obsoletes = None
1025
1026 def read_pkg_file(self, file):
1027 """Reads the metadata values from a file object."""
1028 msg = message_from_file(file)
1029
1030 def _read_field(name):
1031 value = msg[name]
1032 if value == 'UNKNOWN':
1033 return None
1034 return value
1035
1036 def _read_list(name):
1037 values = msg.get_all(name, None)
1038 if values == []:
1039 return None
1040 return values
1041
1042 metadata_version = msg['metadata-version']
1043 self.name = _read_field('name')
1044 self.version = _read_field('version')
1045 self.description = _read_field('summary')
1046 # we are filling author only.
1047 self.author = _read_field('author')
Greg Ward82715e12000-04-21 02:28:14 +00001048 self.maintainer = None
Jason R. Coombs3492e392013-11-10 18:15:03 -05001049 self.author_email = _read_field('author-email')
Greg Ward82715e12000-04-21 02:28:14 +00001050 self.maintainer_email = None
Jason R. Coombs3492e392013-11-10 18:15:03 -05001051 self.url = _read_field('home-page')
1052 self.license = _read_field('license')
1053
1054 if 'download-url' in msg:
1055 self.download_url = _read_field('download-url')
1056 else:
1057 self.download_url = None
1058
1059 self.long_description = _read_field('description')
1060 self.description = _read_field('summary')
1061
1062 if 'keywords' in msg:
1063 self.keywords = _read_field('keywords').split(',')
1064
1065 self.platforms = _read_list('platform')
1066 self.classifiers = _read_list('classifier')
1067
1068 # PEP 314 - these fields only exist in 1.1
1069 if metadata_version == '1.1':
1070 self.requires = _read_list('requires')
1071 self.provides = _read_list('provides')
1072 self.obsoletes = _read_list('obsoletes')
1073 else:
1074 self.requires = None
1075 self.provides = None
1076 self.obsoletes = None
Fred Drakeb94b8492001-12-06 20:51:35 +00001077
Tarek Ziadé188789d2009-05-16 18:37:32 +00001078 def write_pkg_info(self, base_dir):
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001079 """Write the PKG-INFO file into the release tree.
1080 """
Victor Stinnera1bea6e2011-09-05 23:44:56 +02001081 with open(os.path.join(base_dir, 'PKG-INFO'), 'w',
1082 encoding='UTF-8') as pkg_info:
Éric Araujobee5cef2010-11-05 23:51:56 +00001083 self.write_pkg_file(pkg_info)
Fred Drakeb94b8492001-12-06 20:51:35 +00001084
Tarek Ziadé188789d2009-05-16 18:37:32 +00001085 def write_pkg_file(self, file):
Fred Drakedb7b0022005-03-20 22:19:47 +00001086 """Write the PKG-INFO format data to a file object.
1087 """
1088 version = '1.0'
Éric Araujo13e8c8e2011-09-10 01:51:40 +02001089 if (self.provides or self.requires or self.obsoletes or
1090 self.classifiers or self.download_url):
Fred Drakedb7b0022005-03-20 22:19:47 +00001091 version = '1.1'
1092
1093 file.write('Metadata-Version: %s\n' % version)
1094 file.write('Name: %s\n' % self.get_name() )
1095 file.write('Version: %s\n' % self.get_version() )
1096 file.write('Summary: %s\n' % self.get_description() )
1097 file.write('Home-page: %s\n' % self.get_url() )
1098 file.write('Author: %s\n' % self.get_contact() )
1099 file.write('Author-email: %s\n' % self.get_contact_email() )
1100 file.write('License: %s\n' % self.get_license() )
1101 if self.download_url:
1102 file.write('Download-URL: %s\n' % self.download_url)
1103
Tarek Ziadéf11be752009-06-01 22:36:26 +00001104 long_desc = rfc822_escape(self.get_long_description())
Fred Drakedb7b0022005-03-20 22:19:47 +00001105 file.write('Description: %s\n' % long_desc)
1106
Neal Norwitz9d72bb42007-04-17 08:48:32 +00001107 keywords = ','.join(self.get_keywords())
Fred Drakedb7b0022005-03-20 22:19:47 +00001108 if keywords:
1109 file.write('Keywords: %s\n' % keywords )
1110
1111 self._write_list(file, 'Platform', self.get_platforms())
1112 self._write_list(file, 'Classifier', self.get_classifiers())
1113
1114 # PEP 314
1115 self._write_list(file, 'Requires', self.get_requires())
1116 self._write_list(file, 'Provides', self.get_provides())
1117 self._write_list(file, 'Obsoletes', self.get_obsoletes())
1118
Tarek Ziadé188789d2009-05-16 18:37:32 +00001119 def _write_list(self, file, name, values):
Fred Drakedb7b0022005-03-20 22:19:47 +00001120 for value in values:
1121 file.write('%s: %s\n' % (name, value))
1122
Greg Ward82715e12000-04-21 02:28:14 +00001123 # -- Metadata query methods ----------------------------------------
1124
Tarek Ziadé188789d2009-05-16 18:37:32 +00001125 def get_name(self):
Greg Wardfe6462c2000-04-04 01:40:52 +00001126 return self.name or "UNKNOWN"
1127
Greg Ward82715e12000-04-21 02:28:14 +00001128 def get_version(self):
Thomas Hellerbcd89752001-12-06 20:44:19 +00001129 return self.version or "0.0.0"
Greg Wardfe6462c2000-04-04 01:40:52 +00001130
Tarek Ziadé188789d2009-05-16 18:37:32 +00001131 def get_fullname(self):
Greg Ward82715e12000-04-21 02:28:14 +00001132 return "%s-%s" % (self.get_name(), self.get_version())
1133
1134 def get_author(self):
1135 return self.author or "UNKNOWN"
1136
1137 def get_author_email(self):
1138 return self.author_email or "UNKNOWN"
1139
1140 def get_maintainer(self):
1141 return self.maintainer or "UNKNOWN"
1142
1143 def get_maintainer_email(self):
1144 return self.maintainer_email or "UNKNOWN"
1145
1146 def get_contact(self):
Tarek Ziadé188789d2009-05-16 18:37:32 +00001147 return self.maintainer or self.author or "UNKNOWN"
Greg Ward82715e12000-04-21 02:28:14 +00001148
1149 def get_contact_email(self):
Tarek Ziadé188789d2009-05-16 18:37:32 +00001150 return self.maintainer_email or self.author_email or "UNKNOWN"
Greg Ward82715e12000-04-21 02:28:14 +00001151
1152 def get_url(self):
1153 return self.url or "UNKNOWN"
1154
Andrew M. Kuchlingfa7dc572001-08-10 18:49:23 +00001155 def get_license(self):
1156 return self.license or "UNKNOWN"
1157 get_licence = get_license
Fred Drakeb94b8492001-12-06 20:51:35 +00001158
Greg Ward82715e12000-04-21 02:28:14 +00001159 def get_description(self):
1160 return self.description or "UNKNOWN"
Greg Warde5a584e2000-04-26 02:26:55 +00001161
1162 def get_long_description(self):
1163 return self.long_description or "UNKNOWN"
1164
Andrew M. Kuchlinga7210ed2001-03-22 03:06:52 +00001165 def get_keywords(self):
1166 return self.keywords or []
1167
1168 def get_platforms(self):
1169 return self.platforms or ["UNKNOWN"]
1170
Andrew M. Kuchling282e2c32003-01-03 15:24:36 +00001171 def get_classifiers(self):
1172 return self.classifiers or []
1173
Andrew M. Kuchling188d85f2003-02-19 14:16:01 +00001174 def get_download_url(self):
1175 return self.download_url or "UNKNOWN"
1176
Fred Drakedb7b0022005-03-20 22:19:47 +00001177 # PEP 314
Fred Drakedb7b0022005-03-20 22:19:47 +00001178 def get_requires(self):
1179 return self.requires or []
1180
1181 def set_requires(self, value):
1182 import distutils.versionpredicate
1183 for v in value:
1184 distutils.versionpredicate.VersionPredicate(v)
1185 self.requires = value
1186
1187 def get_provides(self):
1188 return self.provides or []
1189
1190 def set_provides(self, value):
1191 value = [v.strip() for v in value]
1192 for v in value:
1193 import distutils.versionpredicate
Fred Drake227e8ff2005-03-21 06:36:32 +00001194 distutils.versionpredicate.split_provision(v)
Fred Drakedb7b0022005-03-20 22:19:47 +00001195 self.provides = value
1196
1197 def get_obsoletes(self):
1198 return self.obsoletes or []
1199
1200 def set_obsoletes(self, value):
1201 import distutils.versionpredicate
1202 for v in value:
1203 distutils.versionpredicate.VersionPredicate(v)
1204 self.obsoletes = value
1205
Tarek Ziadé188789d2009-05-16 18:37:32 +00001206def fix_help_options(options):
Greg Ward2ff78872000-06-24 00:23:20 +00001207 """Convert a 4-tuple 'help_options' list as found in various command
1208 classes to the 3-tuple form required by FancyGetopt.
1209 """
1210 new_options = []
1211 for help_tuple in options:
1212 new_options.append(help_tuple[0:3])
1213 return new_options