mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-11 17:34:04 +01:00
Two levels of pure taxonomy carrying no information, and a 2-directory
cap leaves no room for them. Categories now sit directly under
linux_configuration/: features, fixes, utils, misc, fresh-install,
installers, diagnostics, gaming, boot_recovery, periodic_background, lib,
meta, tests. A script's own lib/ and tests/ are exempt from the cap, so
those stay put.
Depth violations 248 -> 139; roughly 40 of the remainder are inside
digital_wellbeing and hosts, deferred until the guard-lib repoint.
The moves are the easy half. What breaks is every path that counted
levels, and three classes of it had to be found by resolving paths rather
than reading diffs:
- 52 relative `source` lines for lib/common.sh and lib/android.sh. The
correct prefix differs per file: 40 were ../../ and 12 were ../../../,
so a blanket replace would have fixed one set and broken the other.
- REPO_ROOT in 7 fixes/lib/tests harnesses and setup_syncyomi_guard.sh,
each walking up four levels from a directory now two levels shallower.
This caused a real regression -- the fixes suite went red with
"log_warn: command not found" -- caught by running it and comparing
against the pre-move baseline worktree.
- conftest.py's sys.path entries, which took the pytest gate down with
14 collection errors, and the `# shellcheck source=` directives, which
took shellcheck down with SC1091.
16 symlinks in $HOME broke, including the entire i3blocks bar. All
repointed, and cpu_monitor/memory/disk/time/volume were run to confirm
they emit real output rather than merely resolving.
Verified: 1798 tests pass at 100% coverage, 8 of 9 lib/tests suites pass
(the ninth needs the coverage jail, identically at baseline), pre-commit
is clean, and the two untracked secret configs are still ignored after
their gitignore paths changed.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
204 lines
6.0 KiB
Bash
Executable File
204 lines
6.0 KiB
Bash
Executable File
#!/bin/bash
|
|
# Media discovery, archiving and the per-category moves.
|
|
#
|
|
# Sourced by organize_downloads.sh; split out to keep it under the 250-line cap.
|
|
# Sourced rather than run, so it inherits the caller's strict mode and
|
|
# the helper functions and variables defined above the source line.
|
|
|
|
# Function to find media files in a directory (non-recursive for home, avoid common system dirs)
|
|
find_media_files() {
|
|
local search_dir="$1"
|
|
local files=()
|
|
# Directories to exclude under Downloads
|
|
local -a EXCLUDES=(
|
|
".git" ".hg" ".svn" ".cache" "node_modules" "dist" "build" "out" "target" "coverage" "__pycache__" "venv" ".venv"
|
|
# previous staging dirs created by this script
|
|
".media_organize_" "media_organize_"
|
|
# too_big folder for oversized files
|
|
"too_big"
|
|
)
|
|
|
|
if [[ $search_dir == "$HOME_DIR" ]]; then
|
|
# For home directory, only check files directly in ~ (not subdirectories)
|
|
# Exclude common system/config directories
|
|
while IFS= read -r -d '' file; do
|
|
local basename
|
|
basename=$(basename "$file")
|
|
# Skip hidden files and common system directories
|
|
if [[ ! $basename =~ ^\. ]] && [[ -f $file ]]; then
|
|
if is_media_file "$file"; then
|
|
files+=("$file")
|
|
fi
|
|
fi
|
|
done < <(find "$search_dir" -maxdepth 1 -type f -print0 2>/dev/null)
|
|
else
|
|
# For Downloads, search recursively, pruning excluded directories
|
|
# Build prune expression
|
|
local prune_expr=()
|
|
for ex in "${EXCLUDES[@]}"; do
|
|
prune_expr+=(-name "$ex*" -o)
|
|
done
|
|
# Remove trailing -o
|
|
unset 'prune_expr[${#prune_expr[@]}-1]'
|
|
|
|
while IFS= read -r -d '' file; do
|
|
if is_media_file "$file"; then
|
|
files+=("$file")
|
|
fi
|
|
done < <(find "$search_dir" \( -type d \( "${prune_expr[@]}" \) -prune \) -o -type f -print0 2>/dev/null)
|
|
fi
|
|
|
|
printf '%s\n' "${files[@]}"
|
|
}
|
|
|
|
# Function to create timestamped zip archive
|
|
create_media_archive() {
|
|
local files=("$@")
|
|
|
|
if [[ ${#files[@]} -eq 0 ]]; then
|
|
log "No media files found to archive."
|
|
return 0
|
|
fi
|
|
|
|
# Create timestamp for archive name
|
|
local timestamp
|
|
timestamp=$(date '+%Y%m%d_%H%M%S')
|
|
local archive_name="media_archive_${timestamp}.zip"
|
|
local archive_path="$DOWNLOADS_DIR/$archive_name"
|
|
|
|
# Create temporary directory (fallback to /tmp if needed)
|
|
if ! mkdir -p "$TEMP_DIR" 2>/dev/null; then
|
|
TEMP_DIR="/tmp/media_organize_$$"
|
|
mkdir -p "$TEMP_DIR"
|
|
fi
|
|
|
|
# Ensure temp dir is cleaned up on function return; trap unsets itself after running
|
|
trap 'rm -rf "$TEMP_DIR" 2>/dev/null || true; trap - RETURN' RETURN
|
|
|
|
log "Found ${#files[@]} media files to archive."
|
|
log "Creating archive: $archive_path"
|
|
|
|
# Copy files to temp directory maintaining relative structure
|
|
local successfully_copied=()
|
|
local copy_errors=0
|
|
|
|
for file in "${files[@]}"; do
|
|
if [[ -f $file ]]; then
|
|
local relative_path=""
|
|
if [[ $file == "$DOWNLOADS_DIR"* ]]; then
|
|
relative_path="downloads/${file#"$DOWNLOADS_DIR"/}"
|
|
else
|
|
relative_path="home/${file#"$HOME_DIR"/}"
|
|
fi
|
|
|
|
local temp_file="$TEMP_DIR/$relative_path"
|
|
local temp_dir
|
|
temp_dir=$(dirname "$temp_file")
|
|
|
|
mkdir -p "$temp_dir"
|
|
# Check readability first to provide a clearer error
|
|
if [[ ! -r $file ]]; then
|
|
log "WARNING: Cannot read $file (permission denied?)"
|
|
((copy_errors++)) || true
|
|
continue
|
|
fi
|
|
|
|
# Attempt copy and capture any error for logging
|
|
local cp_err
|
|
if cp_err=$(cp -p "$file" "$temp_file" 2>&1); then
|
|
successfully_copied+=("$file")
|
|
else
|
|
# Surface the cp error so the user can see the reason
|
|
log "WARNING: Failed to copy $file -> $cp_err"
|
|
# Special hint for space issues
|
|
if echo "$cp_err" | grep -qi "No space left on device"; then
|
|
log "HINT: Not enough free space to stage files. Using $TEMP_DIR. Free up space or change TEMP_DIR."
|
|
fi
|
|
((copy_errors++)) || true
|
|
fi
|
|
fi
|
|
done
|
|
|
|
if [[ ${#successfully_copied[@]} -eq 0 ]]; then
|
|
log "ERROR: No files were successfully copied to temp directory."
|
|
rm -rf "$TEMP_DIR"
|
|
return 1
|
|
fi
|
|
|
|
if [[ $copy_errors -gt 0 ]]; then
|
|
log "WARNING: $copy_errors files failed to copy."
|
|
fi
|
|
|
|
# Create zip archive with maximum compression
|
|
log "Creating zip archive with ${#successfully_copied[@]} files..."
|
|
cd "$TEMP_DIR"
|
|
if zip -9 -r "$archive_path" . 2>&1; then
|
|
log "Successfully created archive with ${#successfully_copied[@]} files."
|
|
|
|
# Verify the zip file was actually created and is not empty
|
|
if [[ ! -f $archive_path ]]; then
|
|
log "ERROR: Archive file was not created at $archive_path"
|
|
rm -rf "$TEMP_DIR"
|
|
return 1
|
|
fi
|
|
|
|
local archive_size
|
|
archive_size=$(stat -c%s "$archive_path" 2>/dev/null || echo "0")
|
|
if [[ $archive_size -eq 0 ]]; then
|
|
log "ERROR: Archive file is empty"
|
|
rm -rf "$TEMP_DIR"
|
|
return 1
|
|
fi
|
|
|
|
# Remove original files only if zip was successful
|
|
local removed_count=0
|
|
local remove_errors=0
|
|
|
|
log "Starting to remove ${#successfully_copied[@]} original files..."
|
|
|
|
# Temporarily disable strict error handling for file removal
|
|
set +e
|
|
|
|
for file in "${successfully_copied[@]}"; do
|
|
if [[ -f $file ]]; then
|
|
if rm "$file" 2>/dev/null; then
|
|
removed_count=$((removed_count + 1))
|
|
log "Removed: $(basename "$file")"
|
|
else
|
|
remove_errors=$((remove_errors + 1))
|
|
log "ERROR: Failed to remove $(basename "$file")"
|
|
fi
|
|
else
|
|
log "WARNING: File no longer exists: $(basename "$file")"
|
|
fi
|
|
done
|
|
|
|
# Re-enable strict error handling
|
|
set -e
|
|
|
|
log "Successfully removed $removed_count original files."
|
|
if [[ $remove_errors -gt 0 ]]; then
|
|
log "WARNING: Failed to remove $remove_errors files."
|
|
fi
|
|
log "Archive size: $(du -h "$archive_path" | cut -f1)"
|
|
|
|
# Cleanup temp directory (trap will also attempt, which is safe)
|
|
rm -rf "$TEMP_DIR"
|
|
|
|
# Return success only if we removed files or there were no files to remove
|
|
if [[ $removed_count -gt 0 ]] || [[ ${#successfully_copied[@]} -eq 0 ]]; then
|
|
return 0
|
|
else
|
|
log "ERROR: Failed to remove any files after successful archive creation."
|
|
return 1
|
|
fi
|
|
else
|
|
log "ERROR: Failed to create archive. Original files preserved."
|
|
log "Zip command failed."
|
|
rm -rf "$TEMP_DIR"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Main execution
|