mirror of
https://github.com/python/cpython.git
synced 2025-01-26 19:13:43 +08:00
53a79060bb
slightly more brief, and more like the message that an extension will not be built because the built copy is up to date.
103 lines
3.2 KiB
Python
103 lines
3.2 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.core import Command
|
|
from distutils.dep_util import newer
|
|
|
|
# check if Python is called on the first line with this expression.
|
|
# This expression will leave lines using /usr/bin/env alone; presumably
|
|
# the script author knew what they were doing...)
|
|
first_line_re = re.compile(r'^#!(?!\s*/usr/bin/env\b).*python(\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.
|
|
"""
|
|
outfiles = []
|
|
self.mkpath(self.build_dir)
|
|
for script in self.scripts:
|
|
adjust = 0
|
|
outfile = os.path.join(self.build_dir, os.path.basename(script))
|
|
|
|
if not self.force and not newer(script, outfile):
|
|
self.announce("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)
|
|
|
|
if adjust:
|
|
self.announce("copying and adjusting %s -> %s" %
|
|
(script, self.build_dir))
|
|
if not self.dry_run:
|
|
outf = open(outfile, "w")
|
|
outf.write("#!%s%s\n" %
|
|
(os.path.normpath(sys.executable), 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
|