Explorar o código

Remove symlinks before processing a template

Tim Byrne %!s(int64=5) %!d(string=hai) anos
pai
achega
3a192db420
Modificáronse 2 ficheiros con 31 adicións e 3 borrados
  1. 27 0
      test/test_alt.py
  2. 4 3
      yadm

+ 27 - 0
test/test_alt.py

@@ -193,3 +193,30 @@ def test_stale_link_removal(runner, yadm_y, paths):
         source_file = stale_path + '##class.' + tst_class
         source_file = stale_path + '##class.' + tst_class
         assert not paths.work.join(stale_path).exists()
         assert not paths.work.join(stale_path).exists()
         assert str(paths.work.join(source_file)) not in linked
         assert str(paths.work.join(source_file)) not in linked
+
+
+@pytest.mark.usefixtures('ds1_repo_copy')
+def test_template_overwrite_symlink(runner, yadm_y, paths, tst_sys):
+    """Remove symlinks before processing a template
+
+    If a symlink is in the way of the output of a template, the target of the
+    symlink will get the template content. To prevent this, the symlink should
+    be removed just before processing a template.
+    """
+
+    target = paths.work.join(f'test_link##os.{tst_sys}')
+    target.write('target')
+
+    link = paths.work.join('test_link')
+    link.mksymlinkto(target, absolute=1)
+
+    template = paths.work.join('test_link##template.builtin')
+    template.write('test-data')
+
+    run = runner(yadm_y('add', target, template))
+    assert run.success
+    assert run.err == ''
+    assert run.out == ''
+    assert not link.islink()
+    assert target.read().strip() == 'target'
+    assert link.read().strip() == 'test-data'

+ 4 - 3
yadm

@@ -498,15 +498,16 @@ function alt_future_linking() {
       # a template is defined, process the template
       # a template is defined, process the template
       debug "Creating $filename from template $target"
       debug "Creating $filename from template $target"
       [ -n "$loud" ] && echo "Creating $filename from template $target"
       [ -n "$loud" ] && echo "Creating $filename from template $target"
+      # remove any existing symlink before processing template
+      [ -L "$filename" ] && rm -f "$filename"
       "$template_cmd" "$target" "$filename"
       "$template_cmd" "$target" "$filename"
     elif [ -n "$target" ]; then
     elif [ -n "$target" ]; then
       # a link target is defined, create symlink
       # a link target is defined, create symlink
       debug "Linking $target to $filename"
       debug "Linking $target to $filename"
       [ -n "$loud" ] && echo "Linking $target to $filename"
       [ -n "$loud" ] && echo "Linking $target to $filename"
       if [ "$do_copy" -eq 1 ]; then
       if [ "$do_copy" -eq 1 ]; then
-        if [ -L "$filename" ]; then
-          rm -f "$filename"
-        fi
+        # remove any existing symlink before copying
+        [ -L "$filename" ] && rm -f "$filename"
         cp -f "$target" "$filename"
         cp -f "$target" "$filename"
       else
       else
         ln -nfs "$target" "$filename"
         ln -nfs "$target" "$filename"