From 9c526974dcfad0191d77550bd636f242bbfa8367 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Tue, 28 Mar 2023 08:59:51 -0400 Subject: [PATCH] msetup: Allow (re)configure of not empty builddir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also prevent from using a parent directory as builddir by mistake. Co-authored-by: Volker Weißmann Co-authored-by: Charles Brunet --- mesonbuild/msetup.py | 5 ++++- unittests/allplatformstests.py | 1 + unittests/platformagnostictests.py | 35 ++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py index 166f7ef40..0de5b3137 100644 --- a/mesonbuild/msetup.py +++ b/mesonbuild/msetup.py @@ -24,6 +24,7 @@ import argparse import tempfile import shutil import glob +from pathlib import Path from . import environment, interpreter, mesonlib from . import build @@ -157,6 +158,8 @@ class MesonApp: def validate_dirs(self, dir1: str, dir2: str, reconfigure: bool, wipe: bool) -> T.Tuple[str, str]: (src_dir, build_dir) = self.validate_core_dirs(dir1, dir2) + if Path(build_dir) in Path(src_dir).parents: + raise MesonException(f'Build directory {build_dir} cannot be a parent of source directory {src_dir}') if not os.listdir(build_dir): self.add_vcs_ignore_files(build_dir) return src_dir, build_dir @@ -178,7 +181,7 @@ class MesonApp: # Note that making this an error would not be backward compatible (and also isn't # universally agreed on): https://github.com/mesonbuild/meson/pull/4249. raise SystemExit(0) - elif not has_partial_build and 'MESON_RUNNING_IN_PROJECT_TESTS' not in os.environ: + elif not has_partial_build and wipe: raise MesonException(f'Directory is not empty and does not contain a previous build:\n{build_dir}') return src_dir, build_dir diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py index ea9d7952d..0581caf91 100644 --- a/unittests/allplatformstests.py +++ b/unittests/allplatformstests.py @@ -2046,6 +2046,7 @@ class AllPlatformTests(BasePlatformTests): self.assertFalse(os.path.isfile(promoted_wrap)) subprocess.check_call(self.wrap_command + ['promote', 'athing'], cwd=workdir) self.assertTrue(os.path.isfile(promoted_wrap)) + self.new_builddir() # Ensure builddir is not parent or workdir self.init(workdir) self.build() diff --git a/unittests/platformagnostictests.py b/unittests/platformagnostictests.py index 9fb24f357..1dc8eb079 100644 --- a/unittests/platformagnostictests.py +++ b/unittests/platformagnostictests.py @@ -163,3 +163,38 @@ class PlatformAgnosticTests(BasePlatformTests): # Wipe with a different backend is allowed self.init(testdir, extra_args=['--wipe', '--backend=none']) + + def test_validate_dirs(self): + testdir = os.path.join(self.common_test_dir, '1 trivial') + + # Using parent as builddir should fail + self.builddir = os.path.dirname(self.builddir) + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testdir) + self.assertIn('cannot be a parent of source directory', cm.exception.stdout) + + # Reconfigure of empty builddir should work + self.new_builddir() + self.init(testdir, extra_args=['--reconfigure']) + + # Reconfigure of not empty builddir should work + self.new_builddir() + Path(self.builddir, 'dummy').touch() + self.init(testdir, extra_args=['--reconfigure']) + + # Wipe of empty builddir should work + self.new_builddir() + self.init(testdir, extra_args=['--wipe']) + + # Wipe of partial builddir should work + self.new_builddir() + Path(self.builddir, 'meson-private').mkdir() + Path(self.builddir, 'dummy').touch() + self.init(testdir, extra_args=['--wipe']) + + # Wipe of not empty builddir should fail + self.new_builddir() + Path(self.builddir, 'dummy').touch() + with self.assertRaises(subprocess.CalledProcessError) as cm: + self.init(testdir, extra_args=['--wipe']) + self.assertIn('Directory is not empty', cm.exception.stdout)