373 lines
8.9 KiB
Bash
Executable file
373 lines
8.9 KiB
Bash
Executable file
#!/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"
|
|
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
|
|
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 2 -name "*.symlink" -not -path ".git"); do
|
|
dst="$HOME/$(basename "${src%.*}")"
|
|
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
|
|
|
|
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
|
|
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 "$@"
|