@@ -516,7 +516,9 @@ def on_rm_error(func, path, exc_info):
516516 if force and not os .path .exists (path ):
517517 continue
518518 try :
519- if os .path .isdir (path ):
519+ if os .path .islink (path ):
520+ os .remove (path )
521+ elif os .path .isdir (path ):
520522 if not recursive :
521523 stderr .write ("Error: %s is a directory\n " % path )
522524 exitCode = 1
@@ -720,6 +722,23 @@ def processRedirects(cmd, stdin_source, cmd_shenv, opened_files):
720722 return std_fds
721723
722724
725+ def _expandLateSubstitutions (arguments , cwd ):
726+ for i , arg in enumerate (arguments ):
727+ if not isinstance (arg , str ):
728+ continue
729+
730+ def _replaceReadFile (match ):
731+ filePath = match .group (1 )
732+ if not os .path .isabs (filePath ):
733+ filePath = os .path .join (cwd , filePath )
734+ with open (filePath ) as fileHandle :
735+ return fileHandle .read ()
736+
737+ arguments [i ] = re .sub (r"%{readfile:([^}]*)}" , _replaceReadFile , arg )
738+
739+ return arguments
740+
741+
723742def _executeShCmd (cmd , shenv , results , timeoutHelper ):
724743 if timeoutHelper .timeoutReached ():
725744 # Prevent further recursion if the timeout has been hit
@@ -834,6 +853,9 @@ def _executeShCmd(cmd, shenv, results, timeoutHelper):
834853 # Ensure args[0] is hashable.
835854 args [0 ] = expand_glob (args [0 ], cmd_shenv .cwd )[0 ]
836855
856+ # Expand all late substitutions
857+ args = _expandLateSubstitutions (args , cmd_shenv .cwd )
858+
837859 inproc_builtin = inproc_builtins .get (args [0 ], None )
838860 if inproc_builtin and (args [0 ] != "echo" or len (cmd .commands ) == 1 ):
839861 # env calling an in-process builtin is useless, so we take the safe
0 commit comments