diff options
Diffstat (limited to 'wsl/.local/bin/mkln.sh')
-rwxr-xr-x | wsl/.local/bin/mkln.sh | 254 |
1 files changed, 172 insertions, 82 deletions
diff --git a/wsl/.local/bin/mkln.sh b/wsl/.local/bin/mkln.sh index ef174c2..60fd719 100755 --- a/wsl/.local/bin/mkln.sh +++ b/wsl/.local/bin/mkln.sh @@ -1,115 +1,205 @@ #!/usr/bin/env bash -TEMP=$(getopt -o hvqdf --long help,verbose,quiet,debug,force \ - -n 'javawrap' -- "$@") +SCRIPT="$(basename "$0")" -if [ $? != 0 ]; then - echo "Terminating..." >&2 - exit 1 -fi +long='help,verbose,quiet,force,dry-run' +short='hvqfn' + +eval set -- "$(getopt -o $short -l $long -n "$SCRIPT" -- "$@")" -eval set -- "$TEMP" +help() { + cat <<-EOF +$SCRIPT +Toby Vincent <tobyv13@gmail.com> -SCRIPT="$(basename $0)" -VERBOSE=false -QUIET=false -DEBUG=false -FORCE=false +$SCRIPT + Creates symbolic links (for files) or junctions (for directories) from the + windows filesystem to the WSL2 instance using mklink.exe. -read -r -d '' USAGE <<-EOF -USAGE: $SCRIPT [OPTIONS] <SOURCE> <TARGET> +USAGE: + $SCRIPT [OPTIONS] <SOURCE> [TARGET] OPTIONS: - -h, --help Show this message - -v, --verbose Show more output - -q, --quiet Suppress all output - -d, --debug NOT IMPLEMENTED - -f, --force Overwrite items + -h, --help Show this message + -v, --verbose Show more output + -q, --quiet Suppress all output + -f, --force Overwrite items + -n, --dry-run Write output of commands with running them. ARGS: - <SOURCE> <TARGET>... File to link. -EOF + SOURCE (required) + Path to the source file or directory the link should point to. + TARGET (optional) + Path to the location to create the link. [Default: $PWD] +EOF +} + +say() { + if ! $quiet; then + printf "%s: %s\n" "$SCRIPT" "$@" + fi +} + +say_verbose() { + if $verbose; then + say "$@" + fi +} + +say_err() { + say "$@" >&2 +} + +err() { + # shellcheck disable=SC2145 + say_err "ERROR: $@" + exit 1 +} + +err_help() { + help + err "$*" +} + +run() { + if $is_dry_run; then + say "DRYRUN: $*" + return 0 + fi + + say_verbose "running: $*" + + if $quiet; then + "$@" &>/dev/null + else + say "$("$@")" + fi +} + +need() { + for cmd in "$@"; do + if ! command -v "$cmd" >/dev/null 2>&1; then + err "need $cmd (command not found)" + fi + done +} + +trg=$PWD +verbose=false +quiet=false +force=false +is_dry_run=false while true; do - case "$1" in + case "$1" in -h | --help) - echo "$USAGE" - exit 0 - ;; + help + exit 0 + ;; -v | --verbose) - VERBOSE=true - shift - ;; + verbose=true + shift + ;; -q | --quiet) - QUIET=true - shift - ;; - -d | --debug) - DEBUG=true - shift - ;; + quiet=true + shift + ;; -f | --force) - FORCE=true - shift - ;; + force=true + shift + ;; + -n | --dry-run) + is_dry_run=true + shift + ;; --) - shift - break - ;; + shift + break + ;; *) - break - ;; - esac + break + ;; + esac done -if ! command -v powershell.exe &>/dev/null; then - [ "$QUIET" != true ] && echo "Powershell not found in path." >&2 - exit 1 -fi +need powershell.exe +need realpath -if [ -z "$2" ]; then - 2="$(pwd)" -fi +case "$#" in + 0) err_help "must provide at least 1 argument";; + 1) src="$1"; trg="$PWD"; shift;; + 2) src="$1"; trg="$2"; shift 2;; + *) err_help "too many arguments" +esac -[ "$VERBOSE" == true ] && echo "linking $2 -> $1" +while test -L "$src"; do + tmp="$src" + src=$(realpath "$src") + say_verbose "resolved symbolic link $tmp -> $src" +done -if [ -d "$1" ]; then - [ "$VERBOSE" == true ] && echo "$1 is a directory. Creating symbolic link." - args='/D' +if ! test -e "$src"; then + err "$src does not exist." fi -mkdir -p $(dirname $2) +if test -d "$src"; then + say_verbose "$src is a directory. Switching to directory symbolic link." + args='/D' +fi -source=$(wslpath -w $1) -target=$(wslpath -w $(dirname $2))\\$(basename $2) +trg_name=$(basename "$trg") +trg_dir=$(dirname "$trg") -if ls -la "$(dirname $2)/" 2>/dev/null | grep -q "$(basename $2)"; then +if ! test -d "$trg_dir"; then + mkdir -p "$trg_dir" + say_verbose "created directory $trg_dir" +fi - current_path=$(powershell.exe -c "(Get-Item $target).Target" 2>/dev/null) +win_src=$(wslpath -w "$src") +win_trg=$(wslpath -w "$trg_dir")\\"$trg_name" - if [[ "${current_path/*wsl$/}" == *"${source/*wsl$/}"* ]]; then - [ "$VERBOSE" == true ] && echo "$(basename $2) is set correctly. Skipping." - exit 0 - fi +old_trg="$(powershell.exe "(Get-Item $win_trg).FullName" 2>/dev/null)" +old_src="$(powershell.exe "(Get-Item $win_trg).Target" 2>/dev/null)" - if [ "$FORCE" == true ]; then - [ "$VERBOSE" == true ] && echo "$(basename $2) exists. Overwriting." - rm -rf "$2" - else - [ "$QUIET" != true ] && echo "$(basename $target) already exists. Use -f to overwrite." >&2 - exit 1 - fi -fi +old_src="${old_src/*wsl$/}" +new_src="${win_src/*wsl$/}" -mkdir -p "$(dirname $2)" -cmd="cd ~; cmd /c mklink ${args} ${target} ${source}" +if ! $force && test "${old_src#*"$new_src"}" != "$old_src"; then + say_verbose "symbolic link already exists." + exit 0 +fi -if [ "$DEBUG" == true ]; then - [ "$QUIET" != true ] && printf '\nCommand: \n%s\n\n' "powershell.exe -c ${cmd} &>/dev/null" -else - if $QUIET; then - powershell.exe -c "${cmd}" &>/dev/null - else - powershell.exe -c "${cmd}" - fi +say_verbose "$(cat <<-EOF +linking: + WSL paths: + target: $trg + source: $src + Win paths: + target: $win_trg + source: $win_src +EOF +)" + +if test "$old_trg" != ''; then + if $force; then + say_verbose "$(cat <<-EOF +$win_trg already exists. Overwriting. + target: $win_trg + source: $old_src +EOF +)" + rm -rf "$trg" + else + err "$(cat <<-EOF +$win_trg already exists. + Existing file: + target: $win_trg + source: $old_src + + Use -f or --force to overwrite. +EOF +)" + fi fi + +run powershell.exe "cd ~; cmd /c mklink $args $win_trg $win_src" |