mirror of
https://github.com/python/cpython.git
synced 2025-01-26 19:13:43 +08:00
cd8a1148e1
This is a conservative version of SF patch 504889. It uses the log module instead of calling print in various places, and it ignores the verbose argument passed to many functions and set as an attribute on some objects. Instead, it uses the verbosity set on the logger via the command line. The log module is now preferred over announce() and warn() methods that exist only for backwards compatibility. XXX This checkin changes a lot of modules that have no test suite and aren't exercised by the Python build process. It will need substantial testing.
112 lines
3.6 KiB
Python
112 lines
3.6 KiB
Python
"""distutils.command.build_scripts
|
|
|
|
Implements the Distutils 'build_scripts' command."""
|
|
|
|
# created 2000/05/23, Bastian Kleineidam
|
|
|
|
__revision__ = "$Id$"
|
|
|
|
import sys, os, re
|
|
from distutils import sysconfig
|
|
from distutils.core import Command
|
|
from distutils.dep_util import newer
|
|
from distutils.util import convert_path
|
|
from distutils import log
|
|
|
|
# check if Python is called on the first line with this expression
|
|
first_line_re = re.compile(r'^#!.*python[0-9.]*(\s+.*)?$')
|
|
|
|
class build_scripts (Command):
|
|
|
|
description = "\"build\" scripts (copy and fixup #! line)"
|
|
|
|
user_options = [
|
|
('build-dir=', 'd', "directory to \"build\" (copy) to"),
|
|
('force', 'f', "forcibly build everything (ignore file timestamps"),
|
|
]
|
|
|
|
boolean_options = ['force']
|
|
|
|
|
|
def initialize_options (self):
|
|
self.build_dir = None
|
|
self.scripts = None
|
|
self.force = None
|
|
self.outfiles = None
|
|
|
|
def finalize_options (self):
|
|
self.set_undefined_options('build',
|
|
('build_scripts', 'build_dir'),
|
|
('force', 'force'))
|
|
self.scripts = self.distribution.scripts
|
|
|
|
|
|
def run (self):
|
|
if not self.scripts:
|
|
return
|
|
self.copy_scripts()
|
|
|
|
|
|
def copy_scripts (self):
|
|
"""Copy each script listed in 'self.scripts'; if it's marked as a
|
|
Python script in the Unix way (first line matches 'first_line_re',
|
|
ie. starts with "\#!" and contains "python"), then adjust the first
|
|
line to refer to the current Python interpreter as we copy.
|
|
"""
|
|
self.mkpath(self.build_dir)
|
|
for script in self.scripts:
|
|
adjust = 0
|
|
script = convert_path(script)
|
|
outfile = os.path.join(self.build_dir, os.path.basename(script))
|
|
|
|
if not self.force and not newer(script, outfile):
|
|
log.debug("not copying %s (up-to-date)", script)
|
|
continue
|
|
|
|
# Always open the file, but ignore failures in dry-run mode --
|
|
# that way, we'll get accurate feedback if we can read the
|
|
# script.
|
|
try:
|
|
f = open(script, "r")
|
|
except IOError:
|
|
if not self.dry_run:
|
|
raise
|
|
f = None
|
|
else:
|
|
first_line = f.readline()
|
|
if not first_line:
|
|
self.warn("%s is an empty file (skipping)" % script)
|
|
continue
|
|
|
|
match = first_line_re.match(first_line)
|
|
if match:
|
|
adjust = 1
|
|
post_interp = match.group(1) or ''
|
|
|
|
if adjust:
|
|
log.info("copying and adjusting %s -> %s", script,
|
|
self.build_dir)
|
|
if not self.dry_run:
|
|
outf = open(outfile, "w")
|
|
if not sysconfig.python_build:
|
|
outf.write("#!%s%s\n" %
|
|
(os.path.normpath(sys.executable),
|
|
post_interp))
|
|
else:
|
|
outf.write("#!%s%s" %
|
|
(os.path.join(
|
|
sysconfig.get_config_var("BINDIR"),
|
|
"python" + sysconfig.get_config_var("EXE")),
|
|
post_interp))
|
|
outf.writelines(f.readlines())
|
|
outf.close()
|
|
if f:
|
|
f.close()
|
|
else:
|
|
f.close()
|
|
self.copy_file(script, outfile)
|
|
|
|
# copy_scripts ()
|
|
|
|
# class build_scripts
|