changeset 706:d2e965fc31d4

On Windows, make `cmd.exe` built-ins and scripts execute through the shell. Closes #449 + generally improves handling for `<sh:exec file="mycript.bat">` type commands on Windows. Note that executing through Windows shell will throw off the rules for command-line quoting...
author osimons
date Tue, 20 Oct 2009 09:41:16 +0000
parents 9844af477a91
children 0d7d6552477e
files bitten/build/api.py bitten/build/javatools.py bitten/build/shtools.py doc/recipes.txt
diffstat 4 files changed, 20 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/bitten/build/api.py
+++ b/bitten/build/api.py
@@ -50,7 +50,7 @@
 class CommandLine(object):
     """Simple helper for executing subprocesses."""
 
-    def __init__(self, executable, args, input=None, cwd=None):
+    def __init__(self, executable, args, input=None, cwd=None, shell=False):
         """Initialize the CommandLine object.
         
         :param executable: the name of the program to execute
@@ -66,6 +66,7 @@
         self.cwd = cwd
         if self.cwd:
             assert os.path.isdir(self.cwd)
+        self.shell = shell
         self.returncode = None
 
 
@@ -102,7 +103,7 @@
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         cwd=(self.cwd or None),
-                        shell=False,
+                        shell=self.shell,
                         universal_newlines=True,
                         env=None)
         except Exception, e:
--- a/bitten/build/javatools.py
+++ b/bitten/build/javatools.py
@@ -60,7 +60,12 @@
     if target:
         args.append(target)
 
-    cmdline = CommandLine(executable, args, cwd=ctxt.basedir)
+    shell = False
+    if os.name == 'nt':
+        # Need to execute ant.bat through a shell on Windows
+        shell = True
+
+    cmdline = CommandLine(executable, args, cwd=ctxt.basedir, shell=shell)
     for out, err in cmdline.execute():
         if out is not None:
             log.info(out)
--- a/bitten/build/shtools.py
+++ b/bitten/build/shtools.py
@@ -101,6 +101,12 @@
     if file_ and os.path.isfile(resolve(file_)):
         file_ = resolve(file_)
 
+    shell = False
+
+    if file_ and os.name == 'nt':
+        # Need to execute script files through a shell on Windows
+        shell = True
+
     if executable is None:
         executable = file_
     elif file_:
@@ -109,8 +115,7 @@
     # Support important Windows CMD.EXE built-ins (and it does its own quoting)
     if os.name == 'nt' and executable.upper() in ['COPY', 'DIR', 'ECHO',
                 'ERASE', 'DEL', 'MKDIR', 'MD', 'MOVE', 'RMDIR', 'RD', 'TYPE']:
-        args = ['/C', executable] + [arg.strip('"') for arg in args]
-        executable = os.environ['COMSPEC']
+        shell = True
 
     if input_:
         input_file = file(resolve(input_), 'r')
@@ -132,7 +137,7 @@
 
     try:
         cmdline = CommandLine(executable, args, input=input_file,
-                              cwd=dir_)
+                              cwd=dir_, shell=shell)
         log_elem = xmlio.Fragment()
         for out, err in cmdline.execute():
             if out is not None:
--- a/doc/recipes.txt
+++ b/doc/recipes.txt
@@ -125,3 +125,6 @@
   <sh:exec file="echo" args="o\\ne &quot;4 2&quot; \&quot;hi\ there\&quot;"/>
 
 This will pass 3 arguments: ``o\ne`` + ``4 2`` + ``"hi there"``.
+
+**Note:** On Windows, batch scripts and built-ins will execute through a shell.
+This may affect quoting of arguments.
Copyright (C) 2012-2017 Edgewall Software