shell dot on steroids https://pagure.io/shellfu

ffoo.sh.skel 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/bin/bash
  2. FFOO_DIR=${FFOO_DIR:-__FFOO_DIR__}
  3. FFOO_DEBUG=${FFOO_DEBUG:-false}
  4. FFOO_DEBUGINIT=${FFOO_DEBUGINIT:-false}
  5. FFOO_IMPORTED=${FFOO_IMPORTED:-}
  6. FFOO_INCLUDE=${FFOO_INCLUDE:-$FFOO_DIR/include}
  7. FFOO_PRETTY=${FFOO_PRETTY:-plain}
  8. FFOO_PATH=${FFOO_PATH:-}
  9. FFOO_VERBOSE=${FFOO_VERBOSE:-false}
  10. FFOO_VERSION=__VERSION__
  11. ffoo() {
  12. case $1 in
  13. __debug)
  14. $FFOO_DEBUGINIT || return 0
  15. shift
  16. echo "debug: $@" >&2
  17. ;;
  18. __die)
  19. shift
  20. echo "$@" >&2
  21. test -z "$PS1" && exit 3
  22. return 3
  23. ;;
  24. __warn)
  25. shift
  26. echo "$@" >&2
  27. ;;
  28. doc)
  29. ffoo _cat_function "$2" | ffoo _filter_doc
  30. ;;
  31. import)
  32. local mname=$2
  33. ffoo is_imported $mname && return 0
  34. if ffoo _do_import $mname;
  35. then
  36. FFOO_IMPORTED="$FFOO_IMPORTED${FFOO_IMPORTED:+:}$mname"
  37. else
  38. ffoo __die "cannot import module: $mname"
  39. fi
  40. ;;
  41. try_import)
  42. local mname=$2
  43. ( ffoo _do_import $mname )
  44. ;;
  45. is_imported)
  46. local mname=$2
  47. echo "$FFOO_IMPORTED" | tr : \\n | grep -qx "$mname"
  48. ;;
  49. _do_import)
  50. local es=4
  51. ffoo __debug "importing module $mname"
  52. local mpath=$(ffoo _select_mfile $mname)
  53. test -n "$mpath" || {
  54. ffoo __warn "cannot find module: $mname"
  55. return 3
  56. }
  57. ffoo __debug "found module file: $mpath"
  58. bash -n $mpath || return 3
  59. . $mpath
  60. es=$?
  61. local init=__ffoo_${mname}__init
  62. if test "$(type -t $init)" == function;
  63. then
  64. ffoo __debug "launching init function: $init"
  65. $init
  66. es=$?
  67. fi
  68. return $es
  69. ;;
  70. _parse)
  71. # convert stdin from $1 to $2 (can be 1:N conversion)
  72. local src=$2
  73. local tgt=$3
  74. local line
  75. while read line;
  76. do
  77. ffoo _parse_${src}_to_${tgt} "$line"
  78. done
  79. ;;
  80. _parse_path_to_mod)
  81. local fname="${2##*/}"; echo "${fname%%.sh}"
  82. ;;
  83. _parse_fspec_to_mod)
  84. echo "${2%%.*}"
  85. ;;
  86. _parse_fspec_to_fun)
  87. local mod=$(ffoo _parse_fspec_to_mod "$2")
  88. echo "${2##$mod.}"
  89. ;;
  90. _parse_path_to_fspeclist)
  91. grep -HE '^[[:alnum:]_]+\(\) \{' "$2" \
  92. | sed -e 's/^.*\///; s/\.sh:/./; s/(.*//'
  93. ;;
  94. _parse_path_to_fnlist)
  95. grep -E '^[[:alnum:]_]+\(\) \{' "$2" \
  96. | sed -e 's/^.*\///; s/(.*//'
  97. ;;
  98. _cat_function)
  99. local mod=$(ffoo _parse_fspec_to_mod "$2")
  100. local fun=$(ffoo _parse_fspec_to_fun "$2")
  101. local mfname=$(ffoo _select_mfile "$mod")
  102. test -n "$mfname" || ffoo __die "unknown module: $mod"
  103. name=$fun perl -we '
  104. undef $/;
  105. my $name = $ENV{name};
  106. my ($fbody) = <> =~ m/^($name\(\) \{.*?^\}$)/ms;
  107. print "$fbody\n" if defined $fbody;
  108. ' < "$mfname"
  109. ;;
  110. _filter_doc)
  111. # 1. line "^ #$" opens doc
  112. # 2. first line that is not "^ #" closes doc
  113. # 3. first and last line will be stripped
  114. perl -we '
  115. my $isdoc;
  116. while (<>) {
  117. if (m/^ #$/) {
  118. $isdoc = 1;
  119. } elsif (m/^ [^#]/) {
  120. exit;
  121. }
  122. next unless $isdoc;
  123. s/ # ?//;
  124. print;
  125. }' \
  126. | head -n -1 \
  127. | tail -n +2
  128. ;;
  129. _list_modules)
  130. ffoo _list_mfiles "$2" | ffoo _parse path mod
  131. ;;
  132. _list_mfiles)
  133. local ex="${2:-*}"
  134. find $FFOO_INCLUDE ${FFOO_PATH/:/ } -name "$ex.sh"
  135. ;;
  136. _select_mfile)
  137. ffoo _list_mfiles $2 | head -1
  138. ;;
  139. _list_functions)
  140. ffoo _list_mfiles "$2" | ffoo _parse path fspeclist
  141. ;;
  142. _list_functions_in)
  143. ffoo _list_mfiles "$2" | ffoo _parse path fnlist
  144. ;;
  145. *)
  146. ffoo __die "unknown ffoo command: $1"
  147. ;;
  148. esac
  149. }
  150. ffoo __debug "FFOO_DIR='$FFOO_DIR'"
  151. ffoo __debug "FFOO_DEBUG='$FFOO_DEBUG'"
  152. ffoo __debug "FFOO_DEBUGINIT='$FFOO_DEBUGINIT'"
  153. ffoo __debug "FFOO_IMPORTED='$FFOO_IMPORTED'"
  154. ffoo __debug "FFOO_INCLUDE='$FFOO_INCLUDE'"
  155. ffoo __debug "FFOO_PRETTY='$FFOO_PRETTY'"
  156. ffoo __debug "FFOO_PATH='$FFOO_PATH'"
  157. ffoo __debug "FFOO_VERBOSE='$FFOO_VERBOSE'"
  158. ffoo __debug "FFOO_VERSION='$FFOO_VERSION'"