-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathMacros.sh
executable file
·184 lines (178 loc) · 8.23 KB
/
Macros.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#!/bin/sh
#
#/* (C) 2024 Swudu Susuwu, dual licenses: choose [_GPLv2_](./LICENSE_GPLv2) or [_Apache 2_](./LICENSE) (allows all uses). */
#/* Based on ../cxx/Macros.hxx */
#/* TODO: [produce alias (such as {`--silent`, `--quiet`} -> `-s`) groups of options/flags, for `SUSUWU_PROCESS_*` functions.](https://github.com/SwuduSusuwu/SubStack/issues/23) */
#/* TODO: [map options/flags (which `SUSUWU_PROCESS_*` functions use) to descriptions (for `--help` output.)](https://github.com/SwuduSusuwu/SubStack/issues/24) */
export SUSUWU_SH_CONSOLE_PARAMS="$*" #/* For functions which are not passed `$@` */
SUSUWU_SH_HAS_PARAM() ( #/* Usage: `if SUSUWU_SH_HAS_PARAM "--param" "$@";`. [This processes params passed to `${0}`.] */
if [ "$#" -eq 1 ]; then
SUSUWU_SH_HAS_PARAM "${1}" "${SUSUWU_SH_CONSOLE_PARAMS}"
return $?
fi
PARAM=${1}; shift;
for PARAM_W in "$@"; do
if [ "${PARAM}" = "${PARAM_W}" ]; then
return 0
fi
done
return 1
)
SUSUWU_SH_REMOVE_PARAM() ( #/* Usage: `echo "$(SUSUWU_SH_REMOVE_PARAM "--unwanted-param" "$@")"`. [This processes params passed to `${0}`.] */
PARAM=${1}; shift;
NEW_PARAMS=""
SUSUWU_SH_REMOVE_PARAM_FOUND=1
for PARAM_W in "$@"; do
if [ "${PARAM}" != "${PARAM_W}" ]; then
SUSUWU_SH_REMOVE_PARAM_FOUND=0
if [ -z "${NEW_PARAMS}" ]; then
NEW_PARAMS="${PARAM_W}"
elif [ -n "${NEW_PARAMS}" ]; then
NEW_PARAMS="${NEW_PARAMS} ${PARAM_W}" #/* TODO: spaces? */
fi
fi
done
echo "${NEW_PARAMS}"
return ${SUSUWU_SH_REMOVE_PARAM_FOUND}
)
SUSUWU_DIR_SUFFIX_SLASH() ( #/* Usage: `OBJDIR=$(SUSUWU_ENSURE_DIR_SLASH "${OBJDIR}") */
DIR=${1}
if [ "${DIR}" = "${DIR%/}" ]; then #/* "%/" removes slash; if equal after this, original doesn't have '/'. */
DIR="${DIR}/" #/* if original doesn't have, append '/' */
fi
echo "${DIR}" #/* return with slash */
)
SUSUWU_DIR_AFFIX_DOTSLASH() ( #/* Usage: `BINDIR=$(SUSUWU_ENSURE_DIR_SLASH "${BINDIR}") */
DIR=${1}
case "${DIR}" in
./*) #/* original has "./" */
;;
*) #/* default (if original doesn't match "./") */
DIR="./${DIR}" #/* if original doesn't have, affix "./" */
;;
esac
echo "${DIR}" #/* return with "./" */
)
SUSUWU_ESCAPE_SPACES() ( #/* Usage: `SUSUWU_OBJECTLIST="${SUSUWU_OBJECTLIST} $(SUSUWU_ESCAPE_SPACES "${OBJECT}"). */
# echo $(echo "$@" | sed 's/ /\\\ /') #/* Error: `sed not found`, although is installed. */
# echo "\"${@}\""; #/* Error: if `OBJECT="obj/main.o"`, `SUSUWU_BUILD_EXECUTABLE()` gives `clang++: error: no such file or directory: '"obj/main.o"'`. */
NEW_PATH=""
for OLD_PATH in "$@"; do
if [ -z "${NEW_PATH}" ]; then
NEW_PATH="${OLD_PATH}"
elif [ -n "${NEW_PATH}" ]; then
NEW_PATH="${NEW_PATH}\\ ${OLD_PATH}" #/* Error: if `OBJECT="obj/long path.o"`, `SUSUWU_BUILD_EXECUTABLE()` gives `clang++: error: no such file or directory: 'obj/long\'\nclang++: error: no such file or directory: 'path.o'`. TODO: fix this. Is not a regression (`Macros.sh` never supported spaces; `build.sh`'s paths don't have spaces.) */
fi
done
echo "${NEW_PATH}"
)
#/* `SUSUWU_SH_<color>`. Notice: update [cxx/Macros.hxx](cxx/Macros.hxx) if you update those. */
#/* Usage: `SUSUWU_PRINT "${SUSUWU_SH_<warn-level>}" "${SUSUWU_SH_<color>}<message>${SUSUWU_SH_DEFAULT}"`. */
export SUSUWU_SH_DEFAULT="\033[0m"
export SUSUWU_SH_BLACK="\033[0;30m"
export SUSUWU_SH_DARK_GRAY="\033[1;30m"
export SUSUWU_SH_RED="\033[0;31m"
export SUSUWU_SH_LIGHT_RED="\033[1;31m"
export SUSUWU_SH_GREEN="\033[0;32m"
export SUSUWU_SH_LIGHT_GREEN="\033[1;32m"
export SUSUWU_SH_BROWN="\033[0;33m"
export SUSUWU_SH_YELLOW="\033[1;33m"
export SUSUWU_SH_BLUE="\033[0;34m"
export SUSUWU_SH_LIGHT_BLUE="\033[1;34m"
export SUSUWU_SH_PURPLE="\033[0;35m"
export SUSUWU_SH_LIGHT_PURPLE="\033[1;35m"
export SUSUWU_SH_CYAN="\033[0;36m"
export SUSUWU_SH_LIGHT_CYAN="\033[1;36m"
export SUSUWU_SH_LIGHT_GRAY="\033[0;37m"
export SUSUWU_SH_WHITE="\033[1;37m"
#/* `SUSUWU_SH_<warn-level>`. Notice: update [cxx/Macros.hxx](cxx/Macros.hxx) if you update those. */
#/* Usage: `SUSUWU_PRINT "${SUSUWU_SH_<warn-level>}" "<message>"`. */
export SUSUWU_SH_ERROR="${SUSUWU_SH_RED}Error: ${SUSUWU_SH_WHITE}"
export SUSUWU_SH_WARNING="${SUSUWU_SH_PURPLE}Warning: ${SUSUWU_SH_WHITE}"
export SUSUWU_SH_INFO="${SUSUWU_SH_CYAN}Info: ${SUSUWU_SH_WHITE}"
export SUSUWU_SH_SUCCESS="${SUSUWU_SH_GREEN}Success: ${SUSUWU_SH_WHITE}"
export SUSUWU_SH_NOTICE="${SUSUWU_SH_BLUE}Notice: ${SUSUWU_SH_WHITE}"
export SUSUWU_SH_DEBUG="${SUSUWU_SH_BLUE}Debug: ${SUSUWU_SH_WHITE}"
SUSUWU_SH_CLOSE_="${SUSUWU_SH_DEFAULT}"
SUSUWU_S=false
SUSUWU_VERBOSE=false
SUSUWU_PROCESS_S() { #/* Usage: `SUSUWU_PROCESS_S $@`. [This processes params passed to `${0}`.] */
if SUSUWU_SH_HAS_PARAM "-s" "$@"; then
SUSUWU_S=true
fi
}
SUSUWU_PROCESS_VERBOSE() { #/* Usage: `SUSUWU_PROCESS_VERBOSE $@`. [This processes params passed to `${0}`.] */
if SUSUWU_SH_HAS_PARAM "--verbose" "$@"; then
SUSUWU_VERBOSE=true
set -x
fi
}
SUSUWU_SH_HAS_FUNCNAME() ( #/* Usage: `if SUSUWU_SH_HAS_FUNCNAME 2>/dev/null; then echo "${FUNCNAME[0]}(): used FUNCNAME."` */
# [ "$(uname)" = "Darwin" ] && return 0 #redundant (due to `${FUNCNAME[0]}` test).
# test "$(type -t FUNCNAME)" = "array" #always returns "1".
#shellcheck disable=SC2039 #this is a feature test, so disable "In POSIX sh, array references are undefined."
test "${FUNCNAME[0]}" = "SUSUWU_SH_HAS_FUNCNAME" 2>/dev/null #if no arrays, prints "Bad substitution".
return $?
)
if [ -z "${SUSUWU_SH_HAS_FUNCNAME_RESULT}" ]; then
SUSUWU_SH_HAS_FUNCNAME 2>/dev/null #`/bin/sh` ignores the `2>/dev/null` in `SUSUWU_SH_HAS_FUNCNAME()`.
export SUSUWU_SH_HAS_FUNCNAME_RESULT=$? #/* Usage: `if [ ${SUSUWU_SH_HAS_FUNCNAME_RESULT} -eq 0 ]; then echo "${FUNCNAME[0]}: used FUNCNAME."` */
fi
#for var in SUSUWU_SH_FILE SUSUWU_SH_LINE SUSUWU_SH_FUNC; do
# [ -z "${!var}" ] && export "$var=true" #prints "Bad substitution".
#done
export SUSUWU_SH_FILE="${SUSUWU_SH_FILE:-""}"
export SUSUWU_SH_LINE="${SUSUWU_SH_LINE:-""}"
export SUSUWU_SH_FUNC="${SUSUWU_SH_FUNC:-"true"}"
export SUSUWU_SH_FILE_OR_LINE="${SUSUWU_SH_FILE:-${SUSUWU_SH_LINE}}"
SUSUWU_PRINT() ( #/* Usage: `SUSUWU_PRINT ["<optional caller-name>"] "$(SUSUWU_SH_<warn-level>)" "<message>" */
if [ "$#" -eq 3 ]; then
CALLER_FUNC="${1}"; shift
fi
LEVEL="${1}"
MESSAGE="${2}"
case "${LEVEL}" in
"${SUSUWU_SH_NOTICE}")
${SUSUWU_S} && return 1
;;
"${SUSUWU_SH_DEBUG}")
(! ${SUSUWU_VERBOSE}) && return 1
;;
esac
NEW_MESSAGE="[${SUSUWU_SH_FILE:+"$0:"}${SUSUWU_SH_LINE:+"${LINENO}:"}${SUSUWU_SH_FILE_OR_LINE:+" "}${LEVEL}"
if [ "true" = "${SUSUWU_SH_FUNC}" ]; then
if [ -n "${CALLER_FUNC}" ]; then
NEW_MESSAGE="${NEW_MESSAGE}${CALLER_FUNC}: "
elif [ "${SUSUWU_SH_HAS_FUNCNAME_RESULT}" -eq 0 ]; then
#shellcheck disable=SC2039 #if `SUSUWU_SH_HAS_FUNCNAME`, console supports this
NEW_MESSAGE="${NEW_MESSAGE}${FUNCNAME[1]}(): "
elif [ -n "$KSH_VERSION" ]; then
NEW_MESSAGE="${NEW_MESSAGE}${.sh.fun}: "
fi
fi
NEW_MESSAGE="${NEW_MESSAGE}${MESSAGE}${SUSUWU_SH_CLOSE_}]"
printf '%b\n' "${NEW_MESSAGE}" >&2 #/* fd=2 is `std::cerr`/`stderr` */
return $?
)
SUSUWU_DEFAULT_BRANCH() ( #/* Usage: `echo "$(SUSUWU_DEFAULT_BRANCH ["<fallback>"])"` */
DEFAULT_BRANCH="$(git symbolic-ref -q --short "refs/remotes/$(git remote)/HEAD" | sed -n "s/$(git remote)\/\(.*\)/\1/p")" #remote branch
if [ -z "${DEFAULT_BRANCH}" ]; then #if `git remote` not found
DEFAULT_BRANCH="$(git branch --sort=-refname | grep -o -m1 '\b\(main\|master\|trunk\)\b')" #local branch; if you update this, update `README.md#git`.
fi
echo "${DEFAULT_BRANCH:-${1}}" #https://github.com/SwuduSusuwu/SubStack/actions/runs/<number>/job/<number> has bare repos, which use <fallback>.
)
SUSUWU_PRODUCTION_USE() ( #/* Usage: `SUSUWU_PRODUCTION_USE ["<default branch>"]` */
if command -v git >/dev/null && git rev-parse --is-inside-work-tree >/dev/null 2>&1; then #test -d ".git/"; then
THIS_BRANCH="$(git rev-parse --abbrev-ref HEAD)" #detect current branch
if [ -n "${1}" ]; then
DEFAULT_BRANCH="${1}" #use default branch from build script
else
DEFAULT_BRANCH="$(SUSUWU_DEFAULT_BRANCH "${1}")" #detect default branch
fi
if [ "${DEFAULT_BRANCH}" = "${THIS_BRANCH}" ]; then
SUSUWU_PRINT "SUSUWU_PRODUCTION_USE()" "${SUSUWU_SH_NOTICE}" "\`git branch\` is \"${THIS_BRANCH}\"."
else
SUSUWU_PRINT "SUSUWU_PRODUCTION_USE()" "${SUSUWU_SH_WARNING}" "\`git branch\` is \"${THIS_BRANCH}\"; for production use, execute \`git switch ${DEFAULT_BRANCH}\`."
fi
fi
)