class Command(object): def __init__(self, *args, **kwargs): """Create a new workflow step that calls an external program. Each step specifies an external process, which is eventually executed through the Python subprocess library. The arguments given to this constructor are stored in the args attribute, then passed to subprocess.Popen when the run method is invoked. Keyword arguments: name - optional name for identification of this step in a workflow (default: first argument) stdin_fp, stdout_fp, stderr_fp - filepaths used to redirect standard input, output, and error. """ if not args: raise ValueError('Must provide at least one non-keyword argument') self._args = CommandLineArguments(args) self.name = kwargs.get('name', args[0]) self.stdin_fp = kwargs.get('stdin_fp') self.stdout_fp = kwargs.get('stdout_fp') self.stderr_fp = kwargs.get('stderr_fp') self.process = None @property def args(self): return self._args.safe() def run(self, working_dir=None): """Run command in a new process. Returns the subprocess.Popen object. """ logging.info('Running command: %s' % self.args) kwargs = {'cwd': working_dir, 'close_fds': True} if self.stdin_fp is not None: kwargs['stdin'] = open(self.stdin_fp) if self.stdout_fp is not None: kwargs['stdout'] = open(self.stdout_fp, 'w') if self.stderr_fp is not None: kwargs['stderr'] = open(self.stderr_fp, 'w') logging.debug('Popen keyword args: %s' % kwargs) args = self.args self.process = subprocess.Popen(args, **kwargs) # Store the args in an attribute of the process object for reference self.process.args = args return self.process @property def shell_command(self): """Format command for the shell. """ return self._args.format_for_shell()
def __init__(self, *args, **kwargs): """Create a new workflow step that calls an external program. Each step specifies an external process, which is eventually executed through the Python subprocess library. The arguments given to this constructor are stored in the args attribute, then passed to subprocess.Popen when the run method is invoked. Keyword arguments: name - optional name for identification of this step in a workflow (default: first argument) stdin_fp, stdout_fp, stderr_fp - filepaths used to redirect standard input, output, and error. """ if not args: raise ValueError('Must provide at least one non-keyword argument') self._args = CommandLineArguments(args) self.name = kwargs.get('name', args[0]) self.stdin_fp = kwargs.get('stdin_fp') self.stdout_fp = kwargs.get('stdout_fp') self.stderr_fp = kwargs.get('stderr_fp') self.process = None
def test_force(self): ws = CommandLineArguments(['a', 'b', 'c']) self.assertEqual(ws.force(), ['a', 'b', 'c']) def f(): return 'a' xs = CommandLineArguments([f]) self.assertEqual(xs.force(), ['a']) ys = CommandLineArguments([lambda: 'a']) self.assertEqual(ys.force(), ['a'])
def test_safe(self): xs = CommandLineArguments(['a', '', None]) self.assertEqual(xs.safe(), ['a'])