def cmd_output_b(*cmd, **kwargs): retcode = kwargs.pop('retcode', 0) popen_kwargs = { 'stdin': subprocess.PIPE, 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } # py2/py3 on windows are more strict about the types here cmd = tuple(five.n(arg) for arg in cmd) kwargs['env'] = { five.n(key): five.n(value) for key, value in kwargs.pop('env', {}).items() } or None popen_kwargs.update(kwargs) try: cmd = parse_shebang.normalize_cmd(cmd) except parse_shebang.ExecutableNotFoundError as e: returncode, stdout_b, stderr_b = e.to_output() else: proc = subprocess.Popen(cmd, **popen_kwargs) stdout_b, stderr_b = proc.communicate() returncode = proc.returncode if retcode is not None and retcode != returncode: raise CalledProcessError( returncode, cmd, retcode, output=(stdout_b, stderr_b), ) return returncode, stdout_b, stderr_b
def cmd_output(*cmd, **kwargs): retcode = kwargs.pop('retcode', 0) encoding = kwargs.pop('encoding', 'UTF-8') __popen = kwargs.pop('__popen', subprocess.Popen) popen_kwargs = { 'stdin': subprocess.PIPE, 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } # py2/py3 on windows are more strict about the types here cmd = tuple(five.n(arg) for arg in cmd) kwargs['env'] = dict( (five.n(key), five.n(value)) for key, value in kwargs.pop('env', {}).items() ) or None cmd = parse_shebang.normalize_cmd(cmd) popen_kwargs.update(kwargs) proc = __popen(cmd, **popen_kwargs) stdout, stderr = proc.communicate() if encoding is not None and stdout is not None: stdout = stdout.decode(encoding) if encoding is not None and stderr is not None: stderr = stderr.decode(encoding) returncode = proc.returncode if retcode is not None and retcode != returncode: raise CalledProcessError( returncode, cmd, retcode, output=(stdout, stderr), ) return proc.returncode, stdout, stderr
def test_CalledProcessError_str_nooutput(): error = CalledProcessError(1, [five.n('git'), five.n('status')], 0, (five.n(''), five.n(''))) assert str(error) == ("Command: ['git', 'status']\n" "Return code: 1\n" "Expected return code: 0\n" "Output: (none)\n" "Errors: (none)\n")
def _cmd_kwargs(*cmd, **kwargs): # py2/py3 on windows are more strict about the types here cmd = tuple(five.n(arg) for arg in cmd) kwargs['env'] = { five.n(key): five.n(value) for key, value in kwargs.pop('env', {}).items() } or None for arg in ('stdin', 'stdout', 'stderr'): kwargs.setdefault(arg, subprocess.PIPE) return cmd, kwargs
def test_CalledProcessError_str_nooutput(): error = CalledProcessError( 1, [five.n('git'), five.n('status')], 0, (five.n(''), five.n('')) ) assert str(error) == ( "Command: ['git', 'status']\n" "Return code: 1\n" "Expected return code: 0\n" "Output: (none)\n" "Errors: (none)\n" )
def test_run_substitutes_prefix(popen_mock, makedirs_mock): instance = PrefixedCommandRunner( 'prefix', popen=popen_mock, makedirs=makedirs_mock, ) ret = instance.run(['{prefix}bar', 'baz'], retcode=None) popen_mock.assert_called_once_with( [five.n(os.path.join('prefix', 'bar')), five.n('baz')], env=None, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) assert ret == (popen_mock.return_value.returncode, 'stdout', 'stderr')
def test_CalledProcessError_str(): error = CalledProcessError( 1, [five.n('git'), five.n('status')], 0, (five.n('stdout'), five.n('stderr')), ) assert str(error) == ("Command: ['git', 'status']\n" "Return code: 1\n" "Expected return code: 0\n" "Output: \n" " stdout\n" "Errors: \n" " stderr\n")
def test_run_substitutes_prefix(popen_mock, makedirs_mock): instance = PrefixedCommandRunner( 'prefix', popen=popen_mock, makedirs=makedirs_mock, ) ret = instance.run(['{prefix}bar', 'baz'], retcode=None) popen_mock.assert_called_once_with( (five.n(os.path.join('prefix', 'bar')), five.n('baz')), env=None, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) assert ret == (popen_mock.return_value.returncode, 'stdout', 'stderr')
def make_archive(name, repo, ref, destdir): """Makes an archive of a repository in the given destdir. :param text name: Name to give the archive. For instance foo. The file that is created will be called foo.tar.gz. :param text repo: Repository to clone. :param text ref: Tag/SHA/branch to check out. :param text destdir: Directory to place archives in. """ output_path = os.path.join(destdir, name + '.tar.gz') with tmpdir() as tempdir: # Clone the repository to the temporary directory cmd_output('git', 'clone', repo, tempdir) with cwd(tempdir): cmd_output('git', 'checkout', ref) # We don't want the '.git' directory # It adds a bunch of size to the archive and we don't use it at # runtime rmtree(os.path.join(tempdir, '.git')) with tarfile.open(five.n(output_path), 'w|gz') as tf: tf.add(tempdir, name) return output_path
def test_CalledProcessError_str(): error = CalledProcessError( 1, [five.n('git'), five.n('status')], 0, (five.n('stdout'), five.n('stderr')), ) assert str(error) == ( "Command: ['git', 'status']\n" "Return code: 1\n" "Expected return code: 0\n" "Output: \n" " stdout\n" "Errors: \n" " stderr\n" )
def cmd_output(*cmd, **kwargs): retcode = kwargs.pop('retcode', 0) encoding = kwargs.pop('encoding', 'UTF-8') __popen = kwargs.pop('__popen', subprocess.Popen) popen_kwargs = { 'stdin': subprocess.PIPE, 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } # py2/py3 on windows are more strict about the types here cmd = tuple(five.n(arg) for arg in cmd) kwargs['env'] = dict( (five.n(key), five.n(value)) for key, value in kwargs.pop('env', {}).items()) or None try: cmd = parse_shebang.normalize_cmd(cmd) except parse_shebang.ExecutableNotFoundError as e: returncode, stdout, stderr = (-1, e.args[0].encode('UTF-8'), b'') else: popen_kwargs.update(kwargs) proc = __popen(cmd, **popen_kwargs) stdout, stderr = proc.communicate() if encoding is not None and stdout is not None: stdout = stdout.decode(encoding) if encoding is not None and stderr is not None: stderr = stderr.decode(encoding) returncode = proc.returncode if retcode is not None and retcode != returncode: raise CalledProcessError( returncode, cmd, retcode, output=(stdout, stderr), ) return returncode, stdout, stderr
def cmd_output(*cmd, **kwargs): retcode = kwargs.pop('retcode', 0) stdin = kwargs.pop('stdin', None) encoding = kwargs.pop('encoding', 'UTF-8') __popen = kwargs.pop('__popen', subprocess.Popen) popen_kwargs = { 'stdin': subprocess.PIPE, 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } if stdin is not None: stdin = stdin.encode('UTF-8') # py2/py3 on windows are more strict about the types here cmd = [five.n(arg) for arg in cmd] kwargs['env'] = dict( (five.n(key), five.n(value)) for key, value in kwargs.pop('env', {}).items()) or None popen_kwargs.update(kwargs) proc = __popen(cmd, **popen_kwargs) stdout, stderr = proc.communicate(stdin) if encoding is not None and stdout is not None: stdout = stdout.decode(encoding) if encoding is not None and stderr is not None: stderr = stderr.decode(encoding) returncode = proc.returncode if retcode is not None and retcode != returncode: raise CalledProcessError( returncode, cmd, retcode, output=(stdout, stderr), ) return proc.returncode, stdout, stderr
def test_from_command_runner_preserves_popen(popen_mock, makedirs_mock): first = PrefixedCommandRunner( 'foo', popen=popen_mock, makedirs=makedirs_mock, ) second = PrefixedCommandRunner.from_command_runner(first, 'bar') second.run(['foo/bar/baz'], retcode=None) popen_mock.assert_called_once_with( [five.n('foo/bar/baz')], env=None, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) makedirs_mock.assert_called_once_with(os.path.join('foo', 'bar') + os.sep)
def cmd_output(*cmd, **kwargs): retcode = kwargs.pop('retcode', 0) encoding = kwargs.pop('encoding', 'UTF-8') popen_kwargs = { 'stdin': subprocess.PIPE, 'stdout': subprocess.PIPE, 'stderr': subprocess.PIPE, } # py2/py3 on windows are more strict about the types here cmd = tuple(five.n(arg) for arg in cmd) kwargs['env'] = { five.n(key): five.n(value) for key, value in kwargs.pop('env', {}).items() } or None try: cmd = parse_shebang.normalize_cmd(cmd) except parse_shebang.ExecutableNotFoundError as e: returncode, stdout, stderr = e.to_output() else: popen_kwargs.update(kwargs) proc = subprocess.Popen(cmd, **popen_kwargs) stdout, stderr = proc.communicate() returncode = proc.returncode if encoding is not None and stdout is not None: stdout = stdout.decode(encoding) if encoding is not None and stderr is not None: stderr = stderr.decode(encoding) if retcode is not None and retcode != returncode: raise CalledProcessError( returncode, cmd, retcode, output=(stdout, stderr), ) return returncode, stdout, stderr
def parse_bytesio(bytesio): """Parse the shebang from a file opened for reading binary.""" if bytesio.read(2) != b'#!': return () first_line = bytesio.readline() try: first_line = first_line.decode('US-ASCII') except UnicodeDecodeError: return () # Require only printable ascii for c in first_line: if c not in printable: return () # shlex.split is horribly broken in py26 on text strings cmd = tuple(shlex.split(five.n(first_line))) if cmd[0] == '/usr/bin/env': cmd = cmd[1:] return cmd