Split up too-long line.
[cvs2svn.git] / cvs2svn_lib / process.py
blob112935a36f602e33c80b96f8e13ff599823fe470
1 # (Be in -*- python -*- mode.)
3 # ====================================================================
4 # Copyright (c) 2000-2008 CollabNet. All rights reserved.
6 # This software is licensed as described in the file COPYING, which
7 # you should have received as part of this distribution. The terms
8 # are also available at http://subversion.tigris.org/license-1.html.
9 # If newer versions of this license are posted there, you may use a
10 # newer version instead, at your option.
12 # This software consists of voluntary contributions made by many
13 # individuals. For exact contribution history, see the revision
14 # history and logs, available at http://cvs2svn.tigris.org/.
15 # ====================================================================
17 """This module contains generic utilities used by cvs2svn."""
20 import subprocess
22 from cvs2svn_lib.common import FatalError
23 from cvs2svn_lib.common import CommandError
26 def call_command(command, **kw):
27 """Call the specified command, checking that it exits successfully.
29 Raise a FatalError if the command cannot be executed, or if it exits
30 with a non-zero exit code. Pass KW as keyword arguments to
31 subprocess.call()."""
33 try:
34 retcode = subprocess.call(command, **kw)
35 if retcode < 0:
36 raise FatalError(
37 'Command terminated by signal %d: "%s"'
38 % (-retcode, ' '.join(command),)
40 elif retcode > 0:
41 raise FatalError(
42 'Command failed with return code %d: "%s"'
43 % (retcode, ' '.join(command),)
45 except OSError, e:
46 raise FatalError(
47 'Command execution failed (%s): "%s"'
48 % (e, ' '.join(command),)
52 class CommandFailedException(Exception):
53 """Exception raised if check_command_runs() fails."""
55 pass
58 def check_command_runs(cmd, cmdname):
59 """Check whether the command CMD can be executed without errors.
61 CMD is a list or string, as accepted by subprocess.Popen(). CMDNAME
62 is the name of the command as it should be included in exception
63 error messages.
65 This function checks three things: (1) the command can be run
66 without throwing an OSError; (2) it exits with status=0; (3) it
67 doesn't output anything to stderr. If any of these conditions is
68 not met, raise a CommandFailedException describing the problem."""
70 try:
71 pipe = subprocess.Popen(
72 cmd,
73 stdin=subprocess.PIPE,
74 stdout=subprocess.PIPE,
75 stderr=subprocess.PIPE,
77 except OSError, e:
78 raise CommandFailedException('error executing %s: %s' % (cmdname, e,))
79 pipe.stdin.close()
80 pipe.stdout.read()
81 errmsg = pipe.stderr.read()
82 status = pipe.wait()
83 if status or errmsg:
84 msg = 'error executing %s: status %s' % (cmdname, status,)
85 if errmsg:
86 msg += ', error output:\n%s' % (errmsg,)
87 raise CommandFailedException(msg)
90 def get_command_output(command):
91 """Run COMMAND and return its stdout.
93 COMMAND is a list of strings. Run the command and return its stdout
94 as a string. If the command exits with a nonzero return code or
95 writes something to stderr, raise a CommandError."""
97 """A file-like object from which revision contents can be read."""
99 pipe = subprocess.Popen(
100 command,
101 stdin=subprocess.PIPE,
102 stdout=subprocess.PIPE,
103 stderr=subprocess.PIPE,
105 (stdout, stderr) = pipe.communicate()
106 if pipe.returncode or stderr:
107 raise CommandError(' '.join(command), pipe.returncode, stderr)
108 return stdout