2020-04-18 01:59:19 +00:00
#/bin/bash
2020-04-18 03:40:30 +00:00
# This script was indeed self-updated!
# Catch signals so we don't leave zombie tasks behind if we Ctrl^C
2020-04-18 03:44:01 +00:00
# No idea why but it seems to prevent the script from working? Disable!
#trap "exit" INT TERM ERR
#trap "kill 0" EXIT
2020-04-18 01:59:19 +00:00
BASEDIR = " $HOME /.git-build "
2020-04-29 21:41:20 +00:00
# So scripts can know we're still running (for autoupdater)
echo " $BASHPID " > $BASEDIR /.LOCK
2020-04-29 15:37:56 +00:00
# Default logging levels (error is always enabled)
INFO = 1
DEBUG = 0
2020-04-29 19:23:29 +00:00
# Extract two letters from $LANG
locale = " ${ LANG : 0 : 2 } "
# Initialize translations
[ -f i18n/$locale .json ] && locale_strings = " $( cat i18n/$locale .json) " || locale_strings = " $( cat i18n/en.json) "
# Takes one argument, looks up translation
trans( ) {
res = " $( echo " $locale_strings " | jq " . $1 " ) "
if [ [ " $res " = "" ] ] ; then
echo " ERROR: Failed to translate $1 "
exit 1
fi
res = ${ res # "\"" }
res = ${ res % "\"" }
echo -n " $res "
}
2020-04-29 15:37:56 +00:00
# We set custom logging functions so that later we can decorate stuff
warn( ) {
2020-04-29 19:23:29 +00:00
[ [ $INFO = 1 ] ] && echo -e " \e[33m $( trans warning) \e[0m $( trans $1 ) " | envsubst > /dev/stderr
2020-04-29 15:37:56 +00:00
}
info( ) {
2020-04-29 19:23:29 +00:00
[ [ $INFO = 1 ] ] && echo " [git-build] $( trans $1 ) " | envsubst
2020-04-29 15:37:56 +00:00
}
error ( ) {
2020-04-29 19:23:29 +00:00
echo -e " \e[31m $( trans error) \e[0m $( trans $1 ) " | envsubst > /dev/stderr
2020-04-29 15:37:56 +00:00
}
2020-04-29 16:15:23 +00:00
debug ( ) {
2020-04-29 19:23:29 +00:00
[ [ $DEBUG = 1 ] ] && echo -e " \e[36m $( trans debug) \e[0m $( trans $1 ) " | envsubst
2020-04-29 16:15:23 +00:00
}
2020-04-29 15:37:56 +00:00
# Logging is done with the LOG="debug|info|error" environment variable
if [ ! -z $LOG ] && [ " $LOG " != "" ] ; then
case $LOG in
"debug" | "DEBUG" )
DEBUG = 1
; ;
"error" | "ERROR" )
INFO = 0
; ;
"info" | "INFO" )
2020-04-29 16:15:23 +00:00
# Default settings
2020-04-29 15:37:56 +00:00
; ;
*)
2020-04-29 19:23:29 +00:00
warn loglevel_bad
2020-04-29 15:37:56 +00:00
; ;
esac
fi
2020-04-18 15:30:57 +00:00
run( ) {
p_name = " $1 "
2020-04-29 19:23:29 +00:00
i18n_task = " $p_name " info run
2020-04-18 15:30:57 +00:00
# Run in background and redirect output to $p_name.log
2020-04-29 19:49:30 +00:00
( GITBUILDCONF = " $CONFDIR " GITBUILDDIR = " $BASEDIR " nohup $BASEDIR /$p_name $p_name > $BASEDIR /$p_name .log 2>& 1) &
2020-04-18 15:30:57 +00:00
}
2020-04-19 12:50:38 +00:00
# Overriden by -f/--force to force rebuild when no update is available
2020-04-19 12:42:48 +00:00
FORCE = 0
2020-04-19 12:50:38 +00:00
# Check if we have host-specific config then LOCAL=0
2020-04-29 16:15:23 +00:00
# TODO: maybe we should just match for $BASEDIR/$HOSTNAME directly? Would allow to fallback to global config for multihost setup where one host is not configured.. but is that desired? Also enables to have more folders in $BASEDIR (maybe logs/)
2020-04-19 12:50:38 +00:00
LOCAL = 1
for folder in $BASEDIR /*/; do
# Hidden folders (repos) are ignored by the pattern, so we can assume if a folder is not config/ then there are host-based configs here.
[ [ " $( basename $folder ) " != "config" ] ] && LOCAL = 0 && break
done
2020-04-19 16:53:07 +00:00
# Pass either local or global config to the task
2020-04-29 19:23:29 +00:00
[ [ LOCAL = 1 ] ] && CONFDIR = $BASEDIR /config || CONFDIR = " $BASEDIR / $HOSTNAME "
export i18n_config = " $CONFDIR "
info config
2020-04-19 16:53:07 +00:00
2020-04-29 16:15:23 +00:00
# Find targeted projects from args and extra arguments
2020-04-19 12:36:19 +00:00
PROJECTS = ( )
for arg in " $@ " ; do
2020-04-19 12:42:48 +00:00
if [ [ " $arg " = "-f" ] ] || [ [ " $arg " = "--force" ] ] ; then
2020-04-29 19:23:29 +00:00
info force_flag
2020-04-19 12:42:48 +00:00
FORCE = 1
2020-04-29 14:38:27 +00:00
# Maybe it's a task name and we find a corresponding source?
2020-04-29 16:15:23 +00:00
# TODO: Support source-less tasks https://tildegit.org/southerntofu/git-build.sh/issues/8
2020-04-19 12:42:48 +00:00
elif [ -f $BASEDIR /$arg .source ] ; then
2020-04-29 19:23:29 +00:00
export i18n_task = " $arg "
debug found_task
2020-04-19 12:42:48 +00:00
PROJECTS += ( " $arg " )
2020-04-29 14:38:27 +00:00
# Maybe it's a repo URL and we find a corresponding task?
elif matches = " $( grep --files-with-matches --word-regexp " $arg " $BASEDIR /*.source) " ; then
# Iterate over the files found to extract the task name
IFS = echo " $matches " | while read -r file; do
task_name = " $( basename " $file " .source) "
# Make sure we don't have a .source file without name lying around, just in case
2020-04-29 16:15:23 +00:00
if [ [ " $task_name " != "" ] ] ; then
2020-04-29 19:23:29 +00:00
export i18n_task = " $task_name " i18n_source = " $arg "
debug found_url
2020-04-29 16:15:23 +00:00
PROJECT += ( " $task_name " )
fi
2020-04-29 14:38:27 +00:00
done
else
2020-04-29 19:23:29 +00:00
export i18n_arg = " $arg "
error unknown_arg
2020-04-29 14:38:27 +00:00
exit 1
2020-04-19 12:42:48 +00:00
fi
2020-04-19 12:36:19 +00:00
done
# If no project argument passed, default to all projects
if [ [ ${# PROJECTS [*] } = 0 ] ] ; then
2020-04-29 19:23:29 +00:00
info no_task
2020-04-29 16:15:23 +00:00
# TODO: sourceless tasks
for file in $BASEDIR /*.source; do
2020-04-19 12:36:19 +00:00
# Extract the project name from path
2020-04-29 16:15:23 +00:00
task = " $( basename $file .source) "
2020-04-29 19:23:29 +00:00
export i18n_task = " $task "
debug found_task
2020-04-29 16:15:23 +00:00
PROJECTS += ( " $task " )
2020-04-19 12:36:19 +00:00
done
fi
2020-04-29 16:15:23 +00:00
# TODO: sourceless tasks
2020-04-19 12:36:19 +00:00
for p_name in ${ PROJECTS [*] } ; do
2020-04-29 19:23:29 +00:00
# For translations
export i18n_task = " $p_name "
debug start_proc
2020-04-19 15:19:55 +00:00
# Check if task should run on host
if [ [ $LOCAL = 0 ] ] ; then
2020-04-29 19:23:29 +00:00
if [ -f $BASEDIR /$p_name .host ] ; then
for_host = " $( cat $BASEDIR /$p_name .host) "
if [ [ " $for_host " != " $HOSTNAME " ] ] ; then
# The task is specifically configured for a different host, ignore
export i18n_host = " $for_host "
debug skipped
continue
fi
2020-04-19 15:19:55 +00:00
fi
# The task has a PROJECT.ignore file in host config, ignore
2020-04-29 19:23:29 +00:00
if [ -f $BASEDIR /$HOSTNAME /$p_name .ignore ] ; then
info host_ignored
continue
fi
2020-04-19 15:19:55 +00:00
fi
2020-04-29 19:23:29 +00:00
info process
2020-04-29 16:15:23 +00:00
# TODO: Should be able to switch branch after a repo was cloned
if [ -f $BASEDIR /$p_name .branch ] ; then
p_branch = " $( cat $BASEDIR /$p_name .branch) "
2020-04-29 19:23:29 +00:00
export i18n_branch = " $p_branch "
info to_branch
2020-04-29 16:15:23 +00:00
else
p_branch = "master"
2020-04-29 19:23:29 +00:00
export i18n_branch = " $p_branch "
debug default_branch
2020-04-29 16:15:23 +00:00
fi
2020-04-18 01:59:19 +00:00
p_dir = " $BASEDIR /. $p_name "
if [ ! -d $p_dir ] ; then
2020-04-18 02:43:14 +00:00
source = " $( cat $BASEDIR /$p_name .source) "
2020-04-29 19:23:29 +00:00
export i18n_source = " $source "
info clone
2020-04-18 14:20:54 +00:00
# Don't forget the git submodules!
2020-04-29 19:23:29 +00:00
if ! git clone --recursive " $source " " $p_dir " ; then
error clone_failed
exit 1
fi
2020-04-18 15:30:57 +00:00
cd $p_dir
2020-04-18 02:43:14 +00:00
if [ [ " $p_branch " != "master" ] ] ; then
2020-04-29 19:23:29 +00:00
debug checkout
if ! git checkout " $p_branch " ; then
error checkout_failed
exit 1
fi
2020-04-18 01:59:19 +00:00
fi
2020-04-18 15:30:57 +00:00
run $p_name
2020-04-29 16:15:23 +00:00
# Skip to the next task!
continue
2020-04-18 01:59:19 +00:00
fi
2020-04-29 19:23:29 +00:00
debug already_cloned
2020-04-18 01:59:19 +00:00
cd " $p_dir "
2020-04-18 02:47:18 +00:00
# Refresh remote before comparing with local
2020-04-18 03:00:12 +00:00
git fetch --quiet origin
2020-04-18 02:43:14 +00:00
git diff --quiet remotes/origin/$p_branch
if [ [ $? != 0 ] ] ; then
2020-04-29 19:23:29 +00:00
info pull
2020-04-18 14:20:54 +00:00
# Update all submodules, for now only when the main repo changed (TODO)
2020-04-29 19:23:29 +00:00
if ! git pull --quiet --recurse-submodules; then
error pull_failed
exit 1
fi
2020-04-18 15:30:57 +00:00
run $p_name
2020-04-19 12:42:48 +00:00
# If no update was found, we can still force rebuild with -f/--force
elif [ [ $FORCE = 1 ] ] ; then
2020-04-29 19:23:29 +00:00
debug forcing
2020-04-19 12:42:48 +00:00
run $p_name
2020-04-29 16:15:23 +00:00
else
2020-04-29 19:23:29 +00:00
debug no_update
2020-04-18 02:14:58 +00:00
fi
2020-04-18 01:59:19 +00:00
done
2020-04-18 03:19:56 +00:00
2020-04-29 21:41:20 +00:00
# Check the PID in lockfile is still ours, we don't want
# to remove the lockfile if another git-build "owns" it
if [ [ " $( cat $BASEDIR /.LOCK) " = " $BASHPID " ] ] ; then
rm $BASEDIR /.LOCK
fi