grm (6107B)
1 #!/bin/sh 2 # grm: git repo manager, tilde edition 3 4 #---------------+----------+-----------------# 5 # | config | # 6 # +----------+ # 7 8 # root directory of git repositories 9 GRM_REPOS_ROOT="$HOME/public_html" 10 11 # default url prefix (without ending slash) 12 GRM_URL_PREFIX="https://$(hostname -f)/~$USER" 13 14 # path of the post-receive hooks for stagit 15 GRM_POSTRECV_HOOK="$HOME/bin/stagit-post-receive" 16 17 # root directory of stagit web pages 18 STAGIT_WEB_ROOT="$HOME/public_html/git" 19 20 # # 21 # # 22 #--------------------------------------------# 23 24 # for stagit 25 export LC_CTYPE="en_US.UTF-8" 26 27 prog_name="${0##*/}" 28 repos_root=${GRM_REPOS_ROOT:-$HOME/public_html} 29 web_root=${STAGIT_WEB_ROOT:-$HOME/public_html/git} 30 31 recompile_repo() { 32 echo "[$1] recompiling stagit pages..." 33 repo_dir="${repos_root}/${1}.git" 34 repo_web_dir="${web_root}/${repo_name}" 35 cachefile="${repo_dir}/.htmlcache" 36 37 [ -d "$repo_dir" ] || { echo "[$1] repo not found"; return 1; } 38 mkdir -p "$repo_web_dir" 39 40 cd "${repo_web_dir:?}" && \ 41 rm -f "$cachefile" && \ 42 rm -rf "commit" "file" && \ 43 stagit -c "$cachefile" "$repo_dir" && \ 44 ln -sf log.html index.html && \ 45 echo "[$1] done!" 46 } 47 48 rebuild_index() { 49 echo "[index] rebuilding index..." 50 mkdir -p "${web_root}" || return 1; 51 # 1. find all directories in $repos_root ending with .git 52 # 2. exclude any repo marked with stagit-no-index 53 # 3. sort the result 54 # 4. hack for posix compatibility 55 # 5. run stagit-index on the result 56 # 6. export result to index.html 57 find "${repos_root}/." ! -name . -prune \ 58 -type d -name "*.git" \ 59 -exec test ! -e "{}/stagit-no-index" \; \ 60 -print \ 61 | sort -f \ 62 | sed -e 's/"/"\\""/g' -e 's/.*/"&"/' \ 63 | xargs stagit-index \ 64 > "${web_root}/index.html" && \ 65 echo "[index] done!" 66 } 67 68 RED="\033[91m" 69 GREEN="\033[92m" 70 BLUE="\033[94m" 71 RESET="\033[0m" 72 73 grm_new() { 74 set -e 75 url_prefix=${GRM_URL_PREFIX:-https://$(hostname -f)/~$USER} 76 postrecv_path=${GRM_POSTRECV_HOOK:-$HOME/bin/stagit-post-receive} 77 default_desc="a work in progress" 78 79 printf "%b\n> " "${BLUE}repo name${RESET}" 80 read -r repo_name 81 [ -z "$repo_name" ] && \ 82 { echo "no repo name given, exiting..."; exit 1; } 83 84 # now we have the complete path of the repo 85 repo_path="$repos_root/${repo_name}.git" 86 [ -e "$repo_path" ] && \ 87 { echo "repository already exists"; exit 1; } 88 89 printf "%b\n> " "${BLUE}no index? [${GREEN}y/N${BLUE}]${RESET}" 90 read -r hidden 91 92 printf "%b%s%b\n> " "${BLUE}description [${GREEN}" "$default_desc" "${BLUE}]${RESET}" 93 read -r repo_desc 94 repo_desc=${repo_desc:-$default_desc} 95 96 printf "%b%s%b\n> " "${BLUE}owner [${GREEN}" "$USER" "${BLUE}]${RESET}" 97 read -r owner 98 owner=${owner:-$USER} 99 100 printf "%b%s%b\n> " \ 101 "${BLUE}clone url [${GREEN}" "$url_prefix/${repo_name}.git" "${BLUE}]${RESET}" 102 read -r clone_url 103 clone_url=${clone_url:-$url_prefix/${repo_name}.git} 104 105 # start creating repo 106 git init --bare "$repo_path" 107 108 echo "writing stagit metadata..." 109 printf "%s\n" "$repo_desc" > "$repo_path/description" 110 printf "%s\n" "$owner" > "$repo_path/owner" 111 printf "%s\n" "$clone_url" > "$repo_path/url" 112 113 if echo "$hidden" | grep -iq "^y$"; then 114 : >> "$repo_path/stagit-no-index" 115 fi 116 117 echo "installing stagit post-receive hook..." 118 ln -sf "$postrecv_path" "$repo_path/hooks/post-receive" 119 echo "installing post-update hook for updating server info..." 120 mv "$repo_path/hooks/post-update.sample" "$repo_path/hooks/post-update" 121 echo "updating server info for the first time..." 122 git -C "$repo_path" update-server-info 123 124 echo "done!" 125 } 126 127 grm_remove() { 128 [ $# -gt 0 ] || { echo "no repo name given, exiting..."; exit 1; } 129 130 for repo in "$@" 131 do 132 printf "remove %s? [y/N] " "$repo" 133 read -r resp 134 if echo "$resp" | grep -iq "^y$"; then 135 rm -rf "${repos_root:?}/${repo:?}.git" || continue; 136 rm -rf "${web_root:?}/${repo:?}" || continue; 137 fi 138 done 139 # only rebuild index if stagit exists 140 command -v stagit-index >/dev/null && rebuild_index & 141 wait 142 } 143 144 grm_list() { 145 find "${repos_root}/." ! -name . -prune \ 146 -type d -name "*.git" \ 147 -exec basename {} '.git' \; 148 } 149 150 grm_recompile() { 151 for repo_name in "$@" 152 do 153 recompile_repo "$repo_name" & 154 done 155 rebuild_index & 156 wait 157 echo "recompilation done!" 158 } 159 160 grm_recompileall() { 161 grm_list \ 162 | sed -e 's/"/"\\""/g' -e 's/.*/"&"/' \ 163 | xargs "$0" rc 164 } 165 166 grm_info() { 167 [ -z "$1" ] && { echo "no repo name given, exiting..."; exit 1; } 168 169 repo_name=$1 170 repo_dir="${repos_root}/${repo_name}.git" 171 172 [ -d "$repo_dir" ] || { echo "can't find repo named $repo_name"; exit 1; } 173 echo "name: $repo_name" 174 printf "indexed: " 175 176 if [ -e "${repo_dir}/stagit-no-index" ]; then 177 printf "%b\n" "${RED}no${RESET}" 178 else 179 printf "%b\n" "${GREEN}yes${RESET}" 180 fi 181 182 [ -f "${repo_dir}/description" ] && \ 183 echo "description: $(cat "${repo_dir}/description")" 184 185 [ -f "${repo_dir}/owner" ] && \ 186 echo "owner: $(cat "${repo_dir}/owner")" 187 188 [ -f "${repo_dir}/url" ] && \ 189 echo "url: $(cat "${repo_dir}/url")" 190 } 191 192 show_help() { 193 cat << EOF 194 usage: $prog_name <command> [<args>] 195 196 git repo manager, tilde edition 197 198 commands: 199 new create a new repo 200 info repo_name display metadata of the repo 201 ls list all repos 202 rm repo1 [repo2..] remove repos 203 rc recompile stagit index 204 rc repo1 [repo2..] recompile stagit pages for repos, 205 and recompile index 206 rca recompile all repos 207 help show help 208 EOF 209 } 210 211 # parse subcommands 212 case "$1" in 213 new) cmd=new;; 214 ls|list) cmd=list;; 215 rm|remove) cmd=remove;; 216 rc|recompile) cmd=recompile;; 217 rca|recompileall) cmd=recompileall;; 218 info) cmd=info;; 219 *) { show_help; exit; };; 220 esac 221 222 shift 223 grm_"$cmd" "$@"