1
0
Fork 0
mirror of synced 2024-12-04 14:45:36 -05:00

Compare commits

...

12 commits

Author SHA1 Message Date
Ross Smith II
4b251e9289
Merge 7ff657c7a5 into 6ee9b472d1 2024-11-29 23:11:46 +01:00
Erik Flodin
6ee9b472d1
Merge pull request #507 from AVM-Martin/fix/reset-yadm-work-index
fix(clone): reset index of YADM_WORK
2024-11-29 23:10:35 +01:00
AVM.Martin
ae3a149449
style: use pathspec for consistency 2024-11-26 19:22:18 +07:00
AVM.Martin
85e8c1ddfc
docs: fix comment 2024-11-26 19:21:18 +07:00
AVM.Martin
a7939bec7b
style: join arguments 2024-11-26 19:20:59 +07:00
Ross Smith II
7ff657c7a5
Merge branch 'develop' into rasa/improve-template-logic 2024-11-09 18:35:32 -08:00
AVM.Martin
aba434274e
fix(clone): reset index of YADM_WORK 2024-07-21 07:02:49 +07:00
AVM.Martin
12c51e130b
test(clone): run inside YADM_WORK sub-directory
Whenever using `clone` command inside YADM_WORK sub-directory, we need
to checkout the correct repo contents.

Steps to reproduce:

```bash
mkdir $HOME/subdir
cd $HOME/subdir

yadm clone --bootstrap "<repo-url>"
yadm status
```
2024-07-21 07:02:49 +07:00
Ross Smith II
f222c93258 Fix typo causing failed test 2023-10-12 21:18:45 -07:00
Ross Smith II
eb7858e4a6 Fix failed tests 2023-10-12 20:46:39 -07:00
Ross Smith II
1fba041aa7 Always remove temp_file on failure, other cleanup 2023-10-12 07:58:10 -07:00
Ross Smith II
95d7bae7b3
Improve and harden alt file regeneration
Improvements include:

1. Skip writing a temporary file if the file contents are unchanged
2. Better error reporting if templating program fails
3. Better error reporting/handling if file creation, mv, or chmod fail
4. Quiet logs by not outputing "Creating output..." line twice (debug & loud)
2023-10-11 14:58:27 -07:00
2 changed files with 115 additions and 41 deletions

View file

@ -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
View file

@ -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
} }