public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: files/shlib/, files/hooks/
  2013-06-22 15:24 [gentoo-commits] proj/R_overlay:master commit in: files/shlib/, files/hooks/ André Erdmann
@ 2013-06-21 14:09 ` André Erdmann
  0 siblings, 0 replies; 2+ messages in thread
From: André Erdmann @ 2013-06-21 14:09 UTC (permalink / raw
  To: gentoo-commits

commit:     f814f32ab17ace769f25ccf80ca77d93a82c3a92
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 21 14:07:24 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 21 14:07:24 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f814f32a

roverlay/files: shlib, hooks

This commit adds shell script files for running hooks.

shlib/ contains function files and hooks/ contains the actual scripts.

---
 files/hooks/git-snapshot.sh | 103 +++++++++++++
 files/hooks/mux.sh          |  25 ++++
 files/shlib/functions.sh    | 346 ++++++++++++++++++++++++++++++++++++++++++++
 files/shlib/git.sh          |  70 +++++++++
 4 files changed, 544 insertions(+)

diff --git a/files/hooks/git-snapshot.sh b/files/hooks/git-snapshot.sh
new file mode 100644
index 0000000..cc3b2df
--- /dev/null
+++ b/files/hooks/git-snapshot.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# roverlay hook that maintains (creates) a git history of the overlay
+#
+# What this script does:
+#
+# * check whether the git repo exists, else create it
+# * check whether a clean commit can be made, that is (a) there are changes
+#   to commit and (b) the git index does not contain uncommitted changes
+# * then, add/commit changes
+#
+set -u
+
+## load core functions
+. "${FUNCTIONS?}" || exit
+#dont_run_as_root
+
+## load git helper functions
+$lf git
+#autodie qwhich ${GIT}
+
+## "config" for this script
+# FIXME/TODO: remove config here?
+GIT_COMMIT_AUTHOR='undef undef@undef.org'
+GIT_COMMIT_MESSAGE='roverlay updates'
+
+
+## other vars
+EX_ADD_ERR=2
+EX_COMMIT_ERR=3
+
+
+## functions
+
+# void git_try_rollback()
+#
+#  Trap function that tries to reset the git tree/index.
+#
+git_try_rollback() {
+   # release trap
+   trap - INT TERM EXIT
+   run_command_logged ${GIT} reset --mixed --quiet || true
+}
+
+# int git_create_snapshot()
+#
+#  Adds changes and creates a commit.
+#
+git_create_snapshot() {
+   trap git_try_rollback INT TERM EXIT
+
+   # add changes
+   #  --all: add changed, new and deleted files
+   if ! run_command_logged ${GIT} add --all; then
+      git_try_rollback
+      return ${EX_ADD_ERR}
+   fi
+
+   # commit
+   # FIXME:
+   #  --author=?
+   #  --file=? or --message=?
+   if run_command_logged \
+      ${GIT} commit --quiet --no-edit \
+      --message="${GIT_COMMIT_MESSAGE}" --author="${GIT_COMMIT_AUTHOR}"
+   then
+      trap - INT TERM EXIT
+      return 0
+   else
+      git_try_rollback
+      return ${EX_COMMIT_ERR}
+   fi
+}
+
+
+## main
+
+# $GIT_DIR, $S/.git, $HOME/.git, ...?
+if [ -d "${S}/.git" ]; then
+   true
+if [ ! -e "${S}/.git" ]; then
+   einfo "Creating git repo"
+   # FIXME: --shared OK?
+   autodie ${GIT} init --quiet --shared=group "${S}"
+else
+   die "'${S}/.git should be a directory."
+fi
+
+
+if git_has_changes; then
+
+   autodie git_create_snapshot
+
+   ##push changes to local repo?
+   ##
+   ##if ! yesno ${NOSYNC}; then
+   ##   #push changes to remote?
+   ##fi
+
+else
+   veinfo "${SCRIPT_NAME}: nothing to do."
+   exit 0
+fi

diff --git a/files/hooks/mux.sh b/files/hooks/mux.sh
new file mode 100755
index 0000000..0764b4d
--- /dev/null
+++ b/files/hooks/mux.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# simple roverlay hook that runs other hooks (by sourcing them)
+#
+set -u
+
+## load core functions
+. "${FUNCTIONS?}" || exit
+#dont_run_as_root
+
+
+for hookfile in \
+   ${FILESDIR}/hooks/${ROVERLAY_PHASE}/?*.sh \
+   ${FILESDIR}/hooks/?*.${ROVERLAY_PHASE}
+do
+   if [ -f "${hookfile}" ]; then
+      #subshell?
+      #( . "${hookfile}"; ) || ...
+
+      # initial directory should always be $S
+
+      cd "${S}" && . "${hookfile}" || \
+         die "errors occured while running hook '${hookfile}'"
+   fi
+done

diff --git a/files/shlib/functions.sh b/files/shlib/functions.sh
new file mode 100644
index 0000000..d429ff2
--- /dev/null
+++ b/files/shlib/functions.sh
@@ -0,0 +1,346 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# R overlay -- shell functions
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+#
+#
+# Notes:
+# * no bashisms here
+#
+#
+# --- functions provided by this file ---
+#
+# message:
+# void veinfo ( message )
+# void einfo  ( message )
+# void ewarn  ( message )
+# void eerror ( message )
+#
+# core:
+# @noreturn die ( [message], [exit_code] ), raises exit()
+# @noreturn OUT_OF_BOUNDS(), raises die()
+# int  run_command        ( *cmdv )
+# int  run_command_logged ( *cmdv )
+# void autodie            ( *cmdv ), raises die()
+#
+# void load_functions ( *filenames, **SHLIB ), raises die()
+# void dont_run_as_root(), raises die()
+# int  list_has ( word, *list_items )
+# int  qwhich ( *command )
+#
+# fs util:
+# int dodir ( *dir )
+#
+# str util:
+# int  yesno     ( word, **YESNO_YES=0, **YESNO_NO=1, **YESNO_EMPTY=2 )
+# ~int str_strim ( *args )
+# ~int str_upper ( *args )
+# ~int str_lower ( *args )
+# ~int str_field ( fieldspec, *args, **FIELD_SEPARATOR=' ' )
+#
+# int util:
+# @intcheck is_int()
+# @intcheck is_natural()
+# @intcheck is_positive()
+# @intcheck is_negative()
+#
+#
+# --- variables provided by this file ---
+#
+# IFS_DEFAULT
+# IFS_NEWLINE
+#
+# DEVNULL
+#
+# EX_ERR
+# EX_ARG_ERR
+#
+# SCRIPT_FILENAME
+# SCRIPT_NAME
+#
+# lf
+#  "reference" to load_functions()
+#
+# @private __HAVE_CORE_FUNCTIONS__
+#
+# --- END HEADER ---
+
+if [ -z "${__HAVE_CORE_FUNCTIONS__-}" ]; then
+readonly __HAVE_CORE_FUNCTIONS__=y
+
+## make some env vars readonly
+
+readonly FUNCTIONS
+[ -z "${SHLIB-}" ] || readonly SHLIB
+
+readonly DEBUG VERBOSE QUIET NO_COLOR
+
+readonly ROVERLAY_PHASE \
+   OVERLAY S \
+   DISTROOT \
+   TMPDIR T \
+   ADDITIONS_DIR FILESDIR \
+   EBUILD NOSYNC
+
+
+## vars / constants
+
+readonly IFS_DEFAULT="${IFS}"
+readonly IFS_NEWLINE='
+'
+
+: ${DEVNULL:=/dev/null}
+readonly DEVNULL
+
+readonly EX_ERR=2
+readonly EX_ARG_ERR=5
+
+readonly SCRIPT_FILENAME="${0##*/}"
+readonly SCRIPT_NAME="${SCRIPT_FILENAME%.*}"
+
+readonly lf=load_functions
+
+
+## message functions
+
+# void veinfo ( message ) [**DEBUG]
+#
+if [ "${DEBUG:?}" = "y" ]; then
+   veinfo() { echo "$*"; }
+else
+   veinfo() { return 0; }
+fi
+
+# void einfo ( message ) [**VERBOSE]
+#
+if [ "${VERBOSE:?}" = "y" ]; then
+   einfo() { echo "$*"; }
+else
+   einfo() { return 0; }
+fi
+
+# void ewarn ( message ) [**QUIET]
+#
+if [ "${QUIET:?}" != "y" ]; then
+   ewarn() { echo "$*" 1>&2; }
+else
+   ewarn() { return 0; }
+fi
+
+# void eerror ( message )
+#
+eerror() { echo "$*" 1>&2; }
+
+
+## core functions
+
+# @noreturn die ( [message], [exit_code=**EX_ERR] ), raises exit (exit_code)
+#
+#  Prints a message to stderr and exits afterwards.
+#
+die() {
+   if [ -n "${1-}" ]; then
+      eerror "died: ${1}"
+   else
+      eerror "died."
+   fi
+   exit "${2:-${EX_ERR?}}"
+}
+
+# @noreturn OUT_OF_BOUNDS(), raises die (**EX_ARG_ERR)
+#
+#  Catches non-zero shift return and calls die().
+#
+OUT_OF_BOUNDS() { die "shift returned non-zero." ${EX_ARG_ERR?}; }
+
+# int run_command ( *cmdv )
+#
+#  Runs a command and passes its return value. Also logs the command.
+#
+run_command() {
+   veinfo "running command: $*"
+   "$@"
+}
+
+# int run_command_logged ( *cmdv )
+#
+#  Runs a command and passes its return value. Also logs the command + result.
+#
+run_command_logged() {
+   local rc=0
+   veinfo "running command: $*"
+   "$@" || rc=${?}
+   if [ ${rc} -eq 0 ]; then
+      veinfo "command succeeded."
+      return 0
+   else
+      einfo "command '$*' returned ${rc}."
+      return ${rc}
+   fi
+}
+
+# void autodie ( *cmdv ), raises die()
+#
+#  Executes a commands. Dies on non-zero return code.
+#
+autodie() {
+   local rc=0
+   veinfo "running command: $*"
+   "$@" || rc=$?
+   if [ ${rc} -eq 0 ]; then
+      return 0
+   else
+      die "command '$*' returned ${rc}" ${rc}
+   fi
+}
+
+# void load_functions ( *filenames, **SHLIB ), raises die()
+#
+#  Loads zero or more additional shell function files from $SHLIB.
+#  Dies if a file cannot be sourced.
+#
+load_functions() {
+   [ -n "${SHLIB-}" ] || die "\$SHLIB is not set."
+   local f
+   while [ $# -gt 0 ]; do
+      f="${SHLIB}/${1%.sh}.sh"
+      veinfo "Trying to load functions file ${f} ... "
+      . "${f}" || die "failed to load functions file ${f}."
+      shift
+   done
+   return 0
+}
+
+# void dont_run_as_root(), raises die()
+#
+#  Dies if this process is run as root.
+#
+dont_run_as_root() {
+   local uid=$(id -ru)
+   if [ -z "${uid}" ]; then
+      die "cannot get \$uid."
+   elif [ ${uid} -ne 0 2>>${DEVNULL} ]; then
+      return 0
+   else
+      die "bad \$uid ${uid}."
+   fi
+}
+
+# int list_has ( word, *list_items )
+#
+#  Returns true if word is in list_items, else false.
+#
+list_has() {
+   local kw="${1}"
+   shift || OUT_OF_BOUNDS
+
+   while [ $# -gt 0 ]; do
+      [ "x${kw}" != "x${1}" ] || return 0
+      shift
+   done
+   return 1
+}
+
+# int qwhich ( *command )
+#
+#  Returns true if 'which' finds all listed commands, else false.
+#
+qwhich() {
+   while [ $# -gt 0 ]; do
+      which "${1}" 1>>${DEVNULL} 2>>${DEVNULL} || return 1
+      shift
+   done
+   return 0
+}
+
+## fs util functions
+
+# int dodir ( *dir )
+#
+#  Ensures that the given directories exist by creating them if necessary.
+#
+#  Returns the number of directories that could not be created.
+#
+dodir() {
+   local fail=0
+   while [ $# -gt 0 ]; do
+      [ -d "${1}" ] || mkdir -p -- "${1}" || fail=$(( ${fail} + 1 ))
+   done
+   return ${fail}
+}
+
+
+## str util functions
+
+# int yesno ( word, **YESNO_YES=0, **YESNO_NO=1, **YESNO_EMPTY=2 )
+#
+#  Returns:
+#  * YESNO_YES   (0) if word means yes
+#  * YESNO_EMPTY (2) if word is empty
+#  * YESNO_NO    (1) otherwise (word is not empty and does not mean yes)
+#
+yesno() {
+   case "${1-}" in
+      '')
+         return ${YESNO_EMPTY:-2}
+      ;;
+      # yes | y | true | 1 | enable(d) | on
+      [yY][eE][sS]|\
+      [yY]|\
+      [tT][rR][uU][eE]|\
+      1|\
+      [eE][nN][aA][bB][lL][eE]?|\
+      [oO][nN]\
+      )
+         return ${YESNO_YES:-0}
+      ;;
+      *)
+         return ${YESNO_NO:-1}
+      ;;
+   esac
+}
+
+# ~int str_strim ( *args )
+#
+#  Removes whitespace at the beginning + end of a string
+#  and replaces any whitespace sequence within the string
+#  with a single space char.
+#
+str_trim() { sed -r -e 's,^\s+,,' -e 's,\s+$,,' -e 's,\s+, ,g' "$@"; }
+
+# ~int str_upper ( *args )
+str_upper() { tr [:lower:] [:upper:] "$@"; }
+
+# ~int str_lower ( *args )
+str_lower() { tr [:upper:] [:lower:] "$@"; }
+
+# ~int str_field ( fieldspec, *args, **FIELD_SEPARATOR=' ' )
+#
+str_field() { cut -d "${FIELD_SEPARATOR:- }" -f "$@"; }
+
+
+## int util functions
+
+# @funcdef shbool @intcheck [<condition>:=true] <function name> ( word )
+#
+#   Returns true if word is a number and condition(word) evaluates to true.
+#
+
+# @intcheck is_int()
+is_int() {
+   [ -n "${1-}" ] || return 1
+   [ "${1}" -ge 0 2>>${DEVNULL} ] || [ "${1}" -lt 0 2>>${DEVNULL} ]
+}
+
+# @intcheck >=0 is_natural()
+is_natural()  { [ -n "${1-}" ] && [ "${1}" -ge 0 2>>${DEVNULL} ]; }
+
+# @intcheck >0 is_positive()
+is_positive() { [ -n "${1-}" ] && [ "${1}" -gt 0 2>>${DEVNULL} ]; }
+
+# @intcheck <0 is_negative()
+is_negative() { [ -n "${1-}" ] && [ "${1}" -lt 0 2>>${DEVNULL} ]; }
+
+fi

diff --git a/files/shlib/git.sh b/files/shlib/git.sh
new file mode 100644
index 0000000..89c78ce
--- /dev/null
+++ b/files/shlib/git.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# R overlay -- shell functions, git
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+#
+#
+# --- functions provided by this file ---
+#
+# int git_has_changes ( [*files] ), raises die()
+#
+#
+# --- variables provided by this file ---
+#
+# GIT
+# @private __GIT_DIFF_OPTS
+#
+# @private __HAVE_GIT_FUNCTIONS__
+#
+#
+# --- END HEADER ---
+
+if [ -z "${__HAVE_GIT_FUNCTIONS__-}" ]; then
+readonly __HAVE_GIT_FUNCTIONS__=y
+
+if [ -z "${GIT-}" ]; then
+   GIT=$(which git 2>>${DEVNULL?})
+   : ${GIT:=git}
+fi
+
+: ${__GIT_DIFF_OPTS=--no-ext-diff --quiet --ignore-submodules}
+
+
+# int git_has_changes ( [*files] ), raises die()
+#
+# inspired by git-sh-setup.sh, require_clean_work_tree() from the git source
+#
+# Checks whether >the< git repo has unstaged changes. Also checks whether it
+# has any uncommitted changes and dies if there are any (i.e., no clean commit
+# possible).
+#
+# Returns 0 if there's anything to commit, else 1.
+#
+git_has_changes() {
+   ${GIT} rev-parse --quiet --verify HEAD 1>>${DEVNULL} || \
+      die "git rev-parse returned ${?}." ${?}
+   #FIXME: return code if update-index?
+   run_command_logged \
+      ${GIT} update-index -q --ignore-submodules --refresh -- "$@"
+
+   local has_changes
+   if ${GIT} diff-files ${__GIT_DIFF_OPTS} "$@"; then
+      ## return value of zero means no changes
+      veinfo "git index: no changes found"
+      has_changes=1
+   else
+      veinfo "git index: changes found"
+      has_changes=0
+   fi
+
+   if ${GIT} diff-index --cached ${__GIT_DIFF_OPTS} HEAD -- "$@"; then
+      veinfo "git index: no uncommitted changes found (that's good)"
+   else
+      die "uncommitted changes in git index found."
+   fi
+   return ${has_changes}
+}
+
+fi


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* [gentoo-commits] proj/R_overlay:master commit in: files/shlib/, files/hooks/
@ 2013-06-22 15:24 André Erdmann
  2013-06-21 14:09 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
  0 siblings, 1 reply; 2+ messages in thread
From: André Erdmann @ 2013-06-22 15:24 UTC (permalink / raw
  To: gentoo-commits

commit:     f814f32ab17ace769f25ccf80ca77d93a82c3a92
Author:     André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Jun 21 14:07:24 2013 +0000
Commit:     André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Jun 21 14:07:24 2013 +0000
URL:        http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=f814f32a

roverlay/files: shlib, hooks

This commit adds shell script files for running hooks.

shlib/ contains function files and hooks/ contains the actual scripts.

---
 files/hooks/git-snapshot.sh | 103 +++++++++++++
 files/hooks/mux.sh          |  25 ++++
 files/shlib/functions.sh    | 346 ++++++++++++++++++++++++++++++++++++++++++++
 files/shlib/git.sh          |  70 +++++++++
 4 files changed, 544 insertions(+)

diff --git a/files/hooks/git-snapshot.sh b/files/hooks/git-snapshot.sh
new file mode 100644
index 0000000..cc3b2df
--- /dev/null
+++ b/files/hooks/git-snapshot.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# roverlay hook that maintains (creates) a git history of the overlay
+#
+# What this script does:
+#
+# * check whether the git repo exists, else create it
+# * check whether a clean commit can be made, that is (a) there are changes
+#   to commit and (b) the git index does not contain uncommitted changes
+# * then, add/commit changes
+#
+set -u
+
+## load core functions
+. "${FUNCTIONS?}" || exit
+#dont_run_as_root
+
+## load git helper functions
+$lf git
+#autodie qwhich ${GIT}
+
+## "config" for this script
+# FIXME/TODO: remove config here?
+GIT_COMMIT_AUTHOR='undef undef@undef.org'
+GIT_COMMIT_MESSAGE='roverlay updates'
+
+
+## other vars
+EX_ADD_ERR=2
+EX_COMMIT_ERR=3
+
+
+## functions
+
+# void git_try_rollback()
+#
+#  Trap function that tries to reset the git tree/index.
+#
+git_try_rollback() {
+   # release trap
+   trap - INT TERM EXIT
+   run_command_logged ${GIT} reset --mixed --quiet || true
+}
+
+# int git_create_snapshot()
+#
+#  Adds changes and creates a commit.
+#
+git_create_snapshot() {
+   trap git_try_rollback INT TERM EXIT
+
+   # add changes
+   #  --all: add changed, new and deleted files
+   if ! run_command_logged ${GIT} add --all; then
+      git_try_rollback
+      return ${EX_ADD_ERR}
+   fi
+
+   # commit
+   # FIXME:
+   #  --author=?
+   #  --file=? or --message=?
+   if run_command_logged \
+      ${GIT} commit --quiet --no-edit \
+      --message="${GIT_COMMIT_MESSAGE}" --author="${GIT_COMMIT_AUTHOR}"
+   then
+      trap - INT TERM EXIT
+      return 0
+   else
+      git_try_rollback
+      return ${EX_COMMIT_ERR}
+   fi
+}
+
+
+## main
+
+# $GIT_DIR, $S/.git, $HOME/.git, ...?
+if [ -d "${S}/.git" ]; then
+   true
+if [ ! -e "${S}/.git" ]; then
+   einfo "Creating git repo"
+   # FIXME: --shared OK?
+   autodie ${GIT} init --quiet --shared=group "${S}"
+else
+   die "'${S}/.git should be a directory."
+fi
+
+
+if git_has_changes; then
+
+   autodie git_create_snapshot
+
+   ##push changes to local repo?
+   ##
+   ##if ! yesno ${NOSYNC}; then
+   ##   #push changes to remote?
+   ##fi
+
+else
+   veinfo "${SCRIPT_NAME}: nothing to do."
+   exit 0
+fi

diff --git a/files/hooks/mux.sh b/files/hooks/mux.sh
new file mode 100755
index 0000000..0764b4d
--- /dev/null
+++ b/files/hooks/mux.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# simple roverlay hook that runs other hooks (by sourcing them)
+#
+set -u
+
+## load core functions
+. "${FUNCTIONS?}" || exit
+#dont_run_as_root
+
+
+for hookfile in \
+   ${FILESDIR}/hooks/${ROVERLAY_PHASE}/?*.sh \
+   ${FILESDIR}/hooks/?*.${ROVERLAY_PHASE}
+do
+   if [ -f "${hookfile}" ]; then
+      #subshell?
+      #( . "${hookfile}"; ) || ...
+
+      # initial directory should always be $S
+
+      cd "${S}" && . "${hookfile}" || \
+         die "errors occured while running hook '${hookfile}'"
+   fi
+done

diff --git a/files/shlib/functions.sh b/files/shlib/functions.sh
new file mode 100644
index 0000000..d429ff2
--- /dev/null
+++ b/files/shlib/functions.sh
@@ -0,0 +1,346 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# R overlay -- shell functions
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+#
+#
+# Notes:
+# * no bashisms here
+#
+#
+# --- functions provided by this file ---
+#
+# message:
+# void veinfo ( message )
+# void einfo  ( message )
+# void ewarn  ( message )
+# void eerror ( message )
+#
+# core:
+# @noreturn die ( [message], [exit_code] ), raises exit()
+# @noreturn OUT_OF_BOUNDS(), raises die()
+# int  run_command        ( *cmdv )
+# int  run_command_logged ( *cmdv )
+# void autodie            ( *cmdv ), raises die()
+#
+# void load_functions ( *filenames, **SHLIB ), raises die()
+# void dont_run_as_root(), raises die()
+# int  list_has ( word, *list_items )
+# int  qwhich ( *command )
+#
+# fs util:
+# int dodir ( *dir )
+#
+# str util:
+# int  yesno     ( word, **YESNO_YES=0, **YESNO_NO=1, **YESNO_EMPTY=2 )
+# ~int str_strim ( *args )
+# ~int str_upper ( *args )
+# ~int str_lower ( *args )
+# ~int str_field ( fieldspec, *args, **FIELD_SEPARATOR=' ' )
+#
+# int util:
+# @intcheck is_int()
+# @intcheck is_natural()
+# @intcheck is_positive()
+# @intcheck is_negative()
+#
+#
+# --- variables provided by this file ---
+#
+# IFS_DEFAULT
+# IFS_NEWLINE
+#
+# DEVNULL
+#
+# EX_ERR
+# EX_ARG_ERR
+#
+# SCRIPT_FILENAME
+# SCRIPT_NAME
+#
+# lf
+#  "reference" to load_functions()
+#
+# @private __HAVE_CORE_FUNCTIONS__
+#
+# --- END HEADER ---
+
+if [ -z "${__HAVE_CORE_FUNCTIONS__-}" ]; then
+readonly __HAVE_CORE_FUNCTIONS__=y
+
+## make some env vars readonly
+
+readonly FUNCTIONS
+[ -z "${SHLIB-}" ] || readonly SHLIB
+
+readonly DEBUG VERBOSE QUIET NO_COLOR
+
+readonly ROVERLAY_PHASE \
+   OVERLAY S \
+   DISTROOT \
+   TMPDIR T \
+   ADDITIONS_DIR FILESDIR \
+   EBUILD NOSYNC
+
+
+## vars / constants
+
+readonly IFS_DEFAULT="${IFS}"
+readonly IFS_NEWLINE='
+'
+
+: ${DEVNULL:=/dev/null}
+readonly DEVNULL
+
+readonly EX_ERR=2
+readonly EX_ARG_ERR=5
+
+readonly SCRIPT_FILENAME="${0##*/}"
+readonly SCRIPT_NAME="${SCRIPT_FILENAME%.*}"
+
+readonly lf=load_functions
+
+
+## message functions
+
+# void veinfo ( message ) [**DEBUG]
+#
+if [ "${DEBUG:?}" = "y" ]; then
+   veinfo() { echo "$*"; }
+else
+   veinfo() { return 0; }
+fi
+
+# void einfo ( message ) [**VERBOSE]
+#
+if [ "${VERBOSE:?}" = "y" ]; then
+   einfo() { echo "$*"; }
+else
+   einfo() { return 0; }
+fi
+
+# void ewarn ( message ) [**QUIET]
+#
+if [ "${QUIET:?}" != "y" ]; then
+   ewarn() { echo "$*" 1>&2; }
+else
+   ewarn() { return 0; }
+fi
+
+# void eerror ( message )
+#
+eerror() { echo "$*" 1>&2; }
+
+
+## core functions
+
+# @noreturn die ( [message], [exit_code=**EX_ERR] ), raises exit (exit_code)
+#
+#  Prints a message to stderr and exits afterwards.
+#
+die() {
+   if [ -n "${1-}" ]; then
+      eerror "died: ${1}"
+   else
+      eerror "died."
+   fi
+   exit "${2:-${EX_ERR?}}"
+}
+
+# @noreturn OUT_OF_BOUNDS(), raises die (**EX_ARG_ERR)
+#
+#  Catches non-zero shift return and calls die().
+#
+OUT_OF_BOUNDS() { die "shift returned non-zero." ${EX_ARG_ERR?}; }
+
+# int run_command ( *cmdv )
+#
+#  Runs a command and passes its return value. Also logs the command.
+#
+run_command() {
+   veinfo "running command: $*"
+   "$@"
+}
+
+# int run_command_logged ( *cmdv )
+#
+#  Runs a command and passes its return value. Also logs the command + result.
+#
+run_command_logged() {
+   local rc=0
+   veinfo "running command: $*"
+   "$@" || rc=${?}
+   if [ ${rc} -eq 0 ]; then
+      veinfo "command succeeded."
+      return 0
+   else
+      einfo "command '$*' returned ${rc}."
+      return ${rc}
+   fi
+}
+
+# void autodie ( *cmdv ), raises die()
+#
+#  Executes a commands. Dies on non-zero return code.
+#
+autodie() {
+   local rc=0
+   veinfo "running command: $*"
+   "$@" || rc=$?
+   if [ ${rc} -eq 0 ]; then
+      return 0
+   else
+      die "command '$*' returned ${rc}" ${rc}
+   fi
+}
+
+# void load_functions ( *filenames, **SHLIB ), raises die()
+#
+#  Loads zero or more additional shell function files from $SHLIB.
+#  Dies if a file cannot be sourced.
+#
+load_functions() {
+   [ -n "${SHLIB-}" ] || die "\$SHLIB is not set."
+   local f
+   while [ $# -gt 0 ]; do
+      f="${SHLIB}/${1%.sh}.sh"
+      veinfo "Trying to load functions file ${f} ... "
+      . "${f}" || die "failed to load functions file ${f}."
+      shift
+   done
+   return 0
+}
+
+# void dont_run_as_root(), raises die()
+#
+#  Dies if this process is run as root.
+#
+dont_run_as_root() {
+   local uid=$(id -ru)
+   if [ -z "${uid}" ]; then
+      die "cannot get \$uid."
+   elif [ ${uid} -ne 0 2>>${DEVNULL} ]; then
+      return 0
+   else
+      die "bad \$uid ${uid}."
+   fi
+}
+
+# int list_has ( word, *list_items )
+#
+#  Returns true if word is in list_items, else false.
+#
+list_has() {
+   local kw="${1}"
+   shift || OUT_OF_BOUNDS
+
+   while [ $# -gt 0 ]; do
+      [ "x${kw}" != "x${1}" ] || return 0
+      shift
+   done
+   return 1
+}
+
+# int qwhich ( *command )
+#
+#  Returns true if 'which' finds all listed commands, else false.
+#
+qwhich() {
+   while [ $# -gt 0 ]; do
+      which "${1}" 1>>${DEVNULL} 2>>${DEVNULL} || return 1
+      shift
+   done
+   return 0
+}
+
+## fs util functions
+
+# int dodir ( *dir )
+#
+#  Ensures that the given directories exist by creating them if necessary.
+#
+#  Returns the number of directories that could not be created.
+#
+dodir() {
+   local fail=0
+   while [ $# -gt 0 ]; do
+      [ -d "${1}" ] || mkdir -p -- "${1}" || fail=$(( ${fail} + 1 ))
+   done
+   return ${fail}
+}
+
+
+## str util functions
+
+# int yesno ( word, **YESNO_YES=0, **YESNO_NO=1, **YESNO_EMPTY=2 )
+#
+#  Returns:
+#  * YESNO_YES   (0) if word means yes
+#  * YESNO_EMPTY (2) if word is empty
+#  * YESNO_NO    (1) otherwise (word is not empty and does not mean yes)
+#
+yesno() {
+   case "${1-}" in
+      '')
+         return ${YESNO_EMPTY:-2}
+      ;;
+      # yes | y | true | 1 | enable(d) | on
+      [yY][eE][sS]|\
+      [yY]|\
+      [tT][rR][uU][eE]|\
+      1|\
+      [eE][nN][aA][bB][lL][eE]?|\
+      [oO][nN]\
+      )
+         return ${YESNO_YES:-0}
+      ;;
+      *)
+         return ${YESNO_NO:-1}
+      ;;
+   esac
+}
+
+# ~int str_strim ( *args )
+#
+#  Removes whitespace at the beginning + end of a string
+#  and replaces any whitespace sequence within the string
+#  with a single space char.
+#
+str_trim() { sed -r -e 's,^\s+,,' -e 's,\s+$,,' -e 's,\s+, ,g' "$@"; }
+
+# ~int str_upper ( *args )
+str_upper() { tr [:lower:] [:upper:] "$@"; }
+
+# ~int str_lower ( *args )
+str_lower() { tr [:upper:] [:lower:] "$@"; }
+
+# ~int str_field ( fieldspec, *args, **FIELD_SEPARATOR=' ' )
+#
+str_field() { cut -d "${FIELD_SEPARATOR:- }" -f "$@"; }
+
+
+## int util functions
+
+# @funcdef shbool @intcheck [<condition>:=true] <function name> ( word )
+#
+#   Returns true if word is a number and condition(word) evaluates to true.
+#
+
+# @intcheck is_int()
+is_int() {
+   [ -n "${1-}" ] || return 1
+   [ "${1}" -ge 0 2>>${DEVNULL} ] || [ "${1}" -lt 0 2>>${DEVNULL} ]
+}
+
+# @intcheck >=0 is_natural()
+is_natural()  { [ -n "${1-}" ] && [ "${1}" -ge 0 2>>${DEVNULL} ]; }
+
+# @intcheck >0 is_positive()
+is_positive() { [ -n "${1-}" ] && [ "${1}" -gt 0 2>>${DEVNULL} ]; }
+
+# @intcheck <0 is_negative()
+is_negative() { [ -n "${1-}" ] && [ "${1}" -lt 0 2>>${DEVNULL} ]; }
+
+fi

diff --git a/files/shlib/git.sh b/files/shlib/git.sh
new file mode 100644
index 0000000..89c78ce
--- /dev/null
+++ b/files/shlib/git.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+# -*- coding: utf-8 -*-
+# R overlay -- shell functions, git
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+#
+#
+# --- functions provided by this file ---
+#
+# int git_has_changes ( [*files] ), raises die()
+#
+#
+# --- variables provided by this file ---
+#
+# GIT
+# @private __GIT_DIFF_OPTS
+#
+# @private __HAVE_GIT_FUNCTIONS__
+#
+#
+# --- END HEADER ---
+
+if [ -z "${__HAVE_GIT_FUNCTIONS__-}" ]; then
+readonly __HAVE_GIT_FUNCTIONS__=y
+
+if [ -z "${GIT-}" ]; then
+   GIT=$(which git 2>>${DEVNULL?})
+   : ${GIT:=git}
+fi
+
+: ${__GIT_DIFF_OPTS=--no-ext-diff --quiet --ignore-submodules}
+
+
+# int git_has_changes ( [*files] ), raises die()
+#
+# inspired by git-sh-setup.sh, require_clean_work_tree() from the git source
+#
+# Checks whether >the< git repo has unstaged changes. Also checks whether it
+# has any uncommitted changes and dies if there are any (i.e., no clean commit
+# possible).
+#
+# Returns 0 if there's anything to commit, else 1.
+#
+git_has_changes() {
+   ${GIT} rev-parse --quiet --verify HEAD 1>>${DEVNULL} || \
+      die "git rev-parse returned ${?}." ${?}
+   #FIXME: return code if update-index?
+   run_command_logged \
+      ${GIT} update-index -q --ignore-submodules --refresh -- "$@"
+
+   local has_changes
+   if ${GIT} diff-files ${__GIT_DIFF_OPTS} "$@"; then
+      ## return value of zero means no changes
+      veinfo "git index: no changes found"
+      has_changes=1
+   else
+      veinfo "git index: changes found"
+      has_changes=0
+   fi
+
+   if ${GIT} diff-index --cached ${__GIT_DIFF_OPTS} HEAD -- "$@"; then
+      veinfo "git index: no uncommitted changes found (that's good)"
+   else
+      die "uncommitted changes in git index found."
+   fi
+   return ${has_changes}
+}
+
+fi


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-06-22 15:24 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-22 15:24 [gentoo-commits] proj/R_overlay:master commit in: files/shlib/, files/hooks/ André Erdmann
2013-06-21 14:09 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox