aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/angular.js/finalize-version.sh20
-rwxr-xr-xscripts/angular.js/initialize-new-version.sh24
-rwxr-xr-xscripts/angular.js/publish.sh49
-rw-r--r--scripts/bower/README.md15
-rwxr-xr-xscripts/bower/publish.sh173
-rw-r--r--scripts/code.angularjs.org/README.md18
-rwxr-xr-xscripts/code.angularjs.org/publish.sh123
-rwxr-xr-xscripts/jenkins/bump-increment.sh25
-rwxr-xr-xscripts/jenkins/bump-remove-snapshot.sh20
-rwxr-xr-xscripts/jenkins/master.sh43
-rwxr-xr-xscripts/jenkins/release.sh66
-rw-r--r--scripts/utils.inc273
12 files changed, 582 insertions, 267 deletions
diff --git a/scripts/angular.js/finalize-version.sh b/scripts/angular.js/finalize-version.sh
new file mode 100755
index 00000000..e885fd14
--- /dev/null
+++ b/scripts/angular.js/finalize-version.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+echo "############################################"
+echo "## Remove "-snapshot" from version ########"
+echo "############################################"
+
+ARG_DEFS=()
+
+function run {
+ cd ../..
+
+ replaceJsonProp "package.json" "version" "(.*)-snapshot" "\2"
+ VERSION=$(readJsonProp "package.json" "version")
+
+ git add package.json
+ git commit -m "chore(release): cut v$VERSION release"
+ git tag -m "v$VERSION" v$VERSION
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/angular.js/initialize-new-version.sh b/scripts/angular.js/initialize-new-version.sh
new file mode 100755
index 00000000..9d060555
--- /dev/null
+++ b/scripts/angular.js/initialize-new-version.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+echo "############################################"
+echo "## Increment version, add "-snapshot" and set version name ##"
+echo "############################################"
+
+ARG_DEFS=(
+ "--next-version-type=(patch|minor|major)"
+ "--next-version-name=(.+)"
+)
+
+function run {
+ cd ../..
+
+ grunt bump:$NEXT_VERSION_TYPE
+ NEXT_VERSION=$(readJsonProp "package.json" "version")
+ replaceJsonProp "package.json" "version" "(.*)" "\2-snapshot"
+ replaceJsonProp "package.json" "codename" ".*" "$NEXT_VERSION_NAME"
+
+ git add package.json
+ git commit -m "chore(release): start v$NEXT_VERSION ($NEXT_VERSION)"
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/angular.js/publish.sh b/scripts/angular.js/publish.sh
new file mode 100755
index 00000000..d72a393f
--- /dev/null
+++ b/scripts/angular.js/publish.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+# Script for updating angular.js repo from current local build.
+
+echo "#################################"
+echo "## Update angular.js ###"
+echo "#################################"
+
+ARG_DEFS=(
+ "--action=(prepare|publish)"
+ "--next-version-type=(patch|minor|major)"
+ "--next-version-name=(.+)"
+ "[--no_test=true]"
+)
+
+function init {
+ cd ../..
+}
+
+function prepare() {
+
+ if ! git symbolic-ref --short HEAD; then
+ # We are on a detached branch, e.g. jenkins checks out shas instead of branches
+ # Jump onto the master branch and make sure we are using the latest
+ git checkout -f master
+ git merge --ff-only origin/master
+ fi
+
+ ./scripts/angular.js/finalize-version.sh
+
+ # Build
+ if [[ $NO_TEST ]]; then
+ grunt package
+ else
+ ./jenkins_build.sh
+ fi
+
+ ./scripts/angular.js/initialize-new-version.sh --next-version-type=$NEXT_VERSION_TYPE --next-version-name=$NEXT_VERSION_NAME
+}
+
+function publish() {
+ BRANCH=$(git rev-parse --abbrev-ref HEAD)
+ # push the commits to github
+ git push origin $BRANCH
+ # push the release tag
+ git push origin v`cat build/version.txt`
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/bower/README.md b/scripts/bower/README.md
deleted file mode 100644
index 06ba9d61..00000000
--- a/scripts/bower/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Angular Bower Script
-
-Script for updating the Angular bower repos from current local build.
-
-## Instructions
-
-`grunt package`: Build angular locally
-
-```shell
-./publish.sh
-```
-
-## License
-MIT
-
diff --git a/scripts/bower/publish.sh b/scripts/bower/publish.sh
index a2bf3683..ad77aadc 100755
--- a/scripts/bower/publish.sh
+++ b/scripts/bower/publish.sh
@@ -1,88 +1,101 @@
#!/bin/bash
+# Script for updating the Angular bower repos from current local build.
+
echo "#################################"
echo "#### Update bower ###############"
echo "#################################"
-# Enable tracing and exit on first failure
-set -xe
-# Normalize working dir to script dir
-cd `dirname $0`
-
-SCRIPT_DIR=`pwd`
-TMP_DIR=../../tmp
-BUILD_DIR=../../build
-NEW_VERSION=`cat $BUILD_DIR/version.txt`
-
-REPOS=(
- angular \
- angular-animate \
- angular-cookies \
- angular-i18n \
- angular-loader \
- angular-mocks \
- angular-route \
- angular-resource \
- angular-sanitize \
- angular-scenario \
- angular-touch \
+ARG_DEFS=(
+ "--action=(prepare|publish)"
)
-#
-# clone repos
-#
-for repo in "${REPOS[@]}"
-do
- echo "-- Cloning bower-$repo"
- git clone git@github.com:angular/bower-$repo.git $TMP_DIR/bower-$repo
-done
-
-
-#
-# move the files from the build
-#
-
-for repo in "${REPOS[@]}"
-do
- if [ -f $BUILD_DIR/$repo.js ] # ignore i18l
- then
- echo "-- Updating files in bower-$repo"
- cd $TMP_DIR/bower-$repo
- git reset --hard HEAD
- git checkout master
- git fetch --all
- git reset --hard origin/master
- cd $SCRIPT_DIR
- cp $BUILD_DIR/$repo.* $TMP_DIR/bower-$repo/
- fi
-done
-
-# move i18n files
-cp $BUILD_DIR/i18n/*.js $TMP_DIR/bower-angular-i18n/
-
-# move csp.css
-cp $BUILD_DIR/angular-csp.css $TMP_DIR/bower-angular
-
-
-#
-# update bower.json
-# tag each repo
-#
-
-for repo in "${REPOS[@]}"
-do
- echo "-- Updating version in bower-$repo to $NEW_VERSION"
- cd $TMP_DIR/bower-$repo
- sed -i .tmp -E 's/"(version)":[ ]*".*"/"\1": "'$NEW_VERSION'"/g' bower.json
- sed -i .tmp -E 's/"(angular.*)":[ ]*".*"/"\1": "'$NEW_VERSION'"/g' bower.json
- # delete tmp files
- rm *.tmp
- git add -A
-
- echo "-- Committing, tagging and pushing bower-$repo"
- git commit -m "v$NEW_VERSION"
- git tag v$NEW_VERSION
- git push origin master
- git push origin v$NEW_VERSION
- cd $SCRIPT_DIR
-done
+function init {
+ TMP_DIR=$(resolveDir ../../tmp)
+ BUILD_DIR=$(resolveDir ../../build)
+ NEW_VERSION=$(cat $BUILD_DIR/version.txt)
+ REPOS=(
+ angular
+ angular-animate
+ angular-cookies
+ angular-i18n
+ angular-loader
+ angular-mocks
+ angular-route
+ angular-resource
+ angular-sanitize
+ angular-scenario
+ angular-touch
+ )
+}
+
+
+function prepare {
+ #
+ # clone repos
+ #
+ for repo in "${REPOS[@]}"
+ do
+ echo "-- Cloning bower-$repo"
+ git clone git@github.com:angular/bower-$repo.git $TMP_DIR/bower-$repo
+ done
+
+
+ #
+ # move the files from the build
+ #
+
+ for repo in "${REPOS[@]}"
+ do
+ if [ -f $BUILD_DIR/$repo.js ] # ignore i18l
+ then
+ echo "-- Updating files in bower-$repo"
+ cd $TMP_DIR/bower-$repo
+ git reset --hard HEAD
+ git checkout master
+ git fetch --all
+ git reset --hard origin/master
+ cd $SCRIPT_DIR
+ cp $BUILD_DIR/$repo.* $TMP_DIR/bower-$repo/
+ fi
+ done
+
+ # move i18n files
+ cp $BUILD_DIR/i18n/*.js $TMP_DIR/bower-angular-i18n/
+
+ # move csp.css
+ cp $BUILD_DIR/angular-csp.css $TMP_DIR/bower-angular
+
+
+ #
+ # update bower.json
+ # tag each repo
+ #
+ for repo in "${REPOS[@]}"
+ do
+ echo "-- Updating version in bower-$repo to $NEW_VERSION"
+ cd $TMP_DIR/bower-$repo
+ replaceJsonProp "bower.json" "version" ".*" "$NEW_VERSION"
+ replaceJsonProp "bower.json" "angular.*" ".*" "$NEW_VERSION"
+
+ git add -A
+
+ echo "-- Committing and tagging bower-$repo"
+ git commit -m "v$NEW_VERSION"
+ git tag v$NEW_VERSION
+ cd $SCRIPT_DIR
+ done
+}
+
+function publish {
+ for repo in "${REPOS[@]}"
+ do
+ echo "-- Pushing bower-$repo"
+ cd $TMP_DIR/bower-$repo
+ git push origin master
+ git push origin v$NEW_VERSION
+ cd $SCRIPT_DIR
+ done
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/code.angularjs.org/README.md b/scripts/code.angularjs.org/README.md
deleted file mode 100644
index e3887004..00000000
--- a/scripts/code.angularjs.org/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# code.angular.js.org Script
-
-Script for updating code.angularjs.org repo from current local build.
-
-Note: For a snapshot build, this will fetch the data from the ci server
-and NOT take the local build!
-
-## Instructions
-
-`grunt package`: Build angular locally
-
-```shell
-./publish.sh
-```
-
-## License
-MIT
-
diff --git a/scripts/code.angularjs.org/publish.sh b/scripts/code.angularjs.org/publish.sh
index 352ac10b..4845ad2a 100755
--- a/scripts/code.angularjs.org/publish.sh
+++ b/scripts/code.angularjs.org/publish.sh
@@ -1,62 +1,73 @@
#!/bin/bash
+# Script for updating code.angularjs.org repo from current local build.
+
echo "#################################"
echo "## Update code.angular.js.org ###"
echo "#################################"
-# Enable tracing and exit on first failure
-set -xe
-# Normalize working dir to script dir
-cd `dirname $0`
-
-TMP_DIR=../../tmp
-REPO_DIR=$TMP_DIR/code.angularjs.org
-BUILD_DIR=../../build
-SCRIPT_DIR=`pwd`
-NEW_VERSION=`cat $BUILD_DIR/version.txt`
-
-#
-# Snapshot builds are kept in a temp directory in code.angularjs.org
-# that is filled by calling a php script there.
-#
-if [[ "$NEW_VERSION" =~ sha ]] ;then
- echo "-- updating snapshot version"
- curl -G --data-urlencode "ver=$NEW_VERSION" http://code.angularjs.org/fetchLatestSnapshot.php
- exit 0;
-fi
-
-#
-# clone
-#
-
-echo "-- Cloning code.angularjs.org"
-git clone git@github.com:angular/code.angularjs.org.git $REPO_DIR
-
-#
-# copy the files from the build
-#
-
-echo "-- Updating code.angularjs.org"
-mkdir $REPO_DIR/$NEW_VERSION
-cd $REPO_DIR
-git reset --hard HEAD
-git checkout master
-git fetch --all
-git reset --hard origin/master
-cd $SCRIPT_DIR
-cp -r $BUILD_DIR/* $REPO_DIR/$NEW_VERSION/
-
-#
-# commit and push
-#
-echo "-- Committing and pushing code.angularjs.org"
-cd $REPO_DIR
-git add -A
-git commit -m "v$NEW_VERSION"
-git push origin master
-cd $SCRIPT_DIR
-
-#
-# refresh code.angularjs.org from github
-#
-curl http://code.angularjs.org/gitFetchSite.php \ No newline at end of file
+ARG_DEFS=(
+ "--action=(prepare|publish)"
+)
+
+function init {
+ TMP_DIR=$(resolveDir ../../tmp)
+ BUILD_DIR=$(resolveDir ../../build)
+ REPO_DIR=$TMP_DIR/code.angularjs.org
+ NEW_VERSION=$(cat $BUILD_DIR/version.txt)
+ if [[ "$NEW_VERSION" =~ sha ]]; then
+ IS_SNAPSHOT_BUILD=true
+ else
+ IS_SNAPSHOT_BUILD=
+ fi
+}
+
+function prepare {
+ if [[ $IS_SNAPSHOT_BUILD ]]; then
+ # nothing to prepare for snapshot builds as
+ # code.angularjs.org will fetch the current snapshot from
+ # the build server during publish
+ exit 0
+ fi
+
+ echo "-- Cloning code.angularjs.org"
+ git clone git@github.com:angular/code.angularjs.org.git $REPO_DIR
+
+ #
+ # copy the files from the build
+ #
+ echo "-- Updating code.angularjs.org"
+ mkdir $REPO_DIR/$NEW_VERSION
+ cd $REPO_DIR
+ git reset --hard HEAD
+ git checkout master
+ git fetch --all
+ git reset --hard origin/master
+ cd $SCRIPT_DIR
+ cp -r $BUILD_DIR/* $REPO_DIR/$NEW_VERSION/
+
+ #
+ # commit
+ #
+ echo "-- Committing code.angularjs.org"
+ cd $REPO_DIR
+ git add -A
+ git commit -m "v$NEW_VERSION"
+}
+
+function publish {
+ if [[ $IS_SNAPSHOT_BUILD ]]; then
+ echo "-- Updating snapshot version"
+ curl -G --data-urlencode "ver=$NEW_VERSION" http://code.angularjs.org/fetchLatestSnapshot.php
+ exit 0;
+ fi
+
+ cd $REPO_DIR
+ echo "-- Pushing code.angularjs.org"
+ git push origin master
+
+ echo "-- Refreshing code.angularjs.org"
+ curl http://code.angularjs.org/gitFetchSite.php
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/jenkins/bump-increment.sh b/scripts/jenkins/bump-increment.sh
deleted file mode 100755
index 5e8e4fc7..00000000
--- a/scripts/jenkins/bump-increment.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-echo "############################################"
-echo "## Increment version and add "-snapshot" ##"
-echo "############################################"
-
-if [ "$1" != "patch" -a "$1" != "minor" -a "$1" != "major" ]; then
- echo "Please specify the next version type: patch|minor|major"
- exit 1
-fi
-BUMP_TYPE=$1
-
-# Enable tracing and exit on first failure
-set -xe
-# Normalize working dir to script dir
-cd `dirname $0`/../..
-
-echo "-- increment version "
-grunt bump:$BUMP_TYPE
-NEXT_VERSION=`sed -En 's/.*"version"[ ]*:[ ]*"(.*)".*/\1/p' package.json`
-sed -i .tmp -E 's/"version": "(.*)"/"version": "\1-snapshot"/' package.json
-echo "-- new version: `grep '"version"' package.json`"
-echo "-- commit"
-git add package.json
-git commit -m "chore(release): start v$NEXT_VERSION" \ No newline at end of file
diff --git a/scripts/jenkins/bump-remove-snapshot.sh b/scripts/jenkins/bump-remove-snapshot.sh
deleted file mode 100755
index 9fafb334..00000000
--- a/scripts/jenkins/bump-remove-snapshot.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-echo "############################################"
-echo "## Remove "-snapshot" from version ########"
-echo "############################################"
-
-# Enable tracing and exit on first failure
-set -xe
-# Normalize working dir to script dir
-cd `dirname $0`/../..
-
-echo "-- old version: `grep '"version"' package.json`"
-sed -i .tmp -E 's/"version": "(.*)-snapshot"/"version": "\1"/' package.json
-VERSION=`sed -En 's/.*"version"[ ]*:[ ]*"(.*)".*/\1/p' package.json`
-echo "-- local version: $VERSION"
-
-echo "-- commit and tag with v$VERSION"
-git add package.json
-git commit -m "chore(release): cut v$VERSION release"
-git tag -m "v$VERSION" v$VERSION
diff --git a/scripts/jenkins/master.sh b/scripts/jenkins/master.sh
index a4fe50ac..d5768f58 100755
--- a/scripts/jenkins/master.sh
+++ b/scripts/jenkins/master.sh
@@ -4,22 +4,35 @@ echo "#################################"
echo "#### Update master ##############"
echo "#################################"
-# Enable tracing and exit on first failure
-set -xe
+ARG_DEFS=(
+ "[--no-test=true]"
+)
-cd `dirname $0`/../..
+function build {
+ cd ../..
-echo "#################################"
-echo "#### Jenkins Build ############"
-echo "#################################"
-./jenkins_build.sh
+ if [[ $NO_TEST ]]; then
+ grunt package
+ else
+ ./jenkins_build.sh
+ fi
-echo "#################################"
-echo "## Update code.angular.js.org ###"
-echo "#################################"
-./scripts/code.angularjs.org/publish.sh
+ cd $SCRIPT_DIR
+}
-echo "#################################"
-echo "#### Update bower ###############"
-echo "#################################"
-./scripts/bower/publish.sh \ No newline at end of file
+function phase {
+ ../code.angularjs.org/publish.sh --action=$1
+ ../bower/publish.sh --action=$1
+}
+
+function run {
+ build
+
+ # First prepare all scripts (build, test, commit, tag, ...),
+ # so we are sure everything is all right
+ phase prepare
+ # only then publish to github
+ phase publish
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/jenkins/release.sh b/scripts/jenkins/release.sh
index c0bb49c0..b4eee4c4 100755
--- a/scripts/jenkins/release.sh
+++ b/scripts/jenkins/release.sh
@@ -4,41 +4,31 @@ echo "#################################"
echo "#### Cut release ################"
echo "#################################"
-if [ "$1" != "patch" -a "$1" != "minor" -a "$1" != "major" ]; then
- echo "Please specify the next version type: patch|minor|major"
- exit 1
-fi
-BUMP_TYPE=$1
-
-# Enable tracing and exit on first failure
-set -xe
-
-# Jump onto the master branch and make sure we are using the latest
-git checkout -f master
-git merge --ff-only origin/master
-
-
-# Normalize working dir to script dir
-cd `dirname $0`/../..
-
-
-# Bump versions: remove "-snapshot" suffix
-./scripts/jenkins/bump-remove-snapshot.sh
-
-# Build
-./jenkins_build.sh
-
-# Bump versions: Increment version and add "-snapshot"
-./scripts/jenkins/bump-increment.sh $BUMP_TYPE
-
-echo "-- push to Github"
-# push the commits to github
-git push origin master
-# push the release tag
-git push origin v`cat build/version.txt`
-
-# Update code.angularjs.org
-./scripts/code.angularjs.org/publish.sh
-
-# Update bower
-./scripts/bower/publish.sh
+ARG_DEFS=(
+ "--next_version_type=(patch|minor|major)"
+ "--next-version-name=(.+)"
+ "[--no-test=true]"
+)
+
+function init {
+ NG_ARGS=("$@")
+ if [[ $NO_TEST ]]; then
+ NG_ARGS+=(--no_test=true)
+ fi
+}
+
+function phase {
+ ../angular.js/publish.sh --action=$1 "${NG_ARGS[@]}"
+ ../code.angularjs.org/publish.sh --action=$1
+ ../bower/publish.sh --action=$1
+}
+
+function run {
+ # First prepare all scripts (build, test, commit, tag, ...),
+ # so we are sure everything is all right
+ phase prepare
+ # only then publish to github
+ phase publish
+}
+
+source $(dirname $0)/../utils.inc
diff --git a/scripts/utils.inc b/scripts/utils.inc
new file mode 100644
index 00000000..0465de8f
--- /dev/null
+++ b/scripts/utils.inc
@@ -0,0 +1,273 @@
+# This file provides:
+# - a default control flow
+# * initializes the environment
+# * able to mock "git push" in your script and in all sub scripts
+# * call a function in your script based on the arguments
+# - named argument parsing and automatic generation of the "usage" for your script
+# - intercepting "git push" in your script and all sub scripts
+# - utility functions
+#
+# Usage:
+# - define the variable ARGS_DEF (see below) with the arguments for your script
+# - include this file using `source utils.inc` at the end of your script.
+#
+# Default control flow:
+# 0. Set the current directory to the directory of the script. By this
+# the script can be called from anywhere.
+# 1. Parse the named arguments
+# 2. If the parameter "git_push_dryrun" is set, all calls the `git push` in this script
+# or in child scripts will be intercepted so that the `--dry-run` and `--porcelain` is added
+# to show what the push would do but not actually do it.
+# 3. If the parameter "verbose" is set, the `-x` flag will be set in bash.
+# 4. The function "init" will be called if it exists
+# 5. If the parameter "action" is set, it will call the function with the name of that parameter.
+# Otherwise the function "run" will be called.
+#
+# Named Argument Parsing:
+# - The variable ARGS_DEF defines the valid command arguments
+# * Required args syntax: --paramName=paramRegex
+# * Optional args syntax: [--paramName=paramRegex]
+# * e.g. ARG_DEFS=("--required_param=(.+)" "[--optional_param=(.+)]")
+# - Checks that:
+# * all arguments match to an entry in ARGS_DEF
+# * all required arguments are present
+# * all arguments match their regex
+# - Afterwards, every paramter value will be stored in a variable
+# with the name of the parameter in upper case (with dash converted to underscore).
+#
+# Special arguments that are always available:
+# - "--action=.*": This parameter will be used to dispatch to a function with that name when the
+# script is started
+# - "--git_push_dryrun=true": This will intercept all calls to `git push` in this script
+# or in child scripts so that the `--dry-run` and `--porcelain` is added
+# to show what the push would do but not actually do it.
+# - "--verbose=true": This will set the `-x` flag in bash so that all calls will be logged
+#
+# Utility functions:
+# - readJsonProp
+# - replaceJsonProp
+# - resolveDir
+# - getVar
+# - serVar
+# - isFunction
+
+
+function usage {
+ echo "Usage: ${0} ${ARG_DEFS[@]}"
+ exit 1
+}
+
+
+function parseArgs {
+ local REQUIRED_ARG_NAMES=()
+
+ # -- helper functions
+ function varName {
+ # everything to upper case and dash to underscore
+ echo ${1//-/_} | tr '[:lower:]' '[:upper:]'
+ }
+
+ function readArgDefs {
+ local ARG_DEF
+ local AD_OPTIONAL
+ local AD_NAME
+ local AD_RE
+
+ # -- helper functions
+ function parseArgDef {
+ local ARG_DEF_REGEX="(\[?)--([^=]+)=(.*)"
+ if [[ ! $1 =~ $ARG_DEF_REGEX ]]; then
+ echo "Internal error: arg def has wrong format: $ARG_DEF"
+ exit 1
+ fi
+ AD_OPTIONAL="${BASH_REMATCH[1]}"
+ AD_NAME="${BASH_REMATCH[2]}"
+ AD_RE="${BASH_REMATCH[3]}"
+ if [[ $AD_OPTIONAL ]]; then
+ # Remove last bracket for optional args.
+ # Can't put this into the ARG_DEF_REGEX somehow...
+ AD_RE=${AD_RE%?}
+ fi
+ }
+
+ # -- run
+ for ARG_DEF in "${ARG_DEFS[@]}"
+ do
+ parseArgDef $ARG_DEF
+
+ local AD_NAME_UPPER=$(varName $AD_NAME)
+ setVar "${AD_NAME_UPPER}_OPTIONAL" "$AD_OPTIONAL"
+ setVar "${AD_NAME_UPPER}_RE" "$AD_RE"
+ if [[ ! $AD_OPTIONAL ]]; then
+ REQUIRED_ARG_NAMES+=($AD_NAME)
+ fi
+ done
+ }
+
+ function readAndValidateArgs {
+ local ARG_NAME
+ local ARG_VALUE
+ local ARG_NAME_UPPER
+
+ # -- helper functions
+ function parseArg {
+ local ARG_REGEX="--([^=]+)=?(.*)"
+
+ if [[ ! $1 =~ $ARG_REGEX ]]; then
+ echo "Can't parse argument $i"
+ usage
+ fi
+
+ ARG_NAME="${BASH_REMATCH[1]}"
+ ARG_VALUE="${BASH_REMATCH[2]}"
+ ARG_NAME_UPPER=$(varName $ARG_NAME)
+ }
+
+ function validateArg {
+ local AD_RE=$(getVar ${ARG_NAME_UPPER}_RE)
+
+ if [[ ! $AD_RE ]]; then
+ echo "Unknown option: $ARG_NAME"
+ usage
+ fi
+
+ if [[ ! $ARG_VALUE =~ ^${AD_RE}$ ]]; then
+ echo "Wrong format: $ARG_NAME"
+ usage;
+ fi
+
+ # validate that the "action" option points to a valid function
+ if [[ $ARG_NAME == "action" ]] && ! isFunction $ARG_VALUE; then
+ echo "No action $ARG_VALUE defined in this script"
+ usage;
+ fi
+ }
+
+ # -- run
+ for i in "$@"
+ do
+ parseArg $i
+ validateArg
+ setVar "${ARG_NAME_UPPER}" "$ARG_VALUE"
+ done
+ }
+
+ function checkMissingArgs {
+ local ARG_NAME
+ for ARG_NAME in "${REQUIRED_ARG_NAMES[@]}"
+ do
+ ARG_VALUE=$(getVar $(varName $ARG_NAME))
+
+ if [[ ! $ARG_VALUE ]]; then
+ echo "Missing: $ARG_NAME"
+ usage;
+ fi
+ done
+ }
+
+ # -- run
+ readArgDefs
+ readAndValidateArgs "$@"
+ checkMissingArgs
+
+}
+
+# getVar(varName)
+function getVar {
+ echo ${!1}
+}
+
+# setVar(varName, varValue)
+function setVar {
+ eval "$1=\"$2\""
+}
+
+# isFunction(name)
+# - to be used in an if, so return 0 if successful and 1 if not!
+function isFunction {
+ if [[ $(type -t $1) == "function" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
+
+# readJsonProp(jsonFile, property)
+# - restriction: property needs to be on an own line!
+function readJsonProp {
+ echo $(sed -En 's/.*"'$2'"[ ]*:[ ]*"(.*)".*/\1/p' $1)
+}
+
+# replaceJsonProp(jsonFile, propertyRegex, valueRegex, replacePattern)
+# - note: propertyRegex will be automatically placed into a
+# capturing group! -> all other groups start at index 2!
+function replaceJsonProp {
+ sed -i .tmp -E 's/"('$2')"[ ]*:[ ]*"'$3'"/"\1": "'$4'"/' $1
+ rm $1.tmp
+}
+
+# resolveDir(relativeDir)
+# - resolves a directory relative to the current script
+function resolveDir {
+ echo $(cd $SCRIPT_DIR; cd $1; pwd)
+}
+
+function git_push_dryrun_proxy {
+ echo "## git push dryrun proxy enabled!"
+ export ORIGIN_GIT=$(which git)
+
+ function git {
+ local var
+ ARGS=("$@")
+ if [[ $1 == "push" ]]; then
+ ARGS+=("--dry-run" "--porcelain")
+ echo "####### START GIT PUSH DRYRUN #######"
+ echo "${ARGS[@]}"
+ fi
+ if [[ $1 == "commit" ]]; then
+ echo "${ARGS[@]}"
+ fi
+ $ORIGIN_GIT "${ARGS[@]}"
+ if [[ $1 == "push" ]]; then
+ echo "####### END GIT PUSH DRYRUN #######"
+ fi
+ }
+
+ export -f git
+}
+
+function main {
+ # normalize the working dir to the directory of the script
+ cd $(dirname $0);SCRIPT_DIR=$(pwd)
+
+ ARG_DEFS+=("[--git-push-dryrun=true]" "[--verbose=true]")
+ parseArgs "$@"
+
+ # --git_push_dryrun argument
+ if [[ $GIT_PUSH_DRYRUN ]]; then
+ git_push_dryrun_proxy
+ fi
+
+ # stop on errors
+ set -e
+
+ # --verbose argument
+ if [[ $VERBOSE ]]; then
+ set -x
+ fi
+
+ if isFunction init; then
+ init "$@"
+ fi
+
+ # jump to the function denoted by the --action argument,
+ # otherwise call the "run" function
+ if [[ $ACTION ]]; then
+ $ACTION "$@"
+ else
+ run "$@"
+ fi
+}
+
+
+main "$@"