Working Saturnin-based meta-command

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/bin/bash
  2. # MKit - simple install helper
  3. # See LICENSE file for copyright and license details.
  4. _ini_cat() {
  5. #
  6. # A no-op for text stream
  7. #
  8. local line # each line
  9. while read -r line; do
  10. printf -- "%s\n" "$line"
  11. done
  12. }
  13. _ini_expand() {
  14. #
  15. # Expand reference value (prefix only)
  16. #
  17. local line # each input line
  18. local suffix # tail of the line
  19. local ref # reference
  20. local value # value if reference
  21. while read -r line; do # [foo:bar]/path
  22. suffix="${line#\[*\]}" # /path
  23. ref="${line%$suffix}" # [foo:bar]
  24. ref="${ref%\]}" # [foo:bar
  25. ref="${ref#\[}" # foo:bar
  26. value="$(ini 1value "$ref")" # foo_bar_value
  27. printf -- "%s\n" "$value$suffix" # foo_bar_value/path
  28. done
  29. }
  30. _ini_grepkey() {
  31. #
  32. # Read key from a section
  33. #
  34. local wnt=$1 # wanted key
  35. grep '.' \
  36. | grep -v '\s*#' \
  37. | sed -e 's/ *= */=/; s/ +$//; s/^//;' \
  38. | grep -e "^$wnt=" \
  39. | cut -d= -f2- \
  40. | _ini_maybe_expand
  41. }
  42. _ini_greppath() {
  43. #
  44. # Read key from the right section
  45. #
  46. # E.g. `files:share:my/lib.sh` should read
  47. #
  48. # [files:share]
  49. # my/lib.sh = proj/my/lib.sh
  50. #
  51. local wnt=$1 # wanted path
  52. local wntkey=${wnt##*:} # ^^ key part
  53. local wntsec=${wnt%:$wntkey} # ^^ section part
  54. local override # ENV override (only ENV section)
  55. if test "$wntsec" = 'ENV'; then
  56. override=${!wntkey}
  57. test -n "$override" \
  58. && echo "$override" \
  59. && return
  60. fi
  61. _ini_grepsec "$wntsec" | _ini_grepkey "$wntkey"
  62. }
  63. _ini_grepsec() {
  64. #
  65. # Read one INI section
  66. #
  67. local wnt=$1 # wanted section name
  68. local ok=false # are we in the section?
  69. local line # each input line
  70. grep '.' \
  71. | grep -v '\s*#' \
  72. | while read -r line; do
  73. case "$line" in
  74. \[$wnt\]) ok=true; continue ;;
  75. \[*\]) ok=false; continue ;;
  76. esac
  77. $ok || continue
  78. printf -- "%s\n" "$line"
  79. done \
  80. | sed -e 's/ *= */=/; s/ +$//; s/^//;'
  81. }
  82. _ini_lskeys() {
  83. #
  84. # List keys from a section
  85. #
  86. local sct=$1 # section of interest
  87. _ini_grepsec "$sct" | cut -d= -f1 | awk '!x[$0]++'
  88. }
  89. _ini_maybe_expand() {
  90. #
  91. # Decide whether or not to expand
  92. #
  93. if test "$MKIT_INI_EXPAND" -gt 0; then
  94. MKIT_INI_EXPAND=$(( --MKIT_INI_EXPAND )) _ini_expand
  95. else
  96. _ini_cat
  97. fi
  98. }
  99. ini() {
  100. #
  101. # do ini operation
  102. #
  103. local op=$1 # operator
  104. local arg=$2 # argument
  105. local fn # internal function implementing $op
  106. local limit=_ini_cat # limiting internal function
  107. case $op in
  108. lskeys) fn=_ini_lskeys ;;
  109. sec) fn=_ini_grepsec ;;
  110. values) fn=_ini_greppath ;;
  111. 1value) fn=_ini_greppath; limit="tail -1" ;;
  112. *) die "incorrect use of \`ini()\`"
  113. esac
  114. <"$MKIT_INI" $fn "$arg" | $limit
  115. }
  116. update_version() {
  117. #
  118. # Change project.version in mkit.ini at path $2 to version $1
  119. #
  120. local version=$1 # new version
  121. local inifile=$2 # mkit.ini path
  122. local tmp # mkit.ini cache
  123. tmp=$(mktemp -t mkit.update_version.XXXXXXXX)
  124. <"$inifile" perl -e '
  125. my $hit = 0;
  126. my $done = 0;
  127. foreach (<STDIN>) {
  128. if ($done) { print; next; }
  129. elsif (m/\[project\]/) { $hit++; print; next; }
  130. elsif (m/\[/) { $hit = 0; print; next; }
  131. elsif ($hit) { s/\bversion\b( *)=( *).*/version$1=$2$ARGV[0]/ and $done++; print; }
  132. else { print; next; }
  133. }
  134. ' "$version" >"$tmp" || die "failed to update version in mkit.ini"
  135. mv "$tmp" "$inifile"
  136. }