From 40b2cb8166b4bb579edd6543d625b3289087a6d9 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 2 Mar 2016 11:57:27 -0500 Subject: [PATCH 1/4] TST: Check that we don't hardlink to symlinks --- nipype/utils/tests/test_filemanip.py | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/nipype/utils/tests/test_filemanip.py b/nipype/utils/tests/test_filemanip.py index 2c0aaa44b1..b3a4f71330 100644 --- a/nipype/utils/tests/test_filemanip.py +++ b/nipype/utils/tests/test_filemanip.py @@ -132,6 +132,41 @@ def test_copyfiles(): os.unlink(new_hdr2) +def test_linkchain(): + if os.name is not 'posix': + return + orig_img, orig_hdr = _temp_analyze_files() + pth, fname = os.path.split(orig_img) + new_img1 = os.path.join(pth, 'newfile1.img') + new_hdr1 = os.path.join(pth, 'newfile1.hdr') + new_img2 = os.path.join(pth, 'newfile2.img') + new_hdr2 = os.path.join(pth, 'newfile2.hdr') + new_img3 = os.path.join(pth, 'newfile3.img') + new_hdr3 = os.path.join(pth, 'newfile3.hdr') + copyfile(orig_img, new_img1) + yield assert_true, os.path.islink(new_img1) + yield assert_true, os.path.islink(new_hdr1) + copyfile(new_img1, new_img2, copy=True) + yield assert_false, os.path.islink(new_img2) + yield assert_false, os.path.islink(new_hdr2) + yield assert_false, os.path.samefile(orig_img, new_img2) + yield assert_false, os.path.samefile(orig_hdr, new_hdr2) + copyfile(new_img1, new_img3, copy=True, use_hardlink=True) + yield assert_false, os.path.islink(new_img3) + yield assert_false, os.path.islink(new_hdr3) + yield assert_true, os.path.samefile(orig_img, new_img3) + yield assert_true, os.path.samefile(orig_hdr, new_hdr3) + os.unlink(new_img1) + os.unlink(new_hdr1) + os.unlink(new_img2) + os.unlink(new_hdr2) + os.unlink(new_img3) + os.unlink(new_hdr3) + # final cleanup + os.unlink(orig_img) + os.unlink(orig_hdr) + + def test_filename_to_list(): x = filename_to_list('foo.nii') yield assert_equal, x, ['foo.nii'] From 2b0aef814159bd1bc20154c253b226b0e5a69ea9 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 2 Mar 2016 17:51:31 -0500 Subject: [PATCH 2/4] FIX: Use realpath to determine hardlink source --- nipype/utils/filemanip.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index de6f6760f5..c113c22f33 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -42,7 +42,9 @@ def nipype_hardlink_wrapper(raw_src, raw_dst): If the hardlink fails, then fall back to using a standard copy. """ - src = os.path.normpath(raw_src) + # Use realpath to avoid hardlinking symlinks + src = os.path.realpath(raw_src) + # Use normpath, in case destination is a symlink dst = os.path.normpath(raw_dst) del raw_src del raw_dst From 9b09b0e7b47fc8bb077cd827508d2a8ffb4975dd Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Wed, 2 Mar 2016 22:53:29 -0500 Subject: [PATCH 3/4] FIX: Use same copy args for related files --- nipype/utils/filemanip.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index c113c22f33..646686a441 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -285,12 +285,15 @@ def copyfile(originalfile, newfile, copy=False, create_new=False, matofile = originalfile[:-4] + ".mat" if os.path.exists(matofile): matnfile = newfile[:-4] + ".mat" - copyfile(matofile, matnfile, copy) - copyfile(hdrofile, hdrnfile, copy) + copyfile(matofile, matnfile, copy, create_new, hashmethod, + use_hardlink) + copyfile(hdrofile, hdrnfile, copy, create_new, hashmethod, + use_hardlink) elif originalfile.endswith(".BRIK"): hdrofile = originalfile[:-5] + ".HEAD" hdrnfile = newfile[:-5] + ".HEAD" - copyfile(hdrofile, hdrnfile, copy) + copyfile(hdrofile, hdrnfile, copy, create_new, hashmethod, + use_hardlink) return newfile From 7c26e16e53ea6d38d2d2aaeadefa92ffa19fb770 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 3 Mar 2016 07:39:32 -0500 Subject: [PATCH 4/4] DOC: Update CHANGES --- CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES b/CHANGES index f36491c694..8eb155ffb5 100644 --- a/CHANGES +++ b/CHANGES @@ -21,6 +21,7 @@ Next release * API: Default model level for the bedpostx workflow has been set to "2" following FSL 5.0.9 lead * ENH: New interfaces for interacting with AWS S3: S3DataSink and S3DataGrabber (https://github.com/nipy/nipype/pull/1201) * ENH: Interfaces for MINC tools (https://github.com/nipy/nipype/pull/1304) +* FIX: Use realpath to determine hard link source (https://github.com/nipy/nipype/pull/1388) Release 0.11.0 (September 15, 2015) ============