-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhelpers.py
172 lines (138 loc) · 4.54 KB
/
helpers.py
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
import sys
import curses
import subprocess
def is_shell_installed(shell_name: str) -> bool:
"""
Check if the user's system has the compatible
chosen shell.
Parameters
----------
shell_name : str
Chosen shell name
Returns
-------
bool
Whether the chosen shell is installed on
the user's machine
"""
try:
# Run the shell with the "--version" option to check if it's installed
subprocess.check_call(
[shell_name, "--version"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
return True
except (OSError, subprocess.CalledProcessError):
return False
def is_system_compatible(possible_os_list: list[str]) -> bool:
"""
Check if the user's operating system is compatible with the
covered OS list for the project.
Parameters
----------
possible_os_list : List[str]
List of convered operating systems
Returns
-------
bool
Whether the system is compatible or not
"""
return any(
os_value.lower() in sys.platform.lower()
for os_value in possible_os_list
)
def user_input_confirmation(question: str, default: str = "yes") -> bool:
"""
Ask a yes/no question via input() and return the answer as a boolean value.
Parameters
----------
question : str
Question presented to the user in the prompt
default : str, optional
The presumed answer if the user just hits <Enter>, by default "yes"
The 'default' argument must be:
- "yes": <Enter> is interpreted as a yes,
- "no" or None: meaning an answer is required of the user
Returns
-------
bool
return True for "yes"
return False for "no"
Raises
------
ValueError
If the default parameter is neither a 'yes', 'no' or None,
raise a ValueError.
"""
# Initilize a yes/no value mapper
valid = {"yes": True, "y": True, "ye": True, "no": False, "n": False}
if default == "yes":
prompt = " [Y/n] "
elif default == "no":
prompt = " [y/N] "
else:
raise ValueError("invalid default answer: '%s'" % default)
while True:
choice = input(question + prompt).strip().lower()
if default is not None and choice == "":
return valid[default]
elif choice in valid:
return valid[choice]
else:
print("Please respond with 'yes' or 'no' (or 'y' or 'n').")
def pick_shell(stdscr, options: list, title: str):
# Clear the screen
stdscr.clear()
# Initialize the curses settings
curses.curs_set(0)
stdscr.nodelay(1)
stdscr.keypad(1)
stdscr.timeout(100)
# Initialize the selected options list
selected_options = []
# Initialize the current position of the selection
current_position = 0
while True:
# Clear the screen
stdscr.clear()
# Print the title
stdscr.addstr(0, 0, title, curses.A_BOLD)
# Print the menu options
for i, option in enumerate(options):
if option in selected_options:
stdscr.addstr(i + 2, 4, "[x] " + option, curses.A_REVERSE)
else:
stdscr.addstr(i + 2, 4, "[ ] " + option)
# Display arrow indicator on the current selection
if i == current_position:
stdscr.addstr(i + 2, 0, "->", curses.A_REVERSE)
# Refresh the screen to display changes
stdscr.refresh()
# Wait for user input
key = stdscr.getch()
# Handle user input
if key == ord("q"):
return None
elif key == curses.KEY_UP:
# Move the selection up
current_position -= 1
if current_position < 0:
current_position = len(options) - 1
elif key == curses.KEY_DOWN:
# Move the selection down
current_position += 1
if current_position >= len(options):
current_position = 0
elif key == ord(" "):
# Toggle the selection of the current option
current_option = options[current_position]
if current_option in selected_options:
selected_options.remove(current_option)
else:
selected_options.append(current_option)
elif key == curses.KEY_ENTER or key == 10 or key == 13:
# Process ENTER key to finish selection
if len(selected_options) > 0:
break
return selected_options