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."""
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
34 retcode
= subprocess
.call(command
, **kw
)
37 'Command terminated by signal %d: "%s"'
38 % (-retcode
, ' '.join(command
),)
42 'Command failed with return code %d: "%s"'
43 % (retcode
, ' '.join(command
),)
47 'Command execution failed (%s): "%s"'
48 % (e
, ' '.join(command
),)
52 class CommandFailedException(Exception):
53 """Exception raised if check_command_runs() fails."""
58 def check_command_runs(command
, commandname
):
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
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."""
71 pipe
= subprocess
.Popen(
73 stdin
=subprocess
.PIPE
,
74 stdout
=subprocess
.PIPE
,
75 stderr
=subprocess
.PIPE
,
78 raise CommandFailedException('error executing %s: %s' % (commandname
, e
,))
81 errmsg
= pipe
.stderr
.read()
84 msg
= 'error executing %s: status %s' % (commandname
, status
,)
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(
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
)