#!/usr/bin/env bash

## Copy or move files, and create destination directory as needed, including
## parent directories.
##
## Usage: relocate cp|mv <source>... <dest>
##
## Dependencies: GNU coreutils, GNU sed
##
## I wrote this script because I grew tired of typing `mkdir -p <dir>` before
## using cp and mv to relocate files to nonexistent destination directories. I
## run this script via these aliases:
##
## alias c='relocate cp'
## alias m='relocate mv'

set -euo pipefail
shopt -s inherit_errexit

die() { echo "${0##*/}: $1" >&2; exit 1; }

[[ " $* " =~ ' --help ' ]] && sed -n 's/^## \?//p' "$0" && exit
(( $# < 3 )) && die 'missing argument'

subcmd=$1
[[ $subcmd =~ ^(cp|mv)$ ]] || die 'subcommand must be cp or mv'
sources=("${@:2:$#-2}")
dest=${!#}
subcmd_opts=(-iv)
[[ $subcmd == cp ]] && subcmd_opts+=(-a)

if [[ ${#sources[@]} -eq 1 && -f ${sources[0]} && ! $dest =~ /$ ]]; then
  dest_dir=$(dirname "$dest")
else
  dest_dir=$dest
fi

if [[ ! -d $dest_dir ]]; then
  mkdir -p "$dest_dir"
  [[ ${#sources[@]} -eq 1 && -d ${sources[0]} ]] && subcmd_opts+=(-Tf)
fi

$subcmd "${subcmd_opts[@]}" "${sources[@]}" "$dest"
