You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							257 lines
						
					
					
						
							6.7 KiB
						
					
					
				
			
		
		
	
	
							257 lines
						
					
					
						
							6.7 KiB
						
					
					
				#!/bin/zsh | 
						|
# .files/install | 
						|
# (c) 2014-2017 MORI Taeyeon | 
						|
 | 
						|
# Paths & Utils | 
						|
DOT="$(realpath "$(dirname "$0")")" | 
						|
cd "$DOT" | 
						|
 | 
						|
setopt EXTENDED_GLOB | 
						|
source "$DOT/lib/libzsh-utils.zsh" | 
						|
 | 
						|
 | 
						|
# Parse commandline | 
						|
# ============================= | 
						|
OVERWRITE=false | 
						|
ASK=true | 
						|
 | 
						|
function print_usage() { | 
						|
    echo "Usage: $1 [--help] [--overwrite] [--dont-ask]" | 
						|
    echo | 
						|
    echo "Install Tae's dotfiles" | 
						|
    echo | 
						|
    echo "Parameters:" | 
						|
    echo "    -h, --help    Display this help message" | 
						|
    echo "    --overwrite   Just overwrite existing dotfiles" | 
						|
    echo "    --dont-ask    Don't ask questions. Use default values" | 
						|
} | 
						|
 | 
						|
for arg in "$@"; do | 
						|
    [[ -z "$STATE" ]] && { | 
						|
        case "$arg" in | 
						|
            -h|--help) print_usage "$0"; exit 0;; | 
						|
            --overwrite) OVERWRITE=true;; | 
						|
            --dont-ask) ASK=false;; | 
						|
            *) print_usage "$0"; exit 1;; | 
						|
        esac | 
						|
    } || { | 
						|
        case "$STATE" in | 
						|
            # handle options with parameters | 
						|
        esac | 
						|
        STATE= | 
						|
    } | 
						|
done | 
						|
[[ -n "$STATE" ]] && err "Option $STATE is missing it's parameter!" && exit 1 | 
						|
 | 
						|
 | 
						|
# Helper functions | 
						|
# ============================= | 
						|
function generate() { | 
						|
    [[ -e "$1" ]] && ! $OVERWRITE && ! grep -q "Generated by .files/install" "$1" && \ | 
						|
        err "Custom version of $1 detected. Please delete it before running .files/install" && exit 1 | 
						|
    echo "${2-#} Generated by .files/install" >"$1" | 
						|
    echo "${2-#} `date "+%m/%d/%Y %H:%M:%S"`" >>"$1" | 
						|
    echo >>"$1" | 
						|
    cat >>"$1" | 
						|
} | 
						|
 | 
						|
function relink() { | 
						|
    [[ ! -e "$1" ]] && err "No such file or directory: '$1'" && return 1 | 
						|
    [[ -L "$2" ]] && rm -f "$2" | 
						|
    [[ -e "$2" ]] && ! $OVERWRITE && err "File already exists and isn't a symbolic link: '$2'" && return 1 | 
						|
    color 31 ln -sr "$1" "$2" | 
						|
} | 
						|
 | 
						|
 | 
						|
# Prepare | 
						|
# ============================= | 
						|
# Update git modules | 
						|
msg "Updating git submodules..." | 
						|
git submodule update --init --recursive | 
						|
 | 
						|
# Ask questions about user | 
						|
$ASK && msg "Asking questions..." || err "Not asking any questions:" | 
						|
 | 
						|
# Try to load previous configuration | 
						|
[[ -e "$DOT/etc/user-info" ]] && source "$DOT/etc/user-info" | 
						|
[[ -e "$DOT/etc/hostname" ]] && HOSTNAME=`cat "$DOT/etc/hostname"` | 
						|
 | 
						|
# Retrieve realname from /etc/passwd GECOS | 
						|
[[ -z "$REALNAME" ]] && REALNAME=`grep "^$USER:[^:]*:$UID:" /etc/passwd | cut -d: -f5 | cut -d, -f1` | 
						|
[[ -z "$HOSTNAME" ]] && HOSTNAME=`hostname` | 
						|
 | 
						|
if $ASK; then | 
						|
    ask "  Real name" REALNAME | 
						|
    ask "  E-Mail address" EMAIL | 
						|
    ask "  Computer name" HOSTNAME | 
						|
else | 
						|
    color 36 echo "  default REALNAME=\"$REALNAME\"" | 
						|
    color 36 echo "  default EMAIL=\"$EMAIL\"" | 
						|
    color 36 echo "  default HOSTNAME=\"$HOSTNAME\"" | 
						|
fi | 
						|
 | 
						|
# Write down answers | 
						|
color 32 echo "  Writing etc/user-info" | 
						|
generate "$DOT/etc/user-info" <<EOF | 
						|
REALNAME="$REALNAME" | 
						|
EMAIL="$EMAIL" | 
						|
EOF | 
						|
 | 
						|
color 32 echo "  Writing etc/hostname" | 
						|
echo $HOSTNAME >"$DOT/etc/hostname" | 
						|
 | 
						|
# Handle local-only alternatives | 
						|
HOST_LC=${(L)HOSTNAME} | 
						|
 | 
						|
function refset() { | 
						|
    eval "$1=\$2" | 
						|
} | 
						|
 | 
						|
