Skip to content

Instantly share code, notes, and snippets.

@b0o
Last active May 9, 2020 08:28
Show Gist options
  • Save b0o/2920a291dfa7ac8f555abc7f4eb95f8a to your computer and use it in GitHub Desktop.
Save b0o/2920a291dfa7ac8f555abc7f4eb95f8a to your computer and use it in GitHub Desktop.
#!/bin/bash
# Helper for yglu to assist with importing yaml files into the document
# root.
#
# Depends: yglu - https://github.com/lbovet/yglu/
#
# Copyright (c) 2020 Maddison Hellstrom (github.com/b0o)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
set -euo pipefail
declare base basedir basename
base="$(realpath "${BASH_SOURCE[0]}")"
basedir="$(dirname "$base")"
basename="$(basename "$base")"
function usage() {
echo "usage: $basename [-h] [[<template> <dest>] ...]" >&2
}
declare -a tmpfiles=()
function process_template() {
[[ $# -lt 2 ]] && {
echo "process_template: expected 2 args, got $#" >&2
return 1
}
local template="$1"
local dest="$2"
local tmp_template
local tmp_dest
tmp_template="$(mktemp "${template}-XXXXXX")" || {
echo "error making temp file" >&2
return 1
}
tmpfiles+=("$tmp_template")
tmp_dest="$(mktemp "${dest}-XXXXXX")" || {
echo "error making temp file" >&2
return 1
}
tmpfiles+=("$tmp_dest")
local -a yglu_import
mapfile -t yglu_import << "EOF"
# Merge imports with each other
# primitives, lists: replace, later take precedence
# dicts: merge, contained primitives and lists handled as above
_imported: !-
!for ($_._import)({}): !()
!for $.items(): !()
!if isDict($[1]):
!? $[0]: !? ({result => $[1]}).mergeWith({result => $_._imported.get($[0], null)}, $1, $1).get("result", null)
!if not isDict($[1]):
!? $[0]: !? $[1]
# Merge aggregated imports with document root
# primitives, lists: values in document root take precedence
# dicts: merge, values in document root take precedence, contained primitives and lists handled as above
!for $_._imported.items(): !()
!if $_.get($[0], null) = null:
!? $[0]: !? $[1]
!if $_.get($[0], null) != null and isDict($[1]):
!? $[0]: !? ({result => $_.get($[0], null)}).mergeWith({result => $[1]}, $1, $1).get("result", null)
EOF
awk -v "import=$(printf '%s\n' "${yglu_import[@]}")" \
'/^_import:\s+!\(\)\s*$/ { print import "\n" }; //{ print $0 }' "$1" \
> "$tmp_template"
yglu "$tmp_template" > "$tmp_dest" || {
echo "yglu failed" >&2
return 1
}
cat "$tmp_dest" > "$dest"
}
function main() {
local -a templates=()
local -a dests=()
while [[ $# -gt 0 ]]; do
[[ "$1" =~ ^(-h|--help)$ ]] && {
usage
exit 0
}
if [[ ${#templates[@]} -eq ${#dests[@]} ]]; then
templates+=("$1")
else
dests+=("$1")
fi
shift
done
[[ ${#templates[@]} -ne ${#dests[@]} ]] && {
usage
exit 1
}
[[ ${#templates[@]} -eq 0 && ${#dests[@]} -eq 0 ]] && {
templates=("$basedir/"*.yglu.yml)
dests=("${templates[@]/%.yglu.yml/.yml}")
}
for ((i = 0; i < ${#templates[@]}; i++)); do
local t="${templates[$i]}"
local d="${dests[$i]}"
echo "$t -> $d" >&2
process_template "$t" "$d"
done
}
trap 'rm "${tmpfiles[@]}" 2>/dev/null || true' EXIT
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment