#!/usr/bin/env nu
# Learning nushell by writing a simple updater script
# Mostly just testing out all the different language features
use std assert;
use repo.nu len-unrecorded;
use rust_version.nu get-rust-version;
const required_paths = [".pijul" "flake.nix"];
const prompt_command = $"(ansi red)\(system config\)(ansi reset)";
# Helper function to make sure all necessary paths are present
def assert_path_exists [candidate] {
assert ($candidate | path exists) $"(ansi red) Failed to find required file: (ansi red_bold)($candidate)(ansi reset)";
}
# If not root, need to elevate permissions
let script_location = $env.CURRENT_FILE;
# Get the nix flake dir in 3 steps
# 1: ~/config/src/update.nu
# 2: ~/config/src
# 3: ~/config
let parent_dir = $script_location | path dirname | path dirname;
echo $"(ansi purple)Attempting update in (ansi green_bold)($parent_dir)(ansi reset)";
cd $parent_dir;
# Check all the required paths are here
for required_path in $required_paths {
assert_path_exists $required_path;
}
# Force version control to be clean before continuing
while (len-unrecorded) > 0 {
echo $"(ansi yellow_bold)WARNING(ansi yellow): repository has unrecorded changes:(ansi reset)";
# Drop into terminal to fix
nu --interactive --execute $"cd ($parent_dir); use ($parent_dir | path join src/repo.nu) repl-prompt; $env.PROMPT_COMMAND = {|| repl-prompt }; pijul diff -us";
}
# Before updating, get the current Rust version to see if we need to clean the target directories
let old_rust_version = get-rust-version;
# Update all channels beforehand
sudo nix-channel --update;
nix flake update;
# Using `nh` (https://github.com/viperML/nh), which integrates:
# - `nix-output-monitor` (https://github.com/maralorn/nix-output-monitor)
# - `nvd` (https://gitlab.com/khumba/nvd)
nh os switch . -- --impure;
# Make sure that Rust is roughly up-to-date (less than a week old)
# rust-overlay's selectLatestNightlyWith silently keeps older versions if components/targets are no longer valid
# This code should catch if that happens
let new_rust_version = get-rust-version;
assert greater $new_rust_version ((date now) - 7day) $"This version of Rust was built (ansi red_bold)($new_rust_version | date humanize)(ansi reset)!
Check that all specified targets and extensions are valid.
(ansi yellow_bold)HINT(ansi reset): replace `selectLatestNightlyWith` with `nightly.latest.default.override` to debug.";
# Delete any unused generations
nh clean all --keep 2;
# Since the Rust version has changed anyways, clean all Rust target directories
if $old_rust_version != $new_rust_version {
print $"Removing old Rust target directories: old version was ($old_rust_version | date humanize)";
# `cargo-sweep` seems to require the `time` parameter, so just set it to 0
cargo sweep --time 0 --recursive --max-depth 1 ~/Projects/Rust ~/Projects/Pijul
# Remove the rust-analyzer cache
rm -rf ~/tmp/rust-analyzer
}
# Upgrade nu_scripts repository
do { cd ~/.config/nushell/nu_scripts; git pull }
# Upgrade Nushell plugins
atuin init nu | save --force ~/.config/nushell/plugins/atuin.nu
carapace _carapace nushell | save --force ~/.config/nushell/plugins/carapace.nu
zoxide init nushell | save --force ~/.config/nushell/plugins/zoxide.nu
# Upgrade all the other package managers
nix-shell -p pkg-config openssl libunwind --run "topgrade --disable nix --disable system --yes --no-retry";