function inspect_name() { | 
						|
    # gimme namerefs... | 
						|
    #local -n name=$1 prio=$2 | 
						|
    #local filename=$3 | 
						|
    # Check local-only files | 
						|
    refset $1 ${3%.local} | 
						|
    if [[ ${(P)1} != $3 ]]; then | 
						|
        refset $2 3 | 
						|
        return 0 | 
						|
    fi | 
						|
    # Check hostname-specific file | 
						|
    refset $1 ${3%@*} | 
						|
    if [[ ${(P)1} != $3 ]]; then | 
						|
        refset $2 2 | 
						|
        [[ ${3##*@} == $HOST_LC ]] | 
						|
        return $? | 
						|
    fi | 
						|
    # Standard file | 
						|
    refset $2 1 | 
						|
    return 0 | 
						|
} | 
						|
 | 
						|
function add_names() { | 
						|
    local an_name an_prio | 
						|
    #local -n names=$1 prios=$2 | 
						|
    for an_file in ${(@)argv[3,$#]}; do | 
						|
        if inspect_name an_name an_prio $an_file && [[ $an_prio -gt ${${(P)2}[$an_name]} ]]; then | 
						|
            refset $1\[\$an_name\] $an_file | 
						|
            refset $2\[\$an_name\] $an_prio | 
						|
        fi | 
						|
    done | 
						|
} | 
						|
 | 
						|
# Write files to $HOME | 
						|
# ============================= | 
						|
# Setup dotfiles | 
						|
msg "Linking dotfiles..." | 
						|
(){ | 
						|
    local -A names prios | 
						|
    pushd $DOT/dotfiles | 
						|
    add_names names prios * | 
						|
    for name src in ${(@kv)names}; do | 
						|
        color 32 echo "  Adding .$name" | 
						|
        relink $src $HOME/.$name | 
						|
    done | 
						|
    popd | 
						|
} | 
						|
 | 
						|
# Setup .config | 
						|
: ${XDG_CONFIG_HOME:=~/.config} | 
						|
msg "Linking .config files... ($XDG_CONFIG_HOME)" | 
						|
(){ | 
						|
    function relink_r() { | 
						|
        local target=$1 dest=$2 name=${3:-$2} from | 
						|
        [[ ${target:t} != ${dest:t} ]] && from=" (${target:t})" | 
						|
        if [[ ! -d $target ]]; then | 
						|
            color 32 echo "  Adding $name$from" | 
						|
            if [[ -L $target ]]; then | 
						|
                cp -P $target $dest | 
						|
            else | 
						|
                relink $target $dest | 
						|
            fi | 
						|
        else | 
						|
            if [[ ! -d $dest ]]; then | 
						|
                color 32 echo "  Creating directory $name/$from" | 
						|
                mkdir $dest | 
						|
            elif [[ -n $from ]]; then | 
						|
                color 32 echo "  Adding directory $name/$from" | 
						|
            fi | 
						|
            # This is still slightly ugly | 
						|
            local -A names prios | 
						|
            add_names names prios $target/* | 
						|
            for dst src in ${(@kv)names}; do | 
						|
                relink_r $src $dest/${dst:t} $name/${dst:t} | 
						|
            done | 
						|
        fi | 
						|
    } | 
						|
    pushd $DOT/config | 
						|
    local -A names prios | 
						|
    add_names names prios * | 
						|
    for dst src in ${(@kv)names}; do | 
						|
        relink_r $src $XDG_CONFIG_HOME/$dst $dst | 
						|
    done | 
						|
    popd | 
						|
} | 
						|
 | 
						|
# Setup git | 
						|
# ============================= | 
						|
msg "Setting up Git configuration..." | 
						|
 | 
						|
GIT="$DOT/git" | 
						|
[[ -e "$HOME/.gitconfig" ]] && ! grep -q ".files/install" "$HOME/.gitconfig" && err "Custom ~/.gitconfig already exists! Please remove it before running .files/install" && exit 1 | 
						|
 | 
						|
color 32 echo "  Writing .gitconfig" | 
						|
generate "$HOME/.gitconfig" <<EOF | 
						|
[include] | 
						|
    path = $(relpath "$GIT" "$HOME")/config | 
						|
    path = $(relpath "$GIT" "$HOME")/user-info | 
						|
EOF | 
						|
 | 
						|
[ "`uname -s`" = "Darwin" ] && \ | 
						|
cat >>"$HOME/.gitconfig" <<EOF | 
						|
    path = $(relpath "$GIT" "$HOME")/osx | 
						|
EOF | 
						|
 | 
						|
color 32 echo "  Writing git/user-info" | 
						|
generate "$GIT/user-info" <<EOF | 
						|
[user] | 
						|
    name = $REALNAME | 
						|
    email = $EMAIL | 
						|
EOF | 
						|
 | 
						|
 | 
						|
# Setup ZSH/Prezto | 
						|
# ============================= | 
						|
msg "Setting up ZSH configuration..." | 
						|
ZSH="$DOT/zsh" | 
						|
 | 
						|
color 32 echo "  Writing .zshenv" | 
						|
generate "$HOME/.zshenv" <<EOF | 
						|
export DOTFILES="\$HOME/$(relpath "$DOT" "$HOME")" | 
						|
ZDOTDIR="\$DOTFILES/zsh" | 
						|
[[ -f "\$ZDOTDIR/zshenv" ]] && source "\$ZDOTDIR/zshenv" | 
						|
[[ ! -o LOGIN && "\$SHLVL" == 1 && -f "\$ZDOTDIR/zprofile" ]] && source "\$ZDOTDIR/zprofile" | 
						|
EOF | 
						|
 | 
						|
for file in zshrc zpreztorc zlogin zlogout zprofile; do | 
						|
    color 32 echo "  Adding .$file" | 
						|
    relink "$ZSH/$file" "$ZSH/.$file" | 
						|
done | 
						|
 | 
						|
 | 
						|
# Do misc setup | 
						|
# ============================= | 
						|
test -f "$DOTFILES/install.extra" && "$DOTFILES/install.extra" | 
						|
 | 
						|
# Check login shell | 
						|
if  getent passwd $(id -un) | grep -q 'zsh$'; then | 
						|
    msg "Login shell is already set to zsh, you're good to go!" | 
						|
else | 
						|
    msg "Setting login shell to '$(which zsh)'..." | 
						|
    chsh -s "$(which zsh)" | 
						|
fi | 
						|
 | 
						|
# Done. | 
						|
warn "You may need to relog for all changes to take effect." | 
						|
warn "If you're currently running zsh, you definitely need to at least restart the shell to apply changes." | 
						|
 | 
						|
 |