diff options
author | Nirbheek Chauhan <nirbheek@centricular.com> | 2018-08-12 01:29:00 +0530 |
---|---|---|
committer | Nirbheek Chauhan <nirbheek@centricular.com> | 2018-08-24 03:24:10 +0530 |
commit | 04e25e5975af1c75a34fee49bc94a7a664966440 (patch) | |
tree | e1ae64229ffdde64c5d2719a652d52e23af14907 | |
parent | 1311b8a748d42b663d439504d81c5e633446f330 (diff) | |
download | meson-04e25e5975af1c75a34fee49bc94a7a664966440.zip meson-04e25e5975af1c75a34fee49bc94a7a664966440.tar.gz meson-04e25e5975af1c75a34fee49bc94a7a664966440.tar.bz2 |
install_subdir: Also copy dangling symlinks
Fixes https://github.com/mesonbuild/meson/issues/3914
-rw-r--r-- | mesonbuild/minstall.py | 20 | ||||
-rwxr-xr-x | run_unittests.py | 26 |
2 files changed, 39 insertions, 7 deletions
diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 11c8e5f..14f2fa1 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -191,12 +191,16 @@ class Installer: def should_preserve_existing_file(self, from_file, to_file): if not self.options.only_changed: return False + # Always replace danging symlinks + if os.path.islink(from_file) and not os.path.isfile(from_file): + return False from_time = os.stat(from_file).st_mtime to_time = os.stat(to_file).st_mtime return from_time <= to_time def do_copyfile(self, from_file, to_file): - if not os.path.isfile(from_file): + outdir = os.path.split(to_file)[0] + if not os.path.isfile(from_file) and not os.path.islink(from_file): raise RuntimeError('Tried to install something that isn\'t a file:' '{!r}'.format(from_file)) # copyfile fails if the target file already exists, so remove it to @@ -210,11 +214,13 @@ class Installer: append_to_log(self.lf, '# Preserving old file %s\n' % to_file) print('Preserving existing file %s.' % to_file) return False - os.unlink(to_file) - outdir = os.path.split(to_file)[0] + os.remove(to_file) print('Installing %s to %s' % (from_file, outdir)) - shutil.copyfile(from_file, to_file) - shutil.copystat(from_file, to_file) + if os.path.islink(from_file): + shutil.copy(from_file, outdir, follow_symlinks=False) + else: + shutil.copyfile(from_file, to_file) + shutil.copystat(from_file, to_file) selinux_updates.append(to_file) append_to_log(self.lf, to_file) return True @@ -277,7 +283,7 @@ class Installer: if os.path.isdir(abs_dst): print('Tried to copy file %s but a directory of that name already exists.' % abs_dst) if os.path.exists(abs_dst): - os.unlink(abs_dst) + os.remove(abs_dst) parent_dir = os.path.dirname(abs_dst) if not os.path.isdir(parent_dir): os.mkdir(parent_dir) @@ -431,7 +437,7 @@ class Installer: try: symlinkfilename = os.path.join(outdir, alias) try: - os.unlink(symlinkfilename) + os.remove(symlinkfilename) except FileNotFoundError: pass os.symlink(to, symlinkfilename) diff --git a/run_unittests.py b/run_unittests.py index 363cbcd..56bdf79 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -3703,6 +3703,32 @@ endian = 'little' # Ensure that the otool output does not contain self.installdir self.assertNotRegex(out, self.installdir + '.*dylib ') + def test_install_subdir_symlinks(self): + ''' + Test that installation of broken symlinks works fine. + https://github.com/mesonbuild/meson/issues/3914 + ''' + testdir = os.path.join(self.common_test_dir, '66 install subdir') + subdir = os.path.join(testdir, 'sub/sub1') + curdir = os.getcwd() + os.chdir(subdir) + # Can't distribute broken symlinks in the source tree because it breaks + # the creation of zipapps. Create it dynamically and run the test by + # hand. + src = '../../nonexistent.txt' + os.symlink(src, 'test.txt') + try: + self.init(testdir) + self.build() + self.install() + link = os.path.join(self.installdir, 'usr', 'share', 'sub1', 'test.txt') + self.assertTrue(os.path.islink(link), msg=link) + self.assertEqual(src, os.readlink(link)) + self.assertFalse(os.path.isfile(link), msg=link) + finally: + os.remove(os.path.join(subdir, 'test.txt')) + os.chdir(curdir) + class LinuxArmCrossCompileTests(BasePlatformTests): ''' |