11import getpass
22import os
33import shutil
4+ import stat
45import subprocess
56import tempfile
67from shutil import rmtree
78
89import psutil
910
1011from ..exceptions import ExecUtilException
11-
12- from .os_ops import OsOperations , ConnectionParams
12+ from .os_ops import ConnectionParams , OsOperations
1313from .os_ops import pglib
1414
1515try :
1818 from distutils .spawn import find_executable
1919
2020CMD_TIMEOUT_SEC = 60
21+ error_markers = [b'error' , b'Permission denied' , b'fatal' ]
2122
2223
2324class LocalOperations (OsOperations ):
24- def __init__ (self , conn_params : ConnectionParams = ConnectionParams ()):
25- super ().__init__ (conn_params .username )
25+ def __init__ (self , conn_params = None ):
26+ if conn_params is None :
27+ conn_params = ConnectionParams ()
28+ super (LocalOperations , self ).__init__ (conn_params .username )
2629 self .conn_params = conn_params
2730 self .host = conn_params .host
2831 self .ssh_key = None
32+ self .remote = False
2933 self .username = conn_params .username or self .get_user ()
3034
3135 # Command execution
3236 def exec_command (self , cmd , wait_exit = False , verbose = False ,
33- expect_error = False , encoding = None , shell = True , text = False ,
34- input = None , stdout = subprocess .PIPE , stderr = subprocess .PIPE , proc = None ):
37+ expect_error = False , encoding = None , shell = False , text = False ,
38+ input = None , stdin = subprocess . PIPE , stdout = subprocess .PIPE , stderr = subprocess .PIPE , proc = None ):
3539 """
3640 Execute a command in a subprocess.
3741
@@ -49,9 +53,6 @@ def exec_command(self, cmd, wait_exit=False, verbose=False,
4953 - proc: The process to use for subprocess creation.
5054 :return: The output of the subprocess.
5155 """
52- if isinstance (cmd , list ):
53- cmd = ' ' .join (item .decode ('utf-8' ) if isinstance (item , bytes ) else item for item in cmd )
54-
5556 if os .name == 'nt' :
5657 with tempfile .NamedTemporaryFile () as buf :
5758 process = subprocess .Popen (cmd , stdout = buf , stderr = subprocess .STDOUT )
@@ -71,7 +72,7 @@ def exec_command(self, cmd, wait_exit=False, verbose=False,
7172 result , error = process .communicate (input )
7273 exit_status = process .returncode
7374
74- found_error = "error" in error . decode ( encoding or 'utf-8' ). lower ( )
75+ error_found = exit_status != 0 or any ( marker in error for marker in error_markers )
7576
7677 if encoding :
7778 result = result .decode (encoding )
@@ -80,7 +81,7 @@ def exec_command(self, cmd, wait_exit=False, verbose=False,
8081 if expect_error :
8182 raise Exception (result , error )
8283
83- if exit_status != 0 or found_error :
84+ if exit_status != 0 or error_found :
8485 if exit_status == 0 :
8586 exit_status = 1
8687 raise ExecUtilException (message = 'Utility exited with non-zero code. Error `{}`' .format (error ),
@@ -101,7 +102,7 @@ def find_executable(self, executable):
101102
102103 def is_executable (self , file ):
103104 # Check if the file is executable
104- return os .access (file , os . X_OK )
105+ return os .stat (file ). st_mode & stat . S_IXUSR
105106
106107 def set_env (self , var_name , var_val ):
107108 # Check if the directory is already in PATH
@@ -116,9 +117,12 @@ def get_name(self):
116117
117118 # Work with dirs
118119 def makedirs (self , path , remove_existing = False ):
119- if remove_existing and os .path .exists (path ):
120- shutil .rmtree (path )
121- os .makedirs (path , exist_ok = True )
120+ if remove_existing :
121+ shutil .rmtree (path , ignore_errors = True )
122+ try :
123+ os .makedirs (path )
124+ except FileExistsError :
125+ pass
122126
123127 def rmdirs (self , path , ignore_errors = True ):
124128 return rmtree (path , ignore_errors = ignore_errors )
@@ -141,7 +145,7 @@ def pathsep(self):
141145 return pathsep
142146
143147 def mkdtemp (self , prefix = None ):
144- return tempfile .mkdtemp (prefix = prefix )
148+ return tempfile .mkdtemp (prefix = '{}' . format ( prefix ) )
145149
146150 def mkstemp (self , prefix = None ):
147151 fd , filename = tempfile .mkstemp (prefix = prefix )
0 commit comments