@@ -52,10 +52,18 @@ public class PerforceOptions implements Option {
5252 @ Parameter (
5353 names = "--perforce-password" ,
5454 description =
55- "Perforce password or login ticket. Defaults to the P4PASSWD environment variable. If "
56- + " empty, an existing ticket from 'p4 login' is used ." )
55+ "Perforce password. Exchanged for a ticket via login . Defaults to the P4PASSWD"
56+ + " environment variable. Ignored if a token is provided ." )
5757 String password = null ;
5858
59+ @ Parameter (
60+ names = "--perforce-token" ,
61+ description =
62+ "Perforce login ticket to authenticate with directly (as issued by 'p4 login -p'),"
63+ + " instead of exchanging a password. Defaults to the P4TICKET environment variable."
64+ + " Takes precedence over --perforce-password." )
65+ String token = null ;
66+
5967 // Lazily created and cached: a migration only ever talks to one server.
6068 @ Nullable private PerforceServer cachedServer ;
6169
@@ -74,6 +82,7 @@ public PerforceServer server() throws RepoException, ValidationException {
7482 private IOptionsServer connect () throws RepoException , ValidationException {
7583 String resolvedPort = firstNonEmpty (port , env ("P4PORT" ));
7684 String resolvedUser = firstNonEmpty (user , env ("P4USER" ));
85+ String resolvedToken = firstNonEmpty (token , env ("P4TICKET" ));
7786 String resolvedPassword = firstNonEmpty (password , env ("P4PASSWD" ));
7887
7988 if (Strings .isNullOrEmpty (resolvedPort )) {
@@ -87,7 +96,10 @@ private IOptionsServer connect() throws RepoException, ValidationException {
8796 if (!Strings .isNullOrEmpty (resolvedUser )) {
8897 server .setUserName (resolvedUser );
8998 }
90- if (!Strings .isNullOrEmpty (resolvedPassword )) {
99+ if (!Strings .isNullOrEmpty (resolvedToken )) {
100+ // A pre-issued ticket: use it directly, no password-for-ticket exchange.
101+ server .setAuthTicket (resolvedToken );
102+ } else if (!Strings .isNullOrEmpty (resolvedPassword )) {
91103 server .login (resolvedPassword );
92104 }
93105 return server ;
0 commit comments