initial commit
authordanix <danix@danix.xyz>
Tue, 18 Dec 2018 14:12:50 +0000 (15:12 +0100)
committerdanix <danix@danix.xyz>
Tue, 18 Dec 2018 14:12:50 +0000 (15:12 +0100)
README.md [new file with mode: 0644]
clear [new file with mode: 0755]
create [new file with mode: 0755]
delete [new file with mode: 0755]
help [new file with mode: 0755]
list [new file with mode: 0755]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5bb2c72
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# Git Shell Commands
+
+A set of commands to be executed in a limited git shell environment
+
+## How it works
+
+```
+To Do
+```
+
+## List of files
+
+* clear
+* create
+* delete
+* help
+* list
+
+## More resources
+A more detailed explanations with examples of how these scripts work can be found
+on my blog at [danix.xyz](https://danix.xyz/2018/07/git-setup-own-server/).
+
diff --git a/clear b/clear
new file mode 100755 (executable)
index 0000000..5a1d7f4
--- /dev/null
+++ b/clear
@@ -0,0 +1,6 @@
+#! /bin/bash
+
+# usage:       clear - clear the current screen
+#
+
+/usr/bin/clear
diff --git a/create b/create
new file mode 100755 (executable)
index 0000000..04d299a
--- /dev/null
+++ b/create
@@ -0,0 +1,170 @@
+#! /bin/bash
+
+# usage:       create <PROJECT> - create a git bare repository named PROJECT.git
+#              this command will setup the repo and send a mail for confirmation.
+
+GITDIR="/var/git"
+MULTIMAIL="/usr/doc/git-2.14.5/contrib/hooks/multimail/git_multimail.py"
+GITUSER="git"
+GITGRP="git"
+VENVSDIR="/usr/local/venvs"
+USEVENV=false
+
+function is_bare() {
+       repodir=$1
+       if "$(git --git-dir="$repodir" rev-parse --is-bare-repository)" = true
+       then
+               true
+       else
+               false
+       fi
+}
+
+function git_init() {
+       PROJECT=$1
+       echo "creating project \"${PROJECT}.git\""
+       read -p "Describe your project in one line: " DESCRIPTION
+       if [ ! -d ${GITDIR}/${PROJECT}.git ]; then
+               mkdir ${GITDIR}/${PROJECT}.git
+       fi
+       cd ${GITDIR}/${PROJECT}.git
+       git init --bare
+       echo "Remember to insert a README.md file to explain what your project is about."
+       mkdir custom-hooks
+       ln -s $MULTIMAIL custom-hooks/git_multimail.py
+       touch hooks/post-receive
+       cat > hooks/post-receive <<EOPR
+#!/bin/sh
+/usr/bin/pee ${GITDIR}/${PROJECT}.git/custom-hooks/deploy.sh \
+       ${GITDIR}/${PROJECT}.git/custom-hooks/pip_install \
+       ${GITDIR}/${PROJECT}.git/custom-hooks/git_multimail.py
+
+EOPR
+       if [ $USEVENV == true ]; then
+               cat > custom-hooks/pip_install << EOPIP
+#!/bin/sh
+while read oldrev newrev refname; do
+       if [[ \$refname =~ .*/master$ ]]; then
+               # definitely updating master;
+               CHECKFILE=\$(git ls-tree --full-tree -r HEAD |grep requirements.txt |awk '{print \$3}')
+               TMPREQ=\$(git cat-file -p \$CHECKFILE > /tmp/${PROJECT}-req.txt)
+               if [ \$CHECKFILE ]; then
+                       ${VENVSDIR}/${PROJECT}/bin/pip install -r /tmp/${PROJECT}-req.txt
+               fi
+               if git diff-tree --name-only -r -z \$oldrev \$newrev \$CHECKFILE; then
+                       ${VENVSDIR}/${PROJECT}/bin/pip install -r /tmp/${PROJECT}-req.txt
+               fi
+       fi
+done
+EOPIP
+       fi
+       cat >> config <<EOT
+
+[multimailhook]
+       mailer = "sendmail"
+       refchangeShowGraph = true
+       mailingList = "danixland@gmail.com"
+       commitEmailFormat = "html"
+       htmlInIntro = true
+       htmlInFooter = true
+       from = "danix@danix.xyz"
+       administrator = "danix@danix.xyz"
+       quiet = true
+       logFile = "/var/log/multimail.log"
+       errorLogFile = "/var/log/multimail_err.log"
+EOT
+       touch custom-hooks/deploy.sh
+       cat > custom-hooks/deploy.sh <<EODP
+#!/bin/bash
+# Directory where to deploy files from repository
+DPTARGET=""
+# Directory containing repository
+DPGIT_DIR="${GITDIR}/${PROJECT}.git"
+# Branch that is going to be deployed to server
+DPBRANCH="master"
+
+while read oldrev newrev ref
+do
+       # if DPTARGET is empty we don't want deploy for this project
+       if [[ ! "" == \$DPTARGET ]]; then
+               # let's check that we are deploying to the correct branch
+               if [[ \$ref = refs/heads/\${DPBRANCH} ]]; then
+                       echo "Ref \$ref received. Deploying \${DPBRANCH} branch to production..."
+                       git --work-tree=\$DPTARGET --git-dir=\$DPGIT_DIR checkout -f \$DPBRANCH
+                       NOW=\$(date +"%d%m%Y-%H%M")
+                       git tag release_\$NOW \$DPBRANCH
+                       echo "   /==============================="
+                       echo "   | DEPLOYMENT COMPLETED"
+                       echo "   | Target branch: \$DPTARGET"
+                       echo "   | Target folder: \$DPGIT_DIR"
+                       echo "   | Tag name     : release_\$NOW"
+                       echo "   \=============================="
+               else
+                       echo "Ref \$ref received. Doing nothing: only the \${DPBRANCH} branch may be deployed on this server."
+               fi
+       else
+               echo "Target directory not declared. Skipping deploy to server."
+       fi
+done
+
+EODP
+       chmod 0755 hooks/post-receive custom-hooks/deploy.sh
+       echo $DESCRIPTION > description
+       cd ${GITDIR}/
+       chown -R ${GITUSER}:${GITGRP} ${GITDIR}/${PROJECT}.git
+       echo "All done, you can now work on \"${PROJECT}.git\""
+       exit 0
+}
+
+if [ ! -z $1 ]; then
+       if [ "python" == $1 ]; then
+               USEVENV=true
+               # this is a python project. Let's create a virtualenv
+               if [ ! -z $2 ]; then
+                       PROJECT=$2
+               else
+                       read -p 'Python project name: ' PROJECT
+               fi
+               virtualenv ${VENVSDIR}/${PROJECT}
+               echo "virtual environment created inside ${VENVSDIR}/${PROJECT}"
+       else
+               PROJECT=$1
+       fi
+else
+       read -p 'Project name: ' PROJECT
+fi
+
+if [ ! -d ${GITDIR}/${PROJECT}.git ]; then
+       git_init $PROJECT
+else
+       echo "Project directory ${PROJECT}.git already exists."
+       if [ $(ls -A ${GITDIR}/${PROJECT}.git) ]; then
+               if is_bare ${GITDIR}/${PROJECT}.git
+               then
+                       echo "looks like \"${PROJECT}.git\" is an existing git project directory, choose another name."
+                       exit 171
+               else
+                       echo "\"${PROJECT}.git\" is not empty, I can't create a Git Project in it. Choose another name."
+                       exit 172
+               fi
+       else
+               echo "\"${PROJECT}.git\" is an empty directory. Do you want to initialize a Git Project here? [y/N]"
+               read answer
+               case $answer in
+                       Y|y)
+                               git_init $PROJECT       
+                               ;;
+                       N|n)
+                               echo "Aborting due to user request."
+                               exit 173
+                               ;;
+                       *)
+                               # we assume no as default answer.
+                               echo "you said \"$answer\" which I don't understand, so to me is no. Aborting."
+                               exit 177
+                               ;;
+               esac
+       fi
+fi
+
+
diff --git a/delete b/delete
new file mode 100755 (executable)
index 0000000..f8664d4
--- /dev/null
+++ b/delete
@@ -0,0 +1,58 @@
+#! /bin/bash
+
+# usage:       delete <REPOSITORY> - PERMANENTLY delete a repository if existing.
+#              CAREFUL, this action cannot be undone. This command will ask for confirmation.
+
+GITDIR="/var/git"
+
+function is_bare() {
+       repodir=$1
+       if "$(git --git-dir="$repodir" rev-parse --is-bare-repository)" = true
+       then
+               true
+       else
+               false
+       fi
+}
+
+if [ ! -z $1 ]; then
+       PROJECT=$1
+else
+       read -p 'Project to delete: ' PROJECT
+fi
+
+if [ -d ${GITDIR}/${PROJECT}.git ]; then
+       if [[ $(ls -A ${GITDIR}/${PROJECT}.git) ]]; then
+               if is_bare ${GITDIR}/${PROJECT}.git
+               then
+                       echo "You are going to delete the git repository \"${PROJECT}.git\" Do you really want to continue? Note, this action cannot be reverted. [y/N]"
+                       read delAnswer
+                       case $delAnswer in
+                               Y|y)
+                                       rm -rfv ${PROJECT}.git
+                                       if [ $? == 0 ]; then
+                                               echo "Successfully deleted ${PROJECT}.git"
+                                       else
+                                               echo "An error occurred while deleting ${PROJECT}.git"
+                                       fi
+                                       ;;
+                               N|n)
+                                       echo "Aborting due to user request."
+                                       exit 173
+                                       ;;
+                               *)
+                                       echo "you said \"$delAnswer\" which I don't understand. Assuming No. Aborting."
+                                       exit 177
+                                       ;;
+                       esac
+               else
+                       echo "\"${PROJECT}.git\" doesn't look like a git repository. Check with your System Administrator."
+                       exit 177
+               fi
+       else
+               echo "\"${PROJECT}.git\" is an empty directory, Skipping. Check with your System Administrator."
+               exit 177
+       fi
+fi
+
+
diff --git a/help b/help
new file mode 100755 (executable)
index 0000000..19d26ec
--- /dev/null
+++ b/help
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# usage:       help - Lists all the available commands
+#              help <command> - Detailled explanation of how "command" works
+
+if tty -s
+then
+       HELPTEXT="Hi $USER, Run 'help' for help, 'help <command>' for specific help on a command, run 'exit' to exit. Available commands:"
+else
+       HELPTEXT="Hi $USER, Run 'help' for help, 'help <command>' for specific help on a command. Available commands:"
+fi
+
+cd "$(dirname "$0")"
+
+if [[ ! -z $1 ]]; then
+       cmd=$1
+       if [[ -f $cmd && -x $cmd ]]; then
+               awk 'NR>=3&&NR<=4' $cmd | cut -c 3-
+       else
+               echo "command \"$cmd\" doesn't exists"
+       fi
+else
+       echo $HELPTEXT
+       for cmd in *
+       do
+               case "$cmd" in
+               help) ;;
+               *) [ -f "$cmd" ] && [ -x "$cmd" ] && echo "$cmd" ;;
+               esac
+       done
+fi
+
diff --git a/list b/list
new file mode 100755 (executable)
index 0000000..cf77e32
--- /dev/null
+++ b/list
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+# usage:       list - Lists all "bare" repositories on the server
+#              directories which are not bare repos will be skipped
+
+print_if_bare_repo='
+       if "$(git --git-dir="$1" rev-parse --is-bare-repository)" = true
+       then
+               printf "%s\n" "${1#./}"
+       fi
+'
+
+find -type d -name "*.git" -exec sh -c "$print_if_bare_repo" -- \{} \; -prune 2>/dev/null