* [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