[Python-checkins] CVS: distutils/distutils dist.py,1.4,1.5
Greg Ward
python-dev@python.org
Thu, 20 Apr 2000 22:28:19 -0400 (EDT)
Update of /projects/cvsroot/distutils/distutils
In directory newcnri:/tmp/cvs-serv17001/distutils
Modified Files:
dist.py
Log Message:
Patch, originally from Bastian Kleineidam and savagely mutilated by me,
to add the "display metadata" options: --name, --version, --author,
and so forth. Main changes:
* added 'display_options' class attribute to list all the "display only"
options (--help-commands plus the metadata options)
* added DistributionMetadata class as a place to put the actual
metadata information from the setup script (not to be confused with
the metadata display options); the logic dealing with metadata
(eg. return self.name or "UNKNOWN") is now in this class
* changed 'parse_command_line()' to use the new OO interface provided
by fancy_getopt, mainly so we can get at the original order of
options on the command line, so we can print multiple lines of
distribution meta-data in the order specified by the user
* added 'handle_display_options()' to handle display-only options
Also fixed some crufty old comments/docstrings.
Index: dist.py
===================================================================
RCS file: /projects/cvsroot/distutils/distutils/dist.py,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** dist.py 2000/04/15 22:15:07 1.4
--- dist.py 2000/04/21 02:28:14 1.5
***************
*** 7,11 ****
# (extricated from core.py; actually dates back to the beginning)
! __revision__ = "$Id: dist.py,v 1.4 2000/04/15 22:15:07 gward Exp $"
import sys, string, re
--- 7,11 ----
# (extricated from core.py; actually dates back to the beginning)
! __revision__ = "$Id: dist.py,v 1.5 2000/04/21 02:28:14 gward Exp $"
import sys, string, re
***************
*** 13,17 ****
from copy import copy
from distutils.errors import *
! from distutils.fancy_getopt import fancy_getopt, print_help
--- 13,17 ----
from copy import copy
from distutils.errors import *
! from distutils.fancy_getopt import FancyGetopt, longopt_xlate
***************
*** 41,46 ****
# 'global_options' describes the command-line options that may be
! # supplied to the client (setup.py) prior to any actual commands.
! # Eg. "./setup.py -nv" or "./setup.py --verbose" both take advantage of
# these global options. This list should be kept to a bare minimum,
# since every global option is also valid as a command option -- and we
--- 41,46 ----
# 'global_options' describes the command-line options that may be
! # supplied to the setup script prior to any actual commands.
! # Eg. "./setup.py -n" or "./setup.py --quiet" both take advantage of
# these global options. This list should be kept to a bare minimum,
# since every global option is also valid as a command option -- and we
***************
*** 54,59 ****
"don't actually do anything"),
('help', 'h',
! "show this help message"),
]
negative_opt = {'quiet': 'verbose'}
--- 54,98 ----
"don't actually do anything"),
('help', 'h',
! "show this help message, plus help for any commands " +
! "given on the command-line"),
]
+
+ # options that are not propagated to the commands
+ display_options = [
+ ('help-commands', None,
+ "list all available commands"),
+ ('name', None,
+ "print package name"),
+ ('version', 'V',
+ "print package version"),
+ ('fullname', None,
+ "print <package name>-<version>"),
+ ('author', None,
+ "print the author's name"),
+ ('author-email', None,
+ "print the author's email address"),
+ ('maintainer', None,
+ "print the maintainer's name"),
+ ('maintainer-email', None,
+ "print the maintainer's email address"),
+ ('contact', None,
+ "print the name of the maintainer if present, "
+ "else author"),
+ ('contact-email', None,
+ "print the email of the maintainer if present, "
+ "else author"),
+ ('url', None,
+ "print the URL for this package"),
+ ('licence', None,
+ "print the licence of the package"),
+ ('license', None,
+ "alias for --licence"),
+ ('description', None,
+ "print the package description"),
+ ]
+ display_option_names = map(lambda x: string.translate(x[0], longopt_xlate),
+ display_options)
+
+ # negative options are options that exclude other options
negative_opt = {'quiet': 'verbose'}
***************
*** 76,98 ****
self.dry_run = 0
self.help = 0
! self.help_commands = 0
! # And the "distribution meta-data" options -- these can only
! # come from setup.py (the caller), not the command line
! # (or a hypothetical config file).
! self.name = None
! self.version = None
! self.author = None
! self.author_email = None
! self.maintainer = None
! self.maintainer_email = None
! self.url = None
! self.licence = None
! self.description = None
# 'cmdclass' maps command names to class objects, so we
# can 1) quickly figure out which class to instantiate when
# we need to create a new command object, and 2) have a way
! # for the client to override command classes
self.cmdclass = {}
--- 115,135 ----
self.dry_run = 0
self.help = 0
! for attr in self.display_option_names:
! setattr(self, attr, 0)
! # Store the distribution meta-data (name, version, author, and so
! # forth) in a separate object -- we're getting to have enough
! # information here (and enough command-line options) that it's
! # worth it. Also delegate 'get_XXX()' methods to the 'metadata'
! # object in a sneaky and underhanded (but efficient!) way.
! self.metadata = DistributionMetadata ()
! for attr in dir(self.metadata):
! meth_name = "get_" + attr
! setattr(self, meth_name, getattr(self.metadata, meth_name))
# 'cmdclass' maps command names to class objects, so we
# can 1) quickly figure out which class to instantiate when
# we need to create a new command object, and 2) have a way
! # for the setup script to override command classes
self.cmdclass = {}
***************
*** 100,104 ****
# than of the Distribution itself. We provide aliases for them in
# Distribution as a convenience to the developer.
- # dictionary.
self.packages = None
self.package_dir = None
--- 137,140 ----
***************
*** 129,134 ****
# Now we'll use the attrs dictionary (ultimately, keyword args from
! # the client) to possibly override any or all of these distribution
! # options.
if attrs:
--- 165,171 ----
# Now we'll use the attrs dictionary (ultimately, keyword args from
! # the setup script) to possibly override any or all of these
! # distribution options.
!
if attrs:
***************
*** 150,154 ****
# not already defined is invalid!
for (key,val) in attrs.items():
! if hasattr (self, key):
setattr (self, key, val)
else:
--- 187,193 ----
# not already defined is invalid!
for (key,val) in attrs.items():
! if hasattr (self.metadata, key):
! setattr (self.metadata, key, val)
! elif hasattr (self, key):
setattr (self, key, val)
else:
***************
*** 193,209 ****
self.commands = []
! options = self.global_options + \
! [('help-commands', None,
! "list all available commands")]
! args = fancy_getopt (options, self.negative_opt,
! self, sys.argv[1:])
! # User just wants a list of commands -- we'll print it out and stop
! # processing now (ie. if they ran "setup --help-commands foo bar",
! # we ignore "foo bar").
! if self.help_commands:
! self.print_commands ()
! print
! print usage
return
--- 232,246 ----
self.commands = []
! parser = FancyGetopt (self.global_options + self.display_options)
! parser.set_negative_aliases (self.negative_opt)
! args = parser.getopt (object=self)
! option_order = parser.get_option_order()
!
! # Handle aliases (license == licence)
! if self.license:
! self.licence = 1
! # for display options we return immediately
! if self.handle_display_options(option_order):
return
***************
*** 247,259 ****
negative_opt.update (cmd_obj.negative_opt)
! options = self.global_options + cmd_obj.user_options
! args = fancy_getopt (options, negative_opt,
! cmd_obj, args[1:])
if cmd_obj.help:
! print_help (self.global_options,
! header="Global options:")
print
! print_help (cmd_obj.user_options,
! header="Options for '%s' command:" % command)
print
print usage
--- 284,298 ----
negative_opt.update (cmd_obj.negative_opt)
! parser.set_option_table (self.global_options +
! cmd_obj.user_options)
! parser.set_negative_aliases (negative_opt)
! args = parser.getopt (args[1:], cmd_obj)
if cmd_obj.help:
! parser.set_option_table (self.global_options)
! parser.print_help ("Global options:")
print
!
! parser.set_option_table (cmd_obj.user_options)
! parser.print_help ("Options for '%s' command:" % command)
print
print usage
***************
*** 272,282 ****
# CVS does it -- might as well be consistent.)
if self.help:
! print_help (self.global_options, header="Global options:")
print
for command in self.commands:
klass = self.find_command_class (command)
! print_help (klass.user_options,
! header="Options for '%s' command:" % command)
print
--- 311,331 ----
# CVS does it -- might as well be consistent.)
if self.help:
! parser.set_option_table (self.global_options)
! parser.print_help (
! "Global options (apply to all commands, " +
! "or can be used per command):")
print
+ if not self.commands:
+ parser.set_option_table (self.display_options)
+ parser.print_help (
+ "Information display options (just display " +
+ "information, ignore any commands)")
+ print
+
for command in self.commands:
klass = self.find_command_class (command)
! parser.set_option_table (klass.user_options)
! parser.print_help ("Options for '%s' command:" % command)
print
***************
*** 293,297 ****
--- 342,380 ----
# parse_command_line()
+ def handle_display_options (self, option_order):
+ """If there were any non-global "display-only" options
+ (--help-commands or the metadata display options) on the command
+ line, display the requested info and return true; else return
+ false."""
+
+ from distutils.core import usage
+
+ # User just wants a list of commands -- we'll print it out and stop
+ # processing now (ie. if they ran "setup --help-commands foo bar",
+ # we ignore "foo bar").
+ if self.help_commands:
+ self.print_commands ()
+ print
+ print usage
+ return 1
+
+ # If user supplied any of the "display metadata" options, then
+ # display that metadata in the order in which the user supplied the
+ # metadata options.
+ any_display_options = 0
+ is_display_option = {}
+ for option in self.display_options:
+ is_display_option[option[0]] = 1
+
+ for (opt, val) in option_order:
+ if val and is_display_option.get(opt):
+ opt = string.translate (opt, longopt_xlate)
+ print getattr(self.metadata, "get_"+opt)()
+ any_display_options = 1
+
+ return any_display_options
+ # handle_display_options()
+
def print_command_list (self, commands, header, max_length):
"""Print a subset of the list of all commands -- used by
***************
*** 438,442 ****
def run_commands (self):
! """Run each command that was seen on the client command line.
Uses the list of commands found and cache of command objects
created by 'create_command_obj()'."""
--- 521,525 ----
def run_commands (self):
! """Run each command that was seen on the setup script command line.
Uses the list of commands found and cache of command objects
created by 'create_command_obj()'."""
***************
*** 533,544 ****
not self.has_c_libraries())
def get_name (self):
return self.name or "UNKNOWN"
! def get_full_name (self):
! return "%s-%s" % ((self.name or "UNKNOWN"), (self.version or "???"))
!
! # class Distribution
if __name__ == "__main__":
--- 616,687 ----
not self.has_c_libraries())
+ # -- Metadata query methods ----------------------------------------
+
+ # If you're looking for 'get_name()', 'get_version()', and so forth,
+ # they are defined in a sneaky way: the constructor binds self.get_XXX
+ # to self.metadata.get_XXX. The actual code is in the
+ # DistributionMetadata class, below.
+
+ # class Distribution
+
+
+ class DistributionMetadata:
+ """Dummy class to hold the distribution meta-data: name, version,
+ author, and so forth."""
+
+ def __init__ (self):
+ self.name = None
+ self.version = None
+ self.author = None
+ self.author_email = None
+ self.maintainer = None
+ self.maintainer_email = None
+ self.url = None
+ self.licence = None
+ self.description = None
+
+ # -- Metadata query methods ----------------------------------------
+
def get_name (self):
return self.name or "UNKNOWN"
! def get_version(self):
! return self.version or "???"
!
! def get_fullname (self):
! return "%s-%s" % (self.get_name(), self.get_version())
!
! def get_author(self):
! return self.author or "UNKNOWN"
+ def get_author_email(self):
+ return self.author_email or "UNKNOWN"
+
+ def get_maintainer(self):
+ return self.maintainer or "UNKNOWN"
+
+ def get_maintainer_email(self):
+ return self.maintainer_email or "UNKNOWN"
+
+ def get_contact(self):
+ return (self.maintainer or
+ self.author or
+ "UNKNOWN")
+
+ def get_contact_email(self):
+ return (self.maintainer_email or
+ self.author_email or
+ "UNKNOWN")
+
+ def get_url(self):
+ return self.url or "UNKNOWN"
+
+ def get_licence(self):
+ return self.licence or "UNKNOWN"
+
+ def get_description(self):
+ return self.description or "UNKNOWN"
+
+ # class DistributionMetadata
if __name__ == "__main__":