Add jinja processing to alt command
With the new functionality, when the 'alt' command is called (or automatically triggered), any file with a name ending in '##yadm_tmpl' is treated as a jinja template. The template is processed by envtpl and the result is written to a file without the '##yadm_tmpl' name. The variables passed into the template processing are YADM_CLASS YADM_OS YADM_HOSTNAME YADM_USER These variables are set according to the normal rules for CLASS, OS, HOSTNAME, and USER during the alt processing.
This commit is contained in:
parent
5678e383d8
commit
a479b70d8a
4 changed files with 233 additions and 16 deletions
151
test/113_accept_jinja_alt.bats
Normal file
151
test/113_accept_jinja_alt.bats
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
load common
|
||||||
|
load_fixtures
|
||||||
|
status=;output=; #; populated by bats run()
|
||||||
|
|
||||||
|
IN_REPO=(alt* "dir one")
|
||||||
|
export TEST_TREE_WITH_ALT=1
|
||||||
|
|
||||||
|
|
||||||
|
setup() {
|
||||||
|
destroy_tmp
|
||||||
|
build_repo "${IN_REPO[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function test_alt() {
|
||||||
|
local alt_type="$1"
|
||||||
|
local test_overwrite="$2"
|
||||||
|
local auto_alt="$3"
|
||||||
|
|
||||||
|
#; detemine test parameters
|
||||||
|
case $alt_type in
|
||||||
|
base)
|
||||||
|
real_name="alt-jinja"
|
||||||
|
file_content_match="-${T_SYS}-${T_HOST}-${T_USER}"
|
||||||
|
;;
|
||||||
|
override_all)
|
||||||
|
real_name="alt-jinja"
|
||||||
|
file_content_match="custom_class-custom_system-custom_host-custom_user"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ "$test_overwrite" = "true" ] ; then
|
||||||
|
#; create incorrect links (to overwrite)
|
||||||
|
echo "BAD_CONTENT" "$T_DIR_WORK/$real_name"
|
||||||
|
else
|
||||||
|
#; verify real file doesn't already exist
|
||||||
|
if [ -e "$T_DIR_WORK/$real_name" ] ; then
|
||||||
|
echo "ERROR: real file already exists before running yadm"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#; configure yadm.auto_alt=false
|
||||||
|
if [ "$auto_alt" = "false" ]; then
|
||||||
|
git config --file="$T_YADM_CONFIG" yadm.auto-alt false
|
||||||
|
fi
|
||||||
|
|
||||||
|
#; run yadm (alt or status)
|
||||||
|
if [ -z "$auto_alt" ]; then
|
||||||
|
run "${T_YADM_Y[@]}" alt
|
||||||
|
#; validate status and output
|
||||||
|
if [ "$status" != 0 ] || [[ ! "$output" =~ Creating.+$real_name ]]; then
|
||||||
|
echo "OUTPUT:$output"
|
||||||
|
echo "ERROR: Could not confirm status and output of alt command"
|
||||||
|
return 1;
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
#; running any passed through Git command should trigger auto-alt
|
||||||
|
run "${T_YADM_Y[@]}" status
|
||||||
|
if [ -n "$auto_alt" ] && [[ "$output" =~ Creating.+$real_name ]]; then
|
||||||
|
echo "ERROR: Reporting of jinja processing should not happen"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
#; validate link content
|
||||||
|
if [[ "$alt_type" =~ none ]] || [ "$auto_alt" = "false" ]; then
|
||||||
|
#; no real file should be present
|
||||||
|
if [ -L "$T_DIR_WORK/$real_name" ] ; then
|
||||||
|
echo "ERROR: Real file should not exist"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
#; correct real file should be present
|
||||||
|
local file_content
|
||||||
|
file_content=$(cat "$T_DIR_WORK/$real_name")
|
||||||
|
if [ "$file_content" != "$file_content_match" ]; then
|
||||||
|
echo "file_content: ${file_content}"
|
||||||
|
echo "expected_content: ${file_content_match}"
|
||||||
|
echo "ERROR: Link content is not correct"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Command 'alt' (select jinja)" {
|
||||||
|
echo "
|
||||||
|
When the command 'alt' is provided
|
||||||
|
and file matches ##yadm_tmpl
|
||||||
|
Report jinja template processing
|
||||||
|
Verify that the correct content is written
|
||||||
|
Exit with 0
|
||||||
|
"
|
||||||
|
|
||||||
|
test_alt 'base' 'false' ''
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Command 'auto-alt' (enabled)" {
|
||||||
|
echo "
|
||||||
|
When a command possibly changes the repo
|
||||||
|
and auto-alt is configured true
|
||||||
|
and file matches ##yadm_tmpl
|
||||||
|
automatically process alternates
|
||||||
|
report no linking (not loud)
|
||||||
|
Verify that the correct content is written
|
||||||
|
"
|
||||||
|
|
||||||
|
test_alt 'base' 'false' 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Command 'auto-alt' (disabled)" {
|
||||||
|
echo "
|
||||||
|
When a command possibly changes the repo
|
||||||
|
and auto-alt is configured false
|
||||||
|
and file matches ##yadm_tmpl
|
||||||
|
Report no jinja template processing
|
||||||
|
Verify no content
|
||||||
|
"
|
||||||
|
|
||||||
|
test_alt 'base' 'false' 'false'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Command 'alt' (overwrite existing content)" {
|
||||||
|
echo "
|
||||||
|
When the command 'alt' is provided
|
||||||
|
and file matches ##yadm_tmpl
|
||||||
|
and the real file exists, and is wrong
|
||||||
|
Report jinja template processing
|
||||||
|
Verify that the correct content is written
|
||||||
|
Exit with 0
|
||||||
|
"
|
||||||
|
|
||||||
|
test_alt 'base' 'true' ''
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "Command 'alt' (overwritten settings)" {
|
||||||
|
echo "
|
||||||
|
When the command 'alt' is provided
|
||||||
|
and file matches ##yadm_tmpl
|
||||||
|
after setting local.*
|
||||||
|
Report jinja template processing
|
||||||
|
Verify that the correct content is written
|
||||||
|
Exit with 0
|
||||||
|
"
|
||||||
|
|
||||||
|
GIT_DIR="$T_DIR_REPO" git config local.os custom_system
|
||||||
|
GIT_DIR="$T_DIR_REPO" git config local.user custom_user
|
||||||
|
GIT_DIR="$T_DIR_REPO" git config local.host custom_host
|
||||||
|
GIT_DIR="$T_DIR_REPO" git config local.class custom_class
|
||||||
|
test_alt 'override_all' 'false' ''
|
||||||
|
}
|
|
@ -202,8 +202,10 @@ function create_worktree() {
|
||||||
make_parents "$DIR_WORKTREE/$f"
|
make_parents "$DIR_WORKTREE/$f"
|
||||||
echo "$f" > "$DIR_WORKTREE/$f"
|
echo "$f" > "$DIR_WORKTREE/$f"
|
||||||
done
|
done
|
||||||
|
echo "{{ YADM_CLASS }}-{{ YADM_OS }}-{{ YADM_HOSTNAME }}-{{ YADM_USER }}" > "$DIR_WORKTREE/alt-jinja##yadm_tmpl"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ ! -z "$TEST_TREE_WITH_WILD" ] ; then
|
if [ ! -z "$TEST_TREE_WITH_WILD" ] ; then
|
||||||
#; wildcard test data - yes this is a big mess :(
|
#; wildcard test data - yes this is a big mess :(
|
||||||
#; none
|
#; none
|
||||||
|
|
56
yadm
56
yadm
|
@ -114,30 +114,32 @@ function alt() {
|
||||||
|
|
||||||
require_repo
|
require_repo
|
||||||
|
|
||||||
match_class="$(config local.class)"
|
local_class="$(config local.class)"
|
||||||
if [ -z "$match_class" ] ; then
|
if [ -z "$local_class" ] ; then
|
||||||
match_class="%"
|
match_class="%"
|
||||||
|
else
|
||||||
|
match_class="$local_class"
|
||||||
fi
|
fi
|
||||||
match_class="(%|$match_class)"
|
match_class="(%|$match_class)"
|
||||||
|
|
||||||
match_system="$(config local.os)"
|
local_system="$(config local.os)"
|
||||||
if [ -z "$match_system" ] ; then
|
if [ -z "$local_system" ] ; then
|
||||||
match_system=$(uname -s)
|
local_system=$(uname -s)
|
||||||
fi
|
fi
|
||||||
match_system="(%|$match_system)"
|
match_system="(%|$local_system)"
|
||||||
|
|
||||||
match_host="$(config local.host)"
|
local_host="$(config local.host)"
|
||||||
if [ -z "$match_host" ] ; then
|
if [ -z "$local_host" ] ; then
|
||||||
match_host=$(hostname)
|
local_host=$(hostname)
|
||||||
match_host=${match_host%%.*} #; trim any domain from hostname
|
local_host=${local_host%%.*} #; trim any domain from hostname
|
||||||
fi
|
fi
|
||||||
match_host="(%|$match_host)"
|
match_host="(%|$local_host)"
|
||||||
|
|
||||||
match_user="$(config local.user)"
|
local_user="$(config local.user)"
|
||||||
if [ -z "$match_user" ] ; then
|
if [ -z "$local_user" ] ; then
|
||||||
match_user=$(id -u -n)
|
local_user=$(id -u -n)
|
||||||
fi
|
fi
|
||||||
match_user="(%|$match_user)"
|
match_user="(%|$local_user)"
|
||||||
|
|
||||||
#; regex for matching "<file>##CLASS.SYSTEM.HOSTNAME.USER"
|
#; regex for matching "<file>##CLASS.SYSTEM.HOSTNAME.USER"
|
||||||
match1="^(.+)##(()|$match_system|$match_system\.$match_host|$match_system\.$match_host\.$match_user)$"
|
match1="^(.+)##(()|$match_system|$match_system\.$match_host|$match_system\.$match_host\.$match_user)$"
|
||||||
|
@ -193,6 +195,30 @@ function alt() {
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
|
#; loop over all "tracked" files
|
||||||
|
#; for every file which is a *##yadm_tmpl create a real file
|
||||||
|
local IFS=$'\n'
|
||||||
|
local match="^(.+)##yadm_tmpl"
|
||||||
|
local envtpl_bin=$(which envtpl)
|
||||||
|
for tracked_file in $("$GIT_PROGRAM" ls-files | sort) $(cat "$YADM_ENCRYPT" 2>/dev/null); do
|
||||||
|
tracked_file="$YADM_WORK/$tracked_file"
|
||||||
|
if [ -e "$tracked_file" ] ; then
|
||||||
|
if [[ $tracked_file =~ $match ]] ; then
|
||||||
|
if [[ -z "$envtpl_bin" ]]; then
|
||||||
|
debug "'envtpl' (pip install envtpl) not available, not creating $real_file from template $tracked_file"
|
||||||
|
[ -n "$loud" ] && echo "'envtpl' (pip install envtpl) not available, not creating $real_file from template $tracked_file"
|
||||||
|
else
|
||||||
|
real_file="${BASH_REMATCH[1]}"
|
||||||
|
debug "Creating $real_file from template $tracked_file"
|
||||||
|
[ -n "$loud" ] && echo "Creating $real_file from template $tracked_file"
|
||||||
|
YADM_CLASS="$local_class" YADM_OS="$local_system" \
|
||||||
|
YADM_HOSTNAME="$local_host" YADM_USER="$local_user" \
|
||||||
|
$envtpl_bin < $tracked_file > $real_file
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function bootstrap() {
|
function bootstrap() {
|
||||||
|
|
40
yadm.1
40
yadm.1
|
@ -89,7 +89,8 @@ Instead use the
|
||||||
command (see below).
|
command (see below).
|
||||||
.TP
|
.TP
|
||||||
.B alt
|
.B alt
|
||||||
Create symbolic links for any managed files matching the naming rules describe in the ALTERNATES section.
|
Create symbolic links and process jinja templates for any managed files matching the naming rules describe
|
||||||
|
in the ALTERNATES section.
|
||||||
It is usually unnecessary to run this command, as
|
It is usually unnecessary to run this command, as
|
||||||
.B yadm
|
.B yadm
|
||||||
automatically processes alternates by default.
|
automatically processes alternates by default.
|
||||||
|
@ -473,6 +474,43 @@ using the configuration options
|
||||||
and
|
and
|
||||||
.BR local.user .
|
.BR local.user .
|
||||||
|
|
||||||
|
If
|
||||||
|
.BR envtpl
|
||||||
|
(
|
||||||
|
.BR pip\ install\ envtpl
|
||||||
|
) is available, you can also create
|
||||||
|
.B jinja
|
||||||
|
templates (http://jinja.pocoo.org/) which will transformed into real files.
|
||||||
|
.B yadm
|
||||||
|
will treat files ending in
|
||||||
|
|
||||||
|
##yadm_tmpl
|
||||||
|
|
||||||
|
as jinja templates. During processing, the following variables are
|
||||||
|
set according to the above rules:
|
||||||
|
|
||||||
|
YADM_CLASS
|
||||||
|
YADM_OS
|
||||||
|
YADM_HOSTNAME
|
||||||
|
YADM_USER
|
||||||
|
|
||||||
|
E.g. a file 'whatever##yadm_tmpl' with the following content
|
||||||
|
|
||||||
|
{% if YADM_USER == 'harvey' -%}
|
||||||
|
config={{YADM_CLASS}}-{{ YADM_OS }}
|
||||||
|
{% else -%}
|
||||||
|
config=dev-whatever
|
||||||
|
{% endif -%}
|
||||||
|
|
||||||
|
would output a file with the follwing content, if the username would be 'harvey'
|
||||||
|
|
||||||
|
config=work-Linux
|
||||||
|
|
||||||
|
and the following otherwise:
|
||||||
|
|
||||||
|
config=dev-whatever
|
||||||
|
|
||||||
|
|
||||||
.SH ENCRYPTION
|
.SH ENCRYPTION
|
||||||
It can be useful to manage confidential files, like SSH or GPG keys, across
|
It can be useful to manage confidential files, like SSH or GPG keys, across
|
||||||
multiple systems. However, doing so would put plain text data into a Git
|
multiple systems. However, doing so would put plain text data into a Git
|
||||||
|
|
Loading…
Reference in a new issue