Coverage for mfutil/bash_wrapper.py: 96%

51 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-12-18 16:04 +0000

1import bash 

2 

3 

4class BashWrapperException(Exception): 

5 """Specific exception class for BashWrapper objects.""" 

6 

7 __message = None 

8 __bash_wrapper = None 

9 

10 def __init__(self, message, bash_wrapper=None): 

11 """Constructor. 

12 

13 Args: 

14 message (string): exception message 

15 bash_wrapper (BashWrapper): bash wrapper object 

16 

17 """ 

18 super(BashWrapperException, self).__init__(message) 

19 self.__message = message 

20 self.__bash_wrapper = bash_wrapper 

21 

22 def __repr__(self): 

23 if self.__bash_wrapper is not None: 

24 return "%s exception with message: %s and debug: %s" % \ 

25 (self.__class__.__name__, self.__message, self.__bash_wrapper) 

26 else: 

27 return Exception.__repr__(self) 

28 

29 def __str__(self): 

30 return self.__repr__() 

31 

32 

33class BashWrapper(object): 

34 """Bash command/output wrapper.""" 

35 

36 __bash_cmd = None 

37 __bash_result_object = None 

38 

39 def __init__(self, bash_cmd): 

40 """Constructor. 

41 

42 The constructor executes the given bash command and store result code 

43 and stdout/stderr inside the object. 

44 

45 You can use this object like this:: 

46 

47 bash_wrapper = BashWrapper("ls /tmp") 

48 if bash_wrapper: 

49 print("execution was ok (status_code == 0)") 

50 else: 

51 print("execution was not ok (status_code != 0)") 

52 status_code = bash_wrapper.code 

53 stdout_output = bash_wrapper.stdout 

54 stderr_output = bash_wrapper.stderr 

55 print("full representation with command/code/stdout/stderr: %s" % 

56 bash_wapper) 

57 

58 Args: 

59 bash_cmd (string): complete bash command to execute. 

60 

61 """ 

62 self.__bash_cmd = bash_cmd 

63 self.__bash_result_object = bash.bash(bash_cmd) 

64 

65 def __bool__(self): 

66 return (self.__bash_result_object.code == 0) 

67 

68 def __nonzero__(self): 

69 # python2 compatibility 

70 return self.__bool__() 

71 

72 @property 

73 def code(self): 

74 """Return the status code of the command as int (0 => ok).""" 

75 return self.__bash_result_object.code 

76 

77 @property 

78 def stdout(self): 

79 """Return the stdout output of the command stripped and utf8 decoded. 

80 

81 Returns: 

82 (string) stdout output (stripped and utf8 decoded). 

83 

84 """ 

85 return self.__bash_result_object.stdout.strip().decode('UTF-8') 

86 

87 @property 

88 def stderr(self): 

89 """Return the stderr output of the command stripped and utf8 decoded. 

90 

91 Returns: 

92 (string) stderr output (stripped and utf8 decoded). 

93 

94 """ 

95 return self.__bash_result_object.stderr.strip().decode('UTF-8') 

96 

97 def __repr__(self): 

98 result = [] 

99 result.append("") 

100 result.append("===== BASH COMMAND =======================") 

101 result.append(self.__bash_cmd) 

102 result.append("===== BASH RETURN CODE ===================") 

103 result.append(str(self.code)) 

104 stdout = self.stdout 

105 if stdout and len(stdout) > 0: 

106 result.append("===== BASH STDOUT ========================") 

107 result.append(self.stdout) 

108 stderr = self.stderr 

109 if stderr and len(stderr) > 0: 

110 result.append("===== BASH STDERR ========================") 

111 result.append(self.stderr) 

112 return "\n".join(result) 

113 

114 

115class BashWrapperOrRaise(BashWrapper): 

116 """BashWrapper subclass which raise an exception if status_code != 0.""" 

117 

118 def __init__(self, bash_cmd, exception_class=BashWrapperException, 

119 exception_msg="bad return code"): 

120 """Constructor. 

121 

122 The constructor executes the given bash command and store result code 

123 and stdout/stderr inside the object. 

124 

125 If the status_code is != 0, an exception is raised with all 

126 informations (stdout/stderr/code) inside. 

127 

128 If the status_code is 0, you can use this object like a BashWrapper 

129 one. 

130 

131 Example:: 

132 

133 try: 

134 x = BashWrapperOrRaise("ls /foo/bar") 

135 except BashWrapperException as e: 

136 print("exception with all details: %s" % e) 

137 else: 

138 # here, we have x.code == 0 

139 print("stdout: %s" % x.stdout) 

140 

141 Args: 

142 bash_cmd (string): complete bash command to execute. 

143 exception_class (BashWrapperException): exception class to raise 

144 in case of status_code !=0 (must be a subclass of 

145 BashWrapperException). 

146 exception_msg (string): exception message in case of 

147 status_code != 0. 

148 

149 """ 

150 super(BashWrapperOrRaise, self).__init__(bash_cmd) 

151 if self.code != 0: 

152 raise exception_class(exception_msg, self)