Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cp_r function does not preserve symlinks (unlike cp -r) in copied directory #111

Open
mwu-tow opened this issue Oct 19, 2015 · 4 comments
Open

Comments

@mwu-tow
Copy link

mwu-tow commented Oct 19, 2015

Using Shelly on Linux this time. I have a directory containing a symlink with relative path. If I copy the directory using the cp_r function, it replaces the symlinks with the target files. If I run cp -r command the target directory has symlinks preserved.

Shouldn't cp_r and cp -r do the same things? That's what I'd expect.

@gregwebs
Copy link
Owner

This does seem like nicer default behavior.

Right now I am doing my own descent and using this copyFile function.

sytem-fileio is deprecated now, but I would assume that the behavior from directory is the same.

So it seems like the easiest thing to do is to just insert a symlink check. Interested in adding a test case to Shelly for this?

@mwu-tow
Copy link
Author

mwu-tow commented Oct 19, 2015

I'm not sure how this should be best approached as the test would be platform specific and would require adding such dependency as unix package.

@gregwebs
Copy link
Owner

Can always use conditional compilation for Windows. Maybe there is a library that already implements cp -r cross-platform that can be used?

@kgadek
Copy link

kgadek commented Oct 20, 2015

Making a test case without unix is difficult as well. Symlinks on Windows are rather tricky, they requires admin rights to create them. Bloody hackers and their symlinks!.

Anyway, here is a draft for the test: symlinks with absolute paths.

However, this fails – surprisingly for me – with Exception: FilePath "/Users/foo/bar/baz/shelly/test/a/d1": createSymbolicLink: does not exist (No such file or directory)).

diff --git a/shelly.cabal b/shelly.cabal
index be228a5..a27272b 100644
--- a/shelly.cabal
+++ b/shelly.cabal
@@ -137,7 +137,8 @@ Test-Suite shelly-testsuite
     lifted-base,
     lifted-async,
     enclosed-exceptions,
-    exceptions
+    exceptions,
+    unix

   extensions:
     CPP
diff --git a/test/src/CopySpec.hs b/test/src/CopySpec.hs
index c601c22..9b92b45 100644
--- a/test/src/CopySpec.hs
+++ b/test/src/CopySpec.hs
@@ -10,6 +10,7 @@ import Prelude hiding ( FilePath)
 #endif
 import Control.Monad (forM_)
 import System.IO.Error
+import System.Posix.Files (createSymbolicLink, readSymbolicLink, fileExist, isSymbolicLink)
 import Help

 copySpec :: Spec
@@ -83,3 +84,32 @@ copySpec = do
           writefile "b/d" ""
           cp_r b b `catch_sh` (\e -> liftIO $ assert $ isUserError e)
       assert True
+
+    it "copies the symlinks" $ do
+      shelly $
+        within_dir "test/a" $ do
+
+          d1       <- absPath "d1"
+          writefile d1 ""
+          b_d2     <- absPath "b/d2"
+          b_e1     <- absPath "b/e1"
+          b_e2     <- absPath "b/e2"
+          c_cc_e1  <- absPath "c/cc/e1"
+          c_cc_e2  <- absPath "c/cc/e2"
+
+          mkdir b
+          writefile b_d2 ""
+
+          liftIO $ do
+            createSymbolicLink (show d1) (show b_e1)
+            createSymbolicLink (show b_d2) (show b_e2)
+
+          mkdir_p c
+          cp_r b "c/cc"
+
+          e1_res <- liftIO $ readSymbolicLink (show c_cc_e1)
+          e2_res <- liftIO $ readSymbolicLink (show c_cc_e2)
+
+          liftIO $ assert $ e1_res == (show d1)
+          liftIO $ assert $ e2_res == (show b_d2)
+      assert True

Probably we could make this test-case and requirement on unix conditional.

As for library with cp -r functionality: I'm not aware of any.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants