tg-annihilate.sh: autostash and support --stash and --no-stash
[topgit/pro.git] / Makefile.sh
blobc362caa2143e64e282bf0ba08950d81f34371e89
1 # Makefile.sh - POSIX Makefile scripting adjunct for TopGit
2 # Copyright (C) 2017 Kyle J. McKay
3 # All rights reserved
4 # License GPL2
6 # Set MAKEFILESH_DEBUG to get:
7 # 1. All defined environment variales saved to Makefile.var
8 # 2. set -x
9 # 3. set -v if MAKEFILESH_DEBUG contains "v"
11 if [ -n "$MAKEFILESH_DEBUG" ]; then
12 _setcmd="set -x"
13 case "$MAKEFILESH_DEBUG" in *"v"*) _setcmd="set -vx"; esac
14 eval "$_setcmd && unset _setcmd"
17 # prevent crazy "sh" implementations from exporting functions into environment
18 set +a
20 # wrap it up for safe returns
21 # $1 is the current build target, if any
22 makefile() {
24 POUND="#"
26 # Update if you add any code that requires a newer version of git
27 : "${GIT_MINIMUM_VERSION:=1.8.5}"
29 # This avoids having this in no less than three different places!
30 TG_STATUS_HELP_USAGE="st[atus] [-v] [--exit-code]"
32 # These are initialized here so config.sh or config.mak can change them
33 # They are deliberately left with '$(...)' constructs for make to expand
34 # so that if config.mak just sets prefix they all automatically change
35 [ -n "$prefix" ] || prefix="$HOME"
36 [ -n "$bindir" ] || bindir='$(prefix)/bin'
37 [ -n "$cmddir" ] || cmddir='$(prefix)/libexec/topgit'
38 [ -n "$sharedir" ] || sharedir='$(prefix)/share/topgit'
39 [ -n "$hooksdir" ] || hooksdir='$(prefix)/hooks'
41 v_wildcard commands_in 'tg-[!-]*.sh'
42 v_wildcard utils_in 'tg--*.sh'
43 v_wildcard awk_in 'awk/*.awk'
44 v_wildcard hooks_in 'hooks/*.sh'
45 v_wildcard helpers_in 't/helper/*.sh'
47 v_strip_sfx commands_out .sh $commands_in
48 v_strip_sfx utils_out .sh $utils_in
49 v_strip_sfx awk_out .awk $awk_in
50 v_strip_sfx hooks_out .sh $hooks_in
51 v_strip_sfx helpers_out .sh $helpers_in
53 v_stripadd_sfx help_out .sh .txt tg-help.sh tg-status.sh $commands_in
54 v_stripadd_sfx html_out .sh .html tg-help.sh tg-status.sh tg-tg.sh $commands_in
56 DEPFILE="Makefile.dep"
58 write_auto_deps '' '.sh' tg $commands_out $utils_out $hooks_out $helpers_out
59 } >"$DEPFILE"
61 : "${SHELL_PATH:=/bin/sh}" "${AWK_PATH:=awk}"
62 version="$(
63 test -d .git && git describe --match "topgit-[0-9]*" --abbrev=4 --dirty 2>/dev/null |
64 sed -e 's/^topgit-//')" || :
66 # config.sh is wrapped up for return safety
67 configsh
69 [ -n "$CONFIGMAK" ] || CONFIGMAK="config.mak"
70 [ -f "$CONFIGMAK" ] || CONFIGMAK="Makefile.mt"
72 # config.sh may not unset these
73 : "${SHELL_PATH:=/bin/sh}" "${AWK_PATH:=awk}"
75 case "$AWK_PATH" in */*) AWK_PREFIX=;; *) AWK_PREFIX="/usr/bin/"; esac
76 quotevar SHELL_PATH SHELL_PATH_SQ
77 quotevar AWK_PATH AWK_PATH_SQ
79 v_strip version "$version"
80 version_arg=
81 [ -z "$version" ] || version_arg="-e 's/TG_VERSION=.*/TG_VERSION=\"$version\"/'"
83 DESTDIRBOOL="No"
84 [ -z "$DESTDIR" ] || DESTDIRBOOL="Yes"
86 # the "t/" subdirectory still needs gmake
87 [ -n "$GMAKE" ] || GMAKE="$(cmd_path "gmake")" || : # most common
88 [ -n "$GMAKE" ] || GMAKE="$(cmd_path "gnumake")" || : # sometimes
89 [ -n "$GMAKE" ] || GMAKE='$(MAKE)' || : # perhaps
91 [ -z "$MAKEFILESH_DEBUG" ] || {
92 (unset BUILD_SETTINGS && printenv) | LC_ALL=C grep '^[_A-Za-z][_A-Za-z0-9]*=' | LC_ALL=C sort
93 echo "---- BUILD_SETTINGS VALUE ----"
94 printenv "BUILD_SETTINGS"
95 } >"Makefile.var"
97 # Force TG-BUILD-SETTINGS to be updated now if needed
98 ${MAKE:-make} -f Makefile.mak FORCE_SETTINGS_BUILD=FORCE TG-BUILD-SETTINGS
100 # end of wrapper
104 ## Utility Functions
107 # wrap it up for safety
108 configsh() {
109 [ -f "config.sh" ] || return 0
110 . ./"config.sh"
113 cmd_path() (
114 { "unset" -f command unset unalias "$1"; } >/dev/null 2>&1 || :
115 { "unalias" -a; } >/dev/null 2>&1 || :
116 command -v "$1"
119 # stores the single-quoted value of the variable name passed as
120 # the first argument into the variable name passed as the second
121 # (use quotevar 3 varname "$value" to quote a value directly)
122 quotevar() {
123 eval "set -- \"\${$1}\" \"$2\""
124 case "$1" in *"'"*)
125 set -- "$(printf '%s\nZ\n' "$1" | sed "s/'/'\\\''/g")" "$2"
126 set -- "${1%??}" "$2"
127 esac
128 eval "$2=\"'$1'\""
131 # The result(s) of stripping the second argument from the end of the
132 # third and following argument(s) is joined using a space and stored
133 # in the variable named by the first argument
134 v_strip_sfx() {
135 _var="$1"
136 _sfx="$2"
137 shift 2
138 _result=
139 for _item in "$@"; do
140 _result="$_result ${_item%$_sfx}"
141 done
142 eval "$_var="'"${_result# }"'
143 unset _var _sfx _result _item
146 # The result(s) of appending the second argument to the end of the
147 # third and following argument(s) is joined using a space and stored
148 # in the variable named by the first argument
149 v_add_sfx() {
150 _var="$1"
151 _sfx="$2"
152 shift 2
153 _result=
154 for _item in "$@"; do
155 _result="$_result $_item$_sfx"
156 done
157 eval "$_var="'"${_result# }"'
158 unset _var _sfx _result _item
161 # The result(s) of stripping the second argument from the end of the
162 # fourth and following argument(s) and then appending the third argument is
163 # joined using a space and stored in the variable named by the first argument
164 v_stripadd_sfx() {
165 _var2="$1"
166 _stripsfx="$2"
167 _addsfx="$3"
168 shift 3
169 v_strip_sfx _result2 "$_stripsfx" "$@"
170 v_add_sfx "$_var2" "$_addsfx" $_result2
171 unset _var2 _stripsfx _addsfx _result2
174 # The second and following argument(s) are joined with a space and
175 # stored in the variable named by the first argument
176 v_strip_() {
177 _var="$1"
178 shift
179 eval "$_var="'"$*"'
180 unset _var
183 # The second and following argument(s) are joined with a space and then
184 # the result has leading and trailing whitespace removed and internal
185 # whitespace sequences replaced with a single space and is then stored
186 # in the variable named by the first argument and pathname expansion is
187 # disabled during the stripping process
188 v_strip() {
189 _var="$1"
190 shift
191 set -f
192 v_strip_ "$_var" $*
193 set +f
196 # Expand the second and following argument(s) using pathname expansion but
197 # skipping any that have no match and join all the results using a space and
198 # store that in the variable named by the first argument
199 v_wildcard() {
200 _var="$1"
201 shift
202 _result=
203 for _item in "$@"; do
204 eval "_exp=\"\$(printf ' %s' $_item)\""
205 [ " $_item" = "$_exp" ] && ! [ -e "$_item" ] || _result="$_result$_exp"
206 done
207 eval "$_var="'"${_result# }"'
208 unset _var _result _item _exp
211 # Write the third and following target arguments out as target with a dependency
212 # line(s) to standard output where each line is created by stripping the target
213 # argument suffix specified by the first argument ('' to strip nothing) and
214 # adding the suffix specified by the second argument ('' to add nothing).
215 # Does nothing if "$1" = "$2". (Set $1 = " " and $2 = "" to write out
216 # dependency lines with no prerequisites.)
217 write_auto_deps() {
218 [ "$1" != "$2" ] || return 0
219 _strip="$1"
220 _add="$2"
221 shift 2
222 for _targ in "$@"; do
223 printf '%s: %s\n' "$_targ" "${_targ%$_strip}$_add"
224 done
225 unset _strip _add _targ
229 ## Run "makefile" now
232 set -ea
233 makefile "$@"