1*cda5da8dSAndroid Build Coastguard Worker"""distutils.dist 2*cda5da8dSAndroid Build Coastguard Worker 3*cda5da8dSAndroid Build Coastguard WorkerProvides the Distribution class, which represents the module distribution 4*cda5da8dSAndroid Build Coastguard Workerbeing built/installed/distributed. 5*cda5da8dSAndroid Build Coastguard Worker""" 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard Workerimport sys 8*cda5da8dSAndroid Build Coastguard Workerimport os 9*cda5da8dSAndroid Build Coastguard Workerimport re 10*cda5da8dSAndroid Build Coastguard Workerfrom email import message_from_file 11*cda5da8dSAndroid Build Coastguard Worker 12*cda5da8dSAndroid Build Coastguard Workertry: 13*cda5da8dSAndroid Build Coastguard Worker import warnings 14*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 15*cda5da8dSAndroid Build Coastguard Worker warnings = None 16*cda5da8dSAndroid Build Coastguard Worker 17*cda5da8dSAndroid Build Coastguard Workerfrom distutils.errors import * 18*cda5da8dSAndroid Build Coastguard Workerfrom distutils.fancy_getopt import FancyGetopt, translate_longopt 19*cda5da8dSAndroid Build Coastguard Workerfrom distutils.util import check_environ, strtobool, rfc822_escape 20*cda5da8dSAndroid Build Coastguard Workerfrom distutils import log 21*cda5da8dSAndroid Build Coastguard Workerfrom distutils.debug import DEBUG 22*cda5da8dSAndroid Build Coastguard Worker 23*cda5da8dSAndroid Build Coastguard Worker# Regex to define acceptable Distutils command names. This is not *quite* 24*cda5da8dSAndroid Build Coastguard Worker# the same as a Python NAME -- I don't allow leading underscores. The fact 25*cda5da8dSAndroid Build Coastguard Worker# that they're very similar is no coincidence; the default naming scheme is 26*cda5da8dSAndroid Build Coastguard Worker# to look for a Python module named after the command. 27*cda5da8dSAndroid Build Coastguard Workercommand_re = re.compile(r'^[a-zA-Z]([a-zA-Z0-9_]*)$') 28*cda5da8dSAndroid Build Coastguard Worker 29*cda5da8dSAndroid Build Coastguard Worker 30*cda5da8dSAndroid Build Coastguard Workerdef _ensure_list(value, fieldname): 31*cda5da8dSAndroid Build Coastguard Worker if isinstance(value, str): 32*cda5da8dSAndroid Build Coastguard Worker # a string containing comma separated values is okay. It will 33*cda5da8dSAndroid Build Coastguard Worker # be converted to a list by Distribution.finalize_options(). 34*cda5da8dSAndroid Build Coastguard Worker pass 35*cda5da8dSAndroid Build Coastguard Worker elif not isinstance(value, list): 36*cda5da8dSAndroid Build Coastguard Worker # passing a tuple or an iterator perhaps, warn and convert 37*cda5da8dSAndroid Build Coastguard Worker typename = type(value).__name__ 38*cda5da8dSAndroid Build Coastguard Worker msg = f"Warning: '{fieldname}' should be a list, got type '{typename}'" 39*cda5da8dSAndroid Build Coastguard Worker log.log(log.WARN, msg) 40*cda5da8dSAndroid Build Coastguard Worker value = list(value) 41*cda5da8dSAndroid Build Coastguard Worker return value 42*cda5da8dSAndroid Build Coastguard Worker 43*cda5da8dSAndroid Build Coastguard Worker 44*cda5da8dSAndroid Build Coastguard Workerclass Distribution: 45*cda5da8dSAndroid Build Coastguard Worker """The core of the Distutils. Most of the work hiding behind 'setup' 46*cda5da8dSAndroid Build Coastguard Worker is really done within a Distribution instance, which farms the work out 47*cda5da8dSAndroid Build Coastguard Worker to the Distutils commands specified on the command line. 48*cda5da8dSAndroid Build Coastguard Worker 49*cda5da8dSAndroid Build Coastguard Worker Setup scripts will almost never instantiate Distribution directly, 50*cda5da8dSAndroid Build Coastguard Worker unless the 'setup()' function is totally inadequate to their needs. 51*cda5da8dSAndroid Build Coastguard Worker However, it is conceivable that a setup script might wish to subclass 52*cda5da8dSAndroid Build Coastguard Worker Distribution for some specialized purpose, and then pass the subclass 53*cda5da8dSAndroid Build Coastguard Worker to 'setup()' as the 'distclass' keyword argument. If so, it is 54*cda5da8dSAndroid Build Coastguard Worker necessary to respect the expectations that 'setup' has of Distribution. 55*cda5da8dSAndroid Build Coastguard Worker See the code for 'setup()', in core.py, for details. 56*cda5da8dSAndroid Build Coastguard Worker """ 57*cda5da8dSAndroid Build Coastguard Worker 58*cda5da8dSAndroid Build Coastguard Worker # 'global_options' describes the command-line options that may be 59*cda5da8dSAndroid Build Coastguard Worker # supplied to the setup script prior to any actual commands. 60*cda5da8dSAndroid Build Coastguard Worker # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of 61*cda5da8dSAndroid Build Coastguard Worker # these global options. This list should be kept to a bare minimum, 62*cda5da8dSAndroid Build Coastguard Worker # since every global option is also valid as a command option -- and we 63*cda5da8dSAndroid Build Coastguard Worker # don't want to pollute the commands with too many options that they 64*cda5da8dSAndroid Build Coastguard Worker # have minimal control over. 65*cda5da8dSAndroid Build Coastguard Worker # The fourth entry for verbose means that it can be repeated. 66*cda5da8dSAndroid Build Coastguard Worker global_options = [ 67*cda5da8dSAndroid Build Coastguard Worker ('verbose', 'v', "run verbosely (default)", 1), 68*cda5da8dSAndroid Build Coastguard Worker ('quiet', 'q', "run quietly (turns verbosity off)"), 69*cda5da8dSAndroid Build Coastguard Worker ('dry-run', 'n', "don't actually do anything"), 70*cda5da8dSAndroid Build Coastguard Worker ('help', 'h', "show detailed help message"), 71*cda5da8dSAndroid Build Coastguard Worker ('no-user-cfg', None, 72*cda5da8dSAndroid Build Coastguard Worker 'ignore pydistutils.cfg in your home directory'), 73*cda5da8dSAndroid Build Coastguard Worker ] 74*cda5da8dSAndroid Build Coastguard Worker 75*cda5da8dSAndroid Build Coastguard Worker # 'common_usage' is a short (2-3 line) string describing the common 76*cda5da8dSAndroid Build Coastguard Worker # usage of the setup script. 77*cda5da8dSAndroid Build Coastguard Worker common_usage = """\ 78*cda5da8dSAndroid Build Coastguard WorkerCommon commands: (see '--help-commands' for more) 79*cda5da8dSAndroid Build Coastguard Worker 80*cda5da8dSAndroid Build Coastguard Worker setup.py build will build the package underneath 'build/' 81*cda5da8dSAndroid Build Coastguard Worker setup.py install will install the package 82*cda5da8dSAndroid Build Coastguard Worker""" 83*cda5da8dSAndroid Build Coastguard Worker 84*cda5da8dSAndroid Build Coastguard Worker # options that are not propagated to the commands 85*cda5da8dSAndroid Build Coastguard Worker display_options = [ 86*cda5da8dSAndroid Build Coastguard Worker ('help-commands', None, 87*cda5da8dSAndroid Build Coastguard Worker "list all available commands"), 88*cda5da8dSAndroid Build Coastguard Worker ('name', None, 89*cda5da8dSAndroid Build Coastguard Worker "print package name"), 90*cda5da8dSAndroid Build Coastguard Worker ('version', 'V', 91*cda5da8dSAndroid Build Coastguard Worker "print package version"), 92*cda5da8dSAndroid Build Coastguard Worker ('fullname', None, 93*cda5da8dSAndroid Build Coastguard Worker "print <package name>-<version>"), 94*cda5da8dSAndroid Build Coastguard Worker ('author', None, 95*cda5da8dSAndroid Build Coastguard Worker "print the author's name"), 96*cda5da8dSAndroid Build Coastguard Worker ('author-email', None, 97*cda5da8dSAndroid Build Coastguard Worker "print the author's email address"), 98*cda5da8dSAndroid Build Coastguard Worker ('maintainer', None, 99*cda5da8dSAndroid Build Coastguard Worker "print the maintainer's name"), 100*cda5da8dSAndroid Build Coastguard Worker ('maintainer-email', None, 101*cda5da8dSAndroid Build Coastguard Worker "print the maintainer's email address"), 102*cda5da8dSAndroid Build Coastguard Worker ('contact', None, 103*cda5da8dSAndroid Build Coastguard Worker "print the maintainer's name if known, else the author's"), 104*cda5da8dSAndroid Build Coastguard Worker ('contact-email', None, 105*cda5da8dSAndroid Build Coastguard Worker "print the maintainer's email address if known, else the author's"), 106*cda5da8dSAndroid Build Coastguard Worker ('url', None, 107*cda5da8dSAndroid Build Coastguard Worker "print the URL for this package"), 108*cda5da8dSAndroid Build Coastguard Worker ('license', None, 109*cda5da8dSAndroid Build Coastguard Worker "print the license of the package"), 110*cda5da8dSAndroid Build Coastguard Worker ('licence', None, 111*cda5da8dSAndroid Build Coastguard Worker "alias for --license"), 112*cda5da8dSAndroid Build Coastguard Worker ('description', None, 113*cda5da8dSAndroid Build Coastguard Worker "print the package description"), 114*cda5da8dSAndroid Build Coastguard Worker ('long-description', None, 115*cda5da8dSAndroid Build Coastguard Worker "print the long package description"), 116*cda5da8dSAndroid Build Coastguard Worker ('platforms', None, 117*cda5da8dSAndroid Build Coastguard Worker "print the list of platforms"), 118*cda5da8dSAndroid Build Coastguard Worker ('classifiers', None, 119*cda5da8dSAndroid Build Coastguard Worker "print the list of classifiers"), 120*cda5da8dSAndroid Build Coastguard Worker ('keywords', None, 121*cda5da8dSAndroid Build Coastguard Worker "print the list of keywords"), 122*cda5da8dSAndroid Build Coastguard Worker ('provides', None, 123*cda5da8dSAndroid Build Coastguard Worker "print the list of packages/modules provided"), 124*cda5da8dSAndroid Build Coastguard Worker ('requires', None, 125*cda5da8dSAndroid Build Coastguard Worker "print the list of packages/modules required"), 126*cda5da8dSAndroid Build Coastguard Worker ('obsoletes', None, 127*cda5da8dSAndroid Build Coastguard Worker "print the list of packages/modules made obsolete") 128*cda5da8dSAndroid Build Coastguard Worker ] 129*cda5da8dSAndroid Build Coastguard Worker display_option_names = [translate_longopt(x[0]) for x in display_options] 130*cda5da8dSAndroid Build Coastguard Worker 131*cda5da8dSAndroid Build Coastguard Worker # negative options are options that exclude other options 132*cda5da8dSAndroid Build Coastguard Worker negative_opt = {'quiet': 'verbose'} 133*cda5da8dSAndroid Build Coastguard Worker 134*cda5da8dSAndroid Build Coastguard Worker # -- Creation/initialization methods ------------------------------- 135*cda5da8dSAndroid Build Coastguard Worker 136*cda5da8dSAndroid Build Coastguard Worker def __init__(self, attrs=None): 137*cda5da8dSAndroid Build Coastguard Worker """Construct a new Distribution instance: initialize all the 138*cda5da8dSAndroid Build Coastguard Worker attributes of a Distribution, and then use 'attrs' (a dictionary 139*cda5da8dSAndroid Build Coastguard Worker mapping attribute names to values) to assign some of those 140*cda5da8dSAndroid Build Coastguard Worker attributes their "real" values. (Any attributes not mentioned in 141*cda5da8dSAndroid Build Coastguard Worker 'attrs' will be assigned to some null value: 0, None, an empty list 142*cda5da8dSAndroid Build Coastguard Worker or dictionary, etc.) Most importantly, initialize the 143*cda5da8dSAndroid Build Coastguard Worker 'command_obj' attribute to the empty dictionary; this will be 144*cda5da8dSAndroid Build Coastguard Worker filled in with real command objects by 'parse_command_line()'. 145*cda5da8dSAndroid Build Coastguard Worker """ 146*cda5da8dSAndroid Build Coastguard Worker 147*cda5da8dSAndroid Build Coastguard Worker # Default values for our command-line options 148*cda5da8dSAndroid Build Coastguard Worker self.verbose = 1 149*cda5da8dSAndroid Build Coastguard Worker self.dry_run = 0 150*cda5da8dSAndroid Build Coastguard Worker self.help = 0 151*cda5da8dSAndroid Build Coastguard Worker for attr in self.display_option_names: 152*cda5da8dSAndroid Build Coastguard Worker setattr(self, attr, 0) 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Worker # Store the distribution meta-data (name, version, author, and so 155*cda5da8dSAndroid Build Coastguard Worker # forth) in a separate object -- we're getting to have enough 156*cda5da8dSAndroid Build Coastguard Worker # information here (and enough command-line options) that it's 157*cda5da8dSAndroid Build Coastguard Worker # worth it. Also delegate 'get_XXX()' methods to the 'metadata' 158*cda5da8dSAndroid Build Coastguard Worker # object in a sneaky and underhanded (but efficient!) way. 159*cda5da8dSAndroid Build Coastguard Worker self.metadata = DistributionMetadata() 160*cda5da8dSAndroid Build Coastguard Worker for basename in self.metadata._METHOD_BASENAMES: 161*cda5da8dSAndroid Build Coastguard Worker method_name = "get_" + basename 162*cda5da8dSAndroid Build Coastguard Worker setattr(self, method_name, getattr(self.metadata, method_name)) 163*cda5da8dSAndroid Build Coastguard Worker 164*cda5da8dSAndroid Build Coastguard Worker # 'cmdclass' maps command names to class objects, so we 165*cda5da8dSAndroid Build Coastguard Worker # can 1) quickly figure out which class to instantiate when 166*cda5da8dSAndroid Build Coastguard Worker # we need to create a new command object, and 2) have a way 167*cda5da8dSAndroid Build Coastguard Worker # for the setup script to override command classes 168*cda5da8dSAndroid Build Coastguard Worker self.cmdclass = {} 169*cda5da8dSAndroid Build Coastguard Worker 170*cda5da8dSAndroid Build Coastguard Worker # 'command_packages' is a list of packages in which commands 171*cda5da8dSAndroid Build Coastguard Worker # are searched for. The factory for command 'foo' is expected 172*cda5da8dSAndroid Build Coastguard Worker # to be named 'foo' in the module 'foo' in one of the packages 173*cda5da8dSAndroid Build Coastguard Worker # named here. This list is searched from the left; an error 174*cda5da8dSAndroid Build Coastguard Worker # is raised if no named package provides the command being 175*cda5da8dSAndroid Build Coastguard Worker # searched for. (Always access using get_command_packages().) 176*cda5da8dSAndroid Build Coastguard Worker self.command_packages = None 177*cda5da8dSAndroid Build Coastguard Worker 178*cda5da8dSAndroid Build Coastguard Worker # 'script_name' and 'script_args' are usually set to sys.argv[0] 179*cda5da8dSAndroid Build Coastguard Worker # and sys.argv[1:], but they can be overridden when the caller is 180*cda5da8dSAndroid Build Coastguard Worker # not necessarily a setup script run from the command-line. 181*cda5da8dSAndroid Build Coastguard Worker self.script_name = None 182*cda5da8dSAndroid Build Coastguard Worker self.script_args = None 183*cda5da8dSAndroid Build Coastguard Worker 184*cda5da8dSAndroid Build Coastguard Worker # 'command_options' is where we store command options between 185*cda5da8dSAndroid Build Coastguard Worker # parsing them (from config files, the command-line, etc.) and when 186*cda5da8dSAndroid Build Coastguard Worker # they are actually needed -- ie. when the command in question is 187*cda5da8dSAndroid Build Coastguard Worker # instantiated. It is a dictionary of dictionaries of 2-tuples: 188*cda5da8dSAndroid Build Coastguard Worker # command_options = { command_name : { option : (source, value) } } 189*cda5da8dSAndroid Build Coastguard Worker self.command_options = {} 190*cda5da8dSAndroid Build Coastguard Worker 191*cda5da8dSAndroid Build Coastguard Worker # 'dist_files' is the list of (command, pyversion, file) that 192*cda5da8dSAndroid Build Coastguard Worker # have been created by any dist commands run so far. This is 193*cda5da8dSAndroid Build Coastguard Worker # filled regardless of whether the run is dry or not. pyversion 194*cda5da8dSAndroid Build Coastguard Worker # gives sysconfig.get_python_version() if the dist file is 195*cda5da8dSAndroid Build Coastguard Worker # specific to a Python version, 'any' if it is good for all 196*cda5da8dSAndroid Build Coastguard Worker # Python versions on the target platform, and '' for a source 197*cda5da8dSAndroid Build Coastguard Worker # file. pyversion should not be used to specify minimum or 198*cda5da8dSAndroid Build Coastguard Worker # maximum required Python versions; use the metainfo for that 199*cda5da8dSAndroid Build Coastguard Worker # instead. 200*cda5da8dSAndroid Build Coastguard Worker self.dist_files = [] 201*cda5da8dSAndroid Build Coastguard Worker 202*cda5da8dSAndroid Build Coastguard Worker # These options are really the business of various commands, rather 203*cda5da8dSAndroid Build Coastguard Worker # than of the Distribution itself. We provide aliases for them in 204*cda5da8dSAndroid Build Coastguard Worker # Distribution as a convenience to the developer. 205*cda5da8dSAndroid Build Coastguard Worker self.packages = None 206*cda5da8dSAndroid Build Coastguard Worker self.package_data = {} 207*cda5da8dSAndroid Build Coastguard Worker self.package_dir = None 208*cda5da8dSAndroid Build Coastguard Worker self.py_modules = None 209*cda5da8dSAndroid Build Coastguard Worker self.libraries = None 210*cda5da8dSAndroid Build Coastguard Worker self.headers = None 211*cda5da8dSAndroid Build Coastguard Worker self.ext_modules = None 212*cda5da8dSAndroid Build Coastguard Worker self.ext_package = None 213*cda5da8dSAndroid Build Coastguard Worker self.include_dirs = None 214*cda5da8dSAndroid Build Coastguard Worker self.extra_path = None 215*cda5da8dSAndroid Build Coastguard Worker self.scripts = None 216*cda5da8dSAndroid Build Coastguard Worker self.data_files = None 217*cda5da8dSAndroid Build Coastguard Worker self.password = '' 218*cda5da8dSAndroid Build Coastguard Worker 219*cda5da8dSAndroid Build Coastguard Worker # And now initialize bookkeeping stuff that can't be supplied by 220*cda5da8dSAndroid Build Coastguard Worker # the caller at all. 'command_obj' maps command names to 221*cda5da8dSAndroid Build Coastguard Worker # Command instances -- that's how we enforce that every command 222*cda5da8dSAndroid Build Coastguard Worker # class is a singleton. 223*cda5da8dSAndroid Build Coastguard Worker self.command_obj = {} 224*cda5da8dSAndroid Build Coastguard Worker 225*cda5da8dSAndroid Build Coastguard Worker # 'have_run' maps command names to boolean values; it keeps track 226*cda5da8dSAndroid Build Coastguard Worker # of whether we have actually run a particular command, to make it 227*cda5da8dSAndroid Build Coastguard Worker # cheap to "run" a command whenever we think we might need to -- if 228*cda5da8dSAndroid Build Coastguard Worker # it's already been done, no need for expensive filesystem 229*cda5da8dSAndroid Build Coastguard Worker # operations, we just check the 'have_run' dictionary and carry on. 230*cda5da8dSAndroid Build Coastguard Worker # It's only safe to query 'have_run' for a command class that has 231*cda5da8dSAndroid Build Coastguard Worker # been instantiated -- a false value will be inserted when the 232*cda5da8dSAndroid Build Coastguard Worker # command object is created, and replaced with a true value when 233*cda5da8dSAndroid Build Coastguard Worker # the command is successfully run. Thus it's probably best to use 234*cda5da8dSAndroid Build Coastguard Worker # '.get()' rather than a straight lookup. 235*cda5da8dSAndroid Build Coastguard Worker self.have_run = {} 236*cda5da8dSAndroid Build Coastguard Worker 237*cda5da8dSAndroid Build Coastguard Worker # Now we'll use the attrs dictionary (ultimately, keyword args from 238*cda5da8dSAndroid Build Coastguard Worker # the setup script) to possibly override any or all of these 239*cda5da8dSAndroid Build Coastguard Worker # distribution options. 240*cda5da8dSAndroid Build Coastguard Worker 241*cda5da8dSAndroid Build Coastguard Worker if attrs: 242*cda5da8dSAndroid Build Coastguard Worker # Pull out the set of command options and work on them 243*cda5da8dSAndroid Build Coastguard Worker # specifically. Note that this order guarantees that aliased 244*cda5da8dSAndroid Build Coastguard Worker # command options will override any supplied redundantly 245*cda5da8dSAndroid Build Coastguard Worker # through the general options dictionary. 246*cda5da8dSAndroid Build Coastguard Worker options = attrs.get('options') 247*cda5da8dSAndroid Build Coastguard Worker if options is not None: 248*cda5da8dSAndroid Build Coastguard Worker del attrs['options'] 249*cda5da8dSAndroid Build Coastguard Worker for (command, cmd_options) in options.items(): 250*cda5da8dSAndroid Build Coastguard Worker opt_dict = self.get_option_dict(command) 251*cda5da8dSAndroid Build Coastguard Worker for (opt, val) in cmd_options.items(): 252*cda5da8dSAndroid Build Coastguard Worker opt_dict[opt] = ("setup script", val) 253*cda5da8dSAndroid Build Coastguard Worker 254*cda5da8dSAndroid Build Coastguard Worker if 'licence' in attrs: 255*cda5da8dSAndroid Build Coastguard Worker attrs['license'] = attrs['licence'] 256*cda5da8dSAndroid Build Coastguard Worker del attrs['licence'] 257*cda5da8dSAndroid Build Coastguard Worker msg = "'licence' distribution option is deprecated; use 'license'" 258*cda5da8dSAndroid Build Coastguard Worker if warnings is not None: 259*cda5da8dSAndroid Build Coastguard Worker warnings.warn(msg) 260*cda5da8dSAndroid Build Coastguard Worker else: 261*cda5da8dSAndroid Build Coastguard Worker sys.stderr.write(msg + "\n") 262*cda5da8dSAndroid Build Coastguard Worker 263*cda5da8dSAndroid Build Coastguard Worker # Now work on the rest of the attributes. Any attribute that's 264*cda5da8dSAndroid Build Coastguard Worker # not already defined is invalid! 265*cda5da8dSAndroid Build Coastguard Worker for (key, val) in attrs.items(): 266*cda5da8dSAndroid Build Coastguard Worker if hasattr(self.metadata, "set_" + key): 267*cda5da8dSAndroid Build Coastguard Worker getattr(self.metadata, "set_" + key)(val) 268*cda5da8dSAndroid Build Coastguard Worker elif hasattr(self.metadata, key): 269*cda5da8dSAndroid Build Coastguard Worker setattr(self.metadata, key, val) 270*cda5da8dSAndroid Build Coastguard Worker elif hasattr(self, key): 271*cda5da8dSAndroid Build Coastguard Worker setattr(self, key, val) 272*cda5da8dSAndroid Build Coastguard Worker else: 273*cda5da8dSAndroid Build Coastguard Worker msg = "Unknown distribution option: %s" % repr(key) 274*cda5da8dSAndroid Build Coastguard Worker warnings.warn(msg) 275*cda5da8dSAndroid Build Coastguard Worker 276*cda5da8dSAndroid Build Coastguard Worker # no-user-cfg is handled before other command line args 277*cda5da8dSAndroid Build Coastguard Worker # because other args override the config files, and this 278*cda5da8dSAndroid Build Coastguard Worker # one is needed before we can load the config files. 279*cda5da8dSAndroid Build Coastguard Worker # If attrs['script_args'] wasn't passed, assume false. 280*cda5da8dSAndroid Build Coastguard Worker # 281*cda5da8dSAndroid Build Coastguard Worker # This also make sure we just look at the global options 282*cda5da8dSAndroid Build Coastguard Worker self.want_user_cfg = True 283*cda5da8dSAndroid Build Coastguard Worker 284*cda5da8dSAndroid Build Coastguard Worker if self.script_args is not None: 285*cda5da8dSAndroid Build Coastguard Worker for arg in self.script_args: 286*cda5da8dSAndroid Build Coastguard Worker if not arg.startswith('-'): 287*cda5da8dSAndroid Build Coastguard Worker break 288*cda5da8dSAndroid Build Coastguard Worker if arg == '--no-user-cfg': 289*cda5da8dSAndroid Build Coastguard Worker self.want_user_cfg = False 290*cda5da8dSAndroid Build Coastguard Worker break 291*cda5da8dSAndroid Build Coastguard Worker 292*cda5da8dSAndroid Build Coastguard Worker self.finalize_options() 293*cda5da8dSAndroid Build Coastguard Worker 294*cda5da8dSAndroid Build Coastguard Worker def get_option_dict(self, command): 295*cda5da8dSAndroid Build Coastguard Worker """Get the option dictionary for a given command. If that 296*cda5da8dSAndroid Build Coastguard Worker command's option dictionary hasn't been created yet, then create it 297*cda5da8dSAndroid Build Coastguard Worker and return the new dictionary; otherwise, return the existing 298*cda5da8dSAndroid Build Coastguard Worker option dictionary. 299*cda5da8dSAndroid Build Coastguard Worker """ 300*cda5da8dSAndroid Build Coastguard Worker dict = self.command_options.get(command) 301*cda5da8dSAndroid Build Coastguard Worker if dict is None: 302*cda5da8dSAndroid Build Coastguard Worker dict = self.command_options[command] = {} 303*cda5da8dSAndroid Build Coastguard Worker return dict 304*cda5da8dSAndroid Build Coastguard Worker 305*cda5da8dSAndroid Build Coastguard Worker def dump_option_dicts(self, header=None, commands=None, indent=""): 306*cda5da8dSAndroid Build Coastguard Worker from pprint import pformat 307*cda5da8dSAndroid Build Coastguard Worker 308*cda5da8dSAndroid Build Coastguard Worker if commands is None: # dump all command option dicts 309*cda5da8dSAndroid Build Coastguard Worker commands = sorted(self.command_options.keys()) 310*cda5da8dSAndroid Build Coastguard Worker 311*cda5da8dSAndroid Build Coastguard Worker if header is not None: 312*cda5da8dSAndroid Build Coastguard Worker self.announce(indent + header) 313*cda5da8dSAndroid Build Coastguard Worker indent = indent + " " 314*cda5da8dSAndroid Build Coastguard Worker 315*cda5da8dSAndroid Build Coastguard Worker if not commands: 316*cda5da8dSAndroid Build Coastguard Worker self.announce(indent + "no commands known yet") 317*cda5da8dSAndroid Build Coastguard Worker return 318*cda5da8dSAndroid Build Coastguard Worker 319*cda5da8dSAndroid Build Coastguard Worker for cmd_name in commands: 320*cda5da8dSAndroid Build Coastguard Worker opt_dict = self.command_options.get(cmd_name) 321*cda5da8dSAndroid Build Coastguard Worker if opt_dict is None: 322*cda5da8dSAndroid Build Coastguard Worker self.announce(indent + 323*cda5da8dSAndroid Build Coastguard Worker "no option dict for '%s' command" % cmd_name) 324*cda5da8dSAndroid Build Coastguard Worker else: 325*cda5da8dSAndroid Build Coastguard Worker self.announce(indent + 326*cda5da8dSAndroid Build Coastguard Worker "option dict for '%s' command:" % cmd_name) 327*cda5da8dSAndroid Build Coastguard Worker out = pformat(opt_dict) 328*cda5da8dSAndroid Build Coastguard Worker for line in out.split('\n'): 329*cda5da8dSAndroid Build Coastguard Worker self.announce(indent + " " + line) 330*cda5da8dSAndroid Build Coastguard Worker 331*cda5da8dSAndroid Build Coastguard Worker # -- Config file finding/parsing methods --------------------------- 332*cda5da8dSAndroid Build Coastguard Worker 333*cda5da8dSAndroid Build Coastguard Worker def find_config_files(self): 334*cda5da8dSAndroid Build Coastguard Worker """Find as many configuration files as should be processed for this 335*cda5da8dSAndroid Build Coastguard Worker platform, and return a list of filenames in the order in which they 336*cda5da8dSAndroid Build Coastguard Worker should be parsed. The filenames returned are guaranteed to exist 337*cda5da8dSAndroid Build Coastguard Worker (modulo nasty race conditions). 338*cda5da8dSAndroid Build Coastguard Worker 339*cda5da8dSAndroid Build Coastguard Worker There are three possible config files: distutils.cfg in the 340*cda5da8dSAndroid Build Coastguard Worker Distutils installation directory (ie. where the top-level 341*cda5da8dSAndroid Build Coastguard Worker Distutils __inst__.py file lives), a file in the user's home 342*cda5da8dSAndroid Build Coastguard Worker directory named .pydistutils.cfg on Unix and pydistutils.cfg 343*cda5da8dSAndroid Build Coastguard Worker on Windows/Mac; and setup.cfg in the current directory. 344*cda5da8dSAndroid Build Coastguard Worker 345*cda5da8dSAndroid Build Coastguard Worker The file in the user's home directory can be disabled with the 346*cda5da8dSAndroid Build Coastguard Worker --no-user-cfg option. 347*cda5da8dSAndroid Build Coastguard Worker """ 348*cda5da8dSAndroid Build Coastguard Worker files = [] 349*cda5da8dSAndroid Build Coastguard Worker check_environ() 350*cda5da8dSAndroid Build Coastguard Worker 351*cda5da8dSAndroid Build Coastguard Worker # Where to look for the system-wide Distutils config file 352*cda5da8dSAndroid Build Coastguard Worker sys_dir = os.path.dirname(sys.modules['distutils'].__file__) 353*cda5da8dSAndroid Build Coastguard Worker 354*cda5da8dSAndroid Build Coastguard Worker # Look for the system config file 355*cda5da8dSAndroid Build Coastguard Worker sys_file = os.path.join(sys_dir, "distutils.cfg") 356*cda5da8dSAndroid Build Coastguard Worker if os.path.isfile(sys_file): 357*cda5da8dSAndroid Build Coastguard Worker files.append(sys_file) 358*cda5da8dSAndroid Build Coastguard Worker 359*cda5da8dSAndroid Build Coastguard Worker # What to call the per-user config file 360*cda5da8dSAndroid Build Coastguard Worker if os.name == 'posix': 361*cda5da8dSAndroid Build Coastguard Worker user_filename = ".pydistutils.cfg" 362*cda5da8dSAndroid Build Coastguard Worker else: 363*cda5da8dSAndroid Build Coastguard Worker user_filename = "pydistutils.cfg" 364*cda5da8dSAndroid Build Coastguard Worker 365*cda5da8dSAndroid Build Coastguard Worker # And look for the user config file 366*cda5da8dSAndroid Build Coastguard Worker if self.want_user_cfg: 367*cda5da8dSAndroid Build Coastguard Worker user_file = os.path.join(os.path.expanduser('~'), user_filename) 368*cda5da8dSAndroid Build Coastguard Worker if os.path.isfile(user_file): 369*cda5da8dSAndroid Build Coastguard Worker files.append(user_file) 370*cda5da8dSAndroid Build Coastguard Worker 371*cda5da8dSAndroid Build Coastguard Worker # All platforms support local setup.cfg 372*cda5da8dSAndroid Build Coastguard Worker local_file = "setup.cfg" 373*cda5da8dSAndroid Build Coastguard Worker if os.path.isfile(local_file): 374*cda5da8dSAndroid Build Coastguard Worker files.append(local_file) 375*cda5da8dSAndroid Build Coastguard Worker 376*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 377*cda5da8dSAndroid Build Coastguard Worker self.announce("using config files: %s" % ', '.join(files)) 378*cda5da8dSAndroid Build Coastguard Worker 379*cda5da8dSAndroid Build Coastguard Worker return files 380*cda5da8dSAndroid Build Coastguard Worker 381*cda5da8dSAndroid Build Coastguard Worker def parse_config_files(self, filenames=None): 382*cda5da8dSAndroid Build Coastguard Worker from configparser import ConfigParser 383*cda5da8dSAndroid Build Coastguard Worker 384*cda5da8dSAndroid Build Coastguard Worker # Ignore install directory options if we have a venv 385*cda5da8dSAndroid Build Coastguard Worker if sys.prefix != sys.base_prefix: 386*cda5da8dSAndroid Build Coastguard Worker ignore_options = [ 387*cda5da8dSAndroid Build Coastguard Worker 'install-base', 'install-platbase', 'install-lib', 388*cda5da8dSAndroid Build Coastguard Worker 'install-platlib', 'install-purelib', 'install-headers', 389*cda5da8dSAndroid Build Coastguard Worker 'install-scripts', 'install-data', 'prefix', 'exec-prefix', 390*cda5da8dSAndroid Build Coastguard Worker 'home', 'user', 'root'] 391*cda5da8dSAndroid Build Coastguard Worker else: 392*cda5da8dSAndroid Build Coastguard Worker ignore_options = [] 393*cda5da8dSAndroid Build Coastguard Worker 394*cda5da8dSAndroid Build Coastguard Worker ignore_options = frozenset(ignore_options) 395*cda5da8dSAndroid Build Coastguard Worker 396*cda5da8dSAndroid Build Coastguard Worker if filenames is None: 397*cda5da8dSAndroid Build Coastguard Worker filenames = self.find_config_files() 398*cda5da8dSAndroid Build Coastguard Worker 399*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 400*cda5da8dSAndroid Build Coastguard Worker self.announce("Distribution.parse_config_files():") 401*cda5da8dSAndroid Build Coastguard Worker 402*cda5da8dSAndroid Build Coastguard Worker parser = ConfigParser() 403*cda5da8dSAndroid Build Coastguard Worker for filename in filenames: 404*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 405*cda5da8dSAndroid Build Coastguard Worker self.announce(" reading %s" % filename) 406*cda5da8dSAndroid Build Coastguard Worker parser.read(filename) 407*cda5da8dSAndroid Build Coastguard Worker for section in parser.sections(): 408*cda5da8dSAndroid Build Coastguard Worker options = parser.options(section) 409*cda5da8dSAndroid Build Coastguard Worker opt_dict = self.get_option_dict(section) 410*cda5da8dSAndroid Build Coastguard Worker 411*cda5da8dSAndroid Build Coastguard Worker for opt in options: 412*cda5da8dSAndroid Build Coastguard Worker if opt != '__name__' and opt not in ignore_options: 413*cda5da8dSAndroid Build Coastguard Worker val = parser.get(section,opt) 414*cda5da8dSAndroid Build Coastguard Worker opt = opt.replace('-', '_') 415*cda5da8dSAndroid Build Coastguard Worker opt_dict[opt] = (filename, val) 416*cda5da8dSAndroid Build Coastguard Worker 417*cda5da8dSAndroid Build Coastguard Worker # Make the ConfigParser forget everything (so we retain 418*cda5da8dSAndroid Build Coastguard Worker # the original filenames that options come from) 419*cda5da8dSAndroid Build Coastguard Worker parser.__init__() 420*cda5da8dSAndroid Build Coastguard Worker 421*cda5da8dSAndroid Build Coastguard Worker # If there was a "global" section in the config file, use it 422*cda5da8dSAndroid Build Coastguard Worker # to set Distribution options. 423*cda5da8dSAndroid Build Coastguard Worker 424*cda5da8dSAndroid Build Coastguard Worker if 'global' in self.command_options: 425*cda5da8dSAndroid Build Coastguard Worker for (opt, (src, val)) in self.command_options['global'].items(): 426*cda5da8dSAndroid Build Coastguard Worker alias = self.negative_opt.get(opt) 427*cda5da8dSAndroid Build Coastguard Worker try: 428*cda5da8dSAndroid Build Coastguard Worker if alias: 429*cda5da8dSAndroid Build Coastguard Worker setattr(self, alias, not strtobool(val)) 430*cda5da8dSAndroid Build Coastguard Worker elif opt in ('verbose', 'dry_run'): # ugh! 431*cda5da8dSAndroid Build Coastguard Worker setattr(self, opt, strtobool(val)) 432*cda5da8dSAndroid Build Coastguard Worker else: 433*cda5da8dSAndroid Build Coastguard Worker setattr(self, opt, val) 434*cda5da8dSAndroid Build Coastguard Worker except ValueError as msg: 435*cda5da8dSAndroid Build Coastguard Worker raise DistutilsOptionError(msg) 436*cda5da8dSAndroid Build Coastguard Worker 437*cda5da8dSAndroid Build Coastguard Worker # -- Command-line parsing methods ---------------------------------- 438*cda5da8dSAndroid Build Coastguard Worker 439*cda5da8dSAndroid Build Coastguard Worker def parse_command_line(self): 440*cda5da8dSAndroid Build Coastguard Worker """Parse the setup script's command line, taken from the 441*cda5da8dSAndroid Build Coastguard Worker 'script_args' instance attribute (which defaults to 'sys.argv[1:]' 442*cda5da8dSAndroid Build Coastguard Worker -- see 'setup()' in core.py). This list is first processed for 443*cda5da8dSAndroid Build Coastguard Worker "global options" -- options that set attributes of the Distribution 444*cda5da8dSAndroid Build Coastguard Worker instance. Then, it is alternately scanned for Distutils commands 445*cda5da8dSAndroid Build Coastguard Worker and options for that command. Each new command terminates the 446*cda5da8dSAndroid Build Coastguard Worker options for the previous command. The allowed options for a 447*cda5da8dSAndroid Build Coastguard Worker command are determined by the 'user_options' attribute of the 448*cda5da8dSAndroid Build Coastguard Worker command class -- thus, we have to be able to load command classes 449*cda5da8dSAndroid Build Coastguard Worker in order to parse the command line. Any error in that 'options' 450*cda5da8dSAndroid Build Coastguard Worker attribute raises DistutilsGetoptError; any error on the 451*cda5da8dSAndroid Build Coastguard Worker command-line raises DistutilsArgError. If no Distutils commands 452*cda5da8dSAndroid Build Coastguard Worker were found on the command line, raises DistutilsArgError. Return 453*cda5da8dSAndroid Build Coastguard Worker true if command-line was successfully parsed and we should carry 454*cda5da8dSAndroid Build Coastguard Worker on with executing commands; false if no errors but we shouldn't 455*cda5da8dSAndroid Build Coastguard Worker execute commands (currently, this only happens if user asks for 456*cda5da8dSAndroid Build Coastguard Worker help). 457*cda5da8dSAndroid Build Coastguard Worker """ 458*cda5da8dSAndroid Build Coastguard Worker # 459*cda5da8dSAndroid Build Coastguard Worker # We now have enough information to show the Macintosh dialog 460*cda5da8dSAndroid Build Coastguard Worker # that allows the user to interactively specify the "command line". 461*cda5da8dSAndroid Build Coastguard Worker # 462*cda5da8dSAndroid Build Coastguard Worker toplevel_options = self._get_toplevel_options() 463*cda5da8dSAndroid Build Coastguard Worker 464*cda5da8dSAndroid Build Coastguard Worker # We have to parse the command line a bit at a time -- global 465*cda5da8dSAndroid Build Coastguard Worker # options, then the first command, then its options, and so on -- 466*cda5da8dSAndroid Build Coastguard Worker # because each command will be handled by a different class, and 467*cda5da8dSAndroid Build Coastguard Worker # the options that are valid for a particular class aren't known 468*cda5da8dSAndroid Build Coastguard Worker # until we have loaded the command class, which doesn't happen 469*cda5da8dSAndroid Build Coastguard Worker # until we know what the command is. 470*cda5da8dSAndroid Build Coastguard Worker 471*cda5da8dSAndroid Build Coastguard Worker self.commands = [] 472*cda5da8dSAndroid Build Coastguard Worker parser = FancyGetopt(toplevel_options + self.display_options) 473*cda5da8dSAndroid Build Coastguard Worker parser.set_negative_aliases(self.negative_opt) 474*cda5da8dSAndroid Build Coastguard Worker parser.set_aliases({'licence': 'license'}) 475*cda5da8dSAndroid Build Coastguard Worker args = parser.getopt(args=self.script_args, object=self) 476*cda5da8dSAndroid Build Coastguard Worker option_order = parser.get_option_order() 477*cda5da8dSAndroid Build Coastguard Worker log.set_verbosity(self.verbose) 478*cda5da8dSAndroid Build Coastguard Worker 479*cda5da8dSAndroid Build Coastguard Worker # for display options we return immediately 480*cda5da8dSAndroid Build Coastguard Worker if self.handle_display_options(option_order): 481*cda5da8dSAndroid Build Coastguard Worker return 482*cda5da8dSAndroid Build Coastguard Worker while args: 483*cda5da8dSAndroid Build Coastguard Worker args = self._parse_command_opts(parser, args) 484*cda5da8dSAndroid Build Coastguard Worker if args is None: # user asked for help (and got it) 485*cda5da8dSAndroid Build Coastguard Worker return 486*cda5da8dSAndroid Build Coastguard Worker 487*cda5da8dSAndroid Build Coastguard Worker # Handle the cases of --help as a "global" option, ie. 488*cda5da8dSAndroid Build Coastguard Worker # "setup.py --help" and "setup.py --help command ...". For the 489*cda5da8dSAndroid Build Coastguard Worker # former, we show global options (--verbose, --dry-run, etc.) 490*cda5da8dSAndroid Build Coastguard Worker # and display-only options (--name, --version, etc.); for the 491*cda5da8dSAndroid Build Coastguard Worker # latter, we omit the display-only options and show help for 492*cda5da8dSAndroid Build Coastguard Worker # each command listed on the command line. 493*cda5da8dSAndroid Build Coastguard Worker if self.help: 494*cda5da8dSAndroid Build Coastguard Worker self._show_help(parser, 495*cda5da8dSAndroid Build Coastguard Worker display_options=len(self.commands) == 0, 496*cda5da8dSAndroid Build Coastguard Worker commands=self.commands) 497*cda5da8dSAndroid Build Coastguard Worker return 498*cda5da8dSAndroid Build Coastguard Worker 499*cda5da8dSAndroid Build Coastguard Worker # Oops, no commands found -- an end-user error 500*cda5da8dSAndroid Build Coastguard Worker if not self.commands: 501*cda5da8dSAndroid Build Coastguard Worker raise DistutilsArgError("no commands supplied") 502*cda5da8dSAndroid Build Coastguard Worker 503*cda5da8dSAndroid Build Coastguard Worker # All is well: return true 504*cda5da8dSAndroid Build Coastguard Worker return True 505*cda5da8dSAndroid Build Coastguard Worker 506*cda5da8dSAndroid Build Coastguard Worker def _get_toplevel_options(self): 507*cda5da8dSAndroid Build Coastguard Worker """Return the non-display options recognized at the top level. 508*cda5da8dSAndroid Build Coastguard Worker 509*cda5da8dSAndroid Build Coastguard Worker This includes options that are recognized *only* at the top 510*cda5da8dSAndroid Build Coastguard Worker level as well as options recognized for commands. 511*cda5da8dSAndroid Build Coastguard Worker """ 512*cda5da8dSAndroid Build Coastguard Worker return self.global_options + [ 513*cda5da8dSAndroid Build Coastguard Worker ("command-packages=", None, 514*cda5da8dSAndroid Build Coastguard Worker "list of packages that provide distutils commands"), 515*cda5da8dSAndroid Build Coastguard Worker ] 516*cda5da8dSAndroid Build Coastguard Worker 517*cda5da8dSAndroid Build Coastguard Worker def _parse_command_opts(self, parser, args): 518*cda5da8dSAndroid Build Coastguard Worker """Parse the command-line options for a single command. 519*cda5da8dSAndroid Build Coastguard Worker 'parser' must be a FancyGetopt instance; 'args' must be the list 520*cda5da8dSAndroid Build Coastguard Worker of arguments, starting with the current command (whose options 521*cda5da8dSAndroid Build Coastguard Worker we are about to parse). Returns a new version of 'args' with 522*cda5da8dSAndroid Build Coastguard Worker the next command at the front of the list; will be the empty 523*cda5da8dSAndroid Build Coastguard Worker list if there are no more commands on the command line. Returns 524*cda5da8dSAndroid Build Coastguard Worker None if the user asked for help on this command. 525*cda5da8dSAndroid Build Coastguard Worker """ 526*cda5da8dSAndroid Build Coastguard Worker # late import because of mutual dependence between these modules 527*cda5da8dSAndroid Build Coastguard Worker from distutils.cmd import Command 528*cda5da8dSAndroid Build Coastguard Worker 529*cda5da8dSAndroid Build Coastguard Worker # Pull the current command from the head of the command line 530*cda5da8dSAndroid Build Coastguard Worker command = args[0] 531*cda5da8dSAndroid Build Coastguard Worker if not command_re.match(command): 532*cda5da8dSAndroid Build Coastguard Worker raise SystemExit("invalid command name '%s'" % command) 533*cda5da8dSAndroid Build Coastguard Worker self.commands.append(command) 534*cda5da8dSAndroid Build Coastguard Worker 535*cda5da8dSAndroid Build Coastguard Worker # Dig up the command class that implements this command, so we 536*cda5da8dSAndroid Build Coastguard Worker # 1) know that it's a valid command, and 2) know which options 537*cda5da8dSAndroid Build Coastguard Worker # it takes. 538*cda5da8dSAndroid Build Coastguard Worker try: 539*cda5da8dSAndroid Build Coastguard Worker cmd_class = self.get_command_class(command) 540*cda5da8dSAndroid Build Coastguard Worker except DistutilsModuleError as msg: 541*cda5da8dSAndroid Build Coastguard Worker raise DistutilsArgError(msg) 542*cda5da8dSAndroid Build Coastguard Worker 543*cda5da8dSAndroid Build Coastguard Worker # Require that the command class be derived from Command -- want 544*cda5da8dSAndroid Build Coastguard Worker # to be sure that the basic "command" interface is implemented. 545*cda5da8dSAndroid Build Coastguard Worker if not issubclass(cmd_class, Command): 546*cda5da8dSAndroid Build Coastguard Worker raise DistutilsClassError( 547*cda5da8dSAndroid Build Coastguard Worker "command class %s must subclass Command" % cmd_class) 548*cda5da8dSAndroid Build Coastguard Worker 549*cda5da8dSAndroid Build Coastguard Worker # Also make sure that the command object provides a list of its 550*cda5da8dSAndroid Build Coastguard Worker # known options. 551*cda5da8dSAndroid Build Coastguard Worker if not (hasattr(cmd_class, 'user_options') and 552*cda5da8dSAndroid Build Coastguard Worker isinstance(cmd_class.user_options, list)): 553*cda5da8dSAndroid Build Coastguard Worker msg = ("command class %s must provide " 554*cda5da8dSAndroid Build Coastguard Worker "'user_options' attribute (a list of tuples)") 555*cda5da8dSAndroid Build Coastguard Worker raise DistutilsClassError(msg % cmd_class) 556*cda5da8dSAndroid Build Coastguard Worker 557*cda5da8dSAndroid Build Coastguard Worker # If the command class has a list of negative alias options, 558*cda5da8dSAndroid Build Coastguard Worker # merge it in with the global negative aliases. 559*cda5da8dSAndroid Build Coastguard Worker negative_opt = self.negative_opt 560*cda5da8dSAndroid Build Coastguard Worker if hasattr(cmd_class, 'negative_opt'): 561*cda5da8dSAndroid Build Coastguard Worker negative_opt = negative_opt.copy() 562*cda5da8dSAndroid Build Coastguard Worker negative_opt.update(cmd_class.negative_opt) 563*cda5da8dSAndroid Build Coastguard Worker 564*cda5da8dSAndroid Build Coastguard Worker # Check for help_options in command class. They have a different 565*cda5da8dSAndroid Build Coastguard Worker # format (tuple of four) so we need to preprocess them here. 566*cda5da8dSAndroid Build Coastguard Worker if (hasattr(cmd_class, 'help_options') and 567*cda5da8dSAndroid Build Coastguard Worker isinstance(cmd_class.help_options, list)): 568*cda5da8dSAndroid Build Coastguard Worker help_options = fix_help_options(cmd_class.help_options) 569*cda5da8dSAndroid Build Coastguard Worker else: 570*cda5da8dSAndroid Build Coastguard Worker help_options = [] 571*cda5da8dSAndroid Build Coastguard Worker 572*cda5da8dSAndroid Build Coastguard Worker # All commands support the global options too, just by adding 573*cda5da8dSAndroid Build Coastguard Worker # in 'global_options'. 574*cda5da8dSAndroid Build Coastguard Worker parser.set_option_table(self.global_options + 575*cda5da8dSAndroid Build Coastguard Worker cmd_class.user_options + 576*cda5da8dSAndroid Build Coastguard Worker help_options) 577*cda5da8dSAndroid Build Coastguard Worker parser.set_negative_aliases(negative_opt) 578*cda5da8dSAndroid Build Coastguard Worker (args, opts) = parser.getopt(args[1:]) 579*cda5da8dSAndroid Build Coastguard Worker if hasattr(opts, 'help') and opts.help: 580*cda5da8dSAndroid Build Coastguard Worker self._show_help(parser, display_options=0, commands=[cmd_class]) 581*cda5da8dSAndroid Build Coastguard Worker return 582*cda5da8dSAndroid Build Coastguard Worker 583*cda5da8dSAndroid Build Coastguard Worker if (hasattr(cmd_class, 'help_options') and 584*cda5da8dSAndroid Build Coastguard Worker isinstance(cmd_class.help_options, list)): 585*cda5da8dSAndroid Build Coastguard Worker help_option_found=0 586*cda5da8dSAndroid Build Coastguard Worker for (help_option, short, desc, func) in cmd_class.help_options: 587*cda5da8dSAndroid Build Coastguard Worker if hasattr(opts, parser.get_attr_name(help_option)): 588*cda5da8dSAndroid Build Coastguard Worker help_option_found=1 589*cda5da8dSAndroid Build Coastguard Worker if callable(func): 590*cda5da8dSAndroid Build Coastguard Worker func() 591*cda5da8dSAndroid Build Coastguard Worker else: 592*cda5da8dSAndroid Build Coastguard Worker raise DistutilsClassError( 593*cda5da8dSAndroid Build Coastguard Worker "invalid help function %r for help option '%s': " 594*cda5da8dSAndroid Build Coastguard Worker "must be a callable object (function, etc.)" 595*cda5da8dSAndroid Build Coastguard Worker % (func, help_option)) 596*cda5da8dSAndroid Build Coastguard Worker 597*cda5da8dSAndroid Build Coastguard Worker if help_option_found: 598*cda5da8dSAndroid Build Coastguard Worker return 599*cda5da8dSAndroid Build Coastguard Worker 600*cda5da8dSAndroid Build Coastguard Worker # Put the options from the command-line into their official 601*cda5da8dSAndroid Build Coastguard Worker # holding pen, the 'command_options' dictionary. 602*cda5da8dSAndroid Build Coastguard Worker opt_dict = self.get_option_dict(command) 603*cda5da8dSAndroid Build Coastguard Worker for (name, value) in vars(opts).items(): 604*cda5da8dSAndroid Build Coastguard Worker opt_dict[name] = ("command line", value) 605*cda5da8dSAndroid Build Coastguard Worker 606*cda5da8dSAndroid Build Coastguard Worker return args 607*cda5da8dSAndroid Build Coastguard Worker 608*cda5da8dSAndroid Build Coastguard Worker def finalize_options(self): 609*cda5da8dSAndroid Build Coastguard Worker """Set final values for all the options on the Distribution 610*cda5da8dSAndroid Build Coastguard Worker instance, analogous to the .finalize_options() method of Command 611*cda5da8dSAndroid Build Coastguard Worker objects. 612*cda5da8dSAndroid Build Coastguard Worker """ 613*cda5da8dSAndroid Build Coastguard Worker for attr in ('keywords', 'platforms'): 614*cda5da8dSAndroid Build Coastguard Worker value = getattr(self.metadata, attr) 615*cda5da8dSAndroid Build Coastguard Worker if value is None: 616*cda5da8dSAndroid Build Coastguard Worker continue 617*cda5da8dSAndroid Build Coastguard Worker if isinstance(value, str): 618*cda5da8dSAndroid Build Coastguard Worker value = [elm.strip() for elm in value.split(',')] 619*cda5da8dSAndroid Build Coastguard Worker setattr(self.metadata, attr, value) 620*cda5da8dSAndroid Build Coastguard Worker 621*cda5da8dSAndroid Build Coastguard Worker def _show_help(self, parser, global_options=1, display_options=1, 622*cda5da8dSAndroid Build Coastguard Worker commands=[]): 623*cda5da8dSAndroid Build Coastguard Worker """Show help for the setup script command-line in the form of 624*cda5da8dSAndroid Build Coastguard Worker several lists of command-line options. 'parser' should be a 625*cda5da8dSAndroid Build Coastguard Worker FancyGetopt instance; do not expect it to be returned in the 626*cda5da8dSAndroid Build Coastguard Worker same state, as its option table will be reset to make it 627*cda5da8dSAndroid Build Coastguard Worker generate the correct help text. 628*cda5da8dSAndroid Build Coastguard Worker 629*cda5da8dSAndroid Build Coastguard Worker If 'global_options' is true, lists the global options: 630*cda5da8dSAndroid Build Coastguard Worker --verbose, --dry-run, etc. If 'display_options' is true, lists 631*cda5da8dSAndroid Build Coastguard Worker the "display-only" options: --name, --version, etc. Finally, 632*cda5da8dSAndroid Build Coastguard Worker lists per-command help for every command name or command class 633*cda5da8dSAndroid Build Coastguard Worker in 'commands'. 634*cda5da8dSAndroid Build Coastguard Worker """ 635*cda5da8dSAndroid Build Coastguard Worker # late import because of mutual dependence between these modules 636*cda5da8dSAndroid Build Coastguard Worker from distutils.core import gen_usage 637*cda5da8dSAndroid Build Coastguard Worker from distutils.cmd import Command 638*cda5da8dSAndroid Build Coastguard Worker 639*cda5da8dSAndroid Build Coastguard Worker if global_options: 640*cda5da8dSAndroid Build Coastguard Worker if display_options: 641*cda5da8dSAndroid Build Coastguard Worker options = self._get_toplevel_options() 642*cda5da8dSAndroid Build Coastguard Worker else: 643*cda5da8dSAndroid Build Coastguard Worker options = self.global_options 644*cda5da8dSAndroid Build Coastguard Worker parser.set_option_table(options) 645*cda5da8dSAndroid Build Coastguard Worker parser.print_help(self.common_usage + "\nGlobal options:") 646*cda5da8dSAndroid Build Coastguard Worker print('') 647*cda5da8dSAndroid Build Coastguard Worker 648*cda5da8dSAndroid Build Coastguard Worker if display_options: 649*cda5da8dSAndroid Build Coastguard Worker parser.set_option_table(self.display_options) 650*cda5da8dSAndroid Build Coastguard Worker parser.print_help( 651*cda5da8dSAndroid Build Coastguard Worker "Information display options (just display " + 652*cda5da8dSAndroid Build Coastguard Worker "information, ignore any commands)") 653*cda5da8dSAndroid Build Coastguard Worker print('') 654*cda5da8dSAndroid Build Coastguard Worker 655*cda5da8dSAndroid Build Coastguard Worker for command in self.commands: 656*cda5da8dSAndroid Build Coastguard Worker if isinstance(command, type) and issubclass(command, Command): 657*cda5da8dSAndroid Build Coastguard Worker klass = command 658*cda5da8dSAndroid Build Coastguard Worker else: 659*cda5da8dSAndroid Build Coastguard Worker klass = self.get_command_class(command) 660*cda5da8dSAndroid Build Coastguard Worker if (hasattr(klass, 'help_options') and 661*cda5da8dSAndroid Build Coastguard Worker isinstance(klass.help_options, list)): 662*cda5da8dSAndroid Build Coastguard Worker parser.set_option_table(klass.user_options + 663*cda5da8dSAndroid Build Coastguard Worker fix_help_options(klass.help_options)) 664*cda5da8dSAndroid Build Coastguard Worker else: 665*cda5da8dSAndroid Build Coastguard Worker parser.set_option_table(klass.user_options) 666*cda5da8dSAndroid Build Coastguard Worker parser.print_help("Options for '%s' command:" % klass.__name__) 667*cda5da8dSAndroid Build Coastguard Worker print('') 668*cda5da8dSAndroid Build Coastguard Worker 669*cda5da8dSAndroid Build Coastguard Worker print(gen_usage(self.script_name)) 670*cda5da8dSAndroid Build Coastguard Worker 671*cda5da8dSAndroid Build Coastguard Worker def handle_display_options(self, option_order): 672*cda5da8dSAndroid Build Coastguard Worker """If there were any non-global "display-only" options 673*cda5da8dSAndroid Build Coastguard Worker (--help-commands or the metadata display options) on the command 674*cda5da8dSAndroid Build Coastguard Worker line, display the requested info and return true; else return 675*cda5da8dSAndroid Build Coastguard Worker false. 676*cda5da8dSAndroid Build Coastguard Worker """ 677*cda5da8dSAndroid Build Coastguard Worker from distutils.core import gen_usage 678*cda5da8dSAndroid Build Coastguard Worker 679*cda5da8dSAndroid Build Coastguard Worker # User just wants a list of commands -- we'll print it out and stop 680*cda5da8dSAndroid Build Coastguard Worker # processing now (ie. if they ran "setup --help-commands foo bar", 681*cda5da8dSAndroid Build Coastguard Worker # we ignore "foo bar"). 682*cda5da8dSAndroid Build Coastguard Worker if self.help_commands: 683*cda5da8dSAndroid Build Coastguard Worker self.print_commands() 684*cda5da8dSAndroid Build Coastguard Worker print('') 685*cda5da8dSAndroid Build Coastguard Worker print(gen_usage(self.script_name)) 686*cda5da8dSAndroid Build Coastguard Worker return 1 687*cda5da8dSAndroid Build Coastguard Worker 688*cda5da8dSAndroid Build Coastguard Worker # If user supplied any of the "display metadata" options, then 689*cda5da8dSAndroid Build Coastguard Worker # display that metadata in the order in which the user supplied the 690*cda5da8dSAndroid Build Coastguard Worker # metadata options. 691*cda5da8dSAndroid Build Coastguard Worker any_display_options = 0 692*cda5da8dSAndroid Build Coastguard Worker is_display_option = {} 693*cda5da8dSAndroid Build Coastguard Worker for option in self.display_options: 694*cda5da8dSAndroid Build Coastguard Worker is_display_option[option[0]] = 1 695*cda5da8dSAndroid Build Coastguard Worker 696*cda5da8dSAndroid Build Coastguard Worker for (opt, val) in option_order: 697*cda5da8dSAndroid Build Coastguard Worker if val and is_display_option.get(opt): 698*cda5da8dSAndroid Build Coastguard Worker opt = translate_longopt(opt) 699*cda5da8dSAndroid Build Coastguard Worker value = getattr(self.metadata, "get_"+opt)() 700*cda5da8dSAndroid Build Coastguard Worker if opt in ['keywords', 'platforms']: 701*cda5da8dSAndroid Build Coastguard Worker print(','.join(value)) 702*cda5da8dSAndroid Build Coastguard Worker elif opt in ('classifiers', 'provides', 'requires', 703*cda5da8dSAndroid Build Coastguard Worker 'obsoletes'): 704*cda5da8dSAndroid Build Coastguard Worker print('\n'.join(value)) 705*cda5da8dSAndroid Build Coastguard Worker else: 706*cda5da8dSAndroid Build Coastguard Worker print(value) 707*cda5da8dSAndroid Build Coastguard Worker any_display_options = 1 708*cda5da8dSAndroid Build Coastguard Worker 709*cda5da8dSAndroid Build Coastguard Worker return any_display_options 710*cda5da8dSAndroid Build Coastguard Worker 711*cda5da8dSAndroid Build Coastguard Worker def print_command_list(self, commands, header, max_length): 712*cda5da8dSAndroid Build Coastguard Worker """Print a subset of the list of all commands -- used by 713*cda5da8dSAndroid Build Coastguard Worker 'print_commands()'. 714*cda5da8dSAndroid Build Coastguard Worker """ 715*cda5da8dSAndroid Build Coastguard Worker print(header + ":") 716*cda5da8dSAndroid Build Coastguard Worker 717*cda5da8dSAndroid Build Coastguard Worker for cmd in commands: 718*cda5da8dSAndroid Build Coastguard Worker klass = self.cmdclass.get(cmd) 719*cda5da8dSAndroid Build Coastguard Worker if not klass: 720*cda5da8dSAndroid Build Coastguard Worker klass = self.get_command_class(cmd) 721*cda5da8dSAndroid Build Coastguard Worker try: 722*cda5da8dSAndroid Build Coastguard Worker description = klass.description 723*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 724*cda5da8dSAndroid Build Coastguard Worker description = "(no description available)" 725*cda5da8dSAndroid Build Coastguard Worker 726*cda5da8dSAndroid Build Coastguard Worker print(" %-*s %s" % (max_length, cmd, description)) 727*cda5da8dSAndroid Build Coastguard Worker 728*cda5da8dSAndroid Build Coastguard Worker def print_commands(self): 729*cda5da8dSAndroid Build Coastguard Worker """Print out a help message listing all available commands with a 730*cda5da8dSAndroid Build Coastguard Worker description of each. The list is divided into "standard commands" 731*cda5da8dSAndroid Build Coastguard Worker (listed in distutils.command.__all__) and "extra commands" 732*cda5da8dSAndroid Build Coastguard Worker (mentioned in self.cmdclass, but not a standard command). The 733*cda5da8dSAndroid Build Coastguard Worker descriptions come from the command class attribute 734*cda5da8dSAndroid Build Coastguard Worker 'description'. 735*cda5da8dSAndroid Build Coastguard Worker """ 736*cda5da8dSAndroid Build Coastguard Worker import distutils.command 737*cda5da8dSAndroid Build Coastguard Worker std_commands = distutils.command.__all__ 738*cda5da8dSAndroid Build Coastguard Worker is_std = {} 739*cda5da8dSAndroid Build Coastguard Worker for cmd in std_commands: 740*cda5da8dSAndroid Build Coastguard Worker is_std[cmd] = 1 741*cda5da8dSAndroid Build Coastguard Worker 742*cda5da8dSAndroid Build Coastguard Worker extra_commands = [] 743*cda5da8dSAndroid Build Coastguard Worker for cmd in self.cmdclass.keys(): 744*cda5da8dSAndroid Build Coastguard Worker if not is_std.get(cmd): 745*cda5da8dSAndroid Build Coastguard Worker extra_commands.append(cmd) 746*cda5da8dSAndroid Build Coastguard Worker 747*cda5da8dSAndroid Build Coastguard Worker max_length = 0 748*cda5da8dSAndroid Build Coastguard Worker for cmd in (std_commands + extra_commands): 749*cda5da8dSAndroid Build Coastguard Worker if len(cmd) > max_length: 750*cda5da8dSAndroid Build Coastguard Worker max_length = len(cmd) 751*cda5da8dSAndroid Build Coastguard Worker 752*cda5da8dSAndroid Build Coastguard Worker self.print_command_list(std_commands, 753*cda5da8dSAndroid Build Coastguard Worker "Standard commands", 754*cda5da8dSAndroid Build Coastguard Worker max_length) 755*cda5da8dSAndroid Build Coastguard Worker if extra_commands: 756*cda5da8dSAndroid Build Coastguard Worker print() 757*cda5da8dSAndroid Build Coastguard Worker self.print_command_list(extra_commands, 758*cda5da8dSAndroid Build Coastguard Worker "Extra commands", 759*cda5da8dSAndroid Build Coastguard Worker max_length) 760*cda5da8dSAndroid Build Coastguard Worker 761*cda5da8dSAndroid Build Coastguard Worker def get_command_list(self): 762*cda5da8dSAndroid Build Coastguard Worker """Get a list of (command, description) tuples. 763*cda5da8dSAndroid Build Coastguard Worker The list is divided into "standard commands" (listed in 764*cda5da8dSAndroid Build Coastguard Worker distutils.command.__all__) and "extra commands" (mentioned in 765*cda5da8dSAndroid Build Coastguard Worker self.cmdclass, but not a standard command). The descriptions come 766*cda5da8dSAndroid Build Coastguard Worker from the command class attribute 'description'. 767*cda5da8dSAndroid Build Coastguard Worker """ 768*cda5da8dSAndroid Build Coastguard Worker # Currently this is only used on Mac OS, for the Mac-only GUI 769*cda5da8dSAndroid Build Coastguard Worker # Distutils interface (by Jack Jansen) 770*cda5da8dSAndroid Build Coastguard Worker import distutils.command 771*cda5da8dSAndroid Build Coastguard Worker std_commands = distutils.command.__all__ 772*cda5da8dSAndroid Build Coastguard Worker is_std = {} 773*cda5da8dSAndroid Build Coastguard Worker for cmd in std_commands: 774*cda5da8dSAndroid Build Coastguard Worker is_std[cmd] = 1 775*cda5da8dSAndroid Build Coastguard Worker 776*cda5da8dSAndroid Build Coastguard Worker extra_commands = [] 777*cda5da8dSAndroid Build Coastguard Worker for cmd in self.cmdclass.keys(): 778*cda5da8dSAndroid Build Coastguard Worker if not is_std.get(cmd): 779*cda5da8dSAndroid Build Coastguard Worker extra_commands.append(cmd) 780*cda5da8dSAndroid Build Coastguard Worker 781*cda5da8dSAndroid Build Coastguard Worker rv = [] 782*cda5da8dSAndroid Build Coastguard Worker for cmd in (std_commands + extra_commands): 783*cda5da8dSAndroid Build Coastguard Worker klass = self.cmdclass.get(cmd) 784*cda5da8dSAndroid Build Coastguard Worker if not klass: 785*cda5da8dSAndroid Build Coastguard Worker klass = self.get_command_class(cmd) 786*cda5da8dSAndroid Build Coastguard Worker try: 787*cda5da8dSAndroid Build Coastguard Worker description = klass.description 788*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 789*cda5da8dSAndroid Build Coastguard Worker description = "(no description available)" 790*cda5da8dSAndroid Build Coastguard Worker rv.append((cmd, description)) 791*cda5da8dSAndroid Build Coastguard Worker return rv 792*cda5da8dSAndroid Build Coastguard Worker 793*cda5da8dSAndroid Build Coastguard Worker # -- Command class/object methods ---------------------------------- 794*cda5da8dSAndroid Build Coastguard Worker 795*cda5da8dSAndroid Build Coastguard Worker def get_command_packages(self): 796*cda5da8dSAndroid Build Coastguard Worker """Return a list of packages from which commands are loaded.""" 797*cda5da8dSAndroid Build Coastguard Worker pkgs = self.command_packages 798*cda5da8dSAndroid Build Coastguard Worker if not isinstance(pkgs, list): 799*cda5da8dSAndroid Build Coastguard Worker if pkgs is None: 800*cda5da8dSAndroid Build Coastguard Worker pkgs = '' 801*cda5da8dSAndroid Build Coastguard Worker pkgs = [pkg.strip() for pkg in pkgs.split(',') if pkg != ''] 802*cda5da8dSAndroid Build Coastguard Worker if "distutils.command" not in pkgs: 803*cda5da8dSAndroid Build Coastguard Worker pkgs.insert(0, "distutils.command") 804*cda5da8dSAndroid Build Coastguard Worker self.command_packages = pkgs 805*cda5da8dSAndroid Build Coastguard Worker return pkgs 806*cda5da8dSAndroid Build Coastguard Worker 807*cda5da8dSAndroid Build Coastguard Worker def get_command_class(self, command): 808*cda5da8dSAndroid Build Coastguard Worker """Return the class that implements the Distutils command named by 809*cda5da8dSAndroid Build Coastguard Worker 'command'. First we check the 'cmdclass' dictionary; if the 810*cda5da8dSAndroid Build Coastguard Worker command is mentioned there, we fetch the class object from the 811*cda5da8dSAndroid Build Coastguard Worker dictionary and return it. Otherwise we load the command module 812*cda5da8dSAndroid Build Coastguard Worker ("distutils.command." + command) and fetch the command class from 813*cda5da8dSAndroid Build Coastguard Worker the module. The loaded class is also stored in 'cmdclass' 814*cda5da8dSAndroid Build Coastguard Worker to speed future calls to 'get_command_class()'. 815*cda5da8dSAndroid Build Coastguard Worker 816*cda5da8dSAndroid Build Coastguard Worker Raises DistutilsModuleError if the expected module could not be 817*cda5da8dSAndroid Build Coastguard Worker found, or if that module does not define the expected class. 818*cda5da8dSAndroid Build Coastguard Worker """ 819*cda5da8dSAndroid Build Coastguard Worker klass = self.cmdclass.get(command) 820*cda5da8dSAndroid Build Coastguard Worker if klass: 821*cda5da8dSAndroid Build Coastguard Worker return klass 822*cda5da8dSAndroid Build Coastguard Worker 823*cda5da8dSAndroid Build Coastguard Worker for pkgname in self.get_command_packages(): 824*cda5da8dSAndroid Build Coastguard Worker module_name = "%s.%s" % (pkgname, command) 825*cda5da8dSAndroid Build Coastguard Worker klass_name = command 826*cda5da8dSAndroid Build Coastguard Worker 827*cda5da8dSAndroid Build Coastguard Worker try: 828*cda5da8dSAndroid Build Coastguard Worker __import__(module_name) 829*cda5da8dSAndroid Build Coastguard Worker module = sys.modules[module_name] 830*cda5da8dSAndroid Build Coastguard Worker except ImportError: 831*cda5da8dSAndroid Build Coastguard Worker continue 832*cda5da8dSAndroid Build Coastguard Worker 833*cda5da8dSAndroid Build Coastguard Worker try: 834*cda5da8dSAndroid Build Coastguard Worker klass = getattr(module, klass_name) 835*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 836*cda5da8dSAndroid Build Coastguard Worker raise DistutilsModuleError( 837*cda5da8dSAndroid Build Coastguard Worker "invalid command '%s' (no class '%s' in module '%s')" 838*cda5da8dSAndroid Build Coastguard Worker % (command, klass_name, module_name)) 839*cda5da8dSAndroid Build Coastguard Worker 840*cda5da8dSAndroid Build Coastguard Worker self.cmdclass[command] = klass 841*cda5da8dSAndroid Build Coastguard Worker return klass 842*cda5da8dSAndroid Build Coastguard Worker 843*cda5da8dSAndroid Build Coastguard Worker raise DistutilsModuleError("invalid command '%s'" % command) 844*cda5da8dSAndroid Build Coastguard Worker 845*cda5da8dSAndroid Build Coastguard Worker def get_command_obj(self, command, create=1): 846*cda5da8dSAndroid Build Coastguard Worker """Return the command object for 'command'. Normally this object 847*cda5da8dSAndroid Build Coastguard Worker is cached on a previous call to 'get_command_obj()'; if no command 848*cda5da8dSAndroid Build Coastguard Worker object for 'command' is in the cache, then we either create and 849*cda5da8dSAndroid Build Coastguard Worker return it (if 'create' is true) or return None. 850*cda5da8dSAndroid Build Coastguard Worker """ 851*cda5da8dSAndroid Build Coastguard Worker cmd_obj = self.command_obj.get(command) 852*cda5da8dSAndroid Build Coastguard Worker if not cmd_obj and create: 853*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 854*cda5da8dSAndroid Build Coastguard Worker self.announce("Distribution.get_command_obj(): " 855*cda5da8dSAndroid Build Coastguard Worker "creating '%s' command object" % command) 856*cda5da8dSAndroid Build Coastguard Worker 857*cda5da8dSAndroid Build Coastguard Worker klass = self.get_command_class(command) 858*cda5da8dSAndroid Build Coastguard Worker cmd_obj = self.command_obj[command] = klass(self) 859*cda5da8dSAndroid Build Coastguard Worker self.have_run[command] = 0 860*cda5da8dSAndroid Build Coastguard Worker 861*cda5da8dSAndroid Build Coastguard Worker # Set any options that were supplied in config files 862*cda5da8dSAndroid Build Coastguard Worker # or on the command line. (NB. support for error 863*cda5da8dSAndroid Build Coastguard Worker # reporting is lame here: any errors aren't reported 864*cda5da8dSAndroid Build Coastguard Worker # until 'finalize_options()' is called, which means 865*cda5da8dSAndroid Build Coastguard Worker # we won't report the source of the error.) 866*cda5da8dSAndroid Build Coastguard Worker options = self.command_options.get(command) 867*cda5da8dSAndroid Build Coastguard Worker if options: 868*cda5da8dSAndroid Build Coastguard Worker self._set_command_options(cmd_obj, options) 869*cda5da8dSAndroid Build Coastguard Worker 870*cda5da8dSAndroid Build Coastguard Worker return cmd_obj 871*cda5da8dSAndroid Build Coastguard Worker 872*cda5da8dSAndroid Build Coastguard Worker def _set_command_options(self, command_obj, option_dict=None): 873*cda5da8dSAndroid Build Coastguard Worker """Set the options for 'command_obj' from 'option_dict'. Basically 874*cda5da8dSAndroid Build Coastguard Worker this means copying elements of a dictionary ('option_dict') to 875*cda5da8dSAndroid Build Coastguard Worker attributes of an instance ('command'). 876*cda5da8dSAndroid Build Coastguard Worker 877*cda5da8dSAndroid Build Coastguard Worker 'command_obj' must be a Command instance. If 'option_dict' is not 878*cda5da8dSAndroid Build Coastguard Worker supplied, uses the standard option dictionary for this command 879*cda5da8dSAndroid Build Coastguard Worker (from 'self.command_options'). 880*cda5da8dSAndroid Build Coastguard Worker """ 881*cda5da8dSAndroid Build Coastguard Worker command_name = command_obj.get_command_name() 882*cda5da8dSAndroid Build Coastguard Worker if option_dict is None: 883*cda5da8dSAndroid Build Coastguard Worker option_dict = self.get_option_dict(command_name) 884*cda5da8dSAndroid Build Coastguard Worker 885*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 886*cda5da8dSAndroid Build Coastguard Worker self.announce(" setting options for '%s' command:" % command_name) 887*cda5da8dSAndroid Build Coastguard Worker for (option, (source, value)) in option_dict.items(): 888*cda5da8dSAndroid Build Coastguard Worker if DEBUG: 889*cda5da8dSAndroid Build Coastguard Worker self.announce(" %s = %s (from %s)" % (option, value, 890*cda5da8dSAndroid Build Coastguard Worker source)) 891*cda5da8dSAndroid Build Coastguard Worker try: 892*cda5da8dSAndroid Build Coastguard Worker bool_opts = [translate_longopt(o) 893*cda5da8dSAndroid Build Coastguard Worker for o in command_obj.boolean_options] 894*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 895*cda5da8dSAndroid Build Coastguard Worker bool_opts = [] 896*cda5da8dSAndroid Build Coastguard Worker try: 897*cda5da8dSAndroid Build Coastguard Worker neg_opt = command_obj.negative_opt 898*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 899*cda5da8dSAndroid Build Coastguard Worker neg_opt = {} 900*cda5da8dSAndroid Build Coastguard Worker 901*cda5da8dSAndroid Build Coastguard Worker try: 902*cda5da8dSAndroid Build Coastguard Worker is_string = isinstance(value, str) 903*cda5da8dSAndroid Build Coastguard Worker if option in neg_opt and is_string: 904*cda5da8dSAndroid Build Coastguard Worker setattr(command_obj, neg_opt[option], not strtobool(value)) 905*cda5da8dSAndroid Build Coastguard Worker elif option in bool_opts and is_string: 906*cda5da8dSAndroid Build Coastguard Worker setattr(command_obj, option, strtobool(value)) 907*cda5da8dSAndroid Build Coastguard Worker elif hasattr(command_obj, option): 908*cda5da8dSAndroid Build Coastguard Worker setattr(command_obj, option, value) 909*cda5da8dSAndroid Build Coastguard Worker else: 910*cda5da8dSAndroid Build Coastguard Worker raise DistutilsOptionError( 911*cda5da8dSAndroid Build Coastguard Worker "error in %s: command '%s' has no such option '%s'" 912*cda5da8dSAndroid Build Coastguard Worker % (source, command_name, option)) 913*cda5da8dSAndroid Build Coastguard Worker except ValueError as msg: 914*cda5da8dSAndroid Build Coastguard Worker raise DistutilsOptionError(msg) 915*cda5da8dSAndroid Build Coastguard Worker 916*cda5da8dSAndroid Build Coastguard Worker def reinitialize_command(self, command, reinit_subcommands=0): 917*cda5da8dSAndroid Build Coastguard Worker """Reinitializes a command to the state it was in when first 918*cda5da8dSAndroid Build Coastguard Worker returned by 'get_command_obj()': ie., initialized but not yet 919*cda5da8dSAndroid Build Coastguard Worker finalized. This provides the opportunity to sneak option 920*cda5da8dSAndroid Build Coastguard Worker values in programmatically, overriding or supplementing 921*cda5da8dSAndroid Build Coastguard Worker user-supplied values from the config files and command line. 922*cda5da8dSAndroid Build Coastguard Worker You'll have to re-finalize the command object (by calling 923*cda5da8dSAndroid Build Coastguard Worker 'finalize_options()' or 'ensure_finalized()') before using it for 924*cda5da8dSAndroid Build Coastguard Worker real. 925*cda5da8dSAndroid Build Coastguard Worker 926*cda5da8dSAndroid Build Coastguard Worker 'command' should be a command name (string) or command object. If 927*cda5da8dSAndroid Build Coastguard Worker 'reinit_subcommands' is true, also reinitializes the command's 928*cda5da8dSAndroid Build Coastguard Worker sub-commands, as declared by the 'sub_commands' class attribute (if 929*cda5da8dSAndroid Build Coastguard Worker it has one). See the "install" command for an example. Only 930*cda5da8dSAndroid Build Coastguard Worker reinitializes the sub-commands that actually matter, ie. those 931*cda5da8dSAndroid Build Coastguard Worker whose test predicates return true. 932*cda5da8dSAndroid Build Coastguard Worker 933*cda5da8dSAndroid Build Coastguard Worker Returns the reinitialized command object. 934*cda5da8dSAndroid Build Coastguard Worker """ 935*cda5da8dSAndroid Build Coastguard Worker from distutils.cmd import Command 936*cda5da8dSAndroid Build Coastguard Worker if not isinstance(command, Command): 937*cda5da8dSAndroid Build Coastguard Worker command_name = command 938*cda5da8dSAndroid Build Coastguard Worker command = self.get_command_obj(command_name) 939*cda5da8dSAndroid Build Coastguard Worker else: 940*cda5da8dSAndroid Build Coastguard Worker command_name = command.get_command_name() 941*cda5da8dSAndroid Build Coastguard Worker 942*cda5da8dSAndroid Build Coastguard Worker if not command.finalized: 943*cda5da8dSAndroid Build Coastguard Worker return command 944*cda5da8dSAndroid Build Coastguard Worker command.initialize_options() 945*cda5da8dSAndroid Build Coastguard Worker command.finalized = 0 946*cda5da8dSAndroid Build Coastguard Worker self.have_run[command_name] = 0 947*cda5da8dSAndroid Build Coastguard Worker self._set_command_options(command) 948*cda5da8dSAndroid Build Coastguard Worker 949*cda5da8dSAndroid Build Coastguard Worker if reinit_subcommands: 950*cda5da8dSAndroid Build Coastguard Worker for sub in command.get_sub_commands(): 951*cda5da8dSAndroid Build Coastguard Worker self.reinitialize_command(sub, reinit_subcommands) 952*cda5da8dSAndroid Build Coastguard Worker 953*cda5da8dSAndroid Build Coastguard Worker return command 954*cda5da8dSAndroid Build Coastguard Worker 955*cda5da8dSAndroid Build Coastguard Worker # -- Methods that operate on the Distribution ---------------------- 956*cda5da8dSAndroid Build Coastguard Worker 957*cda5da8dSAndroid Build Coastguard Worker def announce(self, msg, level=log.INFO): 958*cda5da8dSAndroid Build Coastguard Worker log.log(level, msg) 959*cda5da8dSAndroid Build Coastguard Worker 960*cda5da8dSAndroid Build Coastguard Worker def run_commands(self): 961*cda5da8dSAndroid Build Coastguard Worker """Run each command that was seen on the setup script command line. 962*cda5da8dSAndroid Build Coastguard Worker Uses the list of commands found and cache of command objects 963*cda5da8dSAndroid Build Coastguard Worker created by 'get_command_obj()'. 964*cda5da8dSAndroid Build Coastguard Worker """ 965*cda5da8dSAndroid Build Coastguard Worker for cmd in self.commands: 966*cda5da8dSAndroid Build Coastguard Worker self.run_command(cmd) 967*cda5da8dSAndroid Build Coastguard Worker 968*cda5da8dSAndroid Build Coastguard Worker # -- Methods that operate on its Commands -------------------------- 969*cda5da8dSAndroid Build Coastguard Worker 970*cda5da8dSAndroid Build Coastguard Worker def run_command(self, command): 971*cda5da8dSAndroid Build Coastguard Worker """Do whatever it takes to run a command (including nothing at all, 972*cda5da8dSAndroid Build Coastguard Worker if the command has already been run). Specifically: if we have 973*cda5da8dSAndroid Build Coastguard Worker already created and run the command named by 'command', return 974*cda5da8dSAndroid Build Coastguard Worker silently without doing anything. If the command named by 'command' 975*cda5da8dSAndroid Build Coastguard Worker doesn't even have a command object yet, create one. Then invoke 976*cda5da8dSAndroid Build Coastguard Worker 'run()' on that command object (or an existing one). 977*cda5da8dSAndroid Build Coastguard Worker """ 978*cda5da8dSAndroid Build Coastguard Worker # Already been here, done that? then return silently. 979*cda5da8dSAndroid Build Coastguard Worker if self.have_run.get(command): 980*cda5da8dSAndroid Build Coastguard Worker return 981*cda5da8dSAndroid Build Coastguard Worker 982*cda5da8dSAndroid Build Coastguard Worker log.info("running %s", command) 983*cda5da8dSAndroid Build Coastguard Worker cmd_obj = self.get_command_obj(command) 984*cda5da8dSAndroid Build Coastguard Worker cmd_obj.ensure_finalized() 985*cda5da8dSAndroid Build Coastguard Worker cmd_obj.run() 986*cda5da8dSAndroid Build Coastguard Worker self.have_run[command] = 1 987*cda5da8dSAndroid Build Coastguard Worker 988*cda5da8dSAndroid Build Coastguard Worker # -- Distribution query methods ------------------------------------ 989*cda5da8dSAndroid Build Coastguard Worker 990*cda5da8dSAndroid Build Coastguard Worker def has_pure_modules(self): 991*cda5da8dSAndroid Build Coastguard Worker return len(self.packages or self.py_modules or []) > 0 992*cda5da8dSAndroid Build Coastguard Worker 993*cda5da8dSAndroid Build Coastguard Worker def has_ext_modules(self): 994*cda5da8dSAndroid Build Coastguard Worker return self.ext_modules and len(self.ext_modules) > 0 995*cda5da8dSAndroid Build Coastguard Worker 996*cda5da8dSAndroid Build Coastguard Worker def has_c_libraries(self): 997*cda5da8dSAndroid Build Coastguard Worker return self.libraries and len(self.libraries) > 0 998*cda5da8dSAndroid Build Coastguard Worker 999*cda5da8dSAndroid Build Coastguard Worker def has_modules(self): 1000*cda5da8dSAndroid Build Coastguard Worker return self.has_pure_modules() or self.has_ext_modules() 1001*cda5da8dSAndroid Build Coastguard Worker 1002*cda5da8dSAndroid Build Coastguard Worker def has_headers(self): 1003*cda5da8dSAndroid Build Coastguard Worker return self.headers and len(self.headers) > 0 1004*cda5da8dSAndroid Build Coastguard Worker 1005*cda5da8dSAndroid Build Coastguard Worker def has_scripts(self): 1006*cda5da8dSAndroid Build Coastguard Worker return self.scripts and len(self.scripts) > 0 1007*cda5da8dSAndroid Build Coastguard Worker 1008*cda5da8dSAndroid Build Coastguard Worker def has_data_files(self): 1009*cda5da8dSAndroid Build Coastguard Worker return self.data_files and len(self.data_files) > 0 1010*cda5da8dSAndroid Build Coastguard Worker 1011*cda5da8dSAndroid Build Coastguard Worker def is_pure(self): 1012*cda5da8dSAndroid Build Coastguard Worker return (self.has_pure_modules() and 1013*cda5da8dSAndroid Build Coastguard Worker not self.has_ext_modules() and 1014*cda5da8dSAndroid Build Coastguard Worker not self.has_c_libraries()) 1015*cda5da8dSAndroid Build Coastguard Worker 1016*cda5da8dSAndroid Build Coastguard Worker # -- Metadata query methods ---------------------------------------- 1017*cda5da8dSAndroid Build Coastguard Worker 1018*cda5da8dSAndroid Build Coastguard Worker # If you're looking for 'get_name()', 'get_version()', and so forth, 1019*cda5da8dSAndroid Build Coastguard Worker # they are defined in a sneaky way: the constructor binds self.get_XXX 1020*cda5da8dSAndroid Build Coastguard Worker # to self.metadata.get_XXX. The actual code is in the 1021*cda5da8dSAndroid Build Coastguard Worker # DistributionMetadata class, below. 1022*cda5da8dSAndroid Build Coastguard Worker 1023*cda5da8dSAndroid Build Coastguard Workerclass DistributionMetadata: 1024*cda5da8dSAndroid Build Coastguard Worker """Dummy class to hold the distribution meta-data: name, version, 1025*cda5da8dSAndroid Build Coastguard Worker author, and so forth. 1026*cda5da8dSAndroid Build Coastguard Worker """ 1027*cda5da8dSAndroid Build Coastguard Worker 1028*cda5da8dSAndroid Build Coastguard Worker _METHOD_BASENAMES = ("name", "version", "author", "author_email", 1029*cda5da8dSAndroid Build Coastguard Worker "maintainer", "maintainer_email", "url", 1030*cda5da8dSAndroid Build Coastguard Worker "license", "description", "long_description", 1031*cda5da8dSAndroid Build Coastguard Worker "keywords", "platforms", "fullname", "contact", 1032*cda5da8dSAndroid Build Coastguard Worker "contact_email", "classifiers", "download_url", 1033*cda5da8dSAndroid Build Coastguard Worker # PEP 314 1034*cda5da8dSAndroid Build Coastguard Worker "provides", "requires", "obsoletes", 1035*cda5da8dSAndroid Build Coastguard Worker ) 1036*cda5da8dSAndroid Build Coastguard Worker 1037*cda5da8dSAndroid Build Coastguard Worker def __init__(self, path=None): 1038*cda5da8dSAndroid Build Coastguard Worker if path is not None: 1039*cda5da8dSAndroid Build Coastguard Worker self.read_pkg_file(open(path)) 1040*cda5da8dSAndroid Build Coastguard Worker else: 1041*cda5da8dSAndroid Build Coastguard Worker self.name = None 1042*cda5da8dSAndroid Build Coastguard Worker self.version = None 1043*cda5da8dSAndroid Build Coastguard Worker self.author = None 1044*cda5da8dSAndroid Build Coastguard Worker self.author_email = None 1045*cda5da8dSAndroid Build Coastguard Worker self.maintainer = None 1046*cda5da8dSAndroid Build Coastguard Worker self.maintainer_email = None 1047*cda5da8dSAndroid Build Coastguard Worker self.url = None 1048*cda5da8dSAndroid Build Coastguard Worker self.license = None 1049*cda5da8dSAndroid Build Coastguard Worker self.description = None 1050*cda5da8dSAndroid Build Coastguard Worker self.long_description = None 1051*cda5da8dSAndroid Build Coastguard Worker self.keywords = None 1052*cda5da8dSAndroid Build Coastguard Worker self.platforms = None 1053*cda5da8dSAndroid Build Coastguard Worker self.classifiers = None 1054*cda5da8dSAndroid Build Coastguard Worker self.download_url = None 1055*cda5da8dSAndroid Build Coastguard Worker # PEP 314 1056*cda5da8dSAndroid Build Coastguard Worker self.provides = None 1057*cda5da8dSAndroid Build Coastguard Worker self.requires = None 1058*cda5da8dSAndroid Build Coastguard Worker self.obsoletes = None 1059*cda5da8dSAndroid Build Coastguard Worker 1060*cda5da8dSAndroid Build Coastguard Worker def read_pkg_file(self, file): 1061*cda5da8dSAndroid Build Coastguard Worker """Reads the metadata values from a file object.""" 1062*cda5da8dSAndroid Build Coastguard Worker msg = message_from_file(file) 1063*cda5da8dSAndroid Build Coastguard Worker 1064*cda5da8dSAndroid Build Coastguard Worker def _read_field(name): 1065*cda5da8dSAndroid Build Coastguard Worker value = msg[name] 1066*cda5da8dSAndroid Build Coastguard Worker if value == 'UNKNOWN': 1067*cda5da8dSAndroid Build Coastguard Worker return None 1068*cda5da8dSAndroid Build Coastguard Worker return value 1069*cda5da8dSAndroid Build Coastguard Worker 1070*cda5da8dSAndroid Build Coastguard Worker def _read_list(name): 1071*cda5da8dSAndroid Build Coastguard Worker values = msg.get_all(name, None) 1072*cda5da8dSAndroid Build Coastguard Worker if values == []: 1073*cda5da8dSAndroid Build Coastguard Worker return None 1074*cda5da8dSAndroid Build Coastguard Worker return values 1075*cda5da8dSAndroid Build Coastguard Worker 1076*cda5da8dSAndroid Build Coastguard Worker metadata_version = msg['metadata-version'] 1077*cda5da8dSAndroid Build Coastguard Worker self.name = _read_field('name') 1078*cda5da8dSAndroid Build Coastguard Worker self.version = _read_field('version') 1079*cda5da8dSAndroid Build Coastguard Worker self.description = _read_field('summary') 1080*cda5da8dSAndroid Build Coastguard Worker # we are filling author only. 1081*cda5da8dSAndroid Build Coastguard Worker self.author = _read_field('author') 1082*cda5da8dSAndroid Build Coastguard Worker self.maintainer = None 1083*cda5da8dSAndroid Build Coastguard Worker self.author_email = _read_field('author-email') 1084*cda5da8dSAndroid Build Coastguard Worker self.maintainer_email = None 1085*cda5da8dSAndroid Build Coastguard Worker self.url = _read_field('home-page') 1086*cda5da8dSAndroid Build Coastguard Worker self.license = _read_field('license') 1087*cda5da8dSAndroid Build Coastguard Worker 1088*cda5da8dSAndroid Build Coastguard Worker if 'download-url' in msg: 1089*cda5da8dSAndroid Build Coastguard Worker self.download_url = _read_field('download-url') 1090*cda5da8dSAndroid Build Coastguard Worker else: 1091*cda5da8dSAndroid Build Coastguard Worker self.download_url = None 1092*cda5da8dSAndroid Build Coastguard Worker 1093*cda5da8dSAndroid Build Coastguard Worker self.long_description = _read_field('description') 1094*cda5da8dSAndroid Build Coastguard Worker self.description = _read_field('summary') 1095*cda5da8dSAndroid Build Coastguard Worker 1096*cda5da8dSAndroid Build Coastguard Worker if 'keywords' in msg: 1097*cda5da8dSAndroid Build Coastguard Worker self.keywords = _read_field('keywords').split(',') 1098*cda5da8dSAndroid Build Coastguard Worker 1099*cda5da8dSAndroid Build Coastguard Worker self.platforms = _read_list('platform') 1100*cda5da8dSAndroid Build Coastguard Worker self.classifiers = _read_list('classifier') 1101*cda5da8dSAndroid Build Coastguard Worker 1102*cda5da8dSAndroid Build Coastguard Worker # PEP 314 - these fields only exist in 1.1 1103*cda5da8dSAndroid Build Coastguard Worker if metadata_version == '1.1': 1104*cda5da8dSAndroid Build Coastguard Worker self.requires = _read_list('requires') 1105*cda5da8dSAndroid Build Coastguard Worker self.provides = _read_list('provides') 1106*cda5da8dSAndroid Build Coastguard Worker self.obsoletes = _read_list('obsoletes') 1107*cda5da8dSAndroid Build Coastguard Worker else: 1108*cda5da8dSAndroid Build Coastguard Worker self.requires = None 1109*cda5da8dSAndroid Build Coastguard Worker self.provides = None 1110*cda5da8dSAndroid Build Coastguard Worker self.obsoletes = None 1111*cda5da8dSAndroid Build Coastguard Worker 1112*cda5da8dSAndroid Build Coastguard Worker def write_pkg_info(self, base_dir): 1113*cda5da8dSAndroid Build Coastguard Worker """Write the PKG-INFO file into the release tree. 1114*cda5da8dSAndroid Build Coastguard Worker """ 1115*cda5da8dSAndroid Build Coastguard Worker with open(os.path.join(base_dir, 'PKG-INFO'), 'w', 1116*cda5da8dSAndroid Build Coastguard Worker encoding='UTF-8') as pkg_info: 1117*cda5da8dSAndroid Build Coastguard Worker self.write_pkg_file(pkg_info) 1118*cda5da8dSAndroid Build Coastguard Worker 1119*cda5da8dSAndroid Build Coastguard Worker def write_pkg_file(self, file): 1120*cda5da8dSAndroid Build Coastguard Worker """Write the PKG-INFO format data to a file object. 1121*cda5da8dSAndroid Build Coastguard Worker """ 1122*cda5da8dSAndroid Build Coastguard Worker version = '1.0' 1123*cda5da8dSAndroid Build Coastguard Worker if (self.provides or self.requires or self.obsoletes or 1124*cda5da8dSAndroid Build Coastguard Worker self.classifiers or self.download_url): 1125*cda5da8dSAndroid Build Coastguard Worker version = '1.1' 1126*cda5da8dSAndroid Build Coastguard Worker 1127*cda5da8dSAndroid Build Coastguard Worker file.write('Metadata-Version: %s\n' % version) 1128*cda5da8dSAndroid Build Coastguard Worker file.write('Name: %s\n' % self.get_name()) 1129*cda5da8dSAndroid Build Coastguard Worker file.write('Version: %s\n' % self.get_version()) 1130*cda5da8dSAndroid Build Coastguard Worker file.write('Summary: %s\n' % self.get_description()) 1131*cda5da8dSAndroid Build Coastguard Worker file.write('Home-page: %s\n' % self.get_url()) 1132*cda5da8dSAndroid Build Coastguard Worker file.write('Author: %s\n' % self.get_contact()) 1133*cda5da8dSAndroid Build Coastguard Worker file.write('Author-email: %s\n' % self.get_contact_email()) 1134*cda5da8dSAndroid Build Coastguard Worker file.write('License: %s\n' % self.get_license()) 1135*cda5da8dSAndroid Build Coastguard Worker if self.download_url: 1136*cda5da8dSAndroid Build Coastguard Worker file.write('Download-URL: %s\n' % self.download_url) 1137*cda5da8dSAndroid Build Coastguard Worker 1138*cda5da8dSAndroid Build Coastguard Worker long_desc = rfc822_escape(self.get_long_description()) 1139*cda5da8dSAndroid Build Coastguard Worker file.write('Description: %s\n' % long_desc) 1140*cda5da8dSAndroid Build Coastguard Worker 1141*cda5da8dSAndroid Build Coastguard Worker keywords = ','.join(self.get_keywords()) 1142*cda5da8dSAndroid Build Coastguard Worker if keywords: 1143*cda5da8dSAndroid Build Coastguard Worker file.write('Keywords: %s\n' % keywords) 1144*cda5da8dSAndroid Build Coastguard Worker 1145*cda5da8dSAndroid Build Coastguard Worker self._write_list(file, 'Platform', self.get_platforms()) 1146*cda5da8dSAndroid Build Coastguard Worker self._write_list(file, 'Classifier', self.get_classifiers()) 1147*cda5da8dSAndroid Build Coastguard Worker 1148*cda5da8dSAndroid Build Coastguard Worker # PEP 314 1149*cda5da8dSAndroid Build Coastguard Worker self._write_list(file, 'Requires', self.get_requires()) 1150*cda5da8dSAndroid Build Coastguard Worker self._write_list(file, 'Provides', self.get_provides()) 1151*cda5da8dSAndroid Build Coastguard Worker self._write_list(file, 'Obsoletes', self.get_obsoletes()) 1152*cda5da8dSAndroid Build Coastguard Worker 1153*cda5da8dSAndroid Build Coastguard Worker def _write_list(self, file, name, values): 1154*cda5da8dSAndroid Build Coastguard Worker for value in values: 1155*cda5da8dSAndroid Build Coastguard Worker file.write('%s: %s\n' % (name, value)) 1156*cda5da8dSAndroid Build Coastguard Worker 1157*cda5da8dSAndroid Build Coastguard Worker # -- Metadata query methods ---------------------------------------- 1158*cda5da8dSAndroid Build Coastguard Worker 1159*cda5da8dSAndroid Build Coastguard Worker def get_name(self): 1160*cda5da8dSAndroid Build Coastguard Worker return self.name or "UNKNOWN" 1161*cda5da8dSAndroid Build Coastguard Worker 1162*cda5da8dSAndroid Build Coastguard Worker def get_version(self): 1163*cda5da8dSAndroid Build Coastguard Worker return self.version or "0.0.0" 1164*cda5da8dSAndroid Build Coastguard Worker 1165*cda5da8dSAndroid Build Coastguard Worker def get_fullname(self): 1166*cda5da8dSAndroid Build Coastguard Worker return "%s-%s" % (self.get_name(), self.get_version()) 1167*cda5da8dSAndroid Build Coastguard Worker 1168*cda5da8dSAndroid Build Coastguard Worker def get_author(self): 1169*cda5da8dSAndroid Build Coastguard Worker return self.author or "UNKNOWN" 1170*cda5da8dSAndroid Build Coastguard Worker 1171*cda5da8dSAndroid Build Coastguard Worker def get_author_email(self): 1172*cda5da8dSAndroid Build Coastguard Worker return self.author_email or "UNKNOWN" 1173*cda5da8dSAndroid Build Coastguard Worker 1174*cda5da8dSAndroid Build Coastguard Worker def get_maintainer(self): 1175*cda5da8dSAndroid Build Coastguard Worker return self.maintainer or "UNKNOWN" 1176*cda5da8dSAndroid Build Coastguard Worker 1177*cda5da8dSAndroid Build Coastguard Worker def get_maintainer_email(self): 1178*cda5da8dSAndroid Build Coastguard Worker return self.maintainer_email or "UNKNOWN" 1179*cda5da8dSAndroid Build Coastguard Worker 1180*cda5da8dSAndroid Build Coastguard Worker def get_contact(self): 1181*cda5da8dSAndroid Build Coastguard Worker return self.maintainer or self.author or "UNKNOWN" 1182*cda5da8dSAndroid Build Coastguard Worker 1183*cda5da8dSAndroid Build Coastguard Worker def get_contact_email(self): 1184*cda5da8dSAndroid Build Coastguard Worker return self.maintainer_email or self.author_email or "UNKNOWN" 1185*cda5da8dSAndroid Build Coastguard Worker 1186*cda5da8dSAndroid Build Coastguard Worker def get_url(self): 1187*cda5da8dSAndroid Build Coastguard Worker return self.url or "UNKNOWN" 1188*cda5da8dSAndroid Build Coastguard Worker 1189*cda5da8dSAndroid Build Coastguard Worker def get_license(self): 1190*cda5da8dSAndroid Build Coastguard Worker return self.license or "UNKNOWN" 1191*cda5da8dSAndroid Build Coastguard Worker get_licence = get_license 1192*cda5da8dSAndroid Build Coastguard Worker 1193*cda5da8dSAndroid Build Coastguard Worker def get_description(self): 1194*cda5da8dSAndroid Build Coastguard Worker return self.description or "UNKNOWN" 1195*cda5da8dSAndroid Build Coastguard Worker 1196*cda5da8dSAndroid Build Coastguard Worker def get_long_description(self): 1197*cda5da8dSAndroid Build Coastguard Worker return self.long_description or "UNKNOWN" 1198*cda5da8dSAndroid Build Coastguard Worker 1199*cda5da8dSAndroid Build Coastguard Worker def get_keywords(self): 1200*cda5da8dSAndroid Build Coastguard Worker return self.keywords or [] 1201*cda5da8dSAndroid Build Coastguard Worker 1202*cda5da8dSAndroid Build Coastguard Worker def set_keywords(self, value): 1203*cda5da8dSAndroid Build Coastguard Worker self.keywords = _ensure_list(value, 'keywords') 1204*cda5da8dSAndroid Build Coastguard Worker 1205*cda5da8dSAndroid Build Coastguard Worker def get_platforms(self): 1206*cda5da8dSAndroid Build Coastguard Worker return self.platforms or ["UNKNOWN"] 1207*cda5da8dSAndroid Build Coastguard Worker 1208*cda5da8dSAndroid Build Coastguard Worker def set_platforms(self, value): 1209*cda5da8dSAndroid Build Coastguard Worker self.platforms = _ensure_list(value, 'platforms') 1210*cda5da8dSAndroid Build Coastguard Worker 1211*cda5da8dSAndroid Build Coastguard Worker def get_classifiers(self): 1212*cda5da8dSAndroid Build Coastguard Worker return self.classifiers or [] 1213*cda5da8dSAndroid Build Coastguard Worker 1214*cda5da8dSAndroid Build Coastguard Worker def set_classifiers(self, value): 1215*cda5da8dSAndroid Build Coastguard Worker self.classifiers = _ensure_list(value, 'classifiers') 1216*cda5da8dSAndroid Build Coastguard Worker 1217*cda5da8dSAndroid Build Coastguard Worker def get_download_url(self): 1218*cda5da8dSAndroid Build Coastguard Worker return self.download_url or "UNKNOWN" 1219*cda5da8dSAndroid Build Coastguard Worker 1220*cda5da8dSAndroid Build Coastguard Worker # PEP 314 1221*cda5da8dSAndroid Build Coastguard Worker def get_requires(self): 1222*cda5da8dSAndroid Build Coastguard Worker return self.requires or [] 1223*cda5da8dSAndroid Build Coastguard Worker 1224*cda5da8dSAndroid Build Coastguard Worker def set_requires(self, value): 1225*cda5da8dSAndroid Build Coastguard Worker import distutils.versionpredicate 1226*cda5da8dSAndroid Build Coastguard Worker for v in value: 1227*cda5da8dSAndroid Build Coastguard Worker distutils.versionpredicate.VersionPredicate(v) 1228*cda5da8dSAndroid Build Coastguard Worker self.requires = list(value) 1229*cda5da8dSAndroid Build Coastguard Worker 1230*cda5da8dSAndroid Build Coastguard Worker def get_provides(self): 1231*cda5da8dSAndroid Build Coastguard Worker return self.provides or [] 1232*cda5da8dSAndroid Build Coastguard Worker 1233*cda5da8dSAndroid Build Coastguard Worker def set_provides(self, value): 1234*cda5da8dSAndroid Build Coastguard Worker value = [v.strip() for v in value] 1235*cda5da8dSAndroid Build Coastguard Worker for v in value: 1236*cda5da8dSAndroid Build Coastguard Worker import distutils.versionpredicate 1237*cda5da8dSAndroid Build Coastguard Worker distutils.versionpredicate.split_provision(v) 1238*cda5da8dSAndroid Build Coastguard Worker self.provides = value 1239*cda5da8dSAndroid Build Coastguard Worker 1240*cda5da8dSAndroid Build Coastguard Worker def get_obsoletes(self): 1241*cda5da8dSAndroid Build Coastguard Worker return self.obsoletes or [] 1242*cda5da8dSAndroid Build Coastguard Worker 1243*cda5da8dSAndroid Build Coastguard Worker def set_obsoletes(self, value): 1244*cda5da8dSAndroid Build Coastguard Worker import distutils.versionpredicate 1245*cda5da8dSAndroid Build Coastguard Worker for v in value: 1246*cda5da8dSAndroid Build Coastguard Worker distutils.versionpredicate.VersionPredicate(v) 1247*cda5da8dSAndroid Build Coastguard Worker self.obsoletes = list(value) 1248*cda5da8dSAndroid Build Coastguard Worker 1249*cda5da8dSAndroid Build Coastguard Workerdef fix_help_options(options): 1250*cda5da8dSAndroid Build Coastguard Worker """Convert a 4-tuple 'help_options' list as found in various command 1251*cda5da8dSAndroid Build Coastguard Worker classes to the 3-tuple form required by FancyGetopt. 1252*cda5da8dSAndroid Build Coastguard Worker """ 1253*cda5da8dSAndroid Build Coastguard Worker new_options = [] 1254*cda5da8dSAndroid Build Coastguard Worker for help_tuple in options: 1255*cda5da8dSAndroid Build Coastguard Worker new_options.append(help_tuple[0:3]) 1256*cda5da8dSAndroid Build Coastguard Worker return new_options 1257