mirror of
https://codeberg.org/muon/home.git
synced 2026-07-04 07:59:33 +00:00
250 lines
8.7 KiB
Nix
250 lines
8.7 KiB
Nix
{
|
||
lib,
|
||
writeShellApplication,
|
||
nvfetcher,
|
||
nix,
|
||
gnused,
|
||
coreutils,
|
||
}:
|
||
writeShellApplication {
|
||
name = "nvft";
|
||
|
||
runtimeInputs = [
|
||
nvfetcher
|
||
nix
|
||
gnused
|
||
coreutils
|
||
];
|
||
|
||
text = ''
|
||
set -euo pipefail
|
||
|
||
# Determine the config directory
|
||
if [[ -n "''${NVFETCHER_CONFIG_DIR:-}" ]]; then
|
||
CONFIG_DIR="$NVFETCHER_CONFIG_DIR"
|
||
elif [[ -f "nvfetcher.toml" ]]; then
|
||
CONFIG_DIR="$(pwd)"
|
||
else
|
||
CONFIG_DIR="''${HOME}/.config/home"
|
||
fi
|
||
|
||
if [[ ! -f "$CONFIG_DIR/nvfetcher.toml" ]]; then
|
||
echo "❌ Error: nvfetcher.toml not found in $CONFIG_DIR"
|
||
exit 1
|
||
fi
|
||
|
||
echo "🚀 Updating sources in $CONFIG_DIR"
|
||
echo ""
|
||
|
||
SOURCES_FILE="$CONFIG_DIR/_sources/generated.nix"
|
||
|
||
# Read Go packages from nvfetcher.toml that need vendorHash updates
|
||
declare -A GO_PACKAGES
|
||
# For now, hardcode the known Go packages
|
||
# TODO: Could parse nvfetcher.toml to auto-detect these
|
||
GO_PACKAGES["mender-cli"]="modules/home/terminal/hr/mender-cli.nix"
|
||
|
||
# Step 0: Save existing hashes before nvfetcher wipes them
|
||
echo "💾 Saving existing hashes..."
|
||
declare -A SAVED_VENDOR_HASHES
|
||
declare -A SAVED_SOURCE_HASHES
|
||
|
||
if [[ -f "$SOURCES_FILE" ]]; then
|
||
for source_name in "''${!GO_PACKAGES[@]}"; do
|
||
# Save vendorHash
|
||
saved_vendor=$(grep -A20 "^ $source_name = " "$SOURCES_FILE" | grep -oP 'vendorHash = "\K[^"]+' || echo "")
|
||
if [[ -n "$saved_vendor" ]]; then
|
||
SAVED_VENDOR_HASHES["$source_name"]="$saved_vendor"
|
||
echo " Saved $source_name vendorHash: $saved_vendor"
|
||
fi
|
||
|
||
# Save source sha256 to detect if source changed
|
||
saved_source=$(grep -A20 "^ $source_name = " "$SOURCES_FILE" | grep -oP 'sha256 = "\K[^"]+' || echo "")
|
||
if [[ -n "$saved_source" ]]; then
|
||
SAVED_SOURCE_HASHES["$source_name"]="$saved_source"
|
||
echo " Saved $source_name sourceHash: $saved_source"
|
||
fi
|
||
done
|
||
fi
|
||
echo ""
|
||
|
||
# Step 1: Run nvfetcher
|
||
echo "📦 Step 1: Running nvfetcher..."
|
||
cd "$CONFIG_DIR"
|
||
if nvfetcher; then
|
||
echo ""
|
||
echo "✅ nvfetcher completed"
|
||
echo ""
|
||
else
|
||
echo ""
|
||
echo "⚠️ nvfetcher had some errors, but continuing with vendor hash updates..."
|
||
echo ""
|
||
fi
|
||
|
||
# Step 2: Restore saved vendorHash values
|
||
echo "📦 Step 2: Restoring saved vendorHash values..."
|
||
for source_name in "''${!SAVED_VENDOR_HASHES[@]}"; do
|
||
saved_hash="''${SAVED_VENDOR_HASHES[$source_name]}"
|
||
echo " Restoring $source_name: $saved_hash"
|
||
|
||
# Add vendorHash back after version line using awk
|
||
awk -v source="$source_name" -v hash="$saved_hash" '
|
||
/^ / && $0 ~ source" = " {in_block=1}
|
||
in_block && /version = / {print; print " vendorHash = \"" hash "\";"; next}
|
||
in_block && /^ };/ {in_block=0}
|
||
{print}
|
||
' "$SOURCES_FILE" > "$SOURCES_FILE.tmp" && mv "$SOURCES_FILE.tmp" "$SOURCES_FILE"
|
||
done
|
||
echo ""
|
||
|
||
# Step 3: Update Go vendor hashes
|
||
echo "📦 Step 3: Checking for Go packages that need vendor hash updates..."
|
||
|
||
if [[ ! -f "$SOURCES_FILE" ]]; then
|
||
echo "❌ Error: Generated sources file not found at $SOURCES_FILE"
|
||
exit 1
|
||
fi
|
||
|
||
if [[ ''${#GO_PACKAGES[@]} -eq 0 ]]; then
|
||
echo "ℹ️ No Go packages configured for vendor hash updates"
|
||
echo ""
|
||
echo "🎉 All updates complete!"
|
||
exit 0
|
||
fi
|
||
|
||
for source_name in "''${!GO_PACKAGES[@]}"; do
|
||
package_path="''${GO_PACKAGES[$source_name]}"
|
||
full_path="$CONFIG_DIR/$package_path"
|
||
|
||
if [[ ! -f "$full_path" ]]; then
|
||
echo "⚠️ Package file not found: $full_path"
|
||
continue
|
||
fi
|
||
|
||
echo ""
|
||
echo "📦 Processing $source_name..."
|
||
|
||
# Check if vendorHash already exists in generated.nix
|
||
current_vendor=$(grep -A20 "^ $source_name = " "$SOURCES_FILE" | grep -oP 'vendorHash = "\K[^"]+' || echo "")
|
||
|
||
if [[ -n "$current_vendor" ]]; then
|
||
echo " Current vendorHash: $current_vendor"
|
||
else
|
||
echo " No vendorHash found"
|
||
fi
|
||
|
||
# Check if source hash changed (indicates version/source update)
|
||
new_source_hash=$(grep -A20 "^ $source_name = " "$SOURCES_FILE" | grep -oP 'sha256 = "\K[^"]+' || echo "")
|
||
old_source_hash="''${SAVED_SOURCE_HASHES[$source_name]:-}"
|
||
|
||
if [[ -n "$old_source_hash" ]] && [[ "$old_source_hash" == "$new_source_hash" ]]; then
|
||
echo " Source unchanged (hash: ''${new_source_hash:0:16}...)"
|
||
echo " ✨ Skipping vendorHash recalculation"
|
||
continue
|
||
elif [[ -n "$old_source_hash" ]]; then
|
||
echo " Source changed!"
|
||
echo " Old: ''${old_source_hash:0:16}..."
|
||
echo " New: ''${new_source_hash:0:16}..."
|
||
echo " → Need to recalculate vendorHash"
|
||
else
|
||
echo " New package, calculating vendorHash..."
|
||
fi
|
||
|
||
# Get version from generated sources
|
||
new_version=$(nix-instantiate --eval --strict --expr "
|
||
let pkgs = import <nixpkgs> {};
|
||
sources = pkgs.callPackage $SOURCES_FILE {};
|
||
in sources.''${source_name}.version
|
||
" 2>/dev/null | tr -d '"' || echo "")
|
||
|
||
if [[ -z "$new_version" ]]; then
|
||
echo "⚠️ Could not determine version from generated sources"
|
||
continue
|
||
fi
|
||
|
||
echo " Version: $new_version"
|
||
|
||
# Create temporary build directory
|
||
temp_build=$(mktemp -d)
|
||
trap 'rm -rf "$temp_build"' EXIT
|
||
|
||
# Copy necessary files
|
||
cp -r "$CONFIG_DIR/_sources" "$temp_build/"
|
||
cp "$full_path" "$temp_build/package.nix"
|
||
|
||
# Create build expression
|
||
cat > "$temp_build/default.nix" << 'NIXEOF'
|
||
{ pkgs ? import <nixpkgs> {} }:
|
||
let
|
||
sources = pkgs.callPackage ./_sources/generated.nix {};
|
||
in
|
||
pkgs.callPackage ./package.nix { inherit sources; }
|
||
NIXEOF
|
||
|
||
# Temporarily replace hash with fakeHash
|
||
# Replace both inherited vendorHash and explicit vendorHash assignments
|
||
sed -i 's|inherit (src) pname version src vendorHash|inherit (src) pname version src;\n vendorHash = lib.fakeHash|g' "$temp_build/package.nix"
|
||
sed -i 's|vendorHash = "[^"]*";|vendorHash = lib.fakeHash;|g' "$temp_build/package.nix"
|
||
|
||
echo " Calculating correct vendor hash..."
|
||
|
||
# Build and extract the correct hash from error message
|
||
vendor_hash=$(nix-build "$temp_build/default.nix" 2>&1 | \
|
||
grep -oP 'got:\s+\K(sha256-[A-Za-z0-9+/=]+)' | \
|
||
head -1 || echo "")
|
||
|
||
if [[ -z "$vendor_hash" ]]; then
|
||
echo "⚠️ Could not calculate vendor hash"
|
||
echo " The package may have built successfully (current hash is correct)"
|
||
echo " Or there may be a build error unrelated to vendorHash"
|
||
continue
|
||
fi
|
||
|
||
echo " New hash: $vendor_hash"
|
||
|
||
# Update the generated.nix file to include vendorHash
|
||
# Find the entry and add/update vendorHash after version
|
||
if grep -q "^ $source_name = " "$SOURCES_FILE"; then
|
||
# Check if vendorHash already exists
|
||
if grep -A20 "^ $source_name = " "$SOURCES_FILE" | grep -q "vendorHash"; then
|
||
# Update existing vendorHash using awk for better multiline handling
|
||
awk -v source="$source_name" -v hash="$vendor_hash" '
|
||
/^ / && $0 ~ source" = " {in_block=1}
|
||
in_block && /vendorHash = / {sub(/vendorHash = "[^"]*"/, "vendorHash = \"" hash "\"")}
|
||
in_block && /^ };/ {in_block=0}
|
||
{print}
|
||
' "$SOURCES_FILE" > "$SOURCES_FILE.tmp" && mv "$SOURCES_FILE.tmp" "$SOURCES_FILE"
|
||
echo "✅ Updated vendorHash in generated.nix"
|
||
else
|
||
# Add vendorHash after version line using awk
|
||
awk -v source="$source_name" -v hash="$vendor_hash" '
|
||
/^ / && $0 ~ source" = " {in_block=1}
|
||
in_block && /version = / {print; print " vendorHash = \"" hash "\";"; next}
|
||
in_block && /^ };/ {in_block=0}
|
||
{print}
|
||
' "$SOURCES_FILE" > "$SOURCES_FILE.tmp" && mv "$SOURCES_FILE.tmp" "$SOURCES_FILE"
|
||
echo "✅ Added vendorHash to generated.nix"
|
||
fi
|
||
else
|
||
echo "⚠️ Could not find $source_name entry in generated.nix"
|
||
fi
|
||
done
|
||
|
||
echo ""
|
||
echo "🎉 All updates complete!"
|
||
echo ""
|
||
echo "Summary:"
|
||
echo " - Source versions and hashes updated by nvfetcher"
|
||
echo " - Go vendor hashes recalculated and updated"
|
||
echo ""
|
||
echo "Next steps:"
|
||
echo " - Review changes: git diff"
|
||
echo " - Test build: home-manager switch or similar"
|
||
echo " - Commit if everything works"
|
||
'';
|
||
|
||
meta = {
|
||
description = "Update nvfetcher sources and Go vendor hashes";
|
||
mainProgram = "nvft";
|
||
};
|
||
}
|