From 30184553c18b82a886ed9a4a1d88e2a6679dd98e Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Thu, 16 Nov 2023 12:03:46 +0000
Subject: [PATCH] MNT: New 'silent' option to run function, which is equivalent
 to passing log={'tee':false}. When calling run(..., submit=True), any log
 argument is passed through to fsl_sub - this means that calling run(...,
 submit=True, silent=True) will prevent the job ID from being printed

---
 fsl/utils/run.py             | 12 ++++++++----
 fsl/wrappers/wrapperutils.py | 11 ++++++++++-
 2 files changed, 18 insertions(+), 5 deletions(-)

diff --git a/fsl/utils/run.py b/fsl/utils/run.py
index 99187527d..04d382ff7 100644
--- a/fsl/utils/run.py
+++ b/fsl/utils/run.py
@@ -188,6 +188,9 @@ def run(*args, **kwargs):
                      - cmd:    Optional file-like or callable to which
                                the command itself is logged.
 
+    :arg silent:   Suppress standard output/error. Equivalent to passing
+                   ``log={'tee' : False}``. Ignored if `log` is also passed.
+
     All other keyword arguments are passed through to the ``subprocess.Popen``
     object (via :func:`_realrun`), unless ``submit=True``, in which case they
     are passed through to the :func:`.fsl_sub` function.
@@ -204,10 +207,11 @@ def run(*args, **kwargs):
     submit         = kwargs.pop('submit',   {})
     cmdonly        = kwargs.pop('cmdonly',  False)
     logg           = kwargs.pop('log',      None)
+    silent         = kwargs.pop('silent',   False)
     args           = prepareArgs(args)
 
     if logg is None:
-        logg = {}
+        logg = {'tee' : not silent}
 
     tee       = logg.get('tee',    True)
     logStdout = logg.get('stdout', None)
@@ -237,7 +241,7 @@ def run(*args, **kwargs):
     # but harmless, as we've popped the "submit" arg above.
     if submit is not None:
         from fsl.wrappers import fsl_sub  # pylint: disable=import-outside-toplevel  # noqa: E501
-        return fsl_sub(*args, **submit, **kwargs)[0].strip()
+        return fsl_sub(*args, log=logg, **submit, **kwargs)[0].strip()
 
     # Run directly - delegate to _realrun
     stdout, stderr, exitcode = _realrun(
@@ -633,10 +637,10 @@ def hold(job_ids, hold_filename=None, timeout=10):
     submit = {
         'jobhold'  : _flatten_job_ids(job_ids),
         'jobtime'  : 1,
-        'name'     : '.hold'
+        'name'     : '.hold',
     }
 
-    run(f'touch {hold_filename}', submit=submit)
+    run(f'touch {hold_filename}', submit=submit, silent=True)
 
     while not op.exists(hold_filename):
         time.sleep(timeout)
diff --git a/fsl/wrappers/wrapperutils.py b/fsl/wrappers/wrapperutils.py
index 3fc318d2c..1a931de2a 100644
--- a/fsl/wrappers/wrapperutils.py
+++ b/fsl/wrappers/wrapperutils.py
@@ -193,7 +193,16 @@ def genxwrapper(func, runner, funccmd=False):
         exitcode = kwargs.pop('exitcode', opts['exitcode'])
         submit   = kwargs.pop('submit',   opts['submit'])
         cmdonly  = kwargs.pop('cmdonly',  opts['cmdonly'])
-        logg     = kwargs.pop('log',      opts['log'])
+        silent   = kwargs.pop('silent',   False)
+
+        # If silent=True, we need to explicitly set
+        # log, as the run function will otherwise
+        # ignore silent and preferentially use the
+        # value we pass for log.
+        if silent:
+            logg = kwargs.pop('log', {'tee' : False})
+        else:
+            logg = kwargs.pop('log', opts['log'])
 
         if funccmd:
             cmd = run.func_to_cmd(func, args=args, kwargs=kwargs,
-- 
GitLab