-
Notifications
You must be signed in to change notification settings - Fork 0
/
pipper.sh
executable file
·231 lines (208 loc) · 7.63 KB
/
pipper.sh
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#!/bin/bash
set -e # Exit immediately if any command returns a non-zero exit status.
# Default name for the virtual environment
VENV_NAME="venv"
# Function to create a virtual environment.
# Accepts an optional Python interpreter version as an argument.
# Usage: create_venv [python-version]
# Example: create_venv python3.8
create_venv() {
local PYTHON
# If a specific Python interpreter is provided, use it.
if [ -n "$1" ]; then
# Check if the specified Python interpreter exists.
if command -v "$1" &>/dev/null; then
PYTHON="$1"
else
# Exit if the specified interpreter is not found.
echo "Error: Python interpreter '$1' not found."
exit 1
fi
# Automatically select a Python interpreter if none is provided.
elif command -v python3 &>/dev/null; then
PYTHON=python3
elif command -v python &>/dev/null; then
PYTHON=python
else
# Exit if no suitable Python interpreter is found.
echo "Error: Neither Python 3 nor Python is available."
exit 1
fi
# Attempt to create a virtual environment with the chosen interpreter.
if ! $PYTHON -m venv "$VENV_NAME"; then
echo "Error: Failed to create virtual environment with $PYTHON."
exit 1
fi
echo "Virtual environment '$VENV_NAME' created."
# Activate the newly created virtual environment.
printf "\n\n"
activate_venv false
}
# Function to launch a sub-shell with the virtual environment activated.
# Usage: launch_venv_shell
# Example: launch_venv_shell
launch_venv_shell() {
if [ -d "$VENV_NAME" ]; then
echo "Launching a sub-shell with the virtual environment activated..."
# Define a command to activate the venv
ACTIVATE_VENV="source $VENV_NAME/bin/activate"
# Define a new PS1 prompt including 'pipper', Python version, virtual environment name, and current directory
NEW_PS1="[pipper-shell python \$(python --version 2>&1 | cut -d ' ' -f 2) \$(basename $VENV_NAME)] \w \$"
# Define a custom greeting message
CUSTOM_GREETING=$'\nHello from pipper shell!'
# Start a new shell instance with the venv activated and new PS1
bash --init-file <(echo "$ACTIVATE_VENV; echo \"$CUSTOM_GREETING\"; export PS1=\"$NEW_PS1 \"")
else
echo "Virtual environment '$VENV_NAME' does not exist. Please create it first."
fi
}
# Function to activate the virtual environment.
# Accepts a boolean argument to decide whether to activate it immediately.
# Usage: activate_venv [true|false]
# Example: activate_venv true
activate_venv() {
local activate="$1"
if [ "$activate" = true ]; then
# Activate the virtual environment.
# shellcheck disable=SC1091
# Purpose: This directive is used to disable ShellCheck warning SC1091.
# Context: Warning SC1091 is triggered when ShellCheck encounters a 'source' or '.'
# command that includes a file not specified as input. This often happens
# when sourcing external scripts, such as activation scripts for virtual
# environments or other scripts that are not part of the project's repository.
# Reason for Disabling:
# - The files being sourced are dynamically generated (like Python virtualenv's 'activate' script),
# and not available for ShellCheck to analyze.
# - These files are standard and trusted, thus not posing a risk that necessitates ShellCheck analysis.
# - Disabling this warning allows us to use such scripts without ShellCheck flagging them as issues,
# keeping the focus on actual potential problems in the script's own code.
source "$VENV_NAME/bin/activate"
else
# Display instructions on how to activate the environment manually.
printf "\n\n"
echo " To activate the virtual environment, run:"
echo " pipper shell"
printf "\n\n"
fi
}
# Function to install Python dependencies from a requirements file.
# Usage: install_requirements
# Example: install_requirements
install_requirements() {
if [ -f "requirements.txt" ]; then
activate_venv true
pip install -r requirements.txt
echo "Requirements installed."
else
echo "requirements.txt not found."
fi
}
# Function to freeze current Python dependencies into a requirements file.
# Usage: freeze_requirements
# Example: freeze_requirements
freeze_requirements() {
activate_venv true
pip freeze > requirements.txt
echo "Requirements frozen into requirements.txt."
}
# Function to uninstall Python dependencies listed in a requirements file.
# Usage: uninstall_requirements
# Example: uninstall_requirements
uninstall_requirements() {
if [ -f "requirements.txt" ]; then
activate_venv true
pip uninstall -y -r requirements.txt
echo "Requirements uninstalled."
else
echo "requirements.txt not found."
fi
}
# Function to run a specified Python script within the virtual environment.
# Accepts the path to a Python script as an argument.
# Usage: run_script [script-path]
# Example: run_script my_file.py
run_script() {
if [ -f "$1" ]; then
activate_venv true
python "$1" # Execute the Python script
else
echo "Error: Script '$1' not found."
exit 1
fi
}
# Function to generate a command for running tests in dry-run mode.
# Accepts optional arguments for the source directory and pattern.
# Usage: run_tests_dry_run [source-dir] [pattern]
# Example: run_tests_dry_run test test*.py
run_tests_dry_run() {
local source_dir="${1:-test}"
local pattern="${2:-test*.py}"
local command="source $VENV_NAME/bin/activate && python -m unittest discover -s '$source_dir' -p '$pattern'"
# Return the generated command.
echo "$command"
}
# Function to execute unit tests within the virtual environment.
# Accepts optional arguments for the source directory, pattern, and echo flag.
# Usage: run_tests [source-dir] [pattern] [--echo]
# Example: run_tests test test*.py --echo
run_tests() {
local source_dir="${1:-test}"
local pattern="${2:-test*.py}"
local echo_flag=false
# Check if '--echo' flag is used to print the command instead of executing.
for arg in "$@"; do
if [ "$arg" = "--echo" ]; then
echo_flag=true
break
fi
done
# Check if the source directory for tests exists.
# This prevents unittest from potentially discovering and running tests outside of intended locations.
if [ ! -d "$source_dir" ]; then
echo "Error: Source directory '$source_dir' does not exist."
exit 1
fi
# Retrieve the command from run_tests_dry_run.
local command
command=$(run_tests_dry_run "$source_dir" "$pattern")
# Either echo the command or execute it, based on the flag.
if [ "$echo_flag" = true ]; then
echo "$command"
else
eval "$command"
fi
}
# Main command switch to execute the appropriate function based on input.
case $1 in
create)
create_venv "$2"
;;
shell)
launch_venv_shell
;;
activate)
activate_venv
;;
install)
install_requirements
;;
freeze)
freeze_requirements
;;
uninstall)
uninstall_requirements
;;
run)
run_script "$2"
;;
test)
run_tests "$2" "$3"
;;
test-dry-run)
run_tests_dry_run "$2" "$3"
;;
*)
# Note: "activate" is intentionally not included, as it is primarily for testing
echo "Usage: $0 {create|shell|install|freeze|uninstall|run|test|test-dry-run}"
;;
esac