Repository: mesonbuild/meson

Issue:
Running `meson` in the source dir without any arguments takes the parent directory as the build dir
This is a major regression over 0.46. The parent dir implicit selection should only be for finding the source directory, not the build directory.


Discussion:
This is likely because of https://github.com/mesonbuild/meson/pull/3612 by @xclaesse 

```python
p.add_argument('builddir', nargs='?', default='..')
p.add_argument('sourcedir', nargs='?', default='.')
```
These default values are wrong. These are the cases:

1. `meson` from inside the builddir where `..` is the sourcedir
2. `meson builddir` from the sourcedir
3. `meson builddir srcdir` from an arbitrary location
4. `meson srcdir builddir` from an arbitrary location

All other invocations must error out. Currently `meson` from the srcdir picks `...` as the builddir.

Resolving patch:
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -41,8 +41,8 @@ def create_parser():
                    help='Special wrap mode to use')
     p.add_argument('--profile-self', action='store_true', dest='profile',
                    help=argparse.SUPPRESS)
-    p.add_argument('builddir', nargs='?', default='..')
-    p.add_argument('sourcedir', nargs='?', default='.')
+    p.add_argument('builddir', nargs='?', default=None)
+    p.add_argument('sourcedir', nargs='?', default=None)
     return p
 
 def wrapmodetype(string):
@@ -331,6 +331,15 @@ def run(original_args, mainfile):
     dir1 = options.builddir
     dir2 = options.sourcedir
     try:
+        if dir1 is None:
+            if dir2 is None:
+                if not os.path.exists('meson.build') and os.path.exists('../meson.build'):
+                    dir2 = '..'
+                else:
+                    raise MesonException('Must specify at least one directory name.')
+            dir1 = os.getcwd()
+        if dir2 is None:
+            dir2 = os.getcwd()
         app = MesonApp(dir1, dir2, handshake, options)
     except Exception as e:
         # Log directory does not exist, so just print
diff --git a/run_unittests.py b/run_unittests.py
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -2406,6 +2406,24 @@ def test_configure_file_warnings(self):
             self.assertEqual(f.read().strip(), b'')
         self.assertRegex(out, r"DEPRECATION:.*\['array'\] is invalid.*dict")
 
+    def test_dirs(self):
+        with tempfile.TemporaryDirectory() as containing:
+            with tempfile.TemporaryDirectory(dir=containing) as srcdir:
+                mfile = os.path.join(srcdir, 'meson.build')
+                of = open(mfile, 'w')
+                of.write("project('foobar', 'c')\n")
+                of.close()
+                pc = subprocess.run(self.setup_command,
+                                    cwd=srcdir,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.DEVNULL)
+                self.assertIn(b'Must specify at least one directory name', pc.stdout)
+                with tempfile.TemporaryDirectory(dir=srcdir) as builddir:
+                    subprocess.run(self.setup_command,
+                                   check=True,
+                                   cwd=builddir,
+                                   stdout=subprocess.DEVNULL,
+                                   stderr=subprocess.DEVNULL)
 
 class FailureTests(BasePlatformTests):
     '''


Test patch: