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" "$@"