dist.py revision 474607777d10562679b1640d3831290b0c4284f7
1fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward"""distutils.dist 2fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 3fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg WardProvides the Distribution class, which represents the module distribution 4fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardbeing built/installed/distributed.""" 5fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 6fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# created 2000/04/03, Greg Ward 7fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# (extricated from core.py; actually dates back to the beginning) 8fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 9fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward__revision__ = "$Id$" 10fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 111426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smithimport sys, os, string, re 12fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardfrom types import * 13fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardfrom copy import copy 14fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardfrom distutils.errors import * 1536c36fec7cd7f056832c2043ec385f6e921c8c83Greg Wardfrom distutils import sysconfig 1682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Wardfrom distutils.fancy_getopt import FancyGetopt, longopt_xlate 171426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smithfrom distutils.util import check_environ 18fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 19fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 20fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# Regex to define acceptable Distutils command names. This is not *quite* 21fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# the same as a Python NAME -- I don't allow leading underscores. The fact 22fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# that they're very similar is no coincidence; the default naming scheme is 23fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward# to look for a Python module named after the command. 24fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardcommand_re = re.compile (r'^[a-zA-Z]([a-zA-Z0-9_]*)$') 25fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 26fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 27fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardclass Distribution: 28fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward """The core of the Distutils. Most of the work hiding behind 29fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 'setup' is really done within a Distribution instance, which 30fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward farms the work out to the Distutils commands specified on the 31fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward command line. 32fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 33fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward Clients will almost never instantiate Distribution directly, 34fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward unless the 'setup' function is totally inadequate to their needs. 35fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward However, it is conceivable that a client might wish to subclass 36fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward Distribution for some specialized purpose, and then pass the 37fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward subclass to 'setup' as the 'distclass' keyword argument. If so, 38fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward it is necessary to respect the expectations that 'setup' has of 39fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward Distribution: it must have a constructor and methods 40fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 'parse_command_line()' and 'run_commands()' with signatures like 41fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward those described below.""" 42fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 43fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 44fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # 'global_options' describes the command-line options that may be 4582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # supplied to the setup script prior to any actual commands. 4682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of 47fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # these global options. This list should be kept to a bare minimum, 48fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # since every global option is also valid as a command option -- and we 49fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # don't want to pollute the commands with too many options that they 50fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # have minimal control over. 51d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward global_options = [('verbose', 'v', "run verbosely (default)"), 52d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward ('quiet', 'q', "run quietly (turns verbosity off)"), 53d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward ('dry-run', 'n', "don't actually do anything"), 54d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward ('help', 'h', "show detailed help message"), 55fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward ] 5682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 5782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # options that are not propagated to the commands 5882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward display_options = [ 5982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('help-commands', None, 6082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "list all available commands"), 6182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('name', None, 6282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print package name"), 6382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('version', 'V', 6482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print package version"), 6582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('fullname', None, 6682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print <package name>-<version>"), 6782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('author', None, 6882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the author's name"), 6982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('author-email', None, 7082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the author's email address"), 7182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('maintainer', None, 7282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the maintainer's name"), 7382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('maintainer-email', None, 7482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the maintainer's email address"), 7582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('contact', None, 76d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "print the maintainer's name if known, else the author's"), 7782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('contact-email', None, 78d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "print the maintainer's email address if known, else the author's"), 7982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('url', None, 8082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the URL for this package"), 8182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('licence', None, 8282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the licence of the package"), 8382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('license', None, 8482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "alias for --licence"), 8582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ('description', None, 8682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "print the package description"), 87e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward ('long-description', None, 88e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward "print the long package description"), 8982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward ] 9082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward display_option_names = map(lambda x: string.translate(x[0], longopt_xlate), 9182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward display_options) 9282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 9382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # negative options are options that exclude other options 94fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward negative_opt = {'quiet': 'verbose'} 95fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 96fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 97fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # -- Creation/initialization methods ------------------------------- 98fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 99fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def __init__ (self, attrs=None): 100fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward """Construct a new Distribution instance: initialize all the 101fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward attributes of a Distribution, and then uses 'attrs' (a 102fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward dictionary mapping attribute names to values) to assign 103fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward some of those attributes their "real" values. (Any attributes 104fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward not mentioned in 'attrs' will be assigned to some null 105fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward value: 0, None, an empty list or dictionary, etc.) Most 106fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward importantly, initialize the 'command_obj' attribute 107fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward to the empty dictionary; this will be filled in with real 108fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward command objects by 'parse_command_line()'.""" 109fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 110fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Default values for our command-line options 111fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.verbose = 1 112fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.dry_run = 0 113fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.help = 0 11482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward for attr in self.display_option_names: 11582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward setattr(self, attr, 0) 11682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 11782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # Store the distribution meta-data (name, version, author, and so 11882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # forth) in a separate object -- we're getting to have enough 11982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # information here (and enough command-line options) that it's 12082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # worth it. Also delegate 'get_XXX()' methods to the 'metadata' 12182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # object in a sneaky and underhanded (but efficient!) way. 12282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.metadata = DistributionMetadata () 1234982f98bc919d2a6377e3e0e82c186bc5b1d70ffGreg Ward method_basenames = dir(self.metadata) + \ 1244982f98bc919d2a6377e3e0e82c186bc5b1d70ffGreg Ward ['fullname', 'contact', 'contact_email'] 1254982f98bc919d2a6377e3e0e82c186bc5b1d70ffGreg Ward for basename in method_basenames: 1264982f98bc919d2a6377e3e0e82c186bc5b1d70ffGreg Ward method_name = "get_" + basename 1274982f98bc919d2a6377e3e0e82c186bc5b1d70ffGreg Ward setattr(self, method_name, getattr(self.metadata, method_name)) 128fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 129fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # 'cmdclass' maps command names to class objects, so we 130fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # can 1) quickly figure out which class to instantiate when 131fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # we need to create a new command object, and 2) have a way 13282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # for the setup script to override command classes 133fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.cmdclass = {} 134fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 135d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # 'command_options' is where we store command options between 136d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # parsing them (from config files, the command-line, etc.) and when 137d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # they are actually needed -- ie. when the command in question is 138d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # instantiated. It is a dictionary of dictionaries of 2-tuples: 139d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # command_options = { command_name : { option : (source, value) } } 1401426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith self.command_options = {} 1411426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 142fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # These options are really the business of various commands, rather 143fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # than of the Distribution itself. We provide aliases for them in 144fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Distribution as a convenience to the developer. 145fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.packages = None 146fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.package_dir = None 147fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.py_modules = None 148fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.libraries = None 149fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.ext_modules = None 150fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.ext_package = None 151fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.include_dirs = None 152fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.extra_path = None 153b2e3bb3d6aaf4ef04211b932c64ef9cd5adc56bbGregory P. Smith self.scripts = None 1546a901dd1bd1d2cfdd744bf7524ccb9b890b28d06Gregory P. Smith self.data_files = None 155fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 156fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # And now initialize bookkeeping stuff that can't be supplied by 157fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # the caller at all. 'command_obj' maps command names to 158fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Command instances -- that's how we enforce that every command 159fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # class is a singleton. 160fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.command_obj = {} 161fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 162fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # 'have_run' maps command names to boolean values; it keeps track 163fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # of whether we have actually run a particular command, to make it 164fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # cheap to "run" a command whenever we think we might need to -- if 165fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # it's already been done, no need for expensive filesystem 166fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # operations, we just check the 'have_run' dictionary and carry on. 167fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # It's only safe to query 'have_run' for a command class that has 168fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # been instantiated -- a false value will be inserted when the 169fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # command object is created, and replaced with a true value when 170fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # the command is succesfully run. Thus it's probably best to use 171fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # '.get()' rather than a straight lookup. 172fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.have_run = {} 173fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 174fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Now we'll use the attrs dictionary (ultimately, keyword args from 17582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # the setup script) to possibly override any or all of these 17682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # distribution options. 17782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 178fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if attrs: 179fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 180fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Pull out the set of command options and work on them 181fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # specifically. Note that this order guarantees that aliased 182fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # command options will override any supplied redundantly 183fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # through the general options dictionary. 184fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward options = attrs.get ('options') 185fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if options: 186fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward del attrs['options'] 187fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for (command, cmd_options) in options.items(): 188d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_obj = self.get_command_obj (command) 189fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for (key, val) in cmd_options.items(): 190fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward cmd_obj.set_option (key, val) 191fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # loop over commands 192fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # if any command options 193fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 194fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Now work on the rest of the attributes. Any attribute that's 195fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # not already defined is invalid! 196fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for (key,val) in attrs.items(): 19782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward if hasattr (self.metadata, key): 19882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward setattr (self.metadata, key, val) 19982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward elif hasattr (self, key): 200fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward setattr (self, key, val) 201fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward else: 20202a1a2b077e969e5fef8504cece5852bf641552dGreg Ward raise DistutilsSetupError, \ 203fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward "invalid distribution option '%s'" % key 204fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 205fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # __init__ () 206fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 207fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 208d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # -- Config file finding/parsing methods --------------------------- 209d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 2101426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith def find_config_files (self): 2111426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith """Find as many configuration files as should be processed for this 2121426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith platform, and return a list of filenames in the order in which they 2131426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith should be parsed. The filenames returned are guaranteed to exist 2141426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith (modulo nasty race conditions). 2151426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2161426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith On Unix, there are three possible config files: pydistutils.cfg in 2171426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith the Distutils installation directory (ie. where the top-level 2181426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith Distutils __inst__.py file lives), .pydistutils.cfg in the user's 2191426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith home directory, and setup.cfg in the current directory. 2201426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2211426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith On Windows and Mac OS, there are two possible config files: 2221426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith pydistutils.cfg in the Python installation directory (sys.prefix) 223d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward and setup.cfg in the current directory. 224d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 2251426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith files = [] 2261426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if os.name == "posix": 2271426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith check_environ() 2281426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2291426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith sys_dir = os.path.dirname(sys.modules['distutils'].__file__) 2301426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith sys_file = os.path.join(sys_dir, "pydistutils.cfg") 2311426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if os.path.isfile(sys_file): 2321426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith files.append(sys_file) 2331426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2341426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith user_file = os.path.join(os.environ.get('HOME'), 2351426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith ".pydistutils.cfg") 2361426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if os.path.isfile(user_file): 2371426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith files.append(user_file) 2381426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2391426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith else: 2401426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith sys_file = os.path.join (sysconfig.PREFIX, "pydistutils.cfg") 2411426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if os.path.isfile(sys_file): 2421426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith files.append(sys_file) 2431426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2441426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith # All platforms support local setup.cfg 2451426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith local_file = "setup.cfg" 2461426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if os.path.isfile(local_file): 2471426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith files.append(local_file) 2481426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2491426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith return files 2501426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2511426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith # find_config_files () 2521426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2531426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2541426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith def parse_config_files (self, filenames=None): 2551426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2561426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith from ConfigParser import ConfigParser 2571426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2581426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith if filenames is None: 2591426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith filenames = self.find_config_files() 2601426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 261474607777d10562679b1640d3831290b0c4284f7Greg Ward print "Distribution.parse_config_files():" 262474607777d10562679b1640d3831290b0c4284f7Greg Ward 2631426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith parser = ConfigParser() 264d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward for filename in filenames: 265474607777d10562679b1640d3831290b0c4284f7Greg Ward print " reading", filename 266d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.read(filename) 267d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward for section in parser.sections(): 268d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward options = parser.options(section) 269d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if not self.command_options.has_key(section): 270d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self.command_options[section] = {} 271d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward opts = self.command_options[section] 272d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 273d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward for opt in options: 274d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if opt != '__name__': 275d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward opts[opt] = (filename, parser.get(section,opt)) 2761426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 277474607777d10562679b1640d3831290b0c4284f7Greg Ward # Make the ConfigParser forget everything (so we retain 278474607777d10562679b1640d3831290b0c4284f7Greg Ward # the original filenames that options come from) -- gag, 279474607777d10562679b1640d3831290b0c4284f7Greg Ward # retch, puke -- another good reason for a distutils- 280474607777d10562679b1640d3831290b0c4284f7Greg Ward # specific config parser (sigh...) 281474607777d10562679b1640d3831290b0c4284f7Greg Ward parser.__init__() 2821426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 2831426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 284d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # -- Command-line parsing methods ---------------------------------- 285fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 286d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward def parse_command_line (self, args): 287d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Parse the setup script's command line. 'args' must be a list 288d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward of command-line arguments, most likely 'sys.argv[1:]' (see the 289d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'setup()' function). This list is first processed for "global 290d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward options" -- options that set attributes of the Distribution 291d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward instance. Then, it is alternately scanned for Distutils 292d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward commands and options for that command. Each new command 293d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward terminates the options for the previous command. The allowed 294d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward options for a command are determined by the 'user_options' 295d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward attribute of the command class -- thus, we have to be able to 296d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward load command classes in order to parse the command line. Any 297d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward error in that 'options' attribute raises DistutilsGetoptError; 298d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward any error on the command-line raises DistutilsArgError. If no 299d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward Distutils commands were found on the command line, raises 300d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward DistutilsArgError. Return true if command-line were 301d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward successfully parsed and we should carry on with executing 302d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward commands; false if no errors but we shouldn't execute commands 303d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward (currently, this only happens if user asks for help). 304d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 305fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # We have to parse the command line a bit at a time -- global 306fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # options, then the first command, then its options, and so on -- 307fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # because each command will be handled by a different class, and 308d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # the options that are valid for a particular class aren't known 309d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # until we have loaded the command class, which doesn't happen 310d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # until we know what the command is. 311fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 312fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.commands = [] 31382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward parser = FancyGetopt (self.global_options + self.display_options) 31482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward parser.set_negative_aliases (self.negative_opt) 31558ec6ede20d0b632f8325e1363aaa6e445ad61efGreg Ward parser.set_aliases ({'license': 'licence'}) 31682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward args = parser.getopt (object=self) 31782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward option_order = parser.get_option_order() 318fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 31982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # for display options we return immediately 32082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward if self.handle_display_options(option_order): 321fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return 322fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 323fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward while args: 324d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward args = self._parse_command_opts(parser, args) 325d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if args is None: # user asked for help (and got it) 326fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return 327fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 328d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Handle the cases of --help as a "global" option, ie. 329d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # "setup.py --help" and "setup.py --help command ...". For the 330d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # former, we show global options (--verbose, --dry-run, etc.) 331d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # and display-only options (--name, --version, etc.); for the 332d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # latter, we omit the display-only options and show help for 333d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # each command listed on the command line. 334d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if self.help: 335d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print "showing 'global' help; commands=", self.commands 336d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self._show_help(parser, 337d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward display_options=len(self.commands) == 0, 338d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward commands=self.commands) 339fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return 340fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 341fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Oops, no commands found -- an end-user error 342fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if not self.commands: 343fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward raise DistutilsArgError, "no commands supplied" 344fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 345fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # All is well: return true 346fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return 1 347fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 348fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # parse_command_line() 349fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 350d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward def _parse_command_opts (self, parser, args): 351d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 352d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Parse the command-line options for a single command. 353d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'parser' must be a FancyGetopt instance; 'args' must be the list 354d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward of arguments, starting with the current command (whose options 355d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward we are about to parse). Returns a new version of 'args' with 356d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward the next command at the front of the list; will be the empty 357d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward list if there are no more commands on the command line. Returns 358d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward None if the user asked for help on this command. 359d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 360d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # late import because of mutual dependence between these modules 361d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward from distutils.cmd import Command 362d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 363d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Pull the current command from the head of the command line 364d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward command = args[0] 365d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if not command_re.match (command): 366d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward raise SystemExit, "invalid command name '%s'" % command 367d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self.commands.append (command) 368d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 369d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Dig up the command class that implements this command, so we 370d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # 1) know that it's a valid command, and 2) know which options 371d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # it takes. 372d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward try: 373d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_class = self.get_command_class (command) 374d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward except DistutilsModuleError, msg: 375d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward raise DistutilsArgError, msg 376d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 377d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Require that the command class be derived from Command -- want 378d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # to be sure that the basic "command" interface is implemented. 379d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if not issubclass (cmd_class, Command): 380d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward raise DistutilsClassError, \ 381d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "command class %s must subclass Command" % cmd_class 382d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 383d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Also make sure that the command object provides a list of its 384d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # known options. 385d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if not (hasattr (cmd_class, 'user_options') and 386d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward type (cmd_class.user_options) is ListType): 387d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward raise DistutilsClassError, \ 388d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward ("command class %s must provide " + 389d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "'user_options' attribute (a list of tuples)") % \ 390d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_class 391d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 392d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # If the command class has a list of negative alias options, 393d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # merge it in with the global negative aliases. 394d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward negative_opt = self.negative_opt 395d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if hasattr (cmd_class, 'negative_opt'): 396d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward negative_opt = copy (negative_opt) 397d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward negative_opt.update (cmd_class.negative_opt) 398d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 399d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # All commands support the global options too, just by adding 400d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # in 'global_options'. 401d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.set_option_table (self.global_options + 402d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_class.user_options) 403d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.set_negative_aliases (negative_opt) 404d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward (args, opts) = parser.getopt (args[1:]) 405474607777d10562679b1640d3831290b0c4284f7Greg Ward if hasattr(opts, 'help') and opts.help: 406d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print "showing help for command", cmd_class 407d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self._show_help(parser, display_options=0, commands=[cmd_class]) 408d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward return 409d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 410d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # Put the options from the command-line into their official 411d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # holding pen, the 'command_options' dictionary. 412d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if not self.command_options.has_key(command): 413d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self.command_options[command] = {} 414d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_opts = self.command_options[command] 415d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward for (name, value) in vars(opts).items(): 416474607777d10562679b1640d3831290b0c4284f7Greg Ward cmd_opts[name] = ("command line", value) 417d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 418d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward return args 419d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 420d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # _parse_command_opts () 421d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 422d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 423d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward def _show_help (self, 424d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser, 425d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward global_options=1, 426d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward display_options=1, 427d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward commands=[]): 428d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Show help for the setup script command-line in the form of 429d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward several lists of command-line options. 'parser' should be a 430d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward FancyGetopt instance; do not expect it to be returned in the 431d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward same state, as its option table will be reset to make it 432d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward generate the correct help text. 433d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 434d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward If 'global_options' is true, lists the global options: 435d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward --verbose, --dry-run, etc. If 'display_options' is true, lists 436d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward the "display-only" options: --name, --version, etc. Finally, 437d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward lists per-command help for every command name or command class 438d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward in 'commands'. 439d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 440d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # late import because of mutual dependence between these modules 441d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward from distutils.core import usage 442d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward from distutils.cmd import Command 443d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 444d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if global_options: 445d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.set_option_table (self.global_options) 446d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.print_help ("Global options:") 447d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print 448d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 449d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if display_options: 450d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.set_option_table (self.display_options) 451d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.print_help ( 452d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "Information display options (just display " + 453d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward "information, ignore any commands)") 454d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print 455d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 456d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward for command in self.commands: 457d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if type(command) is ClassType and issubclass(klass, Command): 458d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = command 459d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward else: 460d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = self.get_command_class (command) 461d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.set_option_table (klass.user_options) 462d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward parser.print_help ("Options for '%s' command:" % klass.__name__) 463d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print 464d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 465d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward print usage 466d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward return 467d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 468d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # _show_help () 469d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 470d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 47182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def handle_display_options (self, option_order): 47282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward """If there were any non-global "display-only" options 473d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward (--help-commands or the metadata display options) on the command 474d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward line, display the requested info and return true; else return 475d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward false. 476d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 47782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward from distutils.core import usage 47882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 47982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # User just wants a list of commands -- we'll print it out and stop 48082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # processing now (ie. if they ran "setup --help-commands foo bar", 48182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # we ignore "foo bar"). 48282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward if self.help_commands: 48382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.print_commands () 48482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward print 48582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward print usage 48682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return 1 48782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 48882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # If user supplied any of the "display metadata" options, then 48982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # display that metadata in the order in which the user supplied the 49082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # metadata options. 49182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward any_display_options = 0 49282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward is_display_option = {} 49382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward for option in self.display_options: 49482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward is_display_option[option[0]] = 1 49582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 49682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward for (opt, val) in option_order: 49782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward if val and is_display_option.get(opt): 49882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward opt = string.translate (opt, longopt_xlate) 49982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward print getattr(self.metadata, "get_"+opt)() 50082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward any_display_options = 1 50182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 50282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return any_display_options 50382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 50482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # handle_display_options() 505fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 506fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def print_command_list (self, commands, header, max_length): 507fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward """Print a subset of the list of all commands -- used by 508d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'print_commands()'. 509d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 510fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 511fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward print header + ":" 512fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 513fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for cmd in commands: 514fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward klass = self.cmdclass.get (cmd) 515fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if not klass: 516d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = self.get_command_class (cmd) 517fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward try: 518fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward description = klass.description 519fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward except AttributeError: 520fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward description = "(no description available)" 521fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 522fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward print " %-*s %s" % (max_length, cmd, description) 523fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 524fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # print_command_list () 525fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 526fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 527fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def print_commands (self): 528d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Print out a help message listing all available commands with a 529d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward description of each. The list is divided into "standard commands" 530d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward (listed in distutils.command.__all__) and "extra commands" 531d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward (mentioned in self.cmdclass, but not a standard command). The 532d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward descriptions come from the command class attribute 533d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'description'. 534d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 535fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 536fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward import distutils.command 537fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward std_commands = distutils.command.__all__ 538fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward is_std = {} 539fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for cmd in std_commands: 540fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward is_std[cmd] = 1 541fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 542fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward extra_commands = [] 543fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for cmd in self.cmdclass.keys(): 544fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if not is_std.get(cmd): 545fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward extra_commands.append (cmd) 546fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 547fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward max_length = 0 548fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for cmd in (std_commands + extra_commands): 549fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if len (cmd) > max_length: 550fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward max_length = len (cmd) 551fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 552fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.print_command_list (std_commands, 553fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward "Standard commands", 554fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward max_length) 555fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if extra_commands: 556fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward print 557fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.print_command_list (extra_commands, 558fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward "Extra commands", 559fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward max_length) 560fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 561fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # print_commands () 562fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 563fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 564fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # -- Command class/object methods ---------------------------------- 565fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 566d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward def get_command_class (self, command): 567d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Return the class that implements the Distutils command named by 568d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'command'. First we check the 'cmdclass' dictionary; if the 569d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward command is mentioned there, we fetch the class object from the 570d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward dictionary and return it. Otherwise we load the command module 571d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward ("distutils.command." + command) and fetch the command class from 572d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward the module. The loaded class is also stored in 'cmdclass' 573d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward to speed future calls to 'get_command_class()'. 5741426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith 5751426354cf649546a2437df75f2c319ff0b456c53Gregory P. Smith Raises DistutilsModuleError if the expected module could not be 576d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward found, or if that module does not define the expected class. 577d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 578d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = self.cmdclass.get(command) 579d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if klass: 580d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward return klass 581fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 582fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward module_name = 'distutils.command.' + command 583fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward klass_name = command 584fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 585fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward try: 586fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward __import__ (module_name) 587fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward module = sys.modules[module_name] 588fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward except ImportError: 589fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward raise DistutilsModuleError, \ 590fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward "invalid command '%s' (no module named '%s')" % \ 591fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward (command, module_name) 592fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 593fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward try: 594d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = getattr(module, klass_name) 595d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward except AttributeError: 596fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward raise DistutilsModuleError, \ 597fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward "invalid command '%s' (no class '%s' in module '%s')" \ 598fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward % (command, klass_name, module_name) 599fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 600d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward self.cmdclass[command] = klass 601fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return klass 602fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 603d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward # get_command_class () 604fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 605d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward def get_command_obj (self, command, create=1): 606d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """Return the command object for 'command'. Normally this object 607d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward is cached on a previous call to 'get_command_obj()'; if no comand 608d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward object for 'command' is in the cache, then we either create and 609d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward return it (if 'create' is true) or return None. 610d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 611d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_obj = self.command_obj.get(command) 612fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if not cmd_obj and create: 613474607777d10562679b1640d3831290b0c4284f7Greg Ward print "Distribution.get_command_obj(): " \ 614474607777d10562679b1640d3831290b0c4284f7Greg Ward "creating '%s' command object" % command 615474607777d10562679b1640d3831290b0c4284f7Greg Ward 616d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward klass = self.get_command_class(command) 617474607777d10562679b1640d3831290b0c4284f7Greg Ward cmd_obj = self.command_obj[command] = klass(self) 618474607777d10562679b1640d3831290b0c4284f7Greg Ward self.have_run[command] = 0 619474607777d10562679b1640d3831290b0c4284f7Greg Ward 620474607777d10562679b1640d3831290b0c4284f7Greg Ward # Set any options that were supplied in config files 621474607777d10562679b1640d3831290b0c4284f7Greg Ward # or on the command line. (NB. support for error 622474607777d10562679b1640d3831290b0c4284f7Greg Ward # reporting is lame here: any errors aren't reported 623474607777d10562679b1640d3831290b0c4284f7Greg Ward # until 'finalize_options()' is called, which means 624474607777d10562679b1640d3831290b0c4284f7Greg Ward # we won't report the source of the error.) 625474607777d10562679b1640d3831290b0c4284f7Greg Ward options = self.command_options.get(command) 626474607777d10562679b1640d3831290b0c4284f7Greg Ward if options: 627474607777d10562679b1640d3831290b0c4284f7Greg Ward print " setting options:" 628474607777d10562679b1640d3831290b0c4284f7Greg Ward for (option, (source, value)) in options.items(): 629474607777d10562679b1640d3831290b0c4284f7Greg Ward print " %s = %s (from %s)" % (option, value, source) 630474607777d10562679b1640d3831290b0c4284f7Greg Ward setattr(cmd_obj, option, value) 631fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 632fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return cmd_obj 633fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 634fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 635fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # -- Methods that operate on the Distribution ---------------------- 636fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 637fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def announce (self, msg, level=1): 638fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward """Print 'msg' if 'level' is greater than or equal to the verbosity 639d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward level recorded in the 'verbose' attribute (which, currently, can be 640d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward only 0 or 1). 641d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 642fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if self.verbose >= level: 643fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward print msg 644fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 645fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 646fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def run_commands (self): 64782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward """Run each command that was seen on the setup script command line. 648d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward Uses the list of commands found and cache of command objects 649d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward created by 'get_command_obj()'.""" 650fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 651fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward for cmd in self.commands: 652fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.run_command (cmd) 653fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 654fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 655fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # -- Methods that operate on its Commands -------------------------- 656fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 657fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def run_command (self, command): 658fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward """Do whatever it takes to run a command (including nothing at all, 659d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward if the command has already been run). Specifically: if we have 660d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward already created and run the command named by 'command', return 661d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward silently without doing anything. If the command named by 'command' 662d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward doesn't even have a command object yet, create one. Then invoke 663d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward 'run()' on that command object (or an existing one). 664d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward """ 665fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 666fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # Already been here, done that? then return silently. 667fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward if self.have_run.get (command): 668fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return 669fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 670fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.announce ("running " + command) 671d5d8a9982b77ef54fcacf8ff7bfa449a2eab35dbGreg Ward cmd_obj = self.get_command_obj (command) 672fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward cmd_obj.ensure_ready () 673fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward cmd_obj.run () 674fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward self.have_run[command] = 1 675fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 676fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 677fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward # -- Distribution query methods ------------------------------------ 678fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 679fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def has_pure_modules (self): 680fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return len (self.packages or self.py_modules or []) > 0 681fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 682fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def has_ext_modules (self): 683fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return self.ext_modules and len (self.ext_modules) > 0 684fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 685fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def has_c_libraries (self): 686fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return self.libraries and len (self.libraries) > 0 687fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 688fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def has_modules (self): 689fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return self.has_pure_modules() or self.has_ext_modules() 690fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 69144a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward def has_scripts (self): 69244a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward return self.scripts and len(self.scripts) > 0 69344a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward 69444a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward def has_data_files (self): 69544a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward return self.data_files and len(self.data_files) > 0 69644a61bbb66cfc6a0821d591ccf33fbc209aab112Greg Ward 697fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def is_pure (self): 698fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return (self.has_pure_modules() and 699fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward not self.has_ext_modules() and 700fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward not self.has_c_libraries()) 701fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 70282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # -- Metadata query methods ---------------------------------------- 70382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 70482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # If you're looking for 'get_name()', 'get_version()', and so forth, 70582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # they are defined in a sneaky way: the constructor binds self.get_XXX 70682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # to self.metadata.get_XXX. The actual code is in the 70782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # DistributionMetadata class, below. 70882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 70982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward# class Distribution 71082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 71182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 71282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Wardclass DistributionMetadata: 71382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward """Dummy class to hold the distribution meta-data: name, version, 71482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward author, and so forth.""" 71582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 71682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def __init__ (self): 71782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.name = None 71882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.version = None 71982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.author = None 72082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.author_email = None 72182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.maintainer = None 72282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.maintainer_email = None 72382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.url = None 72482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.licence = None 72582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.description = None 726e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward self.long_description = None 72782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 72882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward # -- Metadata query methods ---------------------------------------- 72982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 730fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward def get_name (self): 731fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward return self.name or "UNKNOWN" 732fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 73382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_version(self): 73482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.version or "???" 73582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 73682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_fullname (self): 73782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return "%s-%s" % (self.get_name(), self.get_version()) 73882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 73982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_author(self): 74082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.author or "UNKNOWN" 741fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 74282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_author_email(self): 74382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.author_email or "UNKNOWN" 74482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 74582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_maintainer(self): 74682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.maintainer or "UNKNOWN" 74782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 74882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_maintainer_email(self): 74982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.maintainer_email or "UNKNOWN" 75082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 75182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_contact(self): 75282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return (self.maintainer or 75382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.author or 75482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "UNKNOWN") 75582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 75682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_contact_email(self): 75782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return (self.maintainer_email or 75882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward self.author_email or 75982715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward "UNKNOWN") 76082715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 76182715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_url(self): 76282715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.url or "UNKNOWN" 76382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 76482715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_licence(self): 76582715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.licence or "UNKNOWN" 76682715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward 76782715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward def get_description(self): 76882715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward return self.description or "UNKNOWN" 769e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward 770e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward def get_long_description(self): 771e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward return self.long_description or "UNKNOWN" 772e5a584e86572a1ae85d99bc2a77b439d7024934fGreg Ward 77382715e1f11ec1f4c7b13b07ca55f56850c4c3dabGreg Ward# class DistributionMetadata 774fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward 775fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Wardif __name__ == "__main__": 776fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward dist = Distribution () 777fe6462c1f3206dd69659d20b5babab515fc6d4c3Greg Ward print "ok" 778