From f8e0bd593dbb5fa8b79cc565f97b20934923d661 Mon Sep 17 00:00:00 2001 From: Tim Byrne Date: Mon, 29 May 2017 00:17:55 -0500 Subject: [PATCH] Support `yadm.cygwin-copy` configuration (#62) With `yadm.cygwin-copy` set to "true", alternate files will be copies instead of symlinks, but only when running on Cygwin. --- test/115_accept_introspect.bats | 2 +- test/116_accept_cygwin_copy.bats | 102 +++++++++++++++++++++++++++++++ test/common.bash | 12 ++++ yadm | 15 ++++- yadm.1 | 5 ++ 5 files changed, 134 insertions(+), 2 deletions(-) create mode 100644 test/116_accept_cygwin_copy.bats diff --git a/test/115_accept_introspect.bats b/test/115_accept_introspect.bats index c283f6d..0d1922b 100644 --- a/test/115_accept_introspect.bats +++ b/test/115_accept_introspect.bats @@ -73,7 +73,7 @@ function count_introspect() { Exit with 0 " - count_introspect "configs" 0 11 'yadm\.auto-alt' + count_introspect "configs" 0 12 'yadm\.auto-alt' } @test "Command 'introspect' (repo)" { diff --git a/test/116_accept_cygwin_copy.bats b/test/116_accept_cygwin_copy.bats new file mode 100644 index 0000000..07957c9 --- /dev/null +++ b/test/116_accept_cygwin_copy.bats @@ -0,0 +1,102 @@ +load common +load_fixtures + +IN_REPO=(alt*) +export TEST_TREE_WITH_CYGWIN=1 +export SIMULATED_CYGWIN="CYGWIN_NT-6.1-WOW64" + +setup() { + destroy_tmp + build_repo "${IN_REPO[@]}" +} + +test_alt() { + local cygwin_copy="$1" + local is_cygwin="$2" + local expect_link="$3" + + case "$cygwin_copy" in + true|false) + git config --file="$T_YADM_CONFIG" "yadm.cygwin-copy" "$cygwin_copy" + ;; + esac + + if [ "$is_cygwin" = "true" ]; then + echo '#!/bin/sh' > "$T_TMP/uname" + echo "echo $SIMULATED_CYGWIN" >> "$T_TMP/uname" + chmod a+x "$T_TMP/uname" + fi + + local expected_content + expected_content="$T_DIR_WORK/alt-test##$(PATH="$T_TMP:$PATH" uname -s)" + + PATH="$T_TMP:$PATH" run "${T_YADM_Y[@]}" alt + + if [ -L "$T_DIR_WORK/alt-test" ] && [ "$expect_link" != 'true' ] ; then + echo "ERROR: Alt should be a simple file, but isn't" + return 1 + fi + if [ ! -L "$T_DIR_WORK/alt-test" ] && [ "$expect_link" = 'true' ] ; then + echo "ERROR: Alt should use symlink, but doesn't" + return 1 + fi + + if ! diff "$T_DIR_WORK/alt-test" "$expected_content"; then + echo "ERROR: Alt contains different data than expected" + return 1 + fi +} + +@test "Option 'yadm.cygwin-copy' (unset, non-cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is unset + and the OS is not CYGWIN + Verify alternate is a symlink + " + test_alt 'unset' 'false' 'true' +} + +@test "Option 'yadm.cygwin-copy' (true, non-cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is true + and the OS is not CYGWIN + Verify alternate is a symlink + " + test_alt 'true' 'false' 'true' +} + +@test "Option 'yadm.cygwin-copy' (false, non-cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is false + and the OS is not CYGWIN + Verify alternate is a symlink + " + test_alt 'false' 'false' 'true' +} + +@test "Option 'yadm.cygwin-copy' (unset, cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is unset + and the OS is CYGWIN + Verify alternate is a symlink + " + test_alt 'unset' 'true' 'true' +} + +@test "Option 'yadm.cygwin-copy' (true, cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is true + and the OS is CYGWIN + Verify alternate is a copy + " + test_alt 'true' 'true' 'false' +} + +@test "Option 'yadm.cygwin-copy' (false, cygwin)" { + echo " + When the option 'yadm.cygwin-copy' is false + and the OS is CYGWIN + Verify alternate is a symlink + " + test_alt 'false' 'true' 'true' +} diff --git a/test/common.bash b/test/common.bash index 5670ed0..d617db1 100644 --- a/test/common.bash +++ b/test/common.bash @@ -205,6 +205,18 @@ function create_worktree() { echo "{{ YADM_CLASS }}-{{ YADM_OS }}-{{ YADM_HOSTNAME }}-{{ YADM_USER }}" > "$DIR_WORKTREE/alt-jinja##yadm.j2" fi + #; for some cygwin tests + if [ ! -z "$TEST_TREE_WITH_CYGWIN" ] ; then + for f in \ + "alt-test##" \ + "alt-test##$T_SYS" \ + "alt-test##$SIMULATED_CYGWIN" \ + ; + do + make_parents "$DIR_WORKTREE/$f" + echo "$f" > "$DIR_WORKTREE/$f" + done + fi if [ ! -z "$TEST_TREE_WITH_WILD" ] ; then #; wildcard test data - yes this is a big mess :( diff --git a/yadm b/yadm index 5787d65..ada5cab 100755 --- a/yadm +++ b/yadm @@ -175,6 +175,14 @@ function alt() { done < "$YADM_ENCRYPT" fi + #; decide if a copy should be done instead of a symbolic link + local do_copy=0 + if [[ $OPERATING_SYSTEM == CYGWIN* ]] ; then + if [[ $(config --bool yadm.cygwin-copy) == "true" ]] ; then + do_copy=1 + fi + fi + #; loop over all "tracked" files #; for every file which matches the above regex, create a symlink for match in $match1 $match2; do @@ -190,7 +198,11 @@ function alt() { new_link="${BASH_REMATCH[1]}" debug "Linking $alt_path to $new_link" [ -n "$loud" ] && echo "Linking $alt_path to $new_link" - ln -nfs "$alt_path" "$new_link" + if [ "$do_copy" -eq 1 ]; then + cp -f "$alt_path" "$new_link" + else + ln -nfs "$alt_path" "$new_link" + fi last_linked="$alt_path" fi fi @@ -586,6 +598,7 @@ local.os local.user yadm.auto-alt yadm.auto-perms +yadm.cygwin-copy yadm.git-program yadm.gpg-perms yadm.gpg-program diff --git a/yadm.1 b/yadm.1 index a24aa9a..ce31b12 100644 --- a/yadm.1 +++ b/yadm.1 @@ -376,6 +376,11 @@ By default, the first "gpg" found in $PATH is used. .B yadm.git-program Specify an alternate program to use instead of "git". By default, the first "git" found in $PATH is used. +.TP +.B yadm.cygwin-copy +If set to "true", for Cygwin hosts, alternate files will be copies instead of +symbolic links. This might be desirable, because non-Cygwin software may not +properly interpret Cygwin symlinks. .RE These last four "local" configurations are not stored in the