#!/usr/bin/env nu # install.nu — install scripts and config from this repo into the user's home. # # bin/ -> $HOME/bin (made executable, overwrite silently) # config/ -> $HOME/.config/ (mirrored recursively, overwrite silently) # # The repo root is resolved relative to this script's own location, so it # works regardless of the current working directory. def "repo-root" [] { $env.CURRENT_FILE | path dirname | path expand } # Recursively mirror a source directory tree into a target directory, # overwriting existing files and creating needed subdirectories. # Optionally chmod +x each target file. def "install-tree" [source_dir: path, target_dir: path, make_exec: bool] { if not ($source_dir | path exists) { error make { msg: $"Source directory not found: ($source_dir)" } } mkdir $target_dir # Enumerate all files under source_dir (dirs filtered; hidden files included). let files = (glob -D $"($source_dir)/**/*") if ($files | is-empty) { error make { msg: $"No files found in ($source_dir)" } } let installed = ($files | each { |file| let rel = ($file | path relative-to $source_dir) let dest = ($target_dir | path join $rel) # Ensure the parent directory exists, then copy the file. mkdir ($dest | path dirname) cp $file $dest if $make_exec { chmod +x $dest } $dest }) $installed | each { |path| print $"installed: ($path)" } let count = ($installed | length) print $"installed ($count) entries into ($target_dir)" } def "main" [] { let root = (repo-root) let bin_source = ($root | path join bin) let bin_target = ($env.HOME | path join bin | path expand) print $"(ansi cyan_bold)Installing scripts(ansi reset) bin/ -> ($bin_target)" install-tree $bin_source $bin_target true print "" let cfg_source = ($root | path join config) let cfg_target = ($env.HOME | path join .config | path expand) print $"(ansi cyan_bold)Installing config(ansi reset) config/ -> ($cfg_target)" install-tree $cfg_source $cfg_target false }