Compare commits
12 commits
cf8420fba9
...
4b251e9289
Author | SHA1 | Date | |
---|---|---|---|
|
4b251e9289 | ||
|
6ee9b472d1 | ||
|
ae3a149449 | ||
|
85e8c1ddfc | ||
|
a7939bec7b | ||
|
7ff657c7a5 | ||
|
aba434274e | ||
|
12c51e130b | ||
|
f222c93258 | ||
|
eb7858e4a6 | ||
|
1fba041aa7 | ||
|
95d7bae7b3 |
2 changed files with 115 additions and 41 deletions
|
@ -326,3 +326,31 @@ def test_no_repo(
|
||||||
def verify_head(paths, branch):
|
def verify_head(paths, branch):
|
||||||
"""Assert the local repo has the correct head branch"""
|
"""Assert the local repo has the correct head branch"""
|
||||||
assert paths.repo.join("HEAD").read() == f"ref: refs/heads/{branch}\n"
|
assert paths.repo.join("HEAD").read() == f"ref: refs/heads/{branch}\n"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.usefixtures("remote")
|
||||||
|
def test_clone_subdirectory(runner, paths, yadm_cmd, repo_config):
|
||||||
|
"""Test clone from sub-directory of YADM_WORK"""
|
||||||
|
|
||||||
|
# clear out the work path
|
||||||
|
paths.work.remove()
|
||||||
|
paths.work.mkdir()
|
||||||
|
|
||||||
|
# create sub-directory
|
||||||
|
subdir = paths.work.mkdir("subdir")
|
||||||
|
|
||||||
|
# determine remote url
|
||||||
|
remote_url = f"file://{paths.remote}"
|
||||||
|
|
||||||
|
# run the clone command
|
||||||
|
args = ["clone", "-w", paths.work, remote_url]
|
||||||
|
run = runner(command=yadm_cmd(*args), cwd=subdir)
|
||||||
|
|
||||||
|
# clone should succeed, and repo should be configured properly
|
||||||
|
assert successful_clone(run, paths, repo_config)
|
||||||
|
|
||||||
|
# ensure that no changes found as this is a clean dotfiles clone
|
||||||
|
run = runner(command=yadm_cmd("status", "-uno", "--porcelain"), cwd=subdir)
|
||||||
|
assert run.success
|
||||||
|
assert run.out == ""
|
||||||
|
assert run.err == ""
|
||||||
|
|
128
yadm
128
yadm
|
@ -363,8 +363,8 @@ function choose_template_cmd() {
|
||||||
function template_default() {
|
function template_default() {
|
||||||
input="$1"
|
input="$1"
|
||||||
output="$2"
|
output="$2"
|
||||||
temp_file="${output}.$$.$RANDOM"
|
|
||||||
|
|
||||||
|
local awk_pgm
|
||||||
# the explicit "space + tab" character class used below is used because not
|
# the explicit "space + tab" character class used below is used because not
|
||||||
# all versions of awk seem to support the POSIX character classes [[:blank:]]
|
# all versions of awk seem to support the POSIX character classes [[:blank:]]
|
||||||
read -r -d '' awk_pgm << "EOF"
|
read -r -d '' awk_pgm << "EOF"
|
||||||
|
@ -479,7 +479,9 @@ function replace_vars(input) {
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
"${AWK_PROGRAM[0]}" \
|
local source_dir content
|
||||||
|
source_dir=$(dirname "$input")
|
||||||
|
content=$("${AWK_PROGRAM[0]}" \
|
||||||
-v class="$local_class" \
|
-v class="$local_class" \
|
||||||
-v arch="$local_arch" \
|
-v arch="$local_arch" \
|
||||||
-v os="$local_system" \
|
-v os="$local_system" \
|
||||||
|
@ -488,19 +490,20 @@ EOF
|
||||||
-v distro="$local_distro" \
|
-v distro="$local_distro" \
|
||||||
-v distro_family="$local_distro_family" \
|
-v distro_family="$local_distro_family" \
|
||||||
-v source="$input" \
|
-v source="$input" \
|
||||||
-v source_dir="$(dirname "$input")" \
|
-v source_dir="$source_dir" \
|
||||||
"$awk_pgm" \
|
"$awk_pgm" \
|
||||||
"$input" "${local_classes[@]}" > "$temp_file" || rm -f "$temp_file"
|
"$input" "${local_classes[@]}")
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$content"
|
||||||
}
|
}
|
||||||
|
|
||||||
function template_j2cli() {
|
function template_j2cli() {
|
||||||
input="$1"
|
local input="$1"
|
||||||
output="$2"
|
local output="$2"
|
||||||
temp_file="${output}.$$.$RANDOM"
|
local yadm_classes content
|
||||||
|
|
||||||
YADM_CLASS="$local_class" \
|
yadm_classes=$(join_string $'\n' "${local_classes[@]}")
|
||||||
|
content=$(YADM_CLASS="$local_class" \
|
||||||
YADM_ARCH="$local_arch" \
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
YADM_HOSTNAME="$local_host" \
|
YADM_HOSTNAME="$local_host" \
|
||||||
|
@ -508,18 +511,20 @@ function template_j2cli() {
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
YADM_DISTRO_FAMILY="$local_distro_family" \
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input" \
|
YADM_SOURCE="$input" \
|
||||||
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
YADM_CLASSES="$yadm_classes" \
|
||||||
"$J2CLI_PROGRAM" "$input" -o "$temp_file"
|
"$J2CLI_PROGRAM" "$input")
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$content" "$?"
|
||||||
}
|
}
|
||||||
|
|
||||||
function template_envtpl() {
|
function template_envtpl() {
|
||||||
input="$1"
|
local input="$1"
|
||||||
output="$2"
|
local output="$2"
|
||||||
temp_file="${output}.$$.$RANDOM"
|
local yadm_classes content
|
||||||
|
|
||||||
YADM_CLASS="$local_class" \
|
yadm_classes=$(join_string $'\n' "${local_classes[@]}")
|
||||||
|
# shellcheck disable=SC2094
|
||||||
|
content=$(YADM_CLASS="$local_class" \
|
||||||
YADM_ARCH="$local_arch" \
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
YADM_HOSTNAME="$local_host" \
|
YADM_HOSTNAME="$local_host" \
|
||||||
|
@ -527,19 +532,20 @@ function template_envtpl() {
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
YADM_DISTRO_FAMILY="$local_distro_family" \
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input" \
|
YADM_SOURCE="$input" \
|
||||||
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
YADM_CLASSES="$yadm_classes" \
|
||||||
"$ENVTPL_PROGRAM" --keep-template "$input" -o "$temp_file"
|
"$ENVTPL_PROGRAM" <"$input")
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$content" "$?"
|
||||||
}
|
}
|
||||||
|
|
||||||
function template_esh() {
|
function template_esh() {
|
||||||
input="$1"
|
local input="$1"
|
||||||
output="$2"
|
local output="$2"
|
||||||
temp_file="${output}.$$.$RANDOM"
|
local yadm_classes content
|
||||||
|
|
||||||
YADM_CLASSES="$(join_string $'\n' "${local_classes[@]}")" \
|
yadm_classes="$(join_string $'\n' "${local_classes[@]}")"
|
||||||
"$ESH_PROGRAM" -o "$temp_file" "$input" \
|
content=$(YADM_CLASSES="$yadm_classes" \
|
||||||
|
"$ESH_PROGRAM" "$input" \
|
||||||
YADM_CLASS="$local_class" \
|
YADM_CLASS="$local_class" \
|
||||||
YADM_ARCH="$local_arch" \
|
YADM_ARCH="$local_arch" \
|
||||||
YADM_OS="$local_system" \
|
YADM_OS="$local_system" \
|
||||||
|
@ -547,25 +553,60 @@ function template_esh() {
|
||||||
YADM_USER="$local_user" \
|
YADM_USER="$local_user" \
|
||||||
YADM_DISTRO="$local_distro" \
|
YADM_DISTRO="$local_distro" \
|
||||||
YADM_DISTRO_FAMILY="$local_distro_family" \
|
YADM_DISTRO_FAMILY="$local_distro_family" \
|
||||||
YADM_SOURCE="$input"
|
YADM_SOURCE="$input")
|
||||||
|
|
||||||
move_file "$input" "$output" "$temp_file"
|
move_file "$input" "$output" "$content" "$?"
|
||||||
}
|
}
|
||||||
|
|
||||||
function move_file() {
|
function move_file() {
|
||||||
local input=$1
|
local input="$1"
|
||||||
local output=$2
|
local output="$2"
|
||||||
local temp_file=$3
|
local content="$3"
|
||||||
|
local err="${4:-}"
|
||||||
|
|
||||||
[ ! -f "$temp_file" ] && return
|
if [[ -s "$input" && -z "$content" ]]; then
|
||||||
|
debug "Failed to create $output from template $input: error $err"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
# if the output files already exists as read-only, change it to be writable.
|
if [[ -r "$output" ]]; then
|
||||||
# there are some environments in which a read-only file will prevent the move
|
local old_content
|
||||||
# from being successful.
|
old_content=$(< "$output")
|
||||||
[[ -e "$output" && ! -w "$output" ]] && chmod u+w "$output"
|
|
||||||
|
|
||||||
mv -f "$temp_file" "$output"
|
if [[ "$old_content" == "$content" ]]; then
|
||||||
copy_perms "$input" "$output"
|
debug "Not rewriting file as contents have not changed: $output"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if the output files already exists as read-only, change it to be writable.
|
||||||
|
# there are some environments in which a read-only file will prevent the move
|
||||||
|
# from being successful.
|
||||||
|
|
||||||
|
if [[ ! -w "$output" ]]; then
|
||||||
|
if ! chmod u+w "$output"; then
|
||||||
|
debug "Unable to make '$output' writeable"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$loud" ]; then
|
||||||
|
echo "Creating $output from template $input"
|
||||||
|
else
|
||||||
|
debug "Creating $output from template $input"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local temp_file="${output}.$$.$RANDOM"
|
||||||
|
if printf '%s\n' "$content" >"$temp_file"; then
|
||||||
|
if mv -f "$temp_file" "$output"; then
|
||||||
|
copy_perms "$input" "$output"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
debug "Failed to rename '$temp_file' to '$output'"
|
||||||
|
else
|
||||||
|
debug "Failed to create '$temp_file' to generate '$output'"
|
||||||
|
fi
|
||||||
|
rm -f "$temp_file" &>/dev/null
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# ****** yadm Commands ******
|
# ****** yadm Commands ******
|
||||||
|
@ -733,8 +774,6 @@ function alt_linking() {
|
||||||
template_cmd="${alt_template_cmds[$index]}"
|
template_cmd="${alt_template_cmds[$index]}"
|
||||||
if [ -n "$template_cmd" ]; then
|
if [ -n "$template_cmd" ]; then
|
||||||
# a template is defined, process the template
|
# a template is defined, process the template
|
||||||
debug "Creating $tgt from template $src"
|
|
||||||
[ -n "$loud" ] && echo "Creating $tgt from template $src"
|
|
||||||
# ensure the destination path exists
|
# ensure the destination path exists
|
||||||
assert_parent "$tgt"
|
assert_parent "$tgt"
|
||||||
# remove any existing symlink before processing template
|
# remove any existing symlink before processing template
|
||||||
|
@ -853,7 +892,7 @@ function clone() {
|
||||||
rm -rf "$wc"
|
rm -rf "$wc"
|
||||||
|
|
||||||
# then reset the index as the --no-checkout flag makes the index empty
|
# then reset the index as the --no-checkout flag makes the index empty
|
||||||
"$GIT_PROGRAM" reset --quiet -- .
|
"$GIT_PROGRAM" reset --quiet -- ":/"
|
||||||
|
|
||||||
if [ "$YADM_WORK" = "$HOME" ]; then
|
if [ "$YADM_WORK" = "$HOME" ]; then
|
||||||
debug "Determining if repo tracks private directories"
|
debug "Determining if repo tracks private directories"
|
||||||
|
@ -2137,7 +2176,7 @@ function get_mode {
|
||||||
|
|
||||||
# only accept results if they are octal
|
# only accept results if they are octal
|
||||||
if [[ ! $mode =~ ^[0-7]+$ ]] ; then
|
if [[ ! $mode =~ ^[0-7]+$ ]] ; then
|
||||||
mode=""
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$mode"
|
echo "$mode"
|
||||||
|
@ -2147,7 +2186,14 @@ function copy_perms {
|
||||||
local source="$1"
|
local source="$1"
|
||||||
local dest="$2"
|
local dest="$2"
|
||||||
mode=$(get_mode "$source")
|
mode=$(get_mode "$source")
|
||||||
[ -n "$mode" ] && chmod "$mode" "$dest"
|
if [[ -z "$mode" ]]; then
|
||||||
|
debug "Unable to get mode for '$source'"
|
||||||
|
return 0 # to allow tests to pass
|
||||||
|
fi
|
||||||
|
if ! chmod "$mode" "$dest"; then
|
||||||
|
debug "Unable to set mode to '$mode' on '$dest'"
|
||||||
|
return 0 # to allow tests to pass
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue