Added 'script_name' and 'script_args' instance attributes to Distribution.

Changed 'core.setup()' so it sets them to reasonable defaults.
Tweaked how the "usage" string is generated: 'core' now provides
  'gen_usage()', which is used instead of 'USAGE'.
Modified "build_py" and "sdist" commands to refer to
  'self.distribution.script_name' rather than 'sys.argv[0]'.
This commit is contained in:
Greg Ward 2000-08-29 01:15:18 +00:00
parent 31f182e830
commit 9821bf4e62
4 changed files with 58 additions and 37 deletions

View File

@ -177,13 +177,15 @@ class build_py (Command):
self.check_package (package, package_dir) self.check_package (package, package_dir)
module_files = glob (os.path.join (package_dir, "*.py")) module_files = glob (os.path.join (package_dir, "*.py"))
modules = [] modules = []
setup_script = os.path.abspath (sys.argv[0]) setup_script = os.path.abspath(self.distribution.script_name)
for f in module_files: for f in module_files:
abs_f = os.path.abspath (f) abs_f = os.path.abspath (f)
if abs_f != setup_script: if abs_f != setup_script:
module = os.path.splitext (os.path.basename (f))[0] module = os.path.splitext (os.path.basename (f))[0]
modules.append ((package, module, f)) modules.append ((package, module, f))
else:
self.debug_print("excluding %s" % setup_script)
return modules return modules

View File

@ -202,7 +202,10 @@ class sdist (Command):
# manifest, but there's no template -- which will happen if the # manifest, but there's no template -- which will happen if the
# developer elects to generate a manifest some other way -- then we # developer elects to generate a manifest some other way -- then we
# can't regenerate the manifest, so we don't.) # can't regenerate the manifest, so we don't.)
setup_newer = dep_util.newer(sys.argv[0], self.manifest) self.debug_print("checking if %s newer than %s" %
(self.distribution.script_name, self.manifest))
setup_newer = dep_util.newer(self.distribution.script_name,
self.manifest)
# cases: # cases:
# 1) no manifest, template exists: generate manifest # 1) no manifest, template exists: generate manifest

View File

@ -25,26 +25,30 @@ from distutils.extension import Extension
# runs the setup script with no arguments at all. More useful help # runs the setup script with no arguments at all. More useful help
# is generated with various --help options: global help, list commands, # is generated with various --help options: global help, list commands,
# and per-command help. # and per-command help.
usage = """\ USAGE = """\
usage: %s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...] usage: %(script)s [global_opts] cmd1 [cmd1_opts] [cmd2 [cmd2_opts] ...]
or: %s --help [cmd1 cmd2 ...] or: %(script)s --help [cmd1 cmd2 ...]
or: %s --help-commands or: %(script)s --help-commands
or: %s cmd --help or: %(script)s cmd --help
""" % ((os.path.basename(sys.argv[0]),) * 4) """
# If DISTUTILS_DEBUG is anything other than the empty string, we run in # If DISTUTILS_DEBUG is anything other than the empty string, we run in
# debug mode. # debug mode.
DEBUG = os.environ.get('DISTUTILS_DEBUG') DEBUG = os.environ.get('DISTUTILS_DEBUG')
def gen_usage (script_name):
script = os.path.basename(script_name)
return USAGE % vars()
def setup (**attrs): def setup (**attrs):
"""The gateway to the Distutils: do everything your setup script needs """The gateway to the Distutils: do everything your setup script needs
to do, in a highly flexible and user-driven way. Briefly: create a to do, in a highly flexible and user-driven way. Briefly: create a
Distribution instance; find and parse config files; parse the command Distribution instance; find and parse config files; parse the command
line; run each of those commands using the options supplied to line; run each Distutils command found there, customized by the options
'setup()' (as keyword arguments), in config files, and on the command supplied to 'setup()' (as keyword arguments), in config files, and on
line. the command line.
The Distribution instance might be an instance of a class supplied via The Distribution instance might be an instance of a class supplied via
the 'distclass' keyword argument to 'setup'; if no such class is the 'distclass' keyword argument to 'setup'; if no such class is
@ -79,6 +83,11 @@ def setup (**attrs):
else: else:
klass = Distribution klass = Distribution
if not attrs.has_key('script_name'):
attrs['script_name'] = sys.argv[0]
if not attrs.has_key('script_args'):
attrs['script_args'] = sys.argv[1:]
# Create the Distribution instance, using the remaining arguments # Create the Distribution instance, using the remaining arguments
# (ie. everything except distclass) to initialize it # (ie. everything except distclass) to initialize it
try: try:
@ -97,10 +106,11 @@ def setup (**attrs):
# Parse the command line; any command-line errors are the end user's # Parse the command line; any command-line errors are the end user's
# fault, so turn them into SystemExit to suppress tracebacks. # fault, so turn them into SystemExit to suppress tracebacks.
try: try:
ok = dist.parse_command_line (sys.argv[1:]) ok = dist.parse_command_line()
except DistutilsArgError, msg: except DistutilsArgError, msg:
sys.stderr.write (usage + "\n") script = os.path.basename(dist.script_name)
raise SystemExit, "error: %s" % msg raise SystemExit, \
gen_usage(dist.script_name) + "\nerror: %s" % msg
if DEBUG: if DEBUG:
print "options (after parsing command line):" print "options (after parsing command line):"

View File

@ -131,6 +131,12 @@ class Distribution:
# for the setup script to override command classes # for the setup script to override command classes
self.cmdclass = {} self.cmdclass = {}
# 'script_name' and 'script_args' are usually set to sys.argv[0]
# and sys.argv[1:], but they can be overridden when the caller is
# not necessarily a setup script run from the command-line.
self.script_name = None
self.script_args = None
# 'command_options' is where we store command options between # 'command_options' is where we store command options between
# parsing them (from config files, the command-line, etc.) and when # parsing them (from config files, the command-line, etc.) and when
# they are actually needed -- ie. when the command in question is # they are actually needed -- ie. when the command in question is
@ -326,24 +332,24 @@ class Distribution:
# -- Command-line parsing methods ---------------------------------- # -- Command-line parsing methods ----------------------------------
def parse_command_line (self, args): def parse_command_line (self):
"""Parse the setup script's command line. 'args' must be a list """Parse the setup script's command line, taken from the
of command-line arguments, most likely 'sys.argv[1:]' (see the 'script_args' instance attribute (which defaults to 'sys.argv[1:]'
'setup()' function). This list is first processed for "global -- see 'setup()' in core.py). This list is first processed for
options" -- options that set attributes of the Distribution "global options" -- options that set attributes of the Distribution
instance. Then, it is alternately scanned for Distutils instance. Then, it is alternately scanned for Distutils commands
commands and options for that command. Each new command and options for that command. Each new command terminates the
terminates the options for the previous command. The allowed options for the previous command. The allowed options for a
options for a command are determined by the 'user_options' command are determined by the 'user_options' attribute of the
attribute of the command class -- thus, we have to be able to command class -- thus, we have to be able to load command classes
load command classes in order to parse the command line. Any in order to parse the command line. Any error in that 'options'
error in that 'options' attribute raises DistutilsGetoptError; attribute raises DistutilsGetoptError; any error on the
any error on the command-line raises DistutilsArgError. If no command-line raises DistutilsArgError. If no Distutils commands
Distutils commands were found on the command line, raises were found on the command line, raises DistutilsArgError. Return
DistutilsArgError. Return true if command-line were true if command-line were successfully parsed and we should carry
successfully parsed and we should carry on with executing on with executing commands; false if no errors but we shouldn't
commands; false if no errors but we shouldn't execute commands execute commands (currently, this only happens if user asks for
(currently, this only happens if user asks for help). help).
""" """
# We have to parse the command line a bit at a time -- global # We have to parse the command line a bit at a time -- global
# options, then the first command, then its options, and so on -- # options, then the first command, then its options, and so on --
@ -356,7 +362,7 @@ class Distribution:
parser = FancyGetopt (self.global_options + self.display_options) parser = FancyGetopt (self.global_options + self.display_options)
parser.set_negative_aliases (self.negative_opt) parser.set_negative_aliases (self.negative_opt)
parser.set_aliases ({'license': 'licence'}) parser.set_aliases ({'license': 'licence'})
args = parser.getopt (object=self) args = parser.getopt (args=self.script_args, object=self)
option_order = parser.get_option_order() option_order = parser.get_option_order()
# for display options we return immediately # for display options we return immediately
@ -506,7 +512,7 @@ class Distribution:
in 'commands'. in 'commands'.
""" """
# late import because of mutual dependence between these modules # late import because of mutual dependence between these modules
from distutils.core import usage from distutils.core import gen_usage
from distutils.cmd import Command from distutils.cmd import Command
if global_options: if global_options:
@ -535,7 +541,7 @@ class Distribution:
parser.print_help ("Options for '%s' command:" % klass.__name__) parser.print_help ("Options for '%s' command:" % klass.__name__)
print print
print usage print gen_usage(self.script_name)
return return
# _show_help () # _show_help ()
@ -547,7 +553,7 @@ class Distribution:
line, display the requested info and return true; else return line, display the requested info and return true; else return
false. false.
""" """
from distutils.core import usage from distutils.core import gen_usage
# User just wants a list of commands -- we'll print it out and stop # 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", # processing now (ie. if they ran "setup --help-commands foo bar",
@ -555,7 +561,7 @@ class Distribution:
if self.help_commands: if self.help_commands:
self.print_commands () self.print_commands ()
print print
print usage print gen_usage(self.script_name)
return 1 return 1
# If user supplied any of the "display metadata" options, then # If user supplied any of the "display metadata" options, then