summaryrefslogtreecommitdiff
path: root/setuptools/command
diff options
context:
space:
mode:
authorphillip.eby <phillip.eby@6015fed2-1504-0410-9fe1-9d1591cc4771>2006-12-29 17:33:14 +0000
committerphillip.eby <phillip.eby@6015fed2-1504-0410-9fe1-9d1591cc4771>2006-12-29 17:33:14 +0000
commitc4bdbf64153b97bb75531954d6b454f4bc5eba3a (patch)
tree22767ade0820252f1a01c4943b2ae2b1c44f11af /setuptools/command
parentd9afca58a8eed58a4dcfe8bd19fad2506d9a2aad (diff)
downloadpython-setuptools-c4bdbf64153b97bb75531954d6b454f4bc5eba3a.tar.gz
Overhaul Windows script wrappers to support bdist_wininst better.
Scripts installed with bdist_wininst will always use #!python.exe or #!pythonw.exe as the executable name, and the wrappers will look for the executable in the script's parent directory. Since bdist_wininst scripts are installed to Python2X/Scripts, this will look for Python2X/python.exe. Scripts installed by easy_install, however, will still use an absolute executable path. Also fixed: some egg<->exe roundtripping issues, and script #! lines on Windows can now have an arbitrary number of arguments following the Python exe name, and the exe name is quoted if necessary, following the MS command line parsing rules. git-svn-id: http://svn.python.org/projects/sandbox/trunk/setuptools@53191 6015fed2-1504-0410-9fe1-9d1591cc4771
Diffstat (limited to 'setuptools/command')
-rwxr-xr-xsetuptools/command/easy_install.py71
1 files changed, 56 insertions, 15 deletions
diff --git a/setuptools/command/easy_install.py b/setuptools/command/easy_install.py
index 1abf34f..d376df2 100755
--- a/setuptools/command/easy_install.py
+++ b/setuptools/command/easy_install.py
@@ -369,16 +369,15 @@ Please make the appropriate changes for your system and try again.
def install_egg_scripts(self, dist):
"""Write all the scripts for `dist`, unless scripts are excluded"""
-
+ if not self.exclude_scripts and dist.metadata_isdir('scripts'):
+ for script_name in dist.metadata_listdir('scripts'):
+ self.install_script(
+ dist, script_name,
+ dist.get_metadata('scripts/'+script_name).replace('\r','\n')
+ )
+ # we install wrapper scripts second, so they'll overwrite any dupes
+ # created as a result of exe<->egg roundtripping
self.install_wrapper_scripts(dist)
- if self.exclude_scripts or not dist.metadata_isdir('scripts'):
- return
-
- for script_name in dist.metadata_listdir('scripts'):
- self.install_script(
- dist, script_name,
- dist.get_metadata('scripts/'+script_name).replace('\r','\n')
- )
def add_output(self, path):
if os.path.isdir(path):
@@ -408,6 +407,7 @@ Please make the appropriate changes for your system and try again.
+
def easy_install(self, spec, deps=False):
tmpdir = tempfile.mkdtemp(prefix="easy_install-")
download = None
@@ -1407,7 +1407,6 @@ class PthDistributions(Environment):
else:
return path
-
def get_script_header(script_text, executable=sys_executable, wininst=False):
"""Create a #! line, getting options (if any) from script_text"""
from distutils.command.build_scripts import first_line_re
@@ -1418,8 +1417,10 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
options = match.group(1) or ''
if options:
options = ' '+options
- if wininst and sys.platform!='win32':
+ if wininst:
executable = "python.exe"
+ else:
+ executable = nt_quote_arg(executable)
hdr = "#!%(executable)s%(options)s\n" % locals()
if unicode(hdr,'ascii','ignore').encode('ascii') != hdr:
# Non-ascii path to sys.executable, use -x to prevent warnings
@@ -1432,7 +1433,6 @@ def get_script_header(script_text, executable=sys_executable, wininst=False):
hdr = "#!%(executable)s%(options)s\n" % locals()
return hdr
-
def auto_chmod(func, arg, exc):
if func is os.remove and os.name=='nt':
os.chmod(arg, stat.S_IWRITE)
@@ -1474,6 +1474,47 @@ def is_python(text, filename='<string>'):
+def nt_quote_arg(arg):
+ """Quote a command line argument according to Windows parsing rules"""
+
+ result = []
+ needquote = False
+ nb = 0
+
+ needquote = (" " in arg) or ("\t" in arg)
+ if needquote:
+ result.append('"')
+
+ for c in arg:
+ if c == '\\':
+ nb += 1
+ elif c == '"':
+ # double preceding backslashes, then add a \"
+ result.append('\\' * (nb*2) + '\\"')
+ nb = 0
+ else:
+ if nb:
+ result.append('\\' * nb)
+ nb = 0
+ result.append(c)
+
+ if nb:
+ result.append('\\' * nb)
+
+ if needquote:
+ result.append('\\' * nb) # double the trailing backslashes
+ result.append('"')
+
+ return ''.join(result)
+
+
+
+
+
+
+
+
+
def is_python_script(script_text, filename):
"""Is this text, as a whole, a Python script? (as opposed to shell/bat/etc.
"""
@@ -1532,7 +1573,7 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
")\n"
) % locals()
if sys.platform=='win32' or wininst:
- # On Windows, add a .py extension and an .exe launcher
+ # On Windows/wininst, add a .py extension and an .exe launcher
if group=='gui_scripts':
ext, launcher = '-script.pyw', 'gui.exe'
old = ['.pyw']
@@ -1540,9 +1581,9 @@ def get_script_args(dist, executable=sys_executable, wininst=False):
else:
ext, launcher = '-script.py', 'cli.exe'
old = ['.py','.pyc','.pyo']
- new_header = re.sub('(?i)pythonw.exe','pythonw.exe',header)
+ new_header = re.sub('(?i)pythonw.exe','python.exe',header)
- if os.path.exists(new_header[2:-1]):
+ if os.path.exists(new_header[2:-1]) or sys.platform!='win32':
hdr = new_header
else:
hdr = header