Working Saturnin-based meta-command

ini.sh 3.2KB

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