Skip to content

Commit 0ef67ac

Browse files
luked99gitster
authored andcommitted
git-p4: better error reporting when p4 fails
Currently when p4 fails to run, git-p4 just crashes with an obscure error message. For example, if the P4 ticket has expired, you get: Error: Cannot locate perforce checkout of <path> in client view This change checks whether git-p4 can talk to the Perforce server when the first P4 operation is attempted, and tries to print a meaningful error message if it fails. Signed-off-by: Luke Diamand <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b9d34db commit 0ef67ac

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

git-p4.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ def __str__(self):
5050
# Grab changes in blocks of this many revisions, unless otherwise requested
5151
defaultBlockSize = 512
5252

53+
p4_access_checked = False
54+
5355
def p4_build_cmd(cmd):
5456
"""Build a suitable p4 command line.
5557
@@ -91,6 +93,13 @@ def p4_build_cmd(cmd):
9193
real_cmd = ' '.join(real_cmd) + ' ' + cmd
9294
else:
9395
real_cmd += cmd
96+
97+
# now check that we can actually talk to the server
98+
global p4_access_checked
99+
if not p4_access_checked:
100+
p4_access_checked = True # suppress access checks in p4_check_access itself
101+
p4_check_access()
102+
94103
return real_cmd
95104

96105
def git_dir(path):
@@ -264,6 +273,52 @@ def p4_system(cmd):
264273
if retcode:
265274
raise CalledProcessError(retcode, real_cmd)
266275

276+
def die_bad_access(s):
277+
die("failure accessing depot: {0}".format(s.rstrip()))
278+
279+
def p4_check_access(min_expiration=1):
280+
""" Check if we can access Perforce - account still logged in
281+
"""
282+
results = p4CmdList(["login", "-s"])
283+
284+
if len(results) == 0:
285+
# should never get here: always get either some results, or a p4ExitCode
286+
assert("could not parse response from perforce")
287+
288+
result = results[0]
289+
290+
if 'p4ExitCode' in result:
291+
# p4 returned non-zero status, e.g. P4PORT invalid, or p4 not in path
292+
die_bad_access("could not run p4")
293+
294+
code = result.get("code")
295+
if not code:
296+
# we get here if we couldn't connect and there was nothing to unmarshal
297+
die_bad_access("could not connect")
298+
299+
elif code == "stat":
300+
expiry = result.get("TicketExpiration")
301+
if expiry:
302+
expiry = int(expiry)
303+
if expiry > min_expiration:
304+
# ok to carry on
305+
return
306+
else:
307+
die_bad_access("perforce ticket expires in {0} seconds".format(expiry))
308+
309+
else:
310+
# account without a timeout - all ok
311+
return
312+
313+
elif code == "error":
314+
data = result.get("data")
315+
if data:
316+
die_bad_access("p4 error: {0}".format(data))
317+
else:
318+
die_bad_access("unknown error")
319+
else:
320+
die_bad_access("unknown error code {0}".format(code))
321+
267322
_p4_version_string = None
268323
def p4_version_string():
269324
"""Read the version string, showing just the last line, which

t/t9833-errors.sh

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/bin/sh
2+
3+
test_description='git p4 errors'
4+
5+
. ./lib-git-p4.sh
6+
7+
test_expect_success 'start p4d' '
8+
start_p4d
9+
'
10+
11+
test_expect_success 'add p4 files' '
12+
(
13+
cd "$cli" &&
14+
echo file1 >file1 &&
15+
p4 add file1 &&
16+
p4 submit -d "file1"
17+
)
18+
'
19+
20+
# after this test, the default user requires a password
21+
test_expect_success 'error handling' '
22+
git p4 clone --dest="$git" //depot@all &&
23+
(
24+
cd "$git" &&
25+
P4PORT=: test_must_fail git p4 submit 2>errmsg
26+
) &&
27+
p4 passwd -P newpassword &&
28+
(
29+
P4PASSWD=badpassword test_must_fail git p4 clone //depot/foo 2>errmsg &&
30+
grep -q "failure accessing depot.*P4PASSWD" errmsg
31+
)
32+
'
33+
34+
test_expect_success 'ticket logged out' '
35+
P4TICKETS="$cli/tickets" &&
36+
echo "newpassword" | p4 login &&
37+
(
38+
cd "$git" &&
39+
test_commit "ticket-auth-check" &&
40+
p4 logout &&
41+
test_must_fail git p4 submit 2>errmsg &&
42+
grep -q "failure accessing depot" errmsg
43+
)
44+
'
45+
46+
test_expect_success 'create group with short ticket expiry' '
47+
P4TICKETS="$cli/tickets" &&
48+
echo "newpassword" | p4 login &&
49+
p4_add_user short_expiry_user &&
50+
p4 -u short_expiry_user passwd -P password &&
51+
p4 group -i <<-EOF &&
52+
Group: testgroup
53+
Timeout: 3
54+
Users: short_expiry_user
55+
EOF
56+
57+
p4 users | grep short_expiry_user
58+
'
59+
60+
test_expect_success 'git operation with expired ticket' '
61+
P4TICKETS="$cli/tickets" &&
62+
P4USER=short_expiry_user &&
63+
echo "password" | p4 login &&
64+
(
65+
cd "$git" &&
66+
git p4 sync &&
67+
sleep 5 &&
68+
test_must_fail git p4 sync 2>errmsg &&
69+
grep "failure accessing depot" errmsg
70+
)
71+
'
72+
73+
test_expect_success 'kill p4d' '
74+
kill_p4d
75+
'
76+
77+
78+
test_done

0 commit comments

Comments
 (0)