-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbcinit
More file actions
executable file
·443 lines (375 loc) · 14.1 KB
/
Copy pathbcinit
File metadata and controls
executable file
·443 lines (375 loc) · 14.1 KB
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#!/usr/bin/env bash
# bcinit - initialise bash_common
#
# Run once after cloning (and again after updates) to check and install
# everything bash_common needs: system tools (ffmpeg, ffprobe, mediainfo,
# wget, python3), Python packages in the local .venv, bundled completion scripts
# (git, brew, etc.), shell config in ~/.bash_profile / ~/.bashrc, and
# user config file ~/.bcconfig.
#
# Usage: bcinit [-c] [-h]
# -c check only; report what is missing without installing anything
# -h show this help
SCRIPTPATH=$( cd $(dirname $0) ; pwd -P )
source "$SCRIPTPATH/commands/helpers.sh"
source "$SCRIPTPATH/commands/colour.sh"
CHECK_ONLY=0
usage() {
echo "Usage: $(basename $0) [-c] [-h]"
echo " -c check only; report what is missing without installing"
echo " -h show this help"
}
while getopts "ch" OPT; do
case "${OPT}" in
c) CHECK_ONLY=1 ;;
h) usage; exit 0 ;;
*) usage; exit 1 ;;
esac
done
# Detect platform (mirrors .bashrc logic, but standalone so BC_SYSTEM may not be set yet)
case "$(uname -s)" in
Darwin) PLATFORM=darwin ;;
CYGWIN*) PLATFORM=cygwin ;;
*) PLATFORM=unix ;;
esac
# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------
MISSING_SYS=()
MISSING_VENV_PY=()
SHELL_CONFIG_WARNINGS=()
MISSING_CFG=0
BCCFG="$HOME/.bccfg"
BCCONFIG="$HOME/.bcconfig"
BC_VENV="$SCRIPTPATH/.venv"
BC_VENV_PY="$BC_VENV/bin/python"
BC_REQUIREMENTS="$SCRIPTPATH/requirements.txt"
check_sys() {
local cmd=$1
if command_exists "$cmd"; then
colecho -green " [ok] " -normal "$cmd"
else
colecho -red " [missing] " -normal "$cmd"
MISSING_SYS+=("$cmd")
fi
}
_venv_ok() {
# Returns true only if the venv Python is a real, working executable.
# Catches dead symlinks, wrong-Python rebuilds, and missing interpreters.
[ -x "$BC_VENV_PY" ] && "$BC_VENV_PY" -c "import sys; sys.exit(0)" 2>/dev/null
}
check_venv_py() {
local pkg=$1
local import_name=${2:-$1}
if _venv_ok && "$BC_VENV_PY" -c "import $import_name" 2>/dev/null; then
colecho -green " [ok] " -normal "venv: $pkg"
else
colecho -red " [missing] " -normal "venv: $pkg"
MISSING_VENV_PY+=("$pkg")
fi
}
check_shell_sources() {
# check_shell_sources FILE PATTERN "line to add if missing"
local file=$1
local pattern=$2
local suggestion=$3
if [ ! -f "$file" ]; then
colecho -red " [missing] " -normal "$file does not exist"
SHELL_CONFIG_WARNINGS+=("Create $file and add: $suggestion")
elif grep -qF "$pattern" "$file" 2>/dev/null; then
colecho -green " [ok] " -normal "$file sources $pattern"
else
colecho -ye " [warn] " -normal "$file — missing source for $pattern"
SHELL_CONFIG_WARNINGS+=("Add to $file: $suggestion")
fi
}
install_sys_darwin() {
if ! command_exists brew; then
colecho -red "Error:" -normal " brew not found. Install Homebrew first: https://brew.sh"
exit 1
fi
brew install "$@"
}
install_sys_unix() {
if command_exists apt-get; then
sudo apt-get install -y "$@"
elif command_exists dnf; then
sudo dnf install -y "$@"
elif command_exists pacman; then
sudo pacman -S --noconfirm "$@"
else
colecho -red "Error:" -normal " no supported package manager found (apt-get, dnf, pacman)"
exit 1
fi
}
# ---------------------------------------------------------------------------
# Check
# ---------------------------------------------------------------------------
colecho -cyan "bash_common dependency check"
echo ""
colecho -white "System tools:"
check_sys wget
check_sys python3
check_sys ffmpeg
check_sys mediainfo
# ffprobe is bundled with ffmpeg — check it but don't add as a separate install target
if command_exists ffprobe; then
colecho -green " [ok] " -normal "ffprobe (bundled with ffmpeg)"
elif command_exists ffmpeg; then
colecho -ye " [warn] " -normal "ffprobe not found despite ffmpeg being present — reinstall ffmpeg"
fi
# if ffmpeg is missing, ffprobe will be absent too and is fixed by installing ffmpeg
echo ""
colecho -white "Python packages (venv: $BC_VENV):"
if command_exists python3; then
if _venv_ok; then
colecho -green " [ok] " -normal "venv interpreter: $($BC_VENV_PY --version 2>&1)"
else
colecho -red " [broken] " -normal "venv interpreter — will be recreated"
MISSING_VENV_PY+=("__venv__")
fi
check_venv_py markdown2
check_venv_py Flask flask
else
colecho -ye " (skipping Python package checks: python3 not found)"
fi
# ---------------------------------------------------------------------------
# Shell config check
# ---------------------------------------------------------------------------
echo ""
colecho -white "Shell config (~/.bash_profile and ~/.bashrc):"
# ~/.bash_login must not exist — it prevents ~/.bash_profile being read on some systems
if [ -f "$HOME/.bash_login" ]; then
colecho -red " [warn] " -normal "~/.bash_login exists — this prevents ~/.bash_profile from loading"
SHELL_CONFIG_WARNINGS+=("Remove ~/.bash_login (or merge its contents into ~/.bash_profile)")
else
colecho -green " [ok] " -normal "~/.bash_login does not exist"
fi
# ~/.bash_profile must source bash_common .profile
check_shell_sources \
"$HOME/.bash_profile" \
"$SCRIPTPATH/.profile" \
"[ -f $SCRIPTPATH/.profile ] && source $SCRIPTPATH/.profile"
# ~/.bash_profile must source ~/.bashrc so interactive settings apply in login shells
check_shell_sources \
"$HOME/.bash_profile" \
".bashrc" \
"[ -f ~/.bashrc ] && source ~/.bashrc"
# ~/.bashrc must source bash_common .bashrc
check_shell_sources \
"$HOME/.bashrc" \
"$SCRIPTPATH/.bashrc" \
"[ -f $SCRIPTPATH/.bashrc ] && source $SCRIPTPATH/.bashrc"
if [ ${#SHELL_CONFIG_WARNINGS[@]} -gt 0 ]; then
echo ""
colecho -ye "Shell config actions needed:"
for warn in "${SHELL_CONFIG_WARNINGS[@]}"; do
colecho -ye " > " -normal "$warn"
done
fi
# ---------------------------------------------------------------------------
# User config (~/.bcconfig)
# ---------------------------------------------------------------------------
echo ""
colecho -white "User config:"
if [ -f "$BCCONFIG" ]; then
colecho -green " [ok] " -normal "$BCCONFIG"
elif [ -f "$BCCFG/video.ini" ]; then
colecho -ye " [migrate] " -normal "$BCCFG/video.ini → $BCCONFIG (will be migrated)"
MISSING_CFG=1
else
colecho -ye " [missing] " -normal "$BCCONFIG (will be created with defaults)"
MISSING_CFG=1
fi
# ---------------------------------------------------------------------------
# Install
# ---------------------------------------------------------------------------
if [ ${#MISSING_SYS[@]} -eq 0 ] && [ ${#MISSING_VENV_PY[@]} -eq 0 ] && [ ${#SHELL_CONFIG_WARNINGS[@]} -eq 0 ] && [ "$MISSING_CFG" -eq 0 ]; then
echo ""
colecho -green "All dependencies satisfied and shell config looks good."
exit 0
fi
# Shell config warnings are always informational — they never block the dep install
if [ ${#MISSING_SYS[@]} -eq 0 ] && [ ${#MISSING_VENV_PY[@]} -eq 0 ] && [ "$MISSING_CFG" -eq 0 ]; then
echo ""
colecho -green "All dependencies satisfied."
colecho -ye "Review shell config warnings above."
exit 1
fi
if [ "$CHECK_ONLY" -eq 1 ]; then
echo ""
colecho -ye "Check-only mode (-c). Run without -c to install missing dependencies."
exit 1
fi
echo ""
colecho -cyan "Installing missing dependencies..."
if [ ${#MISSING_SYS[@]} -gt 0 ]; then
echo ""
colecho -white "Installing system tools: ${MISSING_SYS[*]}"
case "$PLATFORM" in
darwin)
install_sys_darwin "${MISSING_SYS[@]}"
;;
unix)
install_sys_unix "${MISSING_SYS[@]}"
;;
cygwin)
colecho -ye " Cygwin: please install manually via the Cygwin setup tool: ${MISSING_SYS[*]}"
;;
esac
fi
if [ ${#MISSING_VENV_PY[@]} -gt 0 ]; then
echo ""
colecho -white "Setting up Python virtual environment..."
if [ -d "$BC_VENV" ] && ! _venv_ok; then
colecho -ye " [stale] " -normal "Removing broken venv and recreating with $(python3 --version 2>&1)..."
rm -rf "$BC_VENV"
fi
if [ ! -d "$BC_VENV" ]; then
colecho -white " Creating venv at $BC_VENV using $(python3 --version 2>&1)..."
python3 -m venv "$BC_VENV"
fi
# Remove the internal sentinel used for the broken-venv case
local real_pkgs=()
for pkg in "${MISSING_VENV_PY[@]}"; do
[ "$pkg" != "__venv__" ] && real_pkgs+=("$pkg")
done
"$BC_VENV_PY" -m pip install --quiet --upgrade pip
if [ -f "$BC_REQUIREMENTS" ]; then
colecho -white " Installing from requirements.txt..."
"$BC_VENV_PY" -m pip install -r "$BC_REQUIREMENTS"
elif [ ${#real_pkgs[@]} -gt 0 ]; then
colecho -white " Installing packages: ${real_pkgs[*]}"
"$BC_VENV_PY" -m pip install "${real_pkgs[@]}"
fi
fi
# ---------------------------------------------------------------------------
# User config file (~/.bcconfig)
# ---------------------------------------------------------------------------
echo ""
colecho -white "Writing user config..."
_write_bcconfig_defaults() {
python3 - "$BCCONFIG" "$BCCFG/video.ini" << 'WRITECFG'
import configparser, os, sys
bcconfig_path = sys.argv[1]
old_video_ini = sys.argv[2]
defaults = """\
# bash_common configuration (~/.bcconfig)
# Settings here apply globally; place .bcconfig files in project directories
# to override values for that directory tree (like .gitignore).
# Run `bcconfig` to see the effective settings for your current location.
[bash_common]
# Preferred text editor (used by bash_common helper commands).
editor = mate
[video]
# Default container format for `video convert` when -f is not specified.
# Supported: mp4, mkv, mov, webm
default_format = mp4
[video.convert]
# Video codec.
# mp4 / mkv / mov : libx264 (H.264) or libx265 (H.265, smaller files, slower)
# webm : libvpx-vp9
video_codec = libx264
# Encoding preset — trades encoding speed for compression efficiency.
# Faster presets produce larger files at the same quality level.
# Options: ultrafast superfast veryfast faster fast medium slow slower veryslow
video_preset = medium
# Constant Rate Factor — controls quality (lower = better quality, larger file).
# libx264 : 18 (high quality) to 28 (lower quality), sane default 23
# libx265 : 24-28 range, sane default 28
video_crf = 23
# Audio codec.
# mp4 / mkv / mov : aac or libmp3lame
# webm : libopus
audio_codec = aac
# Audio bitrate.
audio_bitrate = 128k
[video.thumb]
# Default timestamp for `video thumb` when -t is not specified.
# Use HH:MM:SS or a value in seconds. A few seconds in avoids black frames.
time = 00:00:05
[video.normalise]
# Target container format for `video normalise`.
format = mp4
# Target resolution. Videos are scaled to fit within this box (maintaining
# aspect ratio, padded with black bars).
target_width = 1280
target_height = 720
# Video and audio codecs — H.264/AAC gives maximum browser compatibility.
video_codec = libx264
audio_codec = aac
# Encoding quality and speed (see [video.convert] section for details).
video_preset = medium
video_crf = 23
audio_bitrate = 128k
# Where to move original files before transcoding.
# A per-project .bcconfig can override this to keep originals alongside the project.
original_dir = /tmp/video-originals
# Deinterlace interlaced / CRT-sourced footage using yadif.
# auto detect via ffprobe field_order and deinterlace if interlaced
# yes always deinterlace
# no never deinterlace
deinterlace = auto
"""
# Section mapping for migrating old ~/.bccfg/video.ini values
SECTION_MAP = {
"convert": "video.convert",
"normalise": "video.normalise",
"thumb": "video.thumb",
}
# Write the defaults file first
with open(bcconfig_path, "w", encoding="utf-8") as f:
f.write(defaults)
# If an old video.ini exists, overlay its values on top of the defaults
if os.path.isfile(old_video_ini):
old = configparser.RawConfigParser()
old.read(old_video_ini, encoding="utf-8")
new = configparser.RawConfigParser()
new.read(bcconfig_path, encoding="utf-8")
changed = False
for old_sec, new_sec in SECTION_MAP.items():
if old.has_section(old_sec):
for key, value in old.items(old_sec):
if new.has_section(new_sec):
new.set(new_sec, key, value)
changed = True
if changed:
with open(bcconfig_path, "w", encoding="utf-8") as f:
f.write(defaults)
# Re-read and rewrite preserving comments is complex;
# instead append a note that values were migrated
with open(bcconfig_path, "a", encoding="utf-8") as f:
f.write(f"\n# Values above were seeded from {old_video_ini}\n")
print("migrated")
else:
print("created")
else:
print("created")
WRITECFG
}
if [ -f "$BCCONFIG" ]; then
colecho -green " [ok] " -normal "$BCCONFIG (exists, not overwritten)"
else
result=$(_write_bcconfig_defaults)
if [ "$result" = "migrated" ]; then
colecho -green " [migrated] " -normal "$BCCONFIG (values from $BCCFG/video.ini)"
colecho -ye " [note] " -normal "$BCCFG/video.ini is no longer used and can be removed"
else
colecho -green " [created] " -normal "$BCCONFIG"
fi
fi
# ---------------------------------------------------------------------------
# Bundled completion scripts
# ---------------------------------------------------------------------------
echo ""
colecho -white "Downloading bundled completion scripts..."
if command_exists wget; then
wget -q https://raw.githubusercontent.com/git/git/master/contrib/completion/git-completion.bash \
-O "$SCRIPTPATH/completion/git.completion.bash" \
&& colecho -green " [ok] " -normal "git.completion.bash" \
|| colecho -red " [fail] " -normal "git.completion.bash (check network)"
else
colecho -ye " (skipping: wget not found — run bcinit again after installing wget)"
fi
echo ""
colecho -green "Done."