|
#!/bin/bash |
|
|
|
clean_script=$(cat <<'EOF' |
|
#!/bin/bash |
|
|
|
# Define directories to clean |
|
declare -a dirs=( |
|
"$HOME/.vscode/extensions" |
|
"$HOME/.vscode-server/extensions" |
|
) |
|
|
|
# Get total disk capacity (using root / as example, modify mount point as needed) |
|
get_disk_total() { |
|
# Get total capacity of the disk partition where current directory resides |
|
local mount_point="/" # default to root directory |
|
if [ -d "$1" ]; then |
|
# Get mount point for specified directory |
|
mount_point=$(df "$1" | tail -1 | awk '{print $6}') |
|
fi |
|
# Get total disk capacity (bytes) |
|
df -B1 "$mount_point" | tail -1 | awk '{print $2}' |
|
} |
|
|
|
# Get current disk usage |
|
disk_total=$(get_disk_total "$HOME") |
|
human_disk_total=$(numfmt --to=iec $disk_total) |
|
|
|
# Table output functions |
|
print_header() { |
|
printf "+----------------------------------------+---------------------------------------------------------+-------------+\n" |
|
printf "| %-38s | %-55s | %-11s |\n" "Extension" "Version" "Size" |
|
printf "+----------------------------------------+---------------------------------------------------------+-------------+\n" |
|
} |
|
|
|
print_row() { |
|
local ext="$1" |
|
local version="$2" |
|
local size="$3" |
|
# Truncate long text |
|
if [ ${#ext} -gt 38 ]; then |
|
ext="${ext:0:35}..." |
|
fi |
|
if [ ${#version} -gt 55 ]; then |
|
version="${version:0:52}..." |
|
fi |
|
printf "| %-38s | %-55s | %-11s |\n" "$ext" "$version" "$size" |
|
} |
|
|
|
print_footer() { |
|
printf "+----------------------------------------+---------------------------------------------------------+-------------+\n" |
|
} |
|
|
|
echo "Total Disk Capacity: $human_disk_total" |
|
echo "" |
|
|
|
for dir in "${dirs[@]}"; do |
|
# Check if directory exists |
|
if [ ! -d "$dir" ]; then |
|
continue |
|
fi |
|
|
|
echo "========================================" |
|
echo "Processing: $dir" |
|
echo "========================================" |
|
|
|
cd "$dir" || { echo "Failed to enter directory: $dir"; continue; } |
|
|
|
# Get total size of directory before cleaning |
|
dir_size_before=$(du -sb "$dir" | cut -f1) |
|
|
|
# Get list of unique extension name prefixes (without version numbers) |
|
extensions=$(ls | rev | cut -d'-' -f2- | rev | uniq) |
|
|
|
# Initialize cleaning table counter |
|
cleaned_count=0 |
|
|
|
for ext in $extensions; do |
|
# Get all version directories for each extension, sorted (newest last) |
|
versions=$(ls | grep "^$ext" | sort -t. -k2,2V) |
|
count=$(echo "$versions" | wc -l) |
|
|
|
# If multiple versions exist, delete old ones |
|
if [ "$count" -gt 1 ]; then |
|
# Print table header for first cleaned extension |
|
if [ $cleaned_count -eq 0 ]; then |
|
echo "" |
|
echo "Cleaning Old Extension Versions:" |
|
print_header |
|
fi |
|
|
|
# Delete all old versions except the newest one |
|
old_versions=($(echo "$versions" | head -n $((count - 1)))) |
|
for old_version in "${old_versions[@]}"; do |
|
if [ -d "$old_version" ]; then |
|
# Calculate size of directory to be deleted |
|
size=$(du -sb "$old_version" | cut -f1) |
|
human_size=$(numfmt --to=iec $size) |
|
# Print table row |
|
print_row "$ext" "$old_version" "$human_size" |
|
rm -rf "$old_version" |
|
cleaned_count=$((cleaned_count + 1)) |
|
fi |
|
done |
|
fi |
|
done |
|
|
|
# Print table footer if any extensions were cleaned |
|
if [ $cleaned_count -gt 0 ]; then |
|
print_footer |
|
echo "Cleaned $cleaned_count old extension versions" |
|
echo "" |
|
else |
|
echo "No old versions need cleaning" |
|
echo "" |
|
fi |
|
|
|
# Calculate freed space as percentage of original directory size |
|
dir_size_after=$(du -sb "$dir" | cut -f1) |
|
dir_freed=$((dir_size_before - dir_size_after)) |
|
if [ "$dir_size_before" -gt 0 ]; then |
|
dir_percent=$(echo "$dir_freed $dir_size_before" | awk '{printf "%.3f", $1 * 100 / $2}') |
|
else |
|
dir_percent=0 |
|
fi |
|
|
|
# Calculate freed space as percentage of total disk capacity |
|
if [ "$disk_total" -gt 0 ]; then |
|
dir_disk_percent=$(echo "$dir_freed $disk_total" | awk '{printf "%.3f", $1 * 100 / $2}') |
|
else |
|
dir_disk_percent=0 |
|
fi |
|
|
|
echo "----------------------------------------" |
|
echo "Before: $(numfmt --to=iec $dir_size_before)" |
|
echo "After : $(numfmt --to=iec $dir_size_after)" |
|
echo "Free : $(numfmt --to=iec $dir_freed) (Directory: ${dir_percent}%, Disk: ${dir_disk_percent}%)" |
|
echo "Finish: $dir" |
|
echo |
|
done |
|
EOF |
|
) |
|
|
|
echo "$clean_script" | bash |
|
|
|
echo "" |
|
|
|
|
|
# --------------------------- |
|
# Clean Development Container Old Extension Versions |
|
# --------------------------- |
|
|
|
DOCKER_CMD="sudo docker" |
|
|
|
# Find matching containers |
|
CONTAINERS=$($DOCKER_CMD inspect --format='{{.Config.Image}} {{.Name}} {{.State.Status}}' $(sudo docker ps -aq) | column -t | grep -E 'vsc-.+-uid') |
|
|
|
if [[ -z "$CONTAINERS" ]]; then |
|
echo "No containers matching pattern 'vsc-.+-uid' found" |
|
exit 0 |
|
fi |
|
|
|
# Define command to execute in containers |
|
# Modify this to the command you need to execute |
|
EXEC_CMD="$clean_script" |
|
|
|
echo "Found matching containers:" |
|
echo "========================================" |
|
echo "$CONTAINERS" |
|
echo "========================================" |
|
echo "" |
|
|
|
# Process each container |
|
echo "$CONTAINERS" | while read LINE; do |
|
# Extract container name and status |
|
CONTAINER_NAME=$(echo $LINE | awk '{print $2}') |
|
CONTAINER_STATE=$(echo $LINE | awk '{print $3}') |
|
|
|
echo "----------------------------------------------------------------------------------------------------------------" |
|
echo "----------------------------------------------------------------------------------------------------------------" |
|
|
|
# Get devcontainer remoteUser |
|
remoteUser=$($DOCKER_CMD inspect --format='{{json .Config.Labels}}' "$CONTAINER_NAME" | grep -oE '\\"remoteUser\\":\\"[^"]*\\"' | sed 's/.*:\\"\([^"]*\)\\"/\1/' | tail -n 1) |
|
|
|
echo "Processing container: $CONTAINER_NAME (User: $remoteUser Status: $CONTAINER_STATE)" |
|
|
|
WAS_STOPPED=false |
|
|
|
# Check container status |
|
if [[ $CONTAINER_STATE == "exited" ]]; then |
|
if $DOCKER_CMD start "$CONTAINER_NAME" >/dev/null 2>&1; then |
|
WAS_STOPPED=true |
|
else |
|
echo " ❌ Failed to start container, skipping" |
|
continue |
|
fi |
|
fi |
|
|
|
# Execute command inside container |
|
$DOCKER_CMD exec --user "$remoteUser" "$CONTAINER_NAME" bash -c "$EXEC_CMD" |
|
|
|
# If container was originally stopped, stop it after execution |
|
if [[ "$WAS_STOPPED" == true ]]; then |
|
$DOCKER_CMD stop "$CONTAINER_NAME" >/dev/null 2>&1 || echo " ❌ Failed to stop container" |
|
fi |
|
|
|
echo "" |
|
done |
|
|
|
echo "All development containers processed!" |