forked from Shinonome/alt-illogical-impulse
224 lines
8.2 KiB
Bash
Executable File
224 lines
8.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Dynamic qmldir generator for quickshell configurations
|
|
# This script automatically generates qmldir files based on actual QML files present
|
|
|
|
set -euo pipefail
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
log() {
|
|
echo -e "${GREEN}[qmldir-gen]${NC} $1" >&2
|
|
}
|
|
|
|
warn() {
|
|
echo -e "${YELLOW}[qmldir-gen]${NC} WARNING: $1" >&2
|
|
}
|
|
|
|
error() {
|
|
echo -e "${RED}[qmldir-gen]${NC} ERROR: $1" >&2
|
|
}
|
|
|
|
# Function to check if a QML file is a singleton
|
|
is_singleton() {
|
|
local file="$1"
|
|
grep -q "pragma Singleton" "$file" 2>/dev/null
|
|
}
|
|
|
|
# Function to generate qmldir for a directory
|
|
generate_qmldir() {
|
|
local dir="$1"
|
|
local module_name="$2"
|
|
local qmldir_file="$dir/qmldir"
|
|
|
|
if [[ ! -d "$dir" ]]; then
|
|
warn "Directory $dir does not exist, skipping"
|
|
return 0
|
|
fi
|
|
|
|
log "Generating qmldir for $dir (module: $module_name)"
|
|
|
|
# Start with module declaration
|
|
echo "module $module_name" > "$qmldir_file"
|
|
echo "" >> "$qmldir_file"
|
|
|
|
# Find all QML files and add them
|
|
local count=0
|
|
local singleton_count=0
|
|
while IFS= read -r -d '' file; do
|
|
local basename=$(basename "$file" .qml)
|
|
# Skip files that start with lowercase (usually internal components)
|
|
if [[ "$basename" =~ ^[A-Z] ]]; then
|
|
if is_singleton "$file"; then
|
|
echo "singleton $basename 1.0 $(basename "$file")" >> "$qmldir_file"
|
|
((singleton_count++))
|
|
else
|
|
echo "$basename 1.0 $(basename "$file")" >> "$qmldir_file"
|
|
fi
|
|
((count++))
|
|
fi
|
|
done < <(find "$dir" -maxdepth 1 -name "*.qml" -type f -print0 | sort -z) || true
|
|
|
|
log " → Registered $count components ($singleton_count singletons) in $qmldir_file"
|
|
}
|
|
|
|
# Main function
|
|
main() {
|
|
local quickshell_dir="${1:-$HOME/.config/quickshell/ii}"
|
|
|
|
if [[ ! -d "$quickshell_dir" ]]; then
|
|
error "Quickshell directory $quickshell_dir does not exist"
|
|
exit 1
|
|
fi
|
|
|
|
log "Generating qmldir files for quickshell configuration at $quickshell_dir"
|
|
|
|
# Generate main qmldir (root level components)
|
|
log "Processing root directory..."
|
|
generate_qmldir "$quickshell_dir" "qs"
|
|
|
|
# Copy main qmldir to qs subdirectory for proper module resolution
|
|
if [[ -f "$quickshell_dir/qmldir" && -d "$quickshell_dir/qs" ]]; then
|
|
log "Copying main qmldir to qs subdirectory for module resolution..."
|
|
cp "$quickshell_dir/qmldir" "$quickshell_dir/qs/qmldir"
|
|
log " → Main qmldir copied to qs/qmldir"
|
|
|
|
# Also copy the root-level QML files that are referenced in the qmldir
|
|
log "Copying root-level QML files to qs subdirectory..."
|
|
while IFS= read -r qml_file; do
|
|
if [[ -f "$quickshell_dir/$qml_file" ]]; then
|
|
cp "$quickshell_dir/$qml_file" "$quickshell_dir/qs/$qml_file"
|
|
log " → Copied $qml_file to qs/$qml_file"
|
|
fi
|
|
done < <(grep "\.qml$" "$quickshell_dir/qmldir" | awk '{print $NF}' || true)
|
|
fi
|
|
|
|
# Generate qmldir for modules directory
|
|
if [[ -d "$quickshell_dir/modules" ]]; then
|
|
log "Processing modules directory..."
|
|
generate_qmldir "$quickshell_dir/modules" "qs.modules"
|
|
|
|
# Generate qmldir for each module subdirectory
|
|
while IFS= read -r -d '' module_dir; do
|
|
local module_name=$(basename "$module_dir")
|
|
log "Processing module: $module_name"
|
|
generate_qmldir "$module_dir" "qs.modules.$module_name"
|
|
|
|
# Handle nested subdirectories (like common/functions, common/widgets)
|
|
while IFS= read -r -d '' nested_dir; do
|
|
local nested_name=$(basename "$nested_dir")
|
|
log "Processing nested module: $module_name/$nested_name"
|
|
generate_qmldir "$nested_dir" "qs.modules.$module_name.$nested_name"
|
|
done < <(find "$module_dir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z) || true
|
|
done < <(find "$quickshell_dir/modules" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
|
|
fi
|
|
|
|
# Generate qmldir for services directory
|
|
if [[ -d "$quickshell_dir/services" ]]; then
|
|
log "Processing services directory..."
|
|
generate_qmldir "$quickshell_dir/services" "qs.services"
|
|
|
|
# Generate qmldir for each service subdirectory
|
|
while IFS= read -r -d '' service_dir; do
|
|
local service_name=$(basename "$service_dir")
|
|
log "Processing service: $service_name"
|
|
generate_qmldir "$service_dir" "qs.services.$service_name"
|
|
done < <(find "$quickshell_dir/services" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
|
|
fi
|
|
|
|
# Generate qmldir for qs directory (if it exists)
|
|
if [[ -d "$quickshell_dir/qs" ]]; then
|
|
log "Processing qs directory..."
|
|
# Don't overwrite the main qmldir file we copied earlier
|
|
# Only generate qmldir for subdirectories of qs
|
|
|
|
# Generate qmldir for qs subdirectories
|
|
while IFS= read -r -d '' qs_subdir; do
|
|
local subdir_name=$(basename "$qs_subdir")
|
|
log "Processing qs/$subdir_name"
|
|
generate_qmldir "$qs_subdir" "qs.qs.$subdir_name"
|
|
|
|
# Handle nested qs subdirectories (like qs/modules/common, qs/services/ai)
|
|
while IFS= read -r -d '' nested_qs_dir; do
|
|
local nested_name=$(basename "$nested_qs_dir")
|
|
log "Processing nested qs: $subdir_name/$nested_name"
|
|
generate_qmldir "$nested_qs_dir" "qs.qs.$subdir_name.$nested_name"
|
|
|
|
# Handle deeply nested directories (like qs/modules/common/functions)
|
|
while IFS= read -r -d '' deep_nested_dir; do
|
|
local deep_name=$(basename "$deep_nested_dir")
|
|
log "Processing deep nested qs: $subdir_name/$nested_name/$deep_name"
|
|
generate_qmldir "$deep_nested_dir" "qs.qs.$subdir_name.$nested_name.$deep_name"
|
|
done < <(find "$nested_qs_dir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z) || true
|
|
done < <(find "$qs_subdir" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z) || true
|
|
done < <(find "$quickshell_dir/qs" -mindepth 1 -maxdepth 1 -type d -print0 | sort -z)
|
|
fi
|
|
|
|
log "✅ qmldir generation complete!"
|
|
log "📊 Summary:"
|
|
find "$quickshell_dir" -name "qmldir" -type f | while read -r qmldir_file; do
|
|
local component_count=$(grep -c "\.qml$" "$qmldir_file" || echo "0")
|
|
local singleton_count=$(grep -c "^singleton" "$qmldir_file" || echo "0")
|
|
local relative_path=${qmldir_file#$quickshell_dir/}
|
|
log " → $relative_path: $component_count components ($singleton_count singletons)"
|
|
done
|
|
}
|
|
|
|
# Help function
|
|
show_help() {
|
|
cat << EOF
|
|
Dynamic qmldir Generator for Quickshell
|
|
|
|
USAGE:
|
|
$(basename "$0") [QUICKSHELL_DIR]
|
|
|
|
ARGUMENTS:
|
|
QUICKSHELL_DIR Path to quickshell configuration directory
|
|
Default: \$HOME/.config/quickshell/ii
|
|
|
|
DESCRIPTION:
|
|
This script automatically generates qmldir files for quickshell configurations
|
|
by scanning for QML files and registering them appropriately. This ensures
|
|
that all components are properly registered and available for import.
|
|
|
|
The script handles:
|
|
- Root level components (ReloadPopup, etc.)
|
|
- Module components (bar, overview, etc.)
|
|
- Service components
|
|
- Nested subdirectories (functions, widgets, etc.)
|
|
- Automatic singleton detection via "pragma Singleton"
|
|
- Complex nested directory structures (qs/modules/common/functions)
|
|
|
|
Singleton Detection:
|
|
The script automatically detects QML files with "pragma Singleton" declarations
|
|
and registers them with the "singleton" keyword in qmldir files. This is
|
|
essential for proper Material You theming and service registration.
|
|
|
|
EXAMPLES:
|
|
# Generate for default location
|
|
$(basename "$0")
|
|
|
|
# Generate for custom location
|
|
$(basename "$0") /path/to/quickshell/config
|
|
|
|
# Use in automation
|
|
$(basename "$0") && quickshell -c ii
|
|
|
|
EOF
|
|
}
|
|
|
|
# Parse arguments
|
|
case "${1:-}" in
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
main "$@"
|
|
;;
|
|
esac
|