bashitup 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +145 -0
- package/bashitup.sh +389 -0
- package/bin/bashitup +4 -0
- package/package.json +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sudo-self
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the “Software”), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# bashitup
|
|
2
|
+
|
|
3
|
+
Interactive Bash menu system generator.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Repository
|
|
8
|
+
|
|
9
|
+
https://github.com/sudo-self/bashitup.sh.git
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
* Interactive CLI workflow
|
|
16
|
+
* ASCII banners using figlet
|
|
17
|
+
* Dynamic menu builder (add, edit, delete options)
|
|
18
|
+
* Optional logging and confirmation prompts
|
|
19
|
+
* Generates reusable Bash scripts
|
|
20
|
+
* Works on macOS and Linux
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
Install globally with npm:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g bashitup
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Run:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bashitup
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
This tool depends on `figlet`.
|
|
43
|
+
|
|
44
|
+
### macOS
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
brew install figlet
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Ubuntu / Debian
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
sudo apt install figlet
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Usage
|
|
59
|
+
|
|
60
|
+
Run the CLI:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
bashitup
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Follow the prompts to:
|
|
67
|
+
|
|
68
|
+
1. Set script name
|
|
69
|
+
2. Define banner text
|
|
70
|
+
3. Choose font
|
|
71
|
+
4. Configure options
|
|
72
|
+
5. Add menu items
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Example Output
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
./manager.sh
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Example menu:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
1) Update System
|
|
86
|
+
2) Install Dependencies
|
|
87
|
+
q) Exit
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Project Structure
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
bashitup/
|
|
96
|
+
├── bashitup.sh
|
|
97
|
+
├── bin/
|
|
98
|
+
│ └── bashitup
|
|
99
|
+
├── package.json
|
|
100
|
+
└── README.md
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Development
|
|
106
|
+
|
|
107
|
+
Clone the repository:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
git clone https://github.com/sudo-self/bashitup.sh.git
|
|
111
|
+
cd bashitup.sh
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
Link locally:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm link
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Run:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
bashitup
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Notes
|
|
129
|
+
|
|
130
|
+
* npm installs a global command (`bashitup`)
|
|
131
|
+
* No build step required
|
|
132
|
+
* Implemented entirely in Bash
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## License
|
|
137
|
+
|
|
138
|
+
MIT
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Contributing
|
|
143
|
+
|
|
144
|
+
Pull requests are welcome.
|
|
145
|
+
|
package/bashitup.sh
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# ScriptBuilder — Interactive Menu System Generator
|
|
3
|
+
# Builds fully-featured bash menu scripts interactively
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# --- COLORS & FORMATTING ---
|
|
8
|
+
GREEN='\033[0;32m'
|
|
9
|
+
CYAN='\033[0;36m'
|
|
10
|
+
YELLOW='\033[1;33m'
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
BLUE='\033[0;34m'
|
|
13
|
+
BOLD='\033[1m'
|
|
14
|
+
DIM='\033[2m'
|
|
15
|
+
NC='\033[0m'
|
|
16
|
+
|
|
17
|
+
# --- HELPERS ---
|
|
18
|
+
info() { echo -e "${CYAN} ▸ $*${NC}"; }
|
|
19
|
+
success() { echo -e "${GREEN} ✔ $*${NC}"; }
|
|
20
|
+
warn() { echo -e "${YELLOW} ⚠ $*${NC}"; }
|
|
21
|
+
error() { echo -e "${RED} ✖ $*${NC}"; }
|
|
22
|
+
divider() { echo -e "${DIM}────────────────────────────────────────────────────${NC}"; }
|
|
23
|
+
step() { echo -e "\n${BOLD}${YELLOW}[ Step $1 ] $2${NC}"; divider; }
|
|
24
|
+
|
|
25
|
+
# --- DEPENDENCY CHECK ---
|
|
26
|
+
check_deps() {
|
|
27
|
+
local missing=()
|
|
28
|
+
for cmd in figlet; do
|
|
29
|
+
command -v "$cmd" &>/dev/null || missing+=("$cmd")
|
|
30
|
+
done
|
|
31
|
+
if (( ${#missing[@]} > 0 )); then
|
|
32
|
+
error "Missing required tools: ${missing[*]}"
|
|
33
|
+
echo -e " Install with: ${CYAN}sudo apt install ${missing[*]}${NC} (Debian/Ubuntu)"
|
|
34
|
+
echo -e " or: ${CYAN}brew install ${missing[*]}${NC} (macOS)"
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# --- STARTUP LOGO ---
|
|
40
|
+
show_logo() {
|
|
41
|
+
clear
|
|
42
|
+
echo -e "${RED}"
|
|
43
|
+
cat << "EOF"
|
|
44
|
+
d8888b. .d8b. .d8888. db db d888888b d888888b db db d8888b.
|
|
45
|
+
88 `8D d8' `8b 88' YP 88 88 `88' `~~88~~' 88 88 88 `8D
|
|
46
|
+
88oooY' 88ooo88 `8bo. 88ooo88 88 88 88 88 88oodD'
|
|
47
|
+
88~~~b. 88~~~88 `Y8b. 88~~~88 88 88 88 88 88~~~
|
|
48
|
+
88 8D 88 88 db 8D 88 88 .88. 88 88b d88 88
|
|
49
|
+
Y8888P' YP YP `8888Y' YP YP Y888888P YP ~Y8888P' 88
|
|
50
|
+
|
|
51
|
+
EOF
|
|
52
|
+
echo -e "${DIM} >> github.com/sudo-self/bashitup.sh v2.0${NC}"
|
|
53
|
+
echo -e "${NC}"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# --- PROMPT WITH DEFAULT ---
|
|
57
|
+
# Usage: prompt_with_default VAR "Prompt text" "default value"
|
|
58
|
+
# Compatible with bash 3.2+ (no nameref)
|
|
59
|
+
prompt_with_default() {
|
|
60
|
+
local _var="$1"
|
|
61
|
+
local _prompt="$2"
|
|
62
|
+
local _default="${3:-}"
|
|
63
|
+
local _input=""
|
|
64
|
+
if [[ -n "$_default" ]]; then
|
|
65
|
+
read -rp " ${_prompt} [${_default}]: " _input
|
|
66
|
+
_input="${_input:-$_default}"
|
|
67
|
+
eval "${_var}=$(printf '%q' "$_input")"
|
|
68
|
+
else
|
|
69
|
+
while [[ -z "$_input" ]]; do
|
|
70
|
+
read -rp " ${_prompt}: " _input
|
|
71
|
+
[[ -z "$_input" ]] && warn "This field is required."
|
|
72
|
+
done
|
|
73
|
+
eval "${_var}=$(printf '%q' "$_input")"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# --- CONFIRM PROMPT ---
|
|
78
|
+
confirm() {
|
|
79
|
+
local msg="$1"
|
|
80
|
+
local default="${2:-y}"
|
|
81
|
+
local yn_hint="Y/n"
|
|
82
|
+
[[ "$default" == "n" ]] && yn_hint="y/N"
|
|
83
|
+
read -rp " ${msg} [${yn_hint}]: " answer
|
|
84
|
+
answer="${answer:-$default}"
|
|
85
|
+
# tr for bash 3.2 compat (no ${,,} lowercase expansion)
|
|
86
|
+
answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]')
|
|
87
|
+
[[ "$answer" == "y" ]]
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# --- FIGLET FONT PICKER ---
|
|
91
|
+
pick_figlet_font() {
|
|
92
|
+
local available_fonts
|
|
93
|
+
available_fonts=$(figlet -l 2>/dev/null | tr ' ' '\n' | grep -v '^$' | head -20 || echo "standard")
|
|
94
|
+
echo -e "\n${DIM} Available fonts (sample):${NC}"
|
|
95
|
+
local i=1
|
|
96
|
+
local font_list=()
|
|
97
|
+
while IFS= read -r font; do
|
|
98
|
+
font_list+=("$font")
|
|
99
|
+
printf " ${CYAN}%2d)${NC} %-20s" "$i" "$font"
|
|
100
|
+
(( i % 3 == 0 )) && echo
|
|
101
|
+
((i++))
|
|
102
|
+
done <<< "$available_fonts"
|
|
103
|
+
echo -e "\n"
|
|
104
|
+
read -rp " Choose font number (or press Enter for 'standard'): " font_choice
|
|
105
|
+
if [[ -n "$font_choice" && "$font_choice" =~ ^[0-9]+$ ]]; then
|
|
106
|
+
CHOSEN_FONT="${font_list[$((font_choice-1))]:-standard}"
|
|
107
|
+
else
|
|
108
|
+
CHOSEN_FONT="standard"
|
|
109
|
+
fi
|
|
110
|
+
info "Using font: ${CHOSEN_FONT}"
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# --- EDIT MENU ITEMS ---
|
|
114
|
+
edit_menu_items() {
|
|
115
|
+
while true; do
|
|
116
|
+
echo -e "\n${BOLD} Current menu items:${NC}"
|
|
117
|
+
if (( ${#MENU_LABELS[@]} == 0 )); then
|
|
118
|
+
echo -e " ${DIM}(none yet)${NC}"
|
|
119
|
+
else
|
|
120
|
+
for i in "${!MENU_LABELS[@]}"; do
|
|
121
|
+
echo -e " ${CYAN}$((i+1)))${NC} ${MENU_LABELS[$i]} ${DIM}→ ${MENU_COMMANDS[$i]}${NC}"
|
|
122
|
+
done
|
|
123
|
+
fi
|
|
124
|
+
echo
|
|
125
|
+
echo -e " ${GREEN}a)${NC} Add item ${YELLOW}e)${NC} Edit item ${RED}d)${NC} Delete item ${CYAN}done)${NC} Finish"
|
|
126
|
+
read -rp " Action: " action
|
|
127
|
+
action=$(echo "$action" | tr '[:upper:]' '[:lower:]')
|
|
128
|
+
case "$action" in
|
|
129
|
+
a|add)
|
|
130
|
+
echo -e "\n ${CYAN}Option #$((${#MENU_LABELS[@]}+1))${NC}"
|
|
131
|
+
label=""; cmd=""
|
|
132
|
+
prompt_with_default label "Label (e.g., Update System)"
|
|
133
|
+
prompt_with_default cmd "Command to run (e.g., sudo apt update)"
|
|
134
|
+
MENU_LABELS+=("$label")
|
|
135
|
+
MENU_COMMANDS+=("$cmd")
|
|
136
|
+
success "Added: ${label}"
|
|
137
|
+
;;
|
|
138
|
+
e|edit)
|
|
139
|
+
read -rp " Edit item number: " num
|
|
140
|
+
if [[ "$num" =~ ^[0-9]+$ ]] && (( num >= 1 && num <= ${#MENU_LABELS[@]} )); then
|
|
141
|
+
local idx=$((num-1))
|
|
142
|
+
new_label=""; new_cmd=""
|
|
143
|
+
prompt_with_default new_label "New label" "${MENU_LABELS[$idx]}"
|
|
144
|
+
prompt_with_default new_cmd "New command" "${MENU_COMMANDS[$idx]}"
|
|
145
|
+
MENU_LABELS[$idx]="$new_label"
|
|
146
|
+
MENU_COMMANDS[$idx]="$new_cmd"
|
|
147
|
+
success "Updated item $num."
|
|
148
|
+
else
|
|
149
|
+
warn "Invalid item number."
|
|
150
|
+
fi
|
|
151
|
+
;;
|
|
152
|
+
d|delete)
|
|
153
|
+
read -rp " Delete item number: " num
|
|
154
|
+
if [[ "$num" =~ ^[0-9]+$ ]] && (( num >= 1 && num <= ${#MENU_LABELS[@]} )); then
|
|
155
|
+
local idx=$((num-1))
|
|
156
|
+
warn "Removed: ${MENU_LABELS[$idx]}"
|
|
157
|
+
MENU_LABELS=("${MENU_LABELS[@]:0:$idx}" "${MENU_LABELS[@]:$((idx+1))}")
|
|
158
|
+
MENU_COMMANDS=("${MENU_COMMANDS[@]:0:$idx}" "${MENU_COMMANDS[@]:$((idx+1))}")
|
|
159
|
+
else
|
|
160
|
+
warn "Invalid item number."
|
|
161
|
+
fi
|
|
162
|
+
;;
|
|
163
|
+
done|"")
|
|
164
|
+
if (( ${#MENU_LABELS[@]} == 0 )); then
|
|
165
|
+
warn "You need at least one menu item."
|
|
166
|
+
else
|
|
167
|
+
break
|
|
168
|
+
fi
|
|
169
|
+
;;
|
|
170
|
+
*)
|
|
171
|
+
warn "Unknown action."
|
|
172
|
+
;;
|
|
173
|
+
esac
|
|
174
|
+
done
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
# --- GENERATE SCRIPT ---
|
|
178
|
+
generate_script() {
|
|
179
|
+
local filename="$1"
|
|
180
|
+
local banner_text="$2"
|
|
181
|
+
local intro_msg="$3"
|
|
182
|
+
local font="$4"
|
|
183
|
+
local log_enabled="$5"
|
|
184
|
+
local confirm_enabled="$6"
|
|
185
|
+
|
|
186
|
+
local generated_art
|
|
187
|
+
generated_art=$(figlet -f "$font" "$banner_text" 2>/dev/null || figlet "$banner_text")
|
|
188
|
+
|
|
189
|
+
cat > "$filename" << 'SCRIPT_HEADER'
|
|
190
|
+
#!/bin/bash
|
|
191
|
+
# Generated by ScriptBuilder v2.0
|
|
192
|
+
# DO NOT EDIT THE HEADER — re-run scriptbuilder to regenerate
|
|
193
|
+
|
|
194
|
+
set -euo pipefail
|
|
195
|
+
trap 'echo -e "\n${RED}Unexpected error on line $LINENO. Exiting.${NC}"; exit 1' ERR
|
|
196
|
+
|
|
197
|
+
# --- COLORS ---
|
|
198
|
+
CYAN='\033[0;36m'
|
|
199
|
+
GREEN='\033[0;32m'
|
|
200
|
+
YELLOW='\033[1;33m'
|
|
201
|
+
RED='\033[0;31m'
|
|
202
|
+
BOLD='\033[1m'
|
|
203
|
+
DIM='\033[2m'
|
|
204
|
+
NC='\033[0m'
|
|
205
|
+
|
|
206
|
+
SCRIPT_HEADER
|
|
207
|
+
|
|
208
|
+
# Inject runtime config
|
|
209
|
+
cat >> "$filename" << SCRIPT_CONFIG
|
|
210
|
+
# --- RUNTIME CONFIG ---
|
|
211
|
+
LOG_ENABLED="${log_enabled}"
|
|
212
|
+
CONFIRM_ACTIONS="${confirm_enabled}"
|
|
213
|
+
LOG_FILE="\${HOME}/.$(basename "${filename}" .sh).log"
|
|
214
|
+
SCRIPT_CONFIG
|
|
215
|
+
|
|
216
|
+
# Inject generated art as a variable (safer than heredoc in generated code)
|
|
217
|
+
{
|
|
218
|
+
echo ""
|
|
219
|
+
echo "# --- BANNER ART ---"
|
|
220
|
+
echo "BANNER_ART=$(printf '%q' "$generated_art")"
|
|
221
|
+
echo ""
|
|
222
|
+
} >> "$filename"
|
|
223
|
+
|
|
224
|
+
cat >> "$filename" << 'SCRIPT_FUNCS'
|
|
225
|
+
# --- LOGGING ---
|
|
226
|
+
log() {
|
|
227
|
+
if [[ "$LOG_ENABLED" == "true" ]]; then
|
|
228
|
+
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE"
|
|
229
|
+
fi
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
# --- BANNER ---
|
|
233
|
+
show_banner() {
|
|
234
|
+
clear
|
|
235
|
+
echo -e "${CYAN}"
|
|
236
|
+
echo "$BANNER_ART"
|
|
237
|
+
echo -e "${NC}"
|
|
238
|
+
SCRIPT_FUNCS
|
|
239
|
+
|
|
240
|
+
echo " echo -e \"\${YELLOW}${intro_msg}\${NC}\"" >> "$filename"
|
|
241
|
+
echo " echo -e \"\${DIM}────────────────────────────────────────────────────\${NC}\"" >> "$filename"
|
|
242
|
+
echo "}" >> "$filename"
|
|
243
|
+
|
|
244
|
+
cat >> "$filename" << 'SCRIPT_MENU_START'
|
|
245
|
+
|
|
246
|
+
# --- MENU ---
|
|
247
|
+
show_menu() {
|
|
248
|
+
show_banner
|
|
249
|
+
echo -e " ${BOLD}Please choose an option:${NC}\n"
|
|
250
|
+
SCRIPT_MENU_START
|
|
251
|
+
|
|
252
|
+
for i in "${!MENU_LABELS[@]}"; do
|
|
253
|
+
printf " echo -e \" ${CYAN}%d)${NC} %s\"\n" "$((i+1))" "${MENU_LABELS[$i]}" >> "$filename"
|
|
254
|
+
done
|
|
255
|
+
echo " echo -e \" \${DIM}────────────────\${NC}\"" >> "$filename"
|
|
256
|
+
echo " echo -e \" q) Exit\"" >> "$filename"
|
|
257
|
+
echo "}" >> "$filename"
|
|
258
|
+
|
|
259
|
+
cat >> "$filename" << 'SCRIPT_LOOP'
|
|
260
|
+
|
|
261
|
+
# --- RUN COMMAND WITH OPTIONAL CONFIRM ---
|
|
262
|
+
run_cmd() {
|
|
263
|
+
local label="$1"
|
|
264
|
+
local cmd="$2"
|
|
265
|
+
if [[ "$CONFIRM_ACTIONS" == "true" ]]; then
|
|
266
|
+
read -rp " Run '${label}'? [Y/n]: " yn
|
|
267
|
+
yn="${yn:-y}"
|
|
268
|
+
[[ "${yn,,}" != "y" ]] && echo " Skipped." && return
|
|
269
|
+
fi
|
|
270
|
+
log "Running: $label ($cmd)"
|
|
271
|
+
echo -e "${CYAN} ▸ Executing: ${label}...${NC}"
|
|
272
|
+
echo ""
|
|
273
|
+
if eval "$cmd"; then
|
|
274
|
+
log "Success: $label"
|
|
275
|
+
echo -e "\n${GREEN} ✔ Done.${NC}"
|
|
276
|
+
else
|
|
277
|
+
log "Failed: $label (exit $?)"
|
|
278
|
+
echo -e "\n${RED} ✖ Command exited with an error.${NC}"
|
|
279
|
+
fi
|
|
280
|
+
echo ""
|
|
281
|
+
read -rp " Press Enter to continue..."
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
# --- MAIN LOOP ---
|
|
285
|
+
while true; do
|
|
286
|
+
show_menu
|
|
287
|
+
echo ""
|
|
288
|
+
read -rp " Selection: " choice
|
|
289
|
+
case "$choice" in
|
|
290
|
+
SCRIPT_LOOP
|
|
291
|
+
|
|
292
|
+
for i in "${!MENU_COMMANDS[@]}"; do
|
|
293
|
+
printf ' %d)\n' "$((i+1))" >> "$filename"
|
|
294
|
+
printf ' run_cmd %q %q\n' "${MENU_LABELS[$i]}" "${MENU_COMMANDS[$i]}" >> "$filename"
|
|
295
|
+
printf ' ;;\n' >> "$filename"
|
|
296
|
+
done
|
|
297
|
+
|
|
298
|
+
cat >> "$filename" << 'SCRIPT_FOOTER'
|
|
299
|
+
q|Q)
|
|
300
|
+
echo -e "\n Goodbye!\n"
|
|
301
|
+
log "Session ended."
|
|
302
|
+
exit 0
|
|
303
|
+
;;
|
|
304
|
+
*)
|
|
305
|
+
echo -e "${RED} Invalid option: '$choice'${NC}"
|
|
306
|
+
sleep 1
|
|
307
|
+
;;
|
|
308
|
+
esac
|
|
309
|
+
done
|
|
310
|
+
SCRIPT_FOOTER
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
# ============================================================
|
|
314
|
+
# MAIN
|
|
315
|
+
# ============================================================
|
|
316
|
+
check_deps
|
|
317
|
+
show_logo
|
|
318
|
+
|
|
319
|
+
# --- STEP 1: SCRIPT INFO ---
|
|
320
|
+
step 1 "Script Info"
|
|
321
|
+
|
|
322
|
+
FILENAME=""
|
|
323
|
+
prompt_with_default FILENAME "Output filename (without .sh)" "manager"
|
|
324
|
+
[[ "$FILENAME" != *.sh ]] && FILENAME="${FILENAME}.sh"
|
|
325
|
+
|
|
326
|
+
# Warn if file exists
|
|
327
|
+
if [[ -f "$FILENAME" ]]; then
|
|
328
|
+
warn "File '${FILENAME}' already exists."
|
|
329
|
+
confirm "Overwrite it?" || { info "Aborted."; exit 0; }
|
|
330
|
+
fi
|
|
331
|
+
|
|
332
|
+
BANNER_TEXT=""
|
|
333
|
+
prompt_with_default BANNER_TEXT "Banner text (ASCII art)"
|
|
334
|
+
|
|
335
|
+
INTRO_MSG=""
|
|
336
|
+
prompt_with_default INTRO_MSG "Welcome / intro message" "Welcome to your script"
|
|
337
|
+
|
|
338
|
+
# --- STEP 2: FONT ---
|
|
339
|
+
step 2 "Banner Font"
|
|
340
|
+
if confirm "Pick a figlet font interactively?" "n"; then
|
|
341
|
+
pick_figlet_font
|
|
342
|
+
else
|
|
343
|
+
CHOSEN_FONT="standard"
|
|
344
|
+
info "Using default font: standard"
|
|
345
|
+
fi
|
|
346
|
+
|
|
347
|
+
# --- STEP 3: OPTIONS ---
|
|
348
|
+
step 3 "Script Options"
|
|
349
|
+
|
|
350
|
+
LOG_ENABLED="false"
|
|
351
|
+
confirm "Enable action logging to ~/.$(basename "$FILENAME" .sh).log?" "n" && LOG_ENABLED="true"
|
|
352
|
+
|
|
353
|
+
CONFIRM_ENABLED="false"
|
|
354
|
+
confirm "Prompt for confirmation before each action?" "n" && CONFIRM_ENABLED="true"
|
|
355
|
+
|
|
356
|
+
# --- STEP 4: MENU ITEMS ---
|
|
357
|
+
step 4 "Menu Items"
|
|
358
|
+
MENU_LABELS=()
|
|
359
|
+
MENU_COMMANDS=()
|
|
360
|
+
info "Add your menu items. You can also edit/delete them."
|
|
361
|
+
edit_menu_items
|
|
362
|
+
|
|
363
|
+
# --- PREVIEW ---
|
|
364
|
+
echo ""
|
|
365
|
+
step 5 "Preview & Generate"
|
|
366
|
+
echo -e " ${BOLD}Summary:${NC}"
|
|
367
|
+
echo -e " ${DIM}File:${NC} ${YELLOW}${FILENAME}${NC}"
|
|
368
|
+
echo -e " ${DIM}Banner:${NC} ${CYAN}${BANNER_TEXT}${NC} (font: ${CHOSEN_FONT})"
|
|
369
|
+
echo -e " ${DIM}Intro:${NC} ${INTRO_MSG}"
|
|
370
|
+
echo -e " ${DIM}Logging:${NC} ${LOG_ENABLED} ${DIM}Confirm actions:${NC} ${CONFIRM_ENABLED}"
|
|
371
|
+
echo -e " ${DIM}Items:${NC} ${#MENU_LABELS[@]}"
|
|
372
|
+
for i in "${!MENU_LABELS[@]}"; do
|
|
373
|
+
echo -e " ${CYAN}$((i+1)))${NC} ${MENU_LABELS[$i]} ${DIM}→ ${MENU_COMMANDS[$i]}${NC}"
|
|
374
|
+
done
|
|
375
|
+
echo ""
|
|
376
|
+
|
|
377
|
+
confirm "Generate '${FILENAME}'?" || { info "Aborted."; exit 0; }
|
|
378
|
+
|
|
379
|
+
generate_script "$FILENAME" "$BANNER_TEXT" "$INTRO_MSG" "$CHOSEN_FONT" "$LOG_ENABLED" "$CONFIRM_ENABLED"
|
|
380
|
+
chmod +x "$FILENAME"
|
|
381
|
+
|
|
382
|
+
# --- DONE ---
|
|
383
|
+
echo ""
|
|
384
|
+
divider
|
|
385
|
+
success "Created ${YELLOW}${FILENAME}${NC}"
|
|
386
|
+
info "Run it now: ${CYAN}./${FILENAME}${NC}"
|
|
387
|
+
[[ "$LOG_ENABLED" == "true" ]] && info "Logs will be written to: ~/.$(basename "$FILENAME" .sh).log"
|
|
388
|
+
divider
|
|
389
|
+
echo ""
|
package/bin/bashitup
ADDED
package/package.json
ADDED