#!/bin/bash export PLATFORM _TAB_="$(printf "\t")" _SPACE_=' ' _BLANK_="${_SPACE_}${_TAB_}" _IFS_="$IFS" #---------------------------------------- # Shell判定 #---------------------------------------- function is_bash() { [ -n "$BASH_VERSION" ] } function is_zsh() { [ -n "$ZSH_VERSION" ] } #---------------------------------------- # OS判定 #---------------------------------------- # OS名取得 function ostype() { uname | lower } # 環境変数にOS名設定 function os_detect() { export PLATFORM case "$(ostype)" in *'linux'*) PLATFORM='linux' ;; *'darwin'*) PLATFORM='osx' ;; *'bsd'*) PLATFORM='bsd' ;; *) PLATFORM='unknown' ;; esac } # OSX判定 function is_osx() { os_detect if [ "$PLATFORM" = "osx" ]; then return 0 else return 1 fi } alias is_mac=is_osx # GNU/Linux判定 function is_linux() { os_detect if [ "$PLATFORM" = "linux" ]; then return 0 else return 1 fi } # FreeBSD判定 function is_bsd() { os_detect if [ "$PLATFORM" = "bsd" ]; then return 0 else return 1 fi } # OS名取得 function get_os() { local os for os in osx linux bsd; do if is_$os; then echo $os fi done } #---------------------------------------- # echo制御 #---------------------------------------- function e_newline() { printf "\n" } function e_header() { printf " \033[37;1m%s\033[m\n" "$*" } function e_error() { printf " \033[31m%s\033[m\n" "✖ $*" 1>&2 } function e_warning() { printf " \033[31m%s\033[m\n" "$*" } function e_done() { printf " \033[37;1m%s\033[m...\033[32mOK\033[m\n" "✔ $*" } function e_arrow() { printf " \033[37;1m%s\033[m\n" "➜ $*" } function e_indent() { for ((i=0; i<${1:-4}; i++)); do echon " " done if [ -n "$2" ]; then echo "$2" else cat <&0 fi } function e_success() { printf " \033[37;1m%s\033[m%s...\033[32mOK\033[m\n" "✔ " "$*" } function e_failure() { die "${1:-$FUNCNAME}" } # 色と文字列を指定して色付き文字の出力 function ink() { if [ "$#" -eq 0 -o "$#" -gt 2 ]; then echo "Usage: ink " echo "Colors:" echo " black, white, red, green, yellow, blue, purple, cyan, gray" return 1 fi local open="\033[" local close="${open}0m" local black="0;30m" local red="1;31m" local green="1;32m" local yellow="1;33m" local blue="1;34m" local purple="1;35m" local cyan="1;36m" local gray="0;37m" local white="$close" local text="$1" local color="$close" if [ "$#" -eq 2 ]; then text="$2" case "$1" in black | red | green | yellow | blue | purple | cyan | gray | white) eval color="\$$1" ;; esac fi printf "${open}${color}${text}${close}" } # フォーマットと文字列を指定してタイムスタンプ付きの文字列出力 function logging() { if [ "$#" -eq 0 -o "$#" -gt 2 ]; then echo "Usage: logging " echo "Formatting Options:" echo " TITLE, ERROR, WARN, INFO, SUCCESS" return 1 fi local color= local text="$2" case "$1" in TITLE) color=yellow ;; ERROR | WARN) color=red ;; INFO) color=blue ;; SUCCESS) color=green ;; *) text="$1" esac timestamp() { ink gray "[" ink purple "$(date +%H:%M:%S)" ink gray "] " } timestamp; ink "$color" "$text"; echo } function log_pass() { logging SUCCESS "$1" } function log_fail() { logging ERROR "$1" 1>&2 } function log_warn() { logging WARN "$1" } function log_info() { logging INFO "$1" } function log_echo() { logging TITLE "$1" } #---------------------------------------- # ユーティリティ #---------------------------------------- # パスにコマンドが存在するかの確認 function is_exists() { which "$1" >/dev/null 2>&1 return $? } # is_existsのラッパー function has() { is_exists "$@" } # die returns exit code error and echo error message function die() { e_error "$1" 1>&2 exit "${2:-1}" } # 改行なしecho # -n をエミュレート function echon() { echo "$*" | tr -d '\n' } # noecho is the same as echon function noecho() { if [ "$(echo -n)" = "-n" ]; then echo "${*:-> }\c" else echo -n "${@:-> }" fi } # 小文字化 function lower() { if [ $# -eq 0 ]; then cat <&0 elif [ $# -eq 1 ]; then if [ -f "$1" -a -r "$1" ]; then cat "$1" else echo "$1" fi else return 1 fi | tr "[:upper:]" "[:lower:]" } # 大文字化 function upper() { if [ $# -eq 0 ]; then cat <&0 elif [ $# -eq 1 ]; then if [ -f "$1" -a -r "$1" ]; then cat "$1" else echo "$1" fi else return 1 fi | tr "[:lower:]" "[:upper:]" } # 文字数カウント function len() { local length length="$(echo "$1" | wc -c | sed -e 's/ *//')" #echo "$(expr "$length" - 1)" echo $(("$length" - 1)) } # contains returns true if the specified string contains # the specified substring, otherwise returns false # http://stackoverflow.com/questions/2829613/how-do-you-tell-if-a-string-contains-another-string-in-unix-shell-scripting contains() { string="$1" substring="$2" if [ "${string#*$substring}" != "$string" ]; then return 0 # $substring is in $string else return 1 # $substring is not in $string fi } #---------------------------------------- # チェック関数 #---------------------------------------- # ログインShellか確認 function is_login_shell() { [ "$SHLVL" = 1 ] } # GITリポジトリか確認 function is_git_repo() { git rev-parse --is-inside-work-tree &>/dev/null return $? } # GITのリモートが存在してるか確認 function is_git_remote() { git remote show $1 &> /dev/null return $? } # screen起動中 function is_screen_running() { [ ! -z "$STY" ] } # tmux起動中 function is_tmux_runnning() { [ ! -z "$TMUX" ] } # screen or tmux起動中 function is_screen_or_tmux_running() { is_screen_running || is_tmux_runnning } function is_brew_install() { if has "brew"; then brew list | grep "$1" >/dev/null 2>&1; return $? else log_fail "error: require: Homebrew" exit 1 fi } function is_brew_tap_install() { if has "brew"; then brew tap-info "$1" >/dev/null 2>&1; return $? else log_fail "error: require: Homebrew" exit 1 fi } # sshコマンドでログインしてるか function is_ssh_running() { [ ! -z "$SSH_CLIENT" ] } # 数値確認 function is_number() { if [ $# -eq 0 ]; then cat <&0 else echo "$1" fi | grep -E '^[0-9]+$' >/dev/null 2>&1 if [ $? -eq 0 ]; then return 0 else return 1 fi } alias is_int=is_number alias is_num=is_number # ブランク判定 is_empty() { if [ $# -eq 0 ]; then cat <&0 else echo "$1" fi | grep -E "^[$_BLANK_]*$" >/dev/null 2>&1 if [ $? -eq 0 ]; then return 0 else return 1 fi } # インタラクティブモード判定 is_interactive() { if [ "${-/i/}" != "$-" ]; then return 0 fi return 1 } # dotfilesのパス格納変数の定義 if [ -z "${DOTPATH:-}" ]; then DOTPATH=~/.dotfiles export DOTPATH fi # リポジトリのURL定義 DOTFILES_GITHUB="https://github.com/Alfr0475/dotfiles.git" export DOTFILES_GITHUB # ロゴ出力 dotfiles_logo=" _ _ __ ___ _ _ _____ ____ _ _ __ _ _ / \ | |/ _|_ __ / _ \| || |___ | ___| __| | ___ | |_ / _(_) | ___ ___ / _ \ | | |_| '__| | | | || |_ / /|___ \ / _\` |/ _ \| __| |_| | |/ _ \/ __| / ___ \| | _| | | |_| |__ _/ / ___) | | (_| | (_) | |_| _| | | __/\__ \\ /_/ \_\_|_| |_| \___/ |_|/_/ |____/ \__,_|\___/ \__|_| |_|_|\___||___/ *** WHAT IS INSIDE? *** 1. Download https://github.com/Alfr0475/dotfiles.git 2. Symlinking dot files to your home directory 3. Execute all sh files within \`etc/init/\` (optional) See the README for documentation. https://github.com/Alfr0475/dotfiles Copyright (c) 2016 @Alfr0475 Licensed under the MIT license. "; function dotfiles_download() { if [ -d "$DOTPATH" ]; then log_fail "$DOTPATH: already exists" exit 1 fi e_newline e_header "Downloading dotfile..." if is_exists "git"; then # submoduleも一緒にcloneする git clone --recursive "$DOTFILES_GITHUB" "$DOTPATH" elif is_exists "curl" || is_exists "wget"; then local tarball="https://github.com/Alfr0475/dotfiles/archive/master.tar.gz" if is_exists "curl"; then curl -L "$tarball" elif is_exists "wget"; then wget -O - "$tarball" fi | tar xvz if [ ! -d dotfiles-master ]; then log_fail "dotfiles-master: not found" exit 1 fi command mv -f dotfiles-master "$DOTPATH" else log_fail "curl or wget required" exit 1 fi } function dotfiles_deploy() { e_newline e_header "Deploying dotfiles..." if [ ! -d $DOTPATH ]; then log_fail "$DOTPATH: not found" exit 1 fi cd "$DOTPATH" make deploy && e_newline && e_done "Deploy" } function dotfiles_initialize() { # -c の引数が init の時のみ実行 if [ "$1" = "init" ]; then e_newline e_header "Initializing dotfiles..." if [ -f Makefile ]; then make init else log_fail "Makefile: not found" exit 1 fi && e_newline && e_done "Initialize" fi } function dotfiles_install() { # リポジトリダウンロード dotfiles_download && # dotfilesの配置 dotfiles_deploy && # 初期設定スクリプトの実行 dotfiles_initialize "$@" } if echo "$-" | grep -q "i"; then # インタラクティブモードで読み込まれたらインストール処理は実行しない # ライブラリとして機能する LOADED_COMMON=1 export LOADED_COMMON return else # bash以外の起動を認めない if ! is_bash; then return fi # bash a.sh の形を無視する if [ "$0" = "${BASH_SOURCE}" ]; then exit fi # bash -c "$(cat a.sh)" # cat a.sh | bash # 上記2つの形を有効にする # # BASH_EXECUTION_STRING : -c の引数で渡された文字列 # -p : 名前付きパイプであれば真 if [ -n "${BASH_EXECUTION_STRING:-}" ] || [ -p /dev/stdin ]; then # 既にインタラクティブモードで読み込まれていたらインストール処理は実行しない if [ "${LOADED_COMMON:=0}" = 1 ]; then exit fi # error hook登録 # Ctrl+cか終了値が0以外なら引数のコマンドを実行する trap "e_error 'terminated'; exit 1" INT ERR echo "$dotfiles_logo" # $@ に引数を渡す場合は bash に -s で引数を渡す dotfiles_install "$@" if [ -p /dev/stdin ]; then e_warning "Now continue with Rebooting your shell" else e_newline e_arrow "Restarting your shell..." exec "${SHELL}" fi fi fi