diff options
author | phillip.eby <phillip.eby@6015fed2-1504-0410-9fe1-9d1591cc4771> | 2006-12-29 17:33:14 +0000 |
---|---|---|
committer | phillip.eby <phillip.eby@6015fed2-1504-0410-9fe1-9d1591cc4771> | 2006-12-29 17:33:14 +0000 |
commit | c4bdbf64153b97bb75531954d6b454f4bc5eba3a (patch) | |
tree | 22767ade0820252f1a01c4943b2ae2b1c44f11af /setuptools/command | |
parent | d9afca58a8eed58a4dcfe8bd19fad2506d9a2aad (diff) | |
download | python-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-x | setuptools/command/easy_install.py | 71 |
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 |