Support git-crypt (#168)

Support is inherently provided by `enter`, which now supports a command.
I've added a `git-crypt` command, which is really just an alias
under-the-hood for "enter git-crypt".
This commit is contained in:
Tim Byrne 2019-12-15 18:42:21 -06:00
parent b9f5fdaafa
commit d3a2a06184
No known key found for this signature in database
GPG Key ID: 14DB4FC2465A4B12
3 changed files with 92 additions and 31 deletions

View File

@ -89,6 +89,7 @@ def supported_commands():
'decrypt', 'decrypt',
'encrypt', 'encrypt',
'enter', 'enter',
'git-crypt',
'gitconfig', 'gitconfig',
'help', 'help',
'init', 'init',

42
test/test_git_crypt.py Normal file
View File

@ -0,0 +1,42 @@
"""Test git-crypt"""
import pytest
@pytest.mark.parametrize(
'crypt',
[False, 'installed', 'installed-but-failed'],
ids=['not-installed', 'installed', 'installed-but-failed']
)
def test_git_crypt(runner, yadm, paths, tmpdir, crypt):
"""git-crypt tests"""
paths.repo.ensure(dir=True)
bindir = tmpdir.mkdir('bin')
pgm = bindir.join('test-git-crypt')
if crypt:
pgm.write(f'#!/bin/sh\necho git-crypt ran\n')
pgm.chmod(0o775)
if crypt == 'installed-but-failed':
pgm.write('false\n', mode='a')
script = f"""
YADM_TEST=1 source {yadm}
YADM_REPO={paths.repo}
GIT_CRYPT_PROGRAM="{pgm}"
git_crypt "param1"
"""
run = runner(command=['bash'], inp=script)
if crypt:
if crypt == 'installed-but-failed':
assert run.failure
else:
assert run.success
assert run.out.strip() == 'git-crypt ran'
else:
assert run.failure
assert f"command '{pgm}' cannot be located" in run.out
assert run.err == ''

80
yadm
View File

@ -41,6 +41,7 @@ FULL_COMMAND=""
GPG_PROGRAM="gpg" GPG_PROGRAM="gpg"
GIT_PROGRAM="git" GIT_PROGRAM="git"
AWK_PROGRAM=("gawk" "awk") AWK_PROGRAM=("gawk" "awk")
GIT_CRYPT_PROGRAM="git-crypt"
J2CLI_PROGRAM="j2" J2CLI_PROGRAM="j2"
ENVTPL_PROGRAM="envtpl" ENVTPL_PROGRAM="envtpl"
LSB_RELEASE_PROGRAM="lsb_release" LSB_RELEASE_PROGRAM="lsb_release"
@ -76,45 +77,50 @@ function main() {
# parse command line arguments # parse command line arguments
local retval=0 local retval=0
internal_commands="^(alt|bootstrap|clean|clone|config|decrypt|encrypt|enter|help|init|introspect|list|perms|upgrade|version)$" internal_commands="^(alt|bootstrap|clean|clone|config|decrypt|encrypt|enter|git-crypt|help|init|introspect|list|perms|upgrade|version)$"
if [ -z "$*" ] ; then if [ -z "$*" ] ; then
# no argumnts will result in help() # no argumnts will result in help()
help help
elif [[ "$1" =~ $internal_commands ]] ; then elif [[ "$1" =~ $internal_commands ]] ; then
# for internal commands, process all of the arguments # for internal commands, process all of the arguments
YADM_COMMAND="$1" YADM_COMMAND="${1/-/_}"
YADM_ARGS=() YADM_ARGS=()
shift shift
while [[ $# -gt 0 ]] ; do # commands listed below do not process any of the parameters
key="$1" if [[ "$YADM_COMMAND" =~ ^(enter|git_crypt)$ ]] ; then
case $key in YADM_ARGS=("$@")
-a) # used by list() else
LIST_ALL="YES" while [[ $# -gt 0 ]] ; do
;; key="$1"
-d) # used by all commands case $key in
DEBUG="YES" -a) # used by list()
;; LIST_ALL="YES"
-f) # used by init() and clone() ;;
FORCE="YES" -d) # used by all commands
;; DEBUG="YES"
-l) # used by decrypt() ;;
DO_LIST="YES" -f) # used by init() and clone()
[ "$YADM_COMMAND" = "config" ] && YADM_ARGS+=("$1") FORCE="YES"
;; ;;
-w) # used by init() and clone() -l) # used by decrypt()
if [[ ! "$2" =~ ^/ ]] ; then DO_LIST="YES"
error_out "You must specify a fully qualified work tree" [ "$YADM_COMMAND" = "config" ] && YADM_ARGS+=("$1")
fi ;;
YADM_WORK="$2" -w) # used by init() and clone()
shift if [[ ! "$2" =~ ^/ ]] ; then
;; error_out "You must specify a fully qualified work tree"
*) # any unhandled arguments fi
YADM_ARGS+=("$1") YADM_WORK="$2"
;; shift
esac ;;
shift *) # any unhandled arguments
done YADM_ARGS+=("$1")
;;
esac
shift
done
fi
[ ! -d "$YADM_WORK" ] && error_out "Work tree does not exist: [$YADM_WORK]" [ ! -d "$YADM_WORK" ] && error_out "Work tree does not exist: [$YADM_WORK]"
HOOK_COMMAND="$YADM_COMMAND" HOOK_COMMAND="$YADM_COMMAND"
invoke_hook "pre" invoke_hook "pre"
@ -901,6 +907,11 @@ function encrypt() {
} }
function git_crypt() {
require_git_crypt
enter "${GIT_CRYPT_PROGRAM} $*"
}
function enter() { function enter() {
command="$*" command="$*"
require_shell require_shell
@ -983,6 +994,8 @@ Commands:
yadm encrypt - Encrypt files yadm encrypt - Encrypt files
yadm decrypt [-l] - Decrypt files yadm decrypt [-l] - Decrypt files
yadm perms - Fix perms for private files yadm perms - Fix perms for private files
yadm enter [COMMAND] - Run sub-shell with GIT variables set
yadm git-crypt [OPTIONS] - Run git-crypt commands for the yadm repo
Files: Files:
\$HOME/.config/yadm/config - yadm's configuration file \$HOME/.config/yadm/config - yadm's configuration file
@ -1037,6 +1050,7 @@ decrypt
encrypt encrypt
enter enter
gitconfig gitconfig
git-crypt
help help
init init
introspect introspect
@ -1842,6 +1856,10 @@ function require_repo() {
function require_shell() { function require_shell() {
[ -x "$SHELL" ] || error_out "\$SHELL does not refer to an executable." [ -x "$SHELL" ] || error_out "\$SHELL does not refer to an executable."
} }
function require_git_crypt() {
command -v "$GIT_CRYPT_PROGRAM" &> /dev/null ||
error_out "This functionality requires git-crypt to be installed, but the command '$GIT_CRYPT_PROGRAM' cannot be located."
}
function bootstrap_available() { function bootstrap_available() {
[ -f "$YADM_BOOTSTRAP" ] && [ -x "$YADM_BOOTSTRAP" ] && return [ -f "$YADM_BOOTSTRAP" ] && [ -x "$YADM_BOOTSTRAP" ] && return
return 1 return 1