123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #!/bin/bash
  2. usage() {
  3. local self
  4. self="$(basename "$0")"
  5. warn "usage: $self [-f|--force] [+TEMPLATE] FILE"
  6. warn "usage: $self -l|--list"
  7. exit 2
  8. }
  9. warn() {
  10. #
  11. # Print warning
  12. #
  13. echo "$@" >&2
  14. }
  15. die() {
  16. #
  17. # Warn and exit prematurely
  18. #
  19. warn "$@"
  20. exit 3
  21. }
  22. lstemplates() {
  23. #
  24. # Print list of valid templates
  25. #
  26. echo sed
  27. echo pya
  28. echo shellfu
  29. echo Bash
  30. echo Lua
  31. echo Perl
  32. echo py3
  33. echo Python3
  34. echo Python
  35. }
  36. #shellcheck disable=SC2016
  37. mktemplate() {
  38. #
  39. # Print template $Template for $FilePath
  40. #
  41. case "$Template" in
  42. sh)
  43. echo "#!/bin/sh"
  44. echo ''
  45. echo ''
  46. ;;
  47. bash|Bash)
  48. echo "#!/bin/bash"
  49. echo ''
  50. echo ''
  51. ;;
  52. sed)
  53. echo "#!/bin/sed -f"
  54. echo ''
  55. echo ''
  56. ;;
  57. lua|Lua)
  58. echo "#!$(which lua)"
  59. echo ''
  60. ;;
  61. pl|Perl)
  62. echo "#!$(which perl)"
  63. echo ''
  64. echo 'use strict;'
  65. echo 'use warnings;'
  66. echo ''
  67. echo ''
  68. ;;
  69. py|Python)
  70. echo "#!$(which python)"
  71. echo ''
  72. echo "if __name__ == '__main__':"
  73. echo ' '
  74. ;;
  75. py3|Python3)
  76. echo "#!/usr/bin/python3"
  77. echo ''
  78. echo 'import sys'
  79. echo ''
  80. echo ''
  81. echo 'class UsageError(ValueError):'
  82. echo ' pass'
  83. echo ''
  84. echo ''
  85. echo 'def usage():'
  86. echo ' self = sys.argv[0]'
  87. echo ' raise UsageError("usage: %s [-j|-t|-p] YAML_FILE.." % self)'
  88. echo ''
  89. echo ''
  90. echo 'def main(argv):'
  91. echo ' if len(argv) < 2:'
  92. echo ' usage()'
  93. echo ''
  94. echo ''
  95. echo 'if __name__ == "__main__":'
  96. echo ' main(sys.argv[1:])'
  97. ;;
  98. pya)
  99. echo '#!/usr/bin/python'
  100. echo '"""'
  101. echo 'A simple application'
  102. echo '"""'
  103. echo ''
  104. echo 'import sys'
  105. echo ''
  106. echo ''
  107. echo 'class App(object):'
  108. echo ' """'
  109. echo ' Main application class'
  110. echo ' """'
  111. echo ''
  112. echo ' def __init__(self, argv):'
  113. echo ' self.argv = argv'
  114. echo ' # agument decoding and further initializations'
  115. echo ''
  116. echo ' @classmethod'
  117. echo ' def main(cls, argv):'
  118. echo ' """'
  119. echo ' Initialize and launch'
  120. echo ' """'
  121. echo ' app = cls(argv)'
  122. echo ' app.run()'
  123. echo ''
  124. echo ' def run(self):'
  125. echo ' """'
  126. echo ' Run the application'
  127. echo ' """'
  128. echo ' # actual action (calling other methods)'
  129. echo ' print self.argv'
  130. echo ' print __doc__'
  131. echo ''
  132. echo ''
  133. echo 'if __name__ == '__main__':'
  134. echo ' App.main(sys.argv)'
  135. ;;
  136. shellfu)
  137. echo "#!/bin/bash"
  138. echo ""
  139. echo '#shellcheck disable=SC1090'
  140. echo '. "$(sfpath)" || exit 3'
  141. echo ''
  142. echo 'shellfu import pretty'
  143. echo ''
  144. echo 'usage() {'
  145. echo ' mkusage "$@" "[-d] [-v] ARG..."'
  146. echo '}'
  147. echo ''
  148. echo 'main() {'
  149. echo ' while true; do case $1 in'
  150. echo ' -d) PRETTY_DEBUG=true; shift ;;'
  151. echo ' -v) PRETTY_VERBOSE=true; shift ;;'
  152. echo ' -*) usage -w "unknown argument: $1" ;;'
  153. echo ' *) break ;;'
  154. echo ' esac done'
  155. echo '}'
  156. echo ''
  157. echo 'main "$@"'
  158. ;;
  159. *)
  160. die "unknown template or language: $Template"
  161. ;;
  162. esac
  163. }
  164. guess_language() {
  165. #
  166. # Guess intended language from filepath $FilePath
  167. #
  168. local fname # file name
  169. fname="$(basename "$FilePath")"
  170. case "$fname" in
  171. *.*) echo "${fname##*.}" ;;
  172. *) echo "$MKX_DEFAULT_LANG" ;;
  173. esac
  174. }
  175. #
  176. # Default language
  177. #
  178. MKX_DEFAULT_LANG=${MKX_DEFAULT_LANG:-sh}
  179. main() {
  180. local FilePath # destination file path
  181. local Template # built-in template name
  182. local careful # ignore existing file
  183. careful=true
  184. while true; do case $1 in
  185. -f|--force) careful=false; shift ;;
  186. -l|--list) lstemplates; exit 0 ;;
  187. -*) usage ;;
  188. +*) Template="${1:1}"; shift ;;
  189. *) break ;;
  190. esac done
  191. FilePath="$1"
  192. test -n "$FilePath" || usage
  193. test -f "$FilePath" && $careful && die "file already exists: $FilePath"
  194. test -n "$Template" || Template=$(guess_language)
  195. mktemplate > "$FilePath"
  196. chmod +x "$FilePath"
  197. }
  198. main "$@"