Repository: mesonbuild/meson

Issue:
`mesontest --gdb` prints a backtrace when `gdb` is not installed
```sh
$ mesontest -C build --gdb test-bus-error
ninja: Entering directory `/home/vagrant/systemd/build'
ninja: no work to do.
Traceback (most recent call last):
  File "/home/vagrant/.virtualenvs/meson/bin/mesontest", line 4, in <module>
    __import__('pkg_resources').run_script('meson==0.40.0.dev1', 'mesontest')
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/pkg_resources/__init__.py", line 738, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1499, in run_script
    exec(code, namespace, namespace)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 598, in <module>
    sys.exit(run(sys.argv[1:]))
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 595, in run
    return th.run_special()
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 510, in run_special
    self.run_tests(tests)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 468, in run_tests
    res = self.run_single_test(wrap, test)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 234, in run_single_test
    preexec_fn=setsid)
  File "/usr/lib64/python3.5/subprocess.py", line 676, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.5/subprocess.py", line 1282, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'gdb'
```

`mesontest --wrapper some-non-installed-wrapper` prints the backtrace too.
```sh
$ mesontest -C build --wrapper valgrind -v test-path-util
ninja: Entering directory `/home/vagrant/systemd/build'
ninja: no work to do.
Traceback (most recent call last):
  File "/home/vagrant/.virtualenvs/meson/bin/mesontest", line 4, in <module>
    __import__('pkg_resources').run_script('meson==0.40.0.dev1', 'mesontest')
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/pkg_resources/__init__.py", line 738, in run_script
    self.require(requires)[0].run_script(script_name, ns)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/pkg_resources/__init__.py", line 1499, in run_script
    exec(code, namespace, namespace)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 598, in <module>
    sys.exit(run(sys.argv[1:]))
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 595, in run
    return th.run_special()
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 510, in run_special
    self.run_tests(tests)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 480, in run_tests
    self.drain_futures(futures, logfile, jsonlogfile)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 498, in drain_futures
    result.result()
  File "/usr/lib64/python3.5/concurrent/futures/_base.py", line 405, in result
    return self.__get_result()
  File "/usr/lib64/python3.5/concurrent/futures/_base.py", line 357, in __get_result
    raise self._exception
  File "/usr/lib64/python3.5/concurrent/futures/thread.py", line 55, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/vagrant/.virtualenvs/meson/lib/python3.5/site-packages/meson-0.40.0.dev1-py3.5.egg/EGG-INFO/scripts/mesontest", line 234, in run_single_test
    preexec_fn=setsid)
  File "/usr/lib64/python3.5/subprocess.py", line 676, in __init__
    restore_signals, start_new_session)
  File "/usr/lib64/python3.5/subprocess.py", line 1282, in _execute_child
    raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: 'valgrind'
```


Discussion:

Resolving patch:
diff --git a/mesontest.py b/mesontest.py
--- a/mesontest.py
+++ b/mesontest.py
@@ -21,6 +21,7 @@
 import pickle
 from mesonbuild import build
 from mesonbuild import environment
+from mesonbuild.dependencies import ExternalProgram
 
 import time, datetime, multiprocessing, json
 import concurrent.futures as conc
@@ -574,12 +575,21 @@ def run(args):
         print('Can not be both quiet and verbose at the same time.')
         return 1
 
+    check_bin = None
     if options.gdb:
         options.verbose = True
         if options.wrapper:
             print('Must not specify both a wrapper and gdb at the same time.')
             return 1
+        check_bin = 'gdb'
 
+    if options.wrapper:
+        check_bin = options.wrapper[0]
+
+    if check_bin is not None:
+        exe = ExternalProgram(check_bin, silent=True)
+        if not exe.found():
+            sys.exit("Could not find requested program: %s" % check_bin)
     options.wd = os.path.abspath(options.wd)
 
     if not options.no_rebuild:


Test patch: