Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

"""Utilities to call shell programs.""" 

 

import logging 

import os 

import subprocess 

 

from . import common 

from .exceptions import ShellError 

 

 

CMD_PREFIX = "$ " 

OUT_PREFIX = "> " 

 

log = logging.getLogger(__name__) 

 

 

def call(name, *args, _show=True, _shell=False, _ignore=False): 

"""Call a program with arguments. 

 

:param name: name of program to call 

:param args: list of command-line arguments 

:param _show: display the call on stdout 

:param _shell: force executing the program into a real shell 

a Windows shell command (i.e: dir, echo) needs a real shell 

but not a regular program (i.e: calc, git) 

:param _ignore: ignore non-zero return codes 

""" 

program = show(name, *args, stdout=_show) 

 

command = subprocess.run( 

name if _shell else [name, *args], universal_newlines=True, 

stdout=subprocess.PIPE, stderr=subprocess.STDOUT, 

shell=_shell 

) 

 

output = [line.strip() for line in command.stdout.splitlines()] 

for line in output: 

log.debug(OUT_PREFIX + line) 

 

if command.returncode == 0: 

return output 

 

if _ignore: 

log.debug("Ignored error from call to '%s'", name) 

return output 

 

message = ( 

"An external program call failed." + "\n\n" 

"In working directory: " + os.getcwd() + "\n\n" 

"The following command produced a non-zero return code:" + "\n\n" + 

CMD_PREFIX + program + "\n" + 

command.stdout.strip() 

) 

raise ShellError(message, program=program, output=output) 

 

 

def mkdir(path): 

58 ↛ exitline 58 didn't return from function 'mkdir', because the condition on line 58 was never false if not os.path.exists(path): 

59 ↛ 60line 59 didn't jump to line 60, because the condition on line 59 was never true if os.name == 'nt': 

call("mkdir " + path, _shell=True) 

else: 

call('mkdir', '-p', path) 

 

 

def cd(path, _show=True): 

66 ↛ 67line 66 didn't jump to line 67, because the condition on line 66 was never true if os.name == 'nt': 

show('cd', '/D', path, stdout=_show) 

else: 

show('cd', path, stdout=_show) 

os.chdir(path) 

 

 

def ln(source, target): 

74 ↛ 75line 74 didn't jump to line 75, because the condition on line 74 was never true if os.name == 'nt': 

log.warning("Symlinks are not supported on Windows") 

else: 

dirpath = os.path.dirname(target) 

if not os.path.isdir(dirpath): 

mkdir(dirpath) 

call('ln', '-s', source, target) 

 

 

def rm(path): 

84 ↛ 85line 84 didn't jump to line 85, because the condition on line 84 was never true if os.name == 'nt': 

if os.path.isfile(path): 

call("del /Q /F " + path, _shell=True) 

elif os.path.isdir(path): 

call("rmdir /Q /S " + path, _shell=True) 

else: 

call('rm', '-rf', path) 

 

 

def show(name, *args, stdout=True): 

program = ' '.join([name, *args]) 

if stdout: 

common.show(CMD_PREFIX + program, color='shell') 

else: 

log.debug(CMD_PREFIX + program) 

return program