tool 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. #!/usr/bin/env bash
  2. # Copyright (C) 2016 Paul Kocialkowski <contact@paulk.fr>
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. TOOL_ACTIONS_GENERIC=(usage update execute)
  17. TOOL_ACTIONS_HELPERS=(arguments)
  18. TOOL_ACTIONS_FUNCTIONS=(
  19. "${TOOL_ACTIONS_GENERIC[@]}"
  20. "${TOOL_ACTIONS_GENERIC[@]/%/_check}"
  21. "${TOOL_ACTIONS_HELPERS[@]}"
  22. )
  23. tool_include() {
  24. local tool=$1
  25. local tool_path=$( tool_path "$tool" )
  26. unset -f "${TOOL_ACTIONS_FUNCTIONS[@]}"
  27. . "$tool_path/$tool"
  28. tool_helper_include "$tool"
  29. }
  30. tool_helper_include() {
  31. local tool=$1
  32. local tool_path=$( tool_path "$tool" )
  33. local include="$tool_path/$tool-helper"
  34. if [ -f "$include" ]
  35. then
  36. . "$include"
  37. fi
  38. }
  39. tool_check() {
  40. local tool="${1##*/}"
  41. local tool_path="$(tool_path "${tool}")"
  42. if ! [[ -f "${tool_path}/${tool}" ]]; then
  43. return 1
  44. fi
  45. }
  46. tool_function_check() {
  47. local tool=$1
  48. local function=$2
  49. tool_include "$tool"
  50. if ! function_check "$function"
  51. then
  52. return 1
  53. fi
  54. return 0
  55. }
  56. tool_action() {
  57. local action=$1
  58. shift
  59. local tool=$1
  60. shift
  61. local arguments=$@
  62. (
  63. set +e
  64. if ! tool_check "$tool"
  65. then
  66. printf '%s\n' "Tool $tool check failed" >&2
  67. return 1
  68. fi
  69. tool_action_check "$action" "$tool" "$@"
  70. if [ $? -eq 0 ]
  71. then
  72. return 0
  73. fi
  74. tool_include "$tool"
  75. if ! function_check "$action"
  76. then
  77. return 0
  78. fi
  79. printf '%s\n' "Tool $tool $action (with ${arguments:-no argument})" >&2
  80. (
  81. set -e
  82. "$action" "$@"
  83. )
  84. if [ $? -ne 0 ]
  85. then
  86. printf '\n%s\n' "Tool $tool $action (with ${arguments:-no argument}) failed" >&2
  87. return 1
  88. else
  89. printf '\n%s\n' "Tool $tool $action (with ${arguments:-no argument}) completed" >&2
  90. fi
  91. )
  92. }
  93. tool_action_check() {
  94. local action=$1
  95. shift
  96. local tool=$1
  97. shift
  98. (
  99. set +e
  100. if ! tool_check "$tool"
  101. then
  102. printf '%s\n' "Tool $tool check failed" >&2
  103. return 1
  104. fi
  105. tool_include "$tool"
  106. if ! function_check "$action""_check"
  107. then
  108. return 1
  109. fi
  110. for tool_force in $TOOLS_FORCE
  111. do
  112. if [ "$tool_force" = "$tool" ]
  113. then
  114. return 1
  115. fi
  116. done
  117. (
  118. set -e
  119. "$action""_check" "$@"
  120. )
  121. )
  122. }
  123. tool_action_helper() {
  124. local helper=$1
  125. shift
  126. local tool=$1
  127. shift
  128. (
  129. set +e
  130. if ! tool_check "$tool"
  131. then
  132. printf '%s\n' "Tool $tool check failed" >&2
  133. return 1
  134. fi
  135. tool_include "$tool"
  136. if ! function_check "$helper"
  137. then
  138. return 0
  139. fi
  140. (
  141. set -e
  142. "$helper" "$@"
  143. )
  144. )
  145. }
  146. tool_action_arguments_recursive() {
  147. local action=$1
  148. shift
  149. local tool=$1
  150. shift
  151. local action_helper_arguments=$( tool_action_helper "arguments" "$tool" "$@" )
  152. local argument
  153. if [ $? -ne 0 ] || [ -z "$action_helper_arguments" ]
  154. then
  155. tool_action "$action" "$tool" "$@"
  156. else
  157. printf '%s\n' "$action_helper_arguments" | while read argument
  158. do
  159. tool_action_arguments_recursive "$action" "$tool" "$@" "$argument"
  160. done
  161. fi
  162. }
  163. tool_path() {
  164. local tool=$1
  165. local tool_path="$root/$TOOLS/$tool"
  166. printf '%s\n' "$tool_path"
  167. }
  168. tool_sources_path() {
  169. local tool=$1
  170. shift
  171. local path="$root/$TOOLS/$tool/$SOURCES"
  172. local argument
  173. for argument in "" "$@"
  174. do
  175. if ! [ -z "$argument" ]
  176. then
  177. path="$path/$argument"
  178. fi
  179. if directory_filled_check "$path"
  180. then
  181. printf '%s\n' "$path"
  182. return
  183. fi
  184. done
  185. }
  186. tool_usage_actions() {
  187. local tool=$1
  188. shift
  189. printf '\n%s\n' 'Generic actions:'
  190. for action in "${TOOL_ACTIONS_GENERIC[@]}"
  191. do
  192. if function_check "$action"
  193. then
  194. printf '%s\n' " $action"
  195. fi
  196. done
  197. if [ $# -gt 0 ]
  198. then
  199. printf '\n%s\n' 'Specific actions:'
  200. for action in "$@"
  201. do
  202. printf '%s\n' " $action"
  203. done
  204. fi
  205. }
  206. tool_usage_arguments() {
  207. local tool=$1
  208. shift
  209. printf '\n%s\n' 'Arguments:'
  210. tool_usage_arguments_recursive "$tool" " " "$@"
  211. }
  212. tool_usage_arguments_recursive() {
  213. local tool=$1
  214. shift
  215. local spacing=$1
  216. shift
  217. local action_helper_arguments=$( tool_action_helper "arguments" "$tool" "$@" )
  218. local argument
  219. if ! [ -z "$action_helper_arguments" ]
  220. then
  221. printf '%s\n' "$action_helper_arguments" | while read argument
  222. do
  223. printf '%s\n' "$spacing$argument"
  224. tool_usage_arguments_recursive "$tool" " $spacing" "$@" "$argument"
  225. done
  226. fi
  227. }
  228. tool_file_path() {
  229. local tool=$1
  230. shift
  231. local directory=$1
  232. shift
  233. local file=$1
  234. shift
  235. local tool_path=$( tool_path "$tool" )
  236. local path="$tool_path/$directory"
  237. local argument
  238. local file_path
  239. for argument in "" "$@"
  240. do
  241. if ! [ -z "$argument" ]
  242. then
  243. path="$path/$argument"
  244. fi
  245. if ! [ -f "$path/$file" ]
  246. then
  247. continue
  248. fi
  249. file_path="$path/$file"
  250. done
  251. if [ -z "$file_path" ]
  252. then
  253. return 1
  254. fi
  255. printf '%s\n' "$file_path"
  256. }
  257. tool_file_test() {
  258. local file_path=$( tool_file_path "$@" )
  259. test -f "$file_path"
  260. }
  261. tool_file_contents() {
  262. local file_path=$( tool_file_path "$@" )
  263. if [ -f "$file_path" ]
  264. then
  265. cat "$file_path"
  266. fi
  267. }
  268. tool_file_contents_herit() {
  269. local tool=$1
  270. shift
  271. local directory=$1
  272. shift
  273. local file=$1
  274. shift
  275. local tool_path=$( tool_path "$tool" )
  276. local path="$tool_path/$directory"
  277. local argument
  278. local file_path
  279. for argument in "" "$@"
  280. do
  281. if ! [ -z "$argument" ]
  282. then
  283. path="$path/$argument"
  284. fi
  285. file_path="$path/$file"
  286. if ! [ -f "$file_path" ]
  287. then
  288. continue
  289. fi
  290. cat "$file_path"
  291. done
  292. }