♻️ Bash -> POSIX; move some of install to fish
This commit is contained in:
parent
9f5dda2dac
commit
05f5b26907
6 changed files with 616 additions and 427 deletions
|
@ -1,9 +1,11 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
# vim:set ft=bash:
|
|
||||||
|
|
||||||
cd "$(dirname "${BASH_SOURCE[0]}")" \
|
DOT="${DOT:-$HOME/dotfiles}"
|
||||||
&& source "../homebrew/brew_utils.sh" \
|
|
||||||
&& source "../script/utils.sh"
|
# shellcheck source=../homebrew/brew_utils.sh
|
||||||
|
. "$DOT/homebrew/brew_utils.sh"
|
||||||
|
# shellcheck source=../script/utils.sh
|
||||||
|
. "$DOT/script/utils.sh"
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
@ -11,15 +13,11 @@ brew_install "Fish Shell" "fish"
|
||||||
|
|
||||||
fish_path="$(which fish)"
|
fish_path="$(which fish)"
|
||||||
|
|
||||||
if ! grep "$fish_path" < /etc/shells &> /dev/null; then
|
if ! grep "$fish_path" < /etc/shells >/dev/null 2>&1; then
|
||||||
execute \
|
execute \
|
||||||
"printf '%s\n' '$fish_path' | sudo tee -a /etc/shells" \
|
"printf '%s\n' '$fish_path' | sudo tee -a /etc/shells" \
|
||||||
"Add '$fish_path' to '/etc/shells'"
|
"Add '$fish_path' to '/etc/shells'"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
chsh -s "$fish_path" &> /dev/null
|
chsh -s "$fish_path" >/dev/null 2>&1
|
||||||
print_result $? "Make OS use Fish as the default shell"
|
print_result $? "Make OS use Fish as the default shell"
|
||||||
|
|
||||||
execute \
|
|
||||||
"curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher" \
|
|
||||||
"Fisher"
|
|
||||||
|
|
258
script/bootstrap.sh
Executable file
258
script/bootstrap.sh
Executable file
|
@ -0,0 +1,258 @@
|
||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
readonly GITHUB_REPO="punkfairie/dotfiles"
|
||||||
|
|
||||||
|
readonly DOTFILES_ORIGIN="git@github.com:$GITHUB_REPO.git"
|
||||||
|
readonly DOTFILES_TARBALL="https://github.com/$GITHUB_REPO/tarball/main"
|
||||||
|
readonly DOTFILES_UTILS="https://raw.githubusercontent.com/$GITHUB_REPO/main/scripts/utils.sh"
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
export DOT="$HOME/dotfiles" # MUST HAVE NO TRAILING SLASH!!
|
||||||
|
yes_to_all=false
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Download Dotfiles #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
download()
|
||||||
|
{
|
||||||
|
url="$1"
|
||||||
|
output="$2"
|
||||||
|
|
||||||
|
if command -v "curl" >/dev/null 2>&1; then
|
||||||
|
curl \
|
||||||
|
--location \
|
||||||
|
--silent \
|
||||||
|
--show-error \
|
||||||
|
--output "$output" \
|
||||||
|
"$url" \
|
||||||
|
>/dev/null 2>&1
|
||||||
|
|
||||||
|
return $?
|
||||||
|
|
||||||
|
elif command -v "wget" >/dev/null 2>&1; then
|
||||||
|
wget \
|
||||||
|
--quiet \
|
||||||
|
--output-document="$output" \
|
||||||
|
"$url" \
|
||||||
|
>/dev/null 2>&1
|
||||||
|
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
download_utils()
|
||||||
|
{
|
||||||
|
tmp_file="$(mktemp /tmp/XXXXX)"
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
download "$DOTFILES_UTILS" "$tmp_file" \
|
||||||
|
&& . "$tmp_file" \
|
||||||
|
&& rm -rf "$tmp_file" \
|
||||||
|
&& return 0
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
extract()
|
||||||
|
{
|
||||||
|
archive="$1"
|
||||||
|
output_dir="$2"
|
||||||
|
|
||||||
|
if command -v "tar" >/dev/null 2>&1; then
|
||||||
|
tar \
|
||||||
|
--extract \
|
||||||
|
--gzip \
|
||||||
|
--file "$archive" \
|
||||||
|
--strip-components 1 \
|
||||||
|
--directory "$output_dir"
|
||||||
|
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
download_dotfiles()
|
||||||
|
{
|
||||||
|
print_title "Download and extract dotfiles archive"
|
||||||
|
|
||||||
|
tmp_file="$(mktemp /tmp/XXXXX)"
|
||||||
|
|
||||||
|
download "$DOTFILES_TARBALL" "$tmp_file"
|
||||||
|
print_result $? "Download archive" "true"
|
||||||
|
printf "\n"
|
||||||
|
|
||||||
|
if ! $yes_to_all; then
|
||||||
|
|
||||||
|
while [ -e "$DOT" ]; do
|
||||||
|
ask "'$DOT' already exists, do you want to (o)verwrite or (b)ackup the existing directory?"
|
||||||
|
answer="$(get_answer)"
|
||||||
|
|
||||||
|
case $answer in
|
||||||
|
o ) rm -rf "$DOT"; break;;
|
||||||
|
b ) mv "$DOT" "$DOT.bak"; break;;
|
||||||
|
* ) print_warning "Please enter a valid option."
|
||||||
|
esac
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
else
|
||||||
|
rm -rf "$DOT" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$DOT"
|
||||||
|
print_result $? "Create '$DOT'" "true"
|
||||||
|
|
||||||
|
# Extract archive.
|
||||||
|
extract "$tmp_file" "$DOT"
|
||||||
|
print_result $? "Extract archive" "true"
|
||||||
|
|
||||||
|
rm -rf "$tmp_file"
|
||||||
|
print_result $? "Remove archive"
|
||||||
|
|
||||||
|
cd "$DOT/script" \
|
||||||
|
|| return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Xcode #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
are_xcode_cli_tools_installed()
|
||||||
|
{
|
||||||
|
xcode-select --print-path >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
install_xcode_cli_toools()
|
||||||
|
{
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
|
||||||
|
print_title "Xcode"
|
||||||
|
|
||||||
|
xcode-select --install >/dev/null 2>&1
|
||||||
|
|
||||||
|
execute \
|
||||||
|
"until are_xcode_cli_tools_installed; do sleep 5; done" \
|
||||||
|
"Install Xcode Command Line Tools"
|
||||||
|
|
||||||
|
sudo xcodebuild -license accept >/dev/null 2>&1
|
||||||
|
print_result $? "Agree to the terms of the Xcode license"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Setup Gitconfig #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
setup_gitconfig()
|
||||||
|
{
|
||||||
|
cd "$DOT" || return
|
||||||
|
|
||||||
|
if ! [ -f "$DOT/git/.gitconfig.local.symlink" ]; then
|
||||||
|
print_title "Set up gitconfig"
|
||||||
|
|
||||||
|
git_credential="cache"
|
||||||
|
|
||||||
|
if [ "$(uname)" = "Darwin" ]; then
|
||||||
|
git_credential="osxkeychain"
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_question "What is your Github author name?"
|
||||||
|
read -r git_authorname
|
||||||
|
|
||||||
|
print_question "What is your Github author email?"
|
||||||
|
read -r git_authoremail
|
||||||
|
|
||||||
|
sed -e "s/AUTHORNAME/$git_authorname/g" \
|
||||||
|
-e "s/AUTHOREMAIL/$git_authoremail/g" \
|
||||||
|
-e "s/GIT_CREDENTIAL_HELPER/$git_credential/g" \
|
||||||
|
"$DOT/git/.gitconfig.local.symlink.example" > "$DOT/.gitconfig.local.symlink"
|
||||||
|
|
||||||
|
print_result $? "gitconfig"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Initialize Git Repo #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
git_init()
|
||||||
|
{
|
||||||
|
print_title "Initialize Git repository"
|
||||||
|
|
||||||
|
if [ -z "$DOTFILES_ORIGIN" ]; then
|
||||||
|
print_error "Please provide a URL for the Git origin"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! is_git_repository; then
|
||||||
|
cd "$DOT" || print_error "Failed to cd $DOT"
|
||||||
|
|
||||||
|
execute \
|
||||||
|
"git init && git remote add origin $DOTFILES_ORIGIN" \
|
||||||
|
"Initialize the dotfiles Git repository"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Main #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
if [ "$(uname)" != "Linux" ] && [ "$(uname)" != "Darwin" ]; then
|
||||||
|
printf "Sorry, this script is intended only for macOS and Ubuntu!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Load utils.
|
||||||
|
|
||||||
|
if [ -x "${DOT}/script/utils.sh" ]; then
|
||||||
|
. "${DOT}/script/utils.sh" || exit 1
|
||||||
|
else
|
||||||
|
download_utils || exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
skip_questions "$@" \
|
||||||
|
&& yes_to_all=true
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
ask_for_sudo
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
# Check if this script was run directly, and if not, dotfiles will need to be
|
||||||
|
# downloaded.
|
||||||
|
|
||||||
|
printf "%s" "$(sh_source "$0")" | grep "bootstrap.sh" >/dev/null 2>&1 \
|
||||||
|
|| download_dotfiles
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
setup_gitconfig
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
install_xcode_cli_toools
|
||||||
|
|
||||||
|
"$DOT/homebrew/brew.sh"
|
||||||
|
|
||||||
|
"$DOT/fish/install.sh"
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
if cmd_exists "git"; then
|
||||||
|
if [ "$(git config --get remote.origin.url)" != "$DOTFILES_ORIGIN" ]; then
|
||||||
|
git_init
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
119
script/dot
Normal file
119
script/dot
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
# vim:set ft=fish :
|
||||||
|
|
||||||
|
set -q DOT || set -gx DOT "$HOME/dotfiles"
|
||||||
|
|
||||||
|
source "$DOT/script/utils"
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# OS Preferences #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
function set_os_prefs
|
||||||
|
print_title "OS Preferences"
|
||||||
|
|
||||||
|
set os $(uname | string lower)
|
||||||
|
|
||||||
|
"$DOT/os/$os.fish"
|
||||||
|
end
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Symlink Dotfiles #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
function link_file
|
||||||
|
set -f src $argv[1]
|
||||||
|
set -f dst $argv[2]
|
||||||
|
|
||||||
|
set -f overwrite false
|
||||||
|
set -f backup false
|
||||||
|
set -f skip false
|
||||||
|
set -f action
|
||||||
|
|
||||||
|
if [ -f "$dst" ] || [ -d "$dst" ] || [ -L "$dst" ]
|
||||||
|
|
||||||
|
if ! $overwrite_all && ! $backup_all && ! $skip_all
|
||||||
|
set -f current_src (readlink "$dst")
|
||||||
|
|
||||||
|
if [ "$current_src" = "$src" ]
|
||||||
|
set skip true
|
||||||
|
else
|
||||||
|
print_question "File already exists: $dst ($(basename $src)), what do you want to do?\n([s]kip, [S]kip all, [o]verwrite, [O]verwrite all, [b]ackup, [B]ackup all)"
|
||||||
|
read -n 1 action
|
||||||
|
|
||||||
|
switch $action
|
||||||
|
case o
|
||||||
|
set overwrite true
|
||||||
|
case O
|
||||||
|
set overwrite_all true
|
||||||
|
case b
|
||||||
|
set backup true
|
||||||
|
case B
|
||||||
|
set backup_all true
|
||||||
|
case s
|
||||||
|
set skip true
|
||||||
|
case S
|
||||||
|
set skip_all true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
set -q overwrite || set overwrite $overwrite_all
|
||||||
|
set -q backup || set backup $backup_all
|
||||||
|
set -q skip || set skip $skip_all
|
||||||
|
|
||||||
|
if $overwrite
|
||||||
|
rm -rf "$dst"
|
||||||
|
print_success "Removed $dst"
|
||||||
|
end
|
||||||
|
|
||||||
|
if $backup
|
||||||
|
mv "$dst" "{$dst}.bak"
|
||||||
|
print_success "Moved $dst to {$dst}.bak"
|
||||||
|
end
|
||||||
|
|
||||||
|
if $skip
|
||||||
|
print_success "Skipped $src"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ! $skip
|
||||||
|
# See of any directories need to be created.
|
||||||
|
if echo "$dst" | grep -q '/' 2> /dev/null
|
||||||
|
mkdir -p (string replace -r '\/[^\/]+$' '' "$dst")
|
||||||
|
end
|
||||||
|
|
||||||
|
ln -s "$src" "$dst"
|
||||||
|
print_success "Linked $src to $dst"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function make_dst
|
||||||
|
set -l path (string escape --style=regex "$DOT")
|
||||||
|
set -l regex (string join '^\/' $path '\/[a-zA-Z]+\/(.+)\.symlink$')
|
||||||
|
set -l dst (string replace -r $regex '$1' "$argv[1]")
|
||||||
|
|
||||||
|
printf '%s' "$dst"
|
||||||
|
end
|
||||||
|
|
||||||
|
function install_dotfiles
|
||||||
|
print_title "Installing Dotfiles"
|
||||||
|
|
||||||
|
set -g overwrite_all false
|
||||||
|
set -g backup_all false
|
||||||
|
set -g skip_all false
|
||||||
|
|
||||||
|
find -H "$DOT" -name "*.symlink" -not -path ".git" | \
|
||||||
|
while read -l -t src; link_file "$src" "$(make_dst $src)"; end
|
||||||
|
end
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Main #
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
print_title "Installers"
|
||||||
|
find . -name install.fish | while read installer; fish -c "$installer"; end
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
install_dotfiles
|
384
script/dot.sh
384
script/dot.sh
|
@ -1,384 +0,0 @@
|
||||||
#!/usr/bin/env bash
|
|
||||||
# vim:set ft=bash:
|
|
||||||
|
|
||||||
declare -r GITHUB_REPO="punkfairie/dotfiles"
|
|
||||||
|
|
||||||
declare -r DOTFILES_ORIGIN="git@github.com:$GITHUB_REPO.git"
|
|
||||||
declare -r DOTFILES_TARBALL="https://github.com/$GITHUB_REPO/tarball/main"
|
|
||||||
declare -r DOTFILES_UTILS="https://raw.githubusercontent.com/$GITHUB_REPO/main/scripts/utils.sh"
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
declare dotfiles_dir="$HOME/dotfiles" # MUST HAVE NO LEADING SLASH!!
|
|
||||||
declare yes_to_all=false
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Download Dotfiles #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
download()
|
|
||||||
{
|
|
||||||
local url="$1"
|
|
||||||
local output="$2"
|
|
||||||
|
|
||||||
if command -v "curl" &> /dev/null; then
|
|
||||||
curl \
|
|
||||||
--location \
|
|
||||||
--silent \
|
|
||||||
--show-error \
|
|
||||||
--output "$output" \
|
|
||||||
"$url" \
|
|
||||||
&> /dev/null
|
|
||||||
|
|
||||||
return $?
|
|
||||||
|
|
||||||
elif command -v "wget" &> /dev/null; then
|
|
||||||
wget \
|
|
||||||
--quiet \
|
|
||||||
--output-document="$output" \
|
|
||||||
"$url" \
|
|
||||||
&> /dev/null
|
|
||||||
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
download_utils()
|
|
||||||
{
|
|
||||||
local tmp_file=""
|
|
||||||
|
|
||||||
tmp_file="$(mktemp /tmp/XXXXX)"
|
|
||||||
|
|
||||||
download "$DOTFILES_UTILS" "$tmp_file" \
|
|
||||||
&& . "$tmp_file" \
|
|
||||||
&& rm -rf "$tmp_file" \
|
|
||||||
&& return 0
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
extract()
|
|
||||||
{
|
|
||||||
local archive="$1"
|
|
||||||
local output_dir="$2"
|
|
||||||
|
|
||||||
if command -v "tar" &> /dev/null; then
|
|
||||||
tar \
|
|
||||||
--extract \
|
|
||||||
--gzip \
|
|
||||||
--file "$archive" \
|
|
||||||
--strip-components 1 \
|
|
||||||
--directory "$output_dir"
|
|
||||||
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
download_dotfiles()
|
|
||||||
{
|
|
||||||
local tmp_file=""
|
|
||||||
|
|
||||||
print_title "Download and extract dotfiles archive"
|
|
||||||
|
|
||||||
tmp_file="$(mktemp /tmp/XXXXX)"
|
|
||||||
|
|
||||||
download "$DOTFILES_TARBALL" "$tmp_file"
|
|
||||||
print_result $? "Download archive" "true"
|
|
||||||
printf "\n"
|
|
||||||
|
|
||||||
if ! $yes_to_all; then
|
|
||||||
|
|
||||||
while [[ -e $dotfiles_dir ]]; do
|
|
||||||
ask "'$dotfiles_dir' already exists, do you want to (o)verwrite or (b)ackup the existing directory?"
|
|
||||||
answer="$(get_answer)"
|
|
||||||
|
|
||||||
case $answer in
|
|
||||||
o ) rm -rf "$dotfiles_dir"; break;;
|
|
||||||
b ) mv "$dotfiles_dir" "$dotfiles_dir.bak"; break;;
|
|
||||||
* ) print_warning "Please enter a valid option."
|
|
||||||
esac
|
|
||||||
|
|
||||||
done
|
|
||||||
|
|
||||||
else
|
|
||||||
rm -rf "$dotfiles_dir" &> /dev/null
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$dotfiles_dir"
|
|
||||||
print_result $? "Create '$dotfiles_dir'" "true"
|
|
||||||
|
|
||||||
# Extract archive.
|
|
||||||
extract "$tmp_file" "$dotfiles_dir"
|
|
||||||
print_result $? "Extract archive" "true"
|
|
||||||
|
|
||||||
rm -rf "$tmp_file"
|
|
||||||
print_result $? "Remove archive"
|
|
||||||
|
|
||||||
cd "$dotfiles_dir/script" \
|
|
||||||
|| return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Xcode #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
are_xcode_cli_tools_installed()
|
|
||||||
{
|
|
||||||
xcode-select --print-path &> /dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
install_xcode_cli_toools()
|
|
||||||
{
|
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
|
||||||
|
|
||||||
print_title "Xcode"
|
|
||||||
|
|
||||||
xcode-select --install &> /dev/null
|
|
||||||
|
|
||||||
execute \
|
|
||||||
"until are_xcode_cli_tools_installed; do sleep 5; done" \
|
|
||||||
"Install Xcode Command Line Tools"
|
|
||||||
|
|
||||||
sudo xcodebuild -license accept &> /dev/null
|
|
||||||
print_result $? "Agree to the terms of the Xcode license"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Setup Gitconfig #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
setup_gitconfig()
|
|
||||||
{
|
|
||||||
cd "$dotfiles_dir"
|
|
||||||
|
|
||||||
if ! [[ -f $dotfiles_dir/git/.gitconfig.local.symlink ]]; then
|
|
||||||
print_title "Set up gitconfig"
|
|
||||||
|
|
||||||
git_credential="cache"
|
|
||||||
|
|
||||||
if [[ "$(uname)" == "Darwin" ]]; then
|
|
||||||
git_credential="osxkeychain"
|
|
||||||
fi
|
|
||||||
|
|
||||||
print_question "What is your Github author name?"
|
|
||||||
read -e git_authorname
|
|
||||||
|
|
||||||
print_question "What is your Github author email?"
|
|
||||||
read -e git_authoremail
|
|
||||||
|
|
||||||
sed -e "s/AUTHORNAME/$git_authorname/g" \
|
|
||||||
-e "s/AUTHOREMAIL/$git_authoremail/g" \
|
|
||||||
-e "s/GIT_CREDENTIAL_HELPER/$git_credential/g" \
|
|
||||||
$dotfiles_dir/git/.gitconfig.local.symlink.example > $dotfiles_dir/.gitconfig.local.symlink
|
|
||||||
|
|
||||||
print_result $? "gitconfig"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Install Dotfiles #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
link_file()
|
|
||||||
{
|
|
||||||
local src=$1
|
|
||||||
local dst=$2
|
|
||||||
|
|
||||||
local overwrite=
|
|
||||||
local backup=
|
|
||||||
local skip=
|
|
||||||
local action=
|
|
||||||
|
|
||||||
if [ -f "$dst" -o -d "$dst" -o -L "$dst" ]; then
|
|
||||||
|
|
||||||
if ! $overwrite_all && ! $backup_all && ! $skip_all; then
|
|
||||||
local current_src="$(readlink $dst)"
|
|
||||||
|
|
||||||
if [[ "$current_src" == "$src" ]]; then
|
|
||||||
skip=true
|
|
||||||
|
|
||||||
else
|
|
||||||
print_question "File already exists: $dst ($(basename "$src")), what do you want to do?\n\
|
|
||||||
[s]kip, [S]kip all, [o]verwrite, [O]verwrite all, [b]ackup, [B]ackup all?"
|
|
||||||
read -n 1 action
|
|
||||||
|
|
||||||
case "$action" in
|
|
||||||
o ) overwrite=true ;;
|
|
||||||
O ) overwrite_all=true ;;
|
|
||||||
b ) backup=true ;;
|
|
||||||
B ) backup_all=true ;;
|
|
||||||
s ) skip=true ;;
|
|
||||||
S ) skip_all=true ;;
|
|
||||||
* ) ;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
overwrite=${overwrite:-$overwrite_all}
|
|
||||||
backup=${backup:-$backup_all}
|
|
||||||
skip=${skip:-$skip_all}
|
|
||||||
|
|
||||||
if $overwrite; then
|
|
||||||
rm -rf "$dst"
|
|
||||||
print_success "Removed $dst"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $backup; then
|
|
||||||
mv "$dst" "${dst}.bak"
|
|
||||||
print_success "Moved $dst to ${dst}.bak"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if $skip; then
|
|
||||||
print_success "Skipped $src"
|
|
||||||
fi
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $skip != "true" ]]; then # "false" or empty
|
|
||||||
|
|
||||||
# See if any directories need to be created
|
|
||||||
if [[ "$dst" =~ '/' ]]; then
|
|
||||||
mkdir -p "${dst%/*}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
ln -s "$src" "$dst"
|
|
||||||
print_success "Linked $src to $dst"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
install_dotfiles()
|
|
||||||
{
|
|
||||||
print_title "Installing dotfiles"
|
|
||||||
|
|
||||||
local overwrite_all=false
|
|
||||||
local backup_all=false
|
|
||||||
local skip_all=false
|
|
||||||
|
|
||||||
for src in $(find -H "$dotfiles_dir" -maxdepth 5 -name "*.symlink" -not -path ".git"); do
|
|
||||||
dst="${src%.*}"
|
|
||||||
dst="${dst#$dotfiles_dir/}"
|
|
||||||
dst="${dst#*/}"
|
|
||||||
dst="$HOME/$dst"
|
|
||||||
link_file "$src" "$dst"
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Initialize Git Repo #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
git_init()
|
|
||||||
{
|
|
||||||
print_title "Initialize Git repository"
|
|
||||||
|
|
||||||
if [[ -z "$DOTFILES_ORIGIN" ]]; then
|
|
||||||
print_error "Please provide a URL for the Git origin"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ! is_git_repository; then
|
|
||||||
cd $dotfiles_dir || print_error "Failed to cd $dotfiles_dir"
|
|
||||||
|
|
||||||
execute \
|
|
||||||
"git init && git remote add origin $DOTFILES_ORIGIN" \
|
|
||||||
"Initialize the dotfiles Git repository"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Restart OS #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
restart_os()
|
|
||||||
{
|
|
||||||
print_title "Restart"
|
|
||||||
|
|
||||||
ask_for_confirmation "Do you want to restart?"
|
|
||||||
printf "\n"
|
|
||||||
|
|
||||||
if answer_is_yes; then
|
|
||||||
sudo shutdown -r now &> /dev/null
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
################################################################################
|
|
||||||
# Main #
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
main()
|
|
||||||
{
|
|
||||||
if [[ "$(uname)" != "Linux" ]] && [[ "$(uname)" != "Darwin" ]]; then
|
|
||||||
printf "Sorry, this script is intended only for macOS and Ubuntu!"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Load utils.
|
|
||||||
|
|
||||||
if [[ -x "${dotfiles_dir}/script/utils.sh" ]]; then
|
|
||||||
. "${dotfiles_dir}/script/utils.sh" || exit 1
|
|
||||||
else
|
|
||||||
download_utils || exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
skip_questions "$@" \
|
|
||||||
&& yes_to_all=true
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
ask_for_sudo
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
# Check if this script was run directly, and if not, dotfiles will need to be
|
|
||||||
# downloaded.
|
|
||||||
|
|
||||||
printf "%s" "${BASH_SOURCE[0]}" | grep "dot.sh" &> /dev/null \
|
|
||||||
|| download_dotfiles
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
setup_gitconfig
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
install_dotfiles
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
$dotfiles_dir/os/pref.sh
|
|
||||||
|
|
||||||
install_xcode_cli_toools
|
|
||||||
|
|
||||||
$dotfiles_dir/homebrew/brew.sh
|
|
||||||
|
|
||||||
$dotfiles_dir/node/volta.sh
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
print_title "Installers"
|
|
||||||
find . -name install.sh | while read installer ; do sh -c "${installer}" ; done
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
if cmd_exists "git"; then
|
|
||||||
if [[ "$(git config --get remote.origin.url)" != "$DOTFILES_ORIGIN" ]]; then
|
|
||||||
git_init
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
if ! $yes_to_all; then
|
|
||||||
restart_os
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
141
script/utils
Normal file
141
script/utils
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#!/usr/bin/env fish
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
function print_in_color
|
||||||
|
printf '%b' \
|
||||||
|
"$(tput setaf $argv[2] 2> /dev/null)" \
|
||||||
|
$argv[1] \
|
||||||
|
"$(tput sgr0 2> /dev/null)"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_in_red
|
||||||
|
print_in_color $argv[1] 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_in_yellow
|
||||||
|
print_in_color $argv[1] 3
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_in_green
|
||||||
|
print_in_color $argv[1] 2
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_in_purple
|
||||||
|
print_in_color $argv[1] 5
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_title
|
||||||
|
print_in_purple "\n • $argv[1]\n\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_success
|
||||||
|
print_in_green " [✔] $argv[1]\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_warning
|
||||||
|
print_in_yellow " [!] $argv[1]\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_error
|
||||||
|
print_in_red " [✖] $argv[1] $argv[2]\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_question
|
||||||
|
print_in_yellow " [?] $argv[1]\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_result
|
||||||
|
if [ "$argv[1]" -eq 0 ]
|
||||||
|
print_success $argv[2]
|
||||||
|
else
|
||||||
|
print_error $argv[2]
|
||||||
|
end
|
||||||
|
|
||||||
|
return $argv[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
function print_error_stream
|
||||||
|
while read -r line
|
||||||
|
print_error "↳ ERROR: $line"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
function show_spinner
|
||||||
|
set -l frames '/-\|'
|
||||||
|
|
||||||
|
set -l number_of_frames (string length $FRAMES)
|
||||||
|
|
||||||
|
set -l pid $argv[1]
|
||||||
|
set -l cmds $argv[2]
|
||||||
|
set -l msg $argv[3]
|
||||||
|
|
||||||
|
set -l i 0
|
||||||
|
set -l frame_text ""
|
||||||
|
|
||||||
|
printf "\n\n\n"
|
||||||
|
tput cuu 3
|
||||||
|
tput sc
|
||||||
|
|
||||||
|
while kill -0 "$pid" &> /dev/null
|
||||||
|
set i math $i + 1
|
||||||
|
set -l num math % $number_of_frames
|
||||||
|
set -l frame (string sub -s $num -l 1)
|
||||||
|
set frame_text " [$frame] $msg"
|
||||||
|
|
||||||
|
printf '%s' $frame_text
|
||||||
|
|
||||||
|
sleep 0.2
|
||||||
|
|
||||||
|
tput rc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
function set_trap
|
||||||
|
trap -p "$argv[1]" | grep "$argv[2]" &> /dev/null \
|
||||||
|
|| trap "$argv[2]" "$argv[1]"
|
||||||
|
end
|
||||||
|
|
||||||
|
function kill_all_subproccesses
|
||||||
|
set -l i ""
|
||||||
|
|
||||||
|
for i in (jobs -p)
|
||||||
|
kill "$i"
|
||||||
|
wait "$i" &> /dev/null
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
function execute
|
||||||
|
set -l cmds $argv[1]
|
||||||
|
set -q $argv[2] and set -l msg $argv[2] or set -l msg $argv[1]
|
||||||
|
|
||||||
|
set -l tmp_file "$(mktmp /tmp/XXXXX)"
|
||||||
|
|
||||||
|
set -l exit_code 0
|
||||||
|
|
||||||
|
set_trap 'EXIT' 'kill_all_subproccesses'
|
||||||
|
|
||||||
|
eval "$cmds" &> /dev/null 2> $tmp_file &
|
||||||
|
set cmds_pid $last_pid
|
||||||
|
|
||||||
|
show_spinner $cmds_pid $cmds $msg
|
||||||
|
|
||||||
|
wait $cmds_pid &> /dev/null
|
||||||
|
set exit_code $status
|
||||||
|
|
||||||
|
print_result $exit_code $msg
|
||||||
|
|
||||||
|
if [ $exit_code -ne 0 ]
|
||||||
|
print_error_stream < $tmp_file
|
||||||
|
end
|
||||||
|
|
||||||
|
rm -rf "$tmp_file"
|
||||||
|
|
||||||
|
return $exit_code
|
||||||
|
end
|
121
script/utils.sh
121
script/utils.sh
|
@ -1,5 +1,4 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env sh
|
||||||
# vim:set ft=bash:
|
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
@ -21,7 +20,7 @@ skip_questions()
|
||||||
|
|
||||||
ask_for_sudo()
|
ask_for_sudo()
|
||||||
{
|
{
|
||||||
sudo -v &> /dev/null
|
sudo -v >/dev/null 2>&1
|
||||||
|
|
||||||
# Update existing 'sudo' timestamp until this script has finished.
|
# Update existing 'sudo' timestamp until this script has finished.
|
||||||
#
|
#
|
||||||
|
@ -31,7 +30,7 @@ ask_for_sudo()
|
||||||
sudo -n true
|
sudo -n true
|
||||||
sleep 60
|
sleep 60
|
||||||
kill -0 "$$" || exit
|
kill -0 "$$" || exit
|
||||||
done &> /dev/null &
|
done >/dev/null 2>&1 &
|
||||||
}
|
}
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -93,7 +92,7 @@ print_question()
|
||||||
|
|
||||||
print_result()
|
print_result()
|
||||||
{
|
{
|
||||||
if [[ "$1" == 0 ]]; then
|
if [ "$1" = 0 ]; then
|
||||||
print_success "$2"
|
print_success "$2"
|
||||||
else
|
else
|
||||||
print_error "$2"
|
print_error "$2"
|
||||||
|
@ -110,6 +109,17 @@ print_error_stream()
|
||||||
}
|
}
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/32270158
|
||||||
|
# POSIX read -n 1
|
||||||
|
# Usage: var="$(read_char)"
|
||||||
|
read_char()
|
||||||
|
{
|
||||||
|
old=$(stty -g)
|
||||||
|
stty raw -echo min 0
|
||||||
|
printf '%s' "$(dd bs=1 count=1 2>/dev/null)"
|
||||||
|
stty "$old"
|
||||||
|
}
|
||||||
|
|
||||||
ask()
|
ask()
|
||||||
{
|
{
|
||||||
print_question "$1"
|
print_question "$1"
|
||||||
|
@ -124,32 +134,29 @@ get_answer()
|
||||||
ask_for_confirmation()
|
ask_for_confirmation()
|
||||||
{
|
{
|
||||||
print_question "$1 (y/n) "
|
print_question "$1 (y/n) "
|
||||||
read -r -n 1
|
REPLY="$(read_char)"
|
||||||
printf "\n"
|
printf "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
answer_is_yes()
|
answer_is_yes()
|
||||||
{
|
{
|
||||||
[[ "$REPLY" =~ ^[Yy]$ ]] \
|
expr "$REPLY" : '[Yy]$'
|
||||||
&& return 0 \
|
|
||||||
|| return 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
show_spinner()
|
show_spinner()
|
||||||
{
|
{
|
||||||
local -r FRAMES='/-\|'
|
readonly FRAMES='/-\|'
|
||||||
|
|
||||||
# shellcheck disable=SC2034
|
readonly NUMBER_OF_FRAMES=${#FRAMES}
|
||||||
local -r NUMBER_OF_FRAMES=${#FRAMES}
|
|
||||||
|
|
||||||
local -r CMDS="$2"
|
readonly CMDS="$2"
|
||||||
local -r MSG="$3"
|
readonly MSG="$3"
|
||||||
local -r PID="$1"
|
readonly PID="$1"
|
||||||
|
|
||||||
local i=0
|
i=0
|
||||||
local frame_text=""
|
frame_text=""
|
||||||
|
|
||||||
# Provide more space so that the text hopefully doesn't reach the bottom line
|
# Provide more space so that the text hopefully doesn't reach the bottom line
|
||||||
# of the terminal window.
|
# of the terminal window.
|
||||||
|
@ -163,8 +170,11 @@ show_spinner()
|
||||||
tput cuu 3
|
tput cuu 3
|
||||||
tput sc
|
tput sc
|
||||||
|
|
||||||
while kill -0 "$PID" &> /dev/null; do
|
while kill -0 "$PID" >/dev/null 2>&1; do
|
||||||
frame_text=" [${FRAMES:i++%NUMBER_OF_FRAMES:1}] $MSG"
|
i=$((i+1))
|
||||||
|
num=$((i % NUMBER_OF_FRAMES))
|
||||||
|
frame="$(echo $FRAMES | cut -c ${num}-$((num + 1)))"
|
||||||
|
frame_text=" [$frame] $MSG"
|
||||||
|
|
||||||
# Print frame text.
|
# Print frame text.
|
||||||
printf "%s" "$frame_text"
|
printf "%s" "$frame_text"
|
||||||
|
@ -180,40 +190,87 @@ show_spinner()
|
||||||
|
|
||||||
cmd_exists()
|
cmd_exists()
|
||||||
{
|
{
|
||||||
command -v "$1" &> /dev/null
|
command -v "$1" >/dev/null 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
is_git_repository()
|
is_git_repository()
|
||||||
{
|
{
|
||||||
git rev-parse &> /dev/null
|
git rev-parse >/dev/null 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
# https://stackoverflow.com/a/29835459
|
||||||
|
# POSIX compliant way of finding BASH_SOURCE
|
||||||
|
# Usage: sh_source "$0"
|
||||||
|
rreadlink()
|
||||||
|
(
|
||||||
|
target=$1
|
||||||
|
fname=
|
||||||
|
targetDir=
|
||||||
|
CDPATH=
|
||||||
|
|
||||||
|
{ \unalias command; \unset-f command; } >/dev/null 2>&1
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
[ -n "$ZSH_VERSION" ] && options[POSIX_BUILTINS]=on
|
||||||
|
|
||||||
|
while :; do
|
||||||
|
[ -L "$target" ] || [ -e "$target" ] || { command printf '%s\n' "ERROR: $target does not exist." >&2; return 1; }
|
||||||
|
# shellcheck disable=SC2164
|
||||||
|
command cd "$(command dirname -- "$target")"
|
||||||
|
fname=$(command basename -- "$target")
|
||||||
|
[ "$fname" = '/' ] && fname=''
|
||||||
|
|
||||||
|
if [ -L "$fname" ]; then
|
||||||
|
target=$(command ls -l "$fname")
|
||||||
|
target=${target#* -> }
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
break
|
||||||
|
done
|
||||||
|
|
||||||
|
targetDir=$(command pwd -P)
|
||||||
|
if [ "$fname" = '.' ]; then
|
||||||
|
command printf '%s\n' "${targetDir%/}"
|
||||||
|
elif [ "$fname" = '..' ]; then
|
||||||
|
command printf '%s\n' "${targetDir%/}/$fname"
|
||||||
|
fi
|
||||||
|
)
|
||||||
|
|
||||||
|
sh_source()
|
||||||
|
{
|
||||||
|
printf '%s' "$(dirname -- "$(rreadlink "$1")")"
|
||||||
}
|
}
|
||||||
|
|
||||||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
set_trap()
|
set_trap()
|
||||||
{
|
{
|
||||||
trap -p "$1" | grep "$2" &> /dev/null \
|
trap | grep "'$2' $1" >/dev/null 2>&1 \
|
||||||
|| trap '$2' "$1"
|
|| trap '$2' "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_all_subproccesses()
|
kill_all_subproccesses()
|
||||||
{
|
{
|
||||||
local i=""
|
i=""
|
||||||
|
|
||||||
for i in $(jobs -p); do
|
for i in $(jobs -p); do
|
||||||
kill "$i"
|
kill "$i"
|
||||||
wait "$i" &> /dev/null
|
wait "$i" >/dev/null 2>&1
|
||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
execute()
|
execute()
|
||||||
{
|
{
|
||||||
local -r CMDS="$1"
|
readonly CMDS="$1"
|
||||||
local -r MSG="${2:-$1}"
|
readonly MSG="${2:-$1}"
|
||||||
local -r TMP_FILE="$(mktemp /tmp/XXXXX)"
|
|
||||||
|
|
||||||
local exit_code=0
|
readonly TMP_FILE
|
||||||
local cmds_pid=""
|
TMP_FILE="$(mktemp /tmp/XXXXX)"
|
||||||
|
|
||||||
|
exit_code=0
|
||||||
|
cmds_pid=""
|
||||||
|
|
||||||
# If the current process is ended, also end all its subproccesses.
|
# If the current process is ended, also end all its subproccesses.
|
||||||
set_trap "EXIT" "kill_all_subproccesses"
|
set_trap "EXIT" "kill_all_subproccesses"
|
||||||
|
@ -221,7 +278,7 @@ execute()
|
||||||
# Execute commands in background
|
# Execute commands in background
|
||||||
# shellcheck disable=SC2261
|
# shellcheck disable=SC2261
|
||||||
eval "$CMDS" \
|
eval "$CMDS" \
|
||||||
&> /dev/null \
|
>/dev/null 2>&1 \
|
||||||
2> "$TMP_FILE" &
|
2> "$TMP_FILE" &
|
||||||
|
|
||||||
cmds_pid=$!
|
cmds_pid=$!
|
||||||
|
@ -231,13 +288,13 @@ execute()
|
||||||
|
|
||||||
# Wait for the commands to no longer be executing in the background, and then
|
# Wait for the commands to no longer be executing in the background, and then
|
||||||
# get their exit code.
|
# get their exit code.
|
||||||
wait "$cmds_pid" &> /dev/null
|
wait "$cmds_pid" >/dev/null 2>&1
|
||||||
exit_code=$?
|
exit_code=$?
|
||||||
|
|
||||||
# Print output based on what happened.
|
# Print output based on what happened.
|
||||||
print_result $exit_code "$MSG"
|
print_result $exit_code "$MSG"
|
||||||
|
|
||||||
if [[ $exit_code -ne 0 ]]; then
|
if [ $exit_code -ne 0 ]; then
|
||||||
print_error_stream < "$TMP_FILE"
|
print_error_stream < "$TMP_FILE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue