Skip to content

Commit 0ba35f1

Browse files
authored
Merge pull request #2379 from effigies/enh/command_prefix
ENH: Add _cmd_prefix class variable to CommandLine
2 parents b3dacd0 + 822d34d commit 0ba35f1

File tree

6 files changed

+62
-19
lines changed

6 files changed

+62
-19
lines changed

nipype/interfaces/afni/base.py

+5-8
Original file line numberDiff line numberDiff line change
@@ -294,13 +294,10 @@ class AFNIPythonCommandInputSpec(CommandLineInputSpec):
294294
class AFNIPythonCommand(AFNICommand):
295295
@property
296296
def cmd(self):
297-
if spawn.find_executable(super(AFNIPythonCommand,
298-
self).cmd) is not None:
299-
return spawn.find_executable(super(AFNIPythonCommand, self).cmd)
300-
else:
301-
return super(AFNIPythonCommand, self).cmd
297+
orig_cmd = super(AFNIPythonCommand, self).cmd
298+
found = spawn.find_executable(orig_cmd)
299+
return found if found is not None else orig_cmd
302300

303301
@property
304-
def cmdline(self):
305-
return "{} {}".format(self.inputs.py27_path,
306-
super(AFNIPythonCommand, self).cmdline)
302+
def _cmd_prefix(self):
303+
return "{} ".format(self.inputs.py27_path)

nipype/interfaces/base/core.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import platform
2727
import select
2828
import subprocess as sp
29+
import shlex
2930
import sys
3031
from textwrap import wrap
3132
import simplejson as json
@@ -868,6 +869,7 @@ class must be instantiated with a command argument
868869
869870
"""
870871
input_spec = CommandLineInputSpec
872+
_cmd_prefix = ''
871873
_cmd = None
872874
_version = None
873875
_terminal_output = 'stream'
@@ -926,7 +928,7 @@ def cmdline(self):
926928
""" `command` plus any arguments (args)
927929
validates arguments and generates command line"""
928930
self._check_mandatory_inputs()
929-
allargs = [self.cmd] + self._parse_inputs()
931+
allargs = [self._cmd_prefix + self.cmd] + self._parse_inputs()
930932
return ' '.join(allargs)
931933

932934
@property
@@ -997,7 +999,7 @@ def _run_interface(self, runtime, correct_return_codes=(0, )):
997999
runtime.environ.update(out_environ)
9981000

9991001
# which $cmd
1000-
executable_name = self.cmd.split()[0]
1002+
executable_name = shlex.split(self._cmd_prefix + self.cmd)[0]
10011003
cmd_path = which(executable_name, env=runtime.environ)
10021004

10031005
if cmd_path is None:

nipype/interfaces/base/tests/test_core.py

+35
Original file line numberDiff line numberDiff line change
@@ -480,3 +480,38 @@ def test_global_CommandLine_output(tmpdir):
480480
# Check default affects derived interfaces
481481
ci = BET()
482482
assert ci.terminal_output == 'file'
483+
484+
485+
def test_CommandLine_prefix(tmpdir):
486+
tmpdir.chdir()
487+
oop = 'out/of/path'
488+
os.makedirs(oop)
489+
490+
script_name = 'test_script.sh'
491+
script_path = os.path.join(oop, script_name)
492+
with open(script_path, 'w') as script_f:
493+
script_f.write('#!/usr/bin/env bash\necho Success!')
494+
os.chmod(script_path, 0o755)
495+
496+
ci = nib.CommandLine(command=script_name)
497+
with pytest.raises(IOError):
498+
ci.run()
499+
500+
class OOPCLI(nib.CommandLine):
501+
_cmd_prefix = oop + '/'
502+
503+
ci = OOPCLI(command=script_name)
504+
ci.run()
505+
506+
class OOPShell(nib.CommandLine):
507+
_cmd_prefix = 'bash {}/'.format(oop)
508+
509+
ci = OOPShell(command=script_name)
510+
ci.run()
511+
512+
class OOPBadShell(nib.CommandLine):
513+
_cmd_prefix = 'shell_dne {}/'.format(oop)
514+
515+
ci = OOPBadShell(command=script_name)
516+
with pytest.raises(IOError):
517+
ci.run()

nipype/interfaces/freesurfer/preprocess.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -655,8 +655,9 @@ def cmdline(self):
655655
files = self._get_filelist(outdir)
656656
for infile, outfile in files:
657657
if not os.path.exists(outfile):
658-
single_cmd = '%s %s %s' % (self.cmd, infile,
659-
os.path.join(outdir, outfile))
658+
single_cmd = '%s%s %s %s' % (self._cmd_prefix, self.cmd,
659+
infile, os.path.join(outdir,
660+
outfile))
660661
cmd.extend([single_cmd])
661662
return '; '.join(cmd)
662663

nipype/interfaces/minc/minc.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1742,15 +1742,15 @@ def _list_outputs(self):
17421742
@property
17431743
def cmdline(self):
17441744
output_file_base = self.inputs.output_file_base
1745+
orig_cmdline = super(Blur, self).cmdline
17451746

17461747
if isdefined(output_file_base):
1747-
return super(Blur, self).cmdline
1748+
return orig_cmdline
17481749
else:
17491750
# FIXME this seems like a bit of a hack. Can we force output_file
17501751
# to show up in cmdline by default, even if it isn't specified in
17511752
# the instantiation of Pik?
1752-
return '%s %s' % (super(Blur, self).cmdline,
1753-
self._gen_output_base())
1753+
return '%s %s' % (orig_cmdline, self._gen_output_base())
17541754

17551755

17561756
class MathInputSpec(CommandLineInputSpec):

nipype/utils/filemanip.py

+12-4
Original file line numberDiff line numberDiff line change
@@ -774,12 +774,20 @@ def which(cmd, env=None, pathext=None):
774774
return filename
775775
return None
776776

777+
def isexec(path):
778+
return os.path.isfile(path) and os.access(path, os.X_OK)
779+
777780
for ext in pathext:
778781
extcmd = cmd + ext
779-
for directory in path.split(os.pathsep):
780-
filename = op.join(directory, extcmd)
781-
if op.exists(filename):
782-
return filename
782+
fpath, fname = os.path.split(extcmd)
783+
if fpath:
784+
if isexec(extcmd):
785+
return extcmd
786+
else:
787+
for directory in path.split(os.pathsep):
788+
filename = op.join(directory, extcmd)
789+
if isexec(filename):
790+
return filename
783791
return None
784792

785793

0 commit comments

Comments
 (0)