diff --git a/interop_test.go b/interop_test.go index 0cb8482..6b63d42 100644 --- a/interop_test.go +++ b/interop_test.go @@ -349,6 +349,59 @@ func TestInteropSubdirExclude(t *testing.T) { } } +func TestInteropSubdirExcludeMultipleNested(t *testing.T) { + _, source, dest := createSourceFiles(t) + + nested := filepath.Join(source, "nested") + + // create files in source to be copied + subDirs := []string{"nested-expensive", "nested-cheap"} + for _, subdir := range subDirs { + dummy := filepath.Join(nested, subdir, "dummy") + if err := os.MkdirAll(filepath.Dir(dummy), 0755); err != nil { + t.Fatal(err) + } + if err := os.WriteFile(dummy, []byte(subdir), 0644); err != nil { + t.Fatal(err) + } + } + + // start a server to sync from + srv := rsynctest.New(t, rsynctest.InteropModule(source)) + + // sync into dest dir + rsync := exec.Command("rsync", //"/home/michael/src/openrsync/openrsync", + append( + append([]string{ + // "--debug=all4", + "--archive", + // TODO: implement support for include rules + //"-f", "+ *.o", + // NOTE: Using -f is the more modern replacement + // for using --exclude like so: + //"--exclude=dummy", + "-f", "- nested/nested-expensive", + "-f", "- nested/nested-cheap", + "-v", "-v", "-v", "-v", + "--port=" + srv.Port, + }, "rsync://localhost/interop"), + dest)...) + rsync.Stdout = os.Stdout + rsync.Stderr = os.Stderr + if err := rsync.Run(); err != nil { + t.Fatalf("%v: %v", rsync.Args, err) + } + + expensiveFn := filepath.Join(dest, "nested", "nested-expensive", "dummy") + if _, err := os.ReadFile(expensiveFn); !os.IsNotExist(err) { + t.Fatalf("ReadFile(%s) did not return -ENOENT, but %v", expensiveFn, err) + } + cheapFn := filepath.Join(dest, "nested", "nested-cheap", "dummy") + if _, err := os.ReadFile(cheapFn); !os.IsNotExist(err) { + t.Fatalf("ReadFile(%s) did not return -ENOENT, but %v", cheapFn, err) + } +} + func TestInteropRemoteCommand(t *testing.T) { _, source, dest := createSourceFiles(t) diff --git a/rsyncd/flist.go b/rsyncd/flist.go index 310edb0..d4c8d50 100644 --- a/rsyncd/flist.go +++ b/rsyncd/flist.go @@ -48,10 +48,6 @@ func (st *sendTransfer) sendFileList(mod Module, opts *Opts, paths []string, exc return err } - if excl.matches(path) { - return filepath.SkipDir - } - // Only ever transmit long names, like openrsync flags := byte(rsync.XMIT_LONG_NAME) @@ -63,6 +59,10 @@ func (st *sendTransfer) sendFileList(mod Module, opts *Opts, paths []string, exc } // st.logger.Printf("flags for %q: %v", name, flags) + if excl.matches(name) { + return filepath.SkipDir + } + fileList.files = append(fileList.files, file{ path: path, regular: info.Mode().IsRegular(),