2 years agoreg_smith voted up review 29680 (revision 1) for perforce-software-sdp:dev | ||
Add a comment | ||
8 years agoreg_smith modified job000607 for p4perl: P4Perl P4::MergeData::RunMergeTool, quote filename arguments to protect from shell metacharacters Also Perforce internal job088679 has been l...ogged against p4api. Using P4Perl to do a merge that uses P4::MergeData::RunMergeTool to call out to a bash script as the merge tool. On Linux, if filenames have the shell metacharacter "(" in their names it causes bash to fail with "h: -c: line 0: syntax error near unexpected token `(' " Other shell metacharacters would likely cause issues as well. This is expected shell behaviour and you would normally either quote a filename that contains metacharacters or escape the metacharacters. For "(" it works on windows as "(" isn't a windows cmd shell metacharacter. Quoting the arguments passed from RunMergeTool should escape the special meaning of any shell metacharacters. It doesn't seem to be a P4Perl problem directly; invoking P4::MergeData::RunMergeTool, the control is handed over to the native P4.so. Somewhere in P4.so, there's probably a call like system("mergeTool BASE THEIRS YOURS MERGED"). Perhaps that could be adjusted to allow for special characters especially in the parameters. Currently filename args are quoted if they contain spaces which appears to be referred to in the C api that P4Perl interfaces with: https://www.perforce.com/perforce/doc.current/manuals/p4api/index.html include\p4\runcmd.h has the following commends on line 67/68: * NT: quote with " all args, and use CreateProcess() * UNIX: quote with ' args with spaces, and use system() « | ||
8 years agoreg_smith created job000607 for p4perl: P4Perl P4::MergeData::RunMergeTool, quote filename arguments to protect from shell metacharacters Using P4Perl to do a merge that uses P4::MergeDat...a::RunMergeTool to call out to a bash script as the merge tool. On Linux, if filenames have the shell metacharacter "(" in their names it causes bash to fail with "h: -c: line 0: syntax error near unexpected token `(' " Other shell metacharacters would likely cause issues as well. This is expected shell behaviour and you would normally either quote a filename that contains metacharacters or escape the metacharacters. For "(" it works on windows as "(" isn't a windows cmd shell metacharacter. Quoting the arguments passed from RunMergeTool should escape the special meaning of any shell metacharacters. It doesn't seem to be a P4Perl problem directly; invoking P4::MergeData::RunMergeTool, the control is handed over to the native P4.so. Somewhere in P4.so, there's probably a call like system("mergeTool BASE THEIRS YOURS MERGED"). Perhaps that could be adjusted to allow for special characters especially in the parameters. Currently filename args are quoted if they contain spaces which appears to be referred to in the C api that P4Perl interfaces with: https://www.perforce.com/perforce/doc.current/manuals/p4api/index.html include\p4\runcmd.h has the following commends on line 67/68: * NT: quote with " all args, and use CreateProcess() * UNIX: quote with ' args with spaces, and use system() « | ||
9 years agoreg_smith modified job000369 for perforce-software-p4api-net: Ticket in credential is incorrect if user specifies the host name and Display ticket as options for the login command If you specify the host name... in the login options, the credential object appears corrupt as it returns the status message instead of the ticket hash string. Expecting credential object to contain something like 5C484026EF62D950871920709EF0D3E9 but cred.Ticket value actually contains the status message “Success: Password verified.” if host name is specified This is because you specify the host name in the login options, you do not need to do this to log in on the local machine. If you do not pass a machine name, it works correctly From support case 194203. Also mirrored in p4prod under https://swarm.perforce.com/jobs/job080984 and Jira under https://jira.perforce.com:8443/browse/P4APINET-326 « | ||
9 years agoreg_smith modified job000369 for perforce-software-p4api-net: The credential object is corrupt at least for one Login() method override where it returns the status message instead of the ticket hash string. ... Also mirrored in p4prod under https://swarm.perforce.com/jobs/job080984 and Jira under https://jira.perforce.com:8443/browse/P4APINET-326 From case 194203: Credential object is corrupted and totally useless because its property Ticket holds the status message of the ticket instead of the ticket hash string {"Ticket":"Success: Internal password verified.","Expires":"9999-12-31T23:59:59.9999999"} We recompiled your API with a temporary fix, file is attached (this is available here: https://jira.perforce.com:8443/secure/attachment/17184/Connection.cs The fix is at line 726, we basically did the same thing than line 930 which allows us to do this : Options opts = new Options(LoginCmdFlags.DisplayTicket, null); _credential = _connection.Login(password, opts, null); _connection.Credential = _credential; « | ||
9 years agoreg_smith modified job000369 for perforce-software-p4api-net: The credential object is corrupt at least for one Login() method override where it returns the status message instead of the ticket hash string. ... Also mirrored in p4prod under https://swarm.perforce.com/jobs/job080984 and Jira under https://jira.perforce.com:8443/browse/P4APINET-326 From case 194203: Credential object is corrupted and totally useless because its property Ticket holds the status message of the ticket instead of the ticket hash string {"Ticket":"Success: Internal password verified.","Expires":"9999-12-31T23:59:59.9999999"} We recompiled your API with a temporary fix, file is attached (see Connection.cs, will upload). The fix is at line 726, we basically did the same thing than line 930 which allows us to do this : Options opts = new Options(LoginCmdFlags.DisplayTicket, null); _credential = _connection.Login(password, opts, null); _connection.Credential = _credential; « | ||
9 years agoreg_smith modified job000369 for perforce-software-p4api-net: Also mirrored in p4prod under https://swarm.perforce.com/jobs/job080984 and Jira under https://jira.perforce.com:8443/browse/P4APINET-326 The cre...dential object is corrupt at least for one Login() method override where it returns the status message instead of the ticket hash string. From case 194203: Credential object is corrupted and totally useless because its property Ticket holds the status message of the ticket instead of the ticket hash string {"Ticket":"Success: Internal password verified.","Expires":"9999-12-31T23:59:59.9999999"} We recompiled your API with a temporary fix, file is attached (see Connection.cs, will upload). The fix is at line 726, we basically did the same thing than line 930 which allows us to do this : Options opts = new Options(LoginCmdFlags.DisplayTicket, null); _credential = _connection.Login(password, opts, null); _connection.Credential = _credential; « | ||
9 years agoreg_smith modified job000369 for perforce-software-p4api-net: Also mirrored in p4prod under https://swarm.perforce.com/jobs/ and Jira under https://jira.perforce.com:8443/browse/P4APINET-326 The credential o...bject is corrupt at least for one Login() method override where it returns the status message instead of the ticket hash string. From case 194203: Credential object is corrupted and totally useless because its property Ticket holds the status message of the ticket instead of the ticket hash string {"Ticket":"Success: Internal password verified.","Expires":"9999-12-31T23:59:59.9999999"} We recompiled your API with a temporary fix, file is attached (see Connection.cs, will upload). The fix is at line 726, we basically did the same thing than line 930 which allows us to do this : Options opts = new Options(LoginCmdFlags.DisplayTicket, null); _credential = _connection.Login(password, opts, null); _connection.Credential = _credential; « | ||
9 years agoreg_smith created job000369 for perforce-software-p4api-net: Also mirrored in p4prod under job080984 The credential object is corrupt at least for one Login() method override where it returns the status message... instead of the ticket hash string. From case 194203: Credential object is corrupted and totally useless because its property Ticket holds the status message of the ticket instead of the ticket hash string {"Ticket":"Success: Internal password verified.","Expires":"9999-12-31T23:59:59.9999999"} We recompiled your API with a temporary fix, file is attached (see Connection.cs, will upload). The fix is at line 726, we basically did the same thing than line 930 which allows us to do this : Options opts = new Options(LoginCmdFlags.DisplayTicket, null); _credential = _connection.Login(password, opts, null); _connection.Credential = _credential; « | ||
10 years agoreg_smith modified job000222 for Allow capture internally of the error from a failed $p4->connect() rather than going to scripts STDERR on terminal (cross referenced to https://...swarm.perforce.com/jobs/job078669 If a call to $p4->connect fails: $p4->Connect() or die( "Failed to connect to Perforce Server" ); ..Connect() spits out an error message with a helpful hint to check P4PORT e.g. Connect to server failed; check $P4PORT. TCP connect to p4test11:1666 failed. How can this message be intercept and have it in say $p4->Errors (or anywhere else in the script such a variable) and not to the terminal stderr output)? Redefining the STDERR handle to point to a variable for example in the script doesn't capture it, it still goes to the terminal. For example something like this doesn't populate $stderr do { local *STDERR; # redirect STDERR to variable open(STDERR, ">", \$stderr) or die "Can't open STDERR: $!"; eval { $p4->Connect() or die "Error connecting $!" ; } if($@){ print "\$@ = $@"; print "strerr var = $stderr \n"; } } Wrapping the $p4->Connect in an eval block doesn't capture the useful message about checking the port to $! - that's still printed to STDERR on the terminal. eval { $p4->Connect() or die "Error connecting $!" ; }; if($@){ # Do something before bailing out print $@ ; }; A real kludge would be to redirect the script stderr to a temp file and read that in (YUK!). « | ||
10 years agoreg_smith modified job000222 for Allow capture internally of the error from a failed $p4->connect() rather than going to scripts STDERR on terminal (cross referenced to https://...swarm.perforce.com/jobs/job078669 If a call to $p4->connect fails: $p4->Connect() or die( "Failed to connect to Perforce Server" ); ..Connect() spits out an error message with a helpful hint to check P4PORT e.g. Connect to server failed; check $P4PORT. TCP connect to p4test11:1666 failed. How can this message be intercept and have it in say $p4->Errors (or anywhere else in the script such a variable) and not to the terminal stderr output)? Redefining the STDERR handle to point to a variable for example in the script doesn't capture it, it still goes to the terminal. For example something like this doesn't populate $stderr do { local *STDERR; # redirect STDERR to variable open(STDERR, ">", \$stderr) or die "Can't open STDERR: $!"; eval { $p4->Connect() or die "Error connecting $!" ; } if($@){ print "\$@ = $@"; print "strerr var = $stderr \n"; } } Wrapping the $p4->Connect in an eval block doesn't capture the useful message about checking the port - that's still printed to STDERR on the terminal. eval { $p4->Connect() or die "Error connecting $!" ; }; if($@){ # Do something before bailing out print $@ ; }; A real kludge would be to redirect the script stderr to a temp file and read that in (YUK!). « | ||
10 years agoreg_smith modified job000222 for Allow capture internally of the error from a failed $p4->connect() rather than going to scripts STDERR on terminal If a call to $p4->connect... fails: $p4->Connect() or die( "Failed to connect to Perforce Server" ); Cross referenced to https://swarm.perforce.com/jobs/job078669 ..Connect() spits out an error message with a helpful hint to check P4PORT e.g. Connect to server failed; check $P4PORT. TCP connect to p4test11:1666 failed. How can this message be intercept and have it in say $p4->Errors (or anywhere else in the script such a variable) and not to the terminal stderr output)? Redefining the STDERR handle to point to a variable for example in the script doesn't capture it, it still goes to the terminal. For example something like this doesn't populate $stderr do { local *STDERR; # redirect STDERR to variable open(STDERR, ">", \$stderr) or die "Can't open STDERR: $!"; eval { $p4->Connect() or die "Error connecting $!" ; } if($@){ print "\$@ = $@"; print "strerr var = $stderr \n"; } } Wrapping the $p4->Connect in an eval block doesn't capture the useful message about checking the port - that's still printed to STDERR on the terminal. eval { $p4->Connect() or die "Error connecting $!" ; }; if($@){ # Do something before bailing out print $@ ; }; A real kludge would be to redirect the script stderr to a temp file and read that in (YUK!). « | ||
10 years agoreg_smith modified job000222 for Allow capture internally of the error from a failed $p4->connect() rather than going to scripts STDERR on terminal If a call to $p4->connect... fails: $p4->Connect() or die( "Failed to connect to Perforce Server" ); Cross referenced to job078669 ..Connect() spits out an error message with a helpful hint to check P4PORT e.g. Connect to server failed; check $P4PORT. TCP connect to p4test11:1666 failed. How can this message be intercept and have it in say $p4->Errors (or anywhere else in the script such a variable) and not to the terminal stderr output)? Redefining the STDERR handle to point to a variable for example in the script doesn't capture it, it still goes to the terminal. For example something like this doesn't populate $stderr do { local *STDERR; # redirect STDERR to variable open(STDERR, ">", \$stderr) or die "Can't open STDERR: $!"; eval { $p4->Connect() or die "Error connecting $!" ; } if($@){ print "\$@ = $@"; print "strerr var = $stderr \n"; } } Wrapping the $p4->Connect in an eval block doesn't capture the useful message about checking the port - that's still printed to STDERR on the terminal. eval { $p4->Connect() or die "Error connecting $!" ; }; if($@){ # Do something before bailing out print $@ ; }; A real kludge would be to redirect the script stderr to a temp file and read that in (YUK!). « | ||
10 years agoreg_smith created job000222 for Allow capture internally of the error from a failed $p4->connect() rather than going to scripts STDERR on terminal If a call to $p4->connect... fails: $p4->Connect() or die( "Failed to connect to Perforce Server" ); ..Connect() spits out an error message with a helpful hint to check P4PORT e.g. Connect to server failed; check $P4PORT. TCP connect to p4test11:1666 failed. How can this message be intercept and have it in say $p4->Errors (or anywhere else in the script such a variable) and not to the terminal stderr output)? Redefining the STDERR handle to point to a variable for example in the script doesn't capture it, it still goes to the terminal. For example something like this doesn't populate $stderr do { local *STDERR; # redirect STDERR to variable open(STDERR, ">", \$stderr) or die "Can't open STDERR: $!"; eval { $p4->Connect() or die "Error connecting $!" ; } if($@){ print "\$@ = $@"; print "strerr var = $stderr \n"; } } Wrapping the $p4->Connect in an eval block doesn't capture the useful message about checking the port - that's still printed to STDERR on the terminal. eval { $p4->Connect() or die "Error connecting $!" ; }; if($@){ # Do something before bailing out print $@ ; }; A real kludge would be to redirect the script stderr to a temp file and read that in (YUK!). « | ||
10 years agoreg_smith modified job000161 for Calling a p4 diff2 command using P4Perl $p4->RunDiff2 against a depot path that contains a file that has been renamed/integrated/renamed again retu...rns the data structure in an unexpectedly different format. (referenced on p4prod:1666 by https://swarm.perforce.com/jobs/job077621 - In the case with no rename/integrate/rename, the hash values for the keys for rev,type and depotFile are strings as expected. - In the rename case the values are an array ref with 3 elements; the first 2 are empty and the last element is the expected value. It is specific to the case where the untagged output from diff2 contains <none> on the left hand side e.g.: ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === In my testing I renamed a file from Q.h to R.h on my //jam/main/src branch, and merge/copied the changes to //jam/rel2.3/src and then renamed the file from R.h to S.h on //jam/rel2.3/src. i.e. 1. rename //jam/main/src/Q.h to //jam/main/src/R.h 2. integrate //jam/main/src/R.h to //jam/rel2.3/src (so we have added //jam/rel2.3/src/R.h) 3. rename //jam/rel2.3/src/R.h to //jam/rel2.3/src/S.h The raw output from "p4 diff2 -S //jam/dev2.3" reports <none> for the left hand file and the right hand file name is the old file name R.h before the rename to S.h on //jam/rel2.3/src/ p4 diff2 -S //jam/dev2.3 -q ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === The tagged output from "p4 -ztag diff2 -S //jam/dev2.3 -q" appears sensible: ... status right only ... depotFile2 //jam/main/src/R.h ... rev2 1 ... type2 text ... status left only ... depotFile //jam/dev2.3/src/S.h ... rev 1 ... type text ..but if we execute the same command using $p4->RunDiff2, for the 'right only' entry, we get array refs for rev,type and depotfile with the first 2 out of 3 elements empty (rather than the values being strings for the case without a rename) $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); print Dumper($diff2); [ { status => 'right only', rev => [ <<< rev value is array ref undef, <<< empty undef, <<< empty '1' ], type => [ <<< type is array ref undef, <<< empty undef, <<< empty 'text' ], depotFile => [ <<< depotFile is array ref undef, <<< empty undef, <<< empty '//jam/main/src/R.h' ] }, { status => 'left only', <<< this is "normal" with rev,type,depotFile keys having string values rev => '1', type => 'text', depotFile => '//jam/dev2.3/src/S.h' } ] If we set tagged to off with $p4->Tagged(0) the output appears much like the raw p4 equivalent; [ '==== <none> - //jam/main/src/R.h#1 ====', '==== //jam/dev2.3/src/S.h#1 - <none> ===' ] So the information is there but you'd have to check if rev,type and depotfile are array refs to get to them in this case. Test script follows: ##### Start of test script use P4; use Data::Dumper; my $p4 = new P4; $p4->SetClient( $clientname ); $p4->SetPort ( $p4port ); $p4->SetPassword( $p4password ); $p4->Connect() or die( "Failed to connect to Perforce Server" ); $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys=0; # Turn off tagging #$p4->Tagged( 0 ); # disabled # Execute diff2 $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); # Check command execution for errors (defined as sub) checkifError(); # Print out data structure print Dumper($diff2); # Check for execution for errors sub checkifError { if( $p4->ErrorCount() || $p4->WarningCount() ) { print "P4 Errors:\n\n" . $p4->Errors() . "\n" if $p4->ErrorCount(); print "P4 Warnings:\n\n" . $p4->Warnings() . "\n" if $p4->WarningCount(); $p4->Disconnect(); print "Exiting on P4 error!\n"; exit; } } ##### End of test script « | ||
10 years agoreg_smith modified job000161 for Calling a p4 diff2 command using P4Perl $p4->RunDiff2 against a depot path that contains a file that has been renamed/integrated/renamed again retu...rns the data structure in an unexpectedly different format. (referenced on p4prod:1666 by job077621) - In the case with no rename/integrate/rename, the hash values for the keys for rev,type and depotFile are strings as expected. - In the rename case the values are an array ref with 3 elements; the first 2 are empty and the last element is the expected value. It is specific to the case where the untagged output from diff2 contains <none> on the left hand side e.g.: ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === In my testing I renamed a file from Q.h to R.h on my //jam/main/src branch, and merge/copied the changes to //jam/rel2.3/src and then renamed the file from R.h to S.h on //jam/rel2.3/src. i.e. 1. rename //jam/main/src/Q.h to //jam/main/src/R.h 2. integrate //jam/main/src/R.h to //jam/rel2.3/src (so we have added //jam/rel2.3/src/R.h) 3. rename //jam/rel2.3/src/R.h to //jam/rel2.3/src/S.h The raw output from "p4 diff2 -S //jam/dev2.3" reports <none> for the left hand file and the right hand file name is the old file name R.h before the rename to S.h on //jam/rel2.3/src/ p4 diff2 -S //jam/dev2.3 -q ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === The tagged output from "p4 -ztag diff2 -S //jam/dev2.3 -q" appears sensible: ... status right only ... depotFile2 //jam/main/src/R.h ... rev2 1 ... type2 text ... status left only ... depotFile //jam/dev2.3/src/S.h ... rev 1 ... type text ..but if we execute the same command using $p4->RunDiff2, for the 'right only' entry, we get array refs for rev,type and depotfile with the first 2 out of 3 elements empty (rather than the values being strings for the case without a rename) $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); print Dumper($diff2); [ { status => 'right only', rev => [ <<< rev value is array ref undef, <<< empty undef, <<< empty '1' ], type => [ <<< type is array ref undef, <<< empty undef, <<< empty 'text' ], depotFile => [ <<< depotFile is array ref undef, <<< empty undef, <<< empty '//jam/main/src/R.h' ] }, { status => 'left only', <<< this is "normal" with rev,type,depotFile keys having string values rev => '1', type => 'text', depotFile => '//jam/dev2.3/src/S.h' } ] If we set tagged to off with $p4->Tagged(0) the output appears much like the raw p4 equivalent; [ '==== <none> - //jam/main/src/R.h#1 ====', '==== //jam/dev2.3/src/S.h#1 - <none> ===' ] So the information is there but you'd have to check if rev,type and depotfile are array refs to get to them in this case. Test script follows: ##### Start of test script use P4; use Data::Dumper; my $p4 = new P4; $p4->SetClient( $clientname ); $p4->SetPort ( $p4port ); $p4->SetPassword( $p4password ); $p4->Connect() or die( "Failed to connect to Perforce Server" ); $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys=0; # Turn off tagging #$p4->Tagged( 0 ); # disabled # Execute diff2 $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); # Check command execution for errors (defined as sub) checkifError(); # Print out data structure print Dumper($diff2); # Check for execution for errors sub checkifError { if( $p4->ErrorCount() || $p4->WarningCount() ) { print "P4 Errors:\n\n" . $p4->Errors() . "\n" if $p4->ErrorCount(); print "P4 Warnings:\n\n" . $p4->Warnings() . "\n" if $p4->WarningCount(); $p4->Disconnect(); print "Exiting on P4 error!\n"; exit; } } ##### End of test script « | ||
10 years agoreg_smith modified job000161 for Calling a p4 diff2 command using P4Perl $p4->RunDiff2 against a depot path that contains a file that has been renamed/integrated/renamed again retu...rns the data structure in an unexpectedly different data structure. (referenced on p4prod:1666 by job077621) - In the case with no rename/integrate/rename, the hash values for the keys for rev,type and depotFile are strings as expected. - In the rename case the values are an array ref with 3 elements; the first 2 are empty and the last element is the expected value. It is specific to the case where the untagged output from diff2 contains <none> on the left hand side e.g.: ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === In my testing I renamed a file from Q.h to R.h on my //jam/main/src branch, and merge/copied the changes to //jam/rel2.3/src and then renamed the file from R.h to S.h on //jam/rel2.3/src. i.e. 1. rename //jam/main/src/Q.h to //jam/main/src/R.h 2. integrate //jam/main/src/R.h to //jam/rel2.3/src (so we have added //jam/rel2.3/src/R.h) 3. rename //jam/rel2.3/src/R.h to //jam/rel2.3/src/S.h The raw output from "p4 diff2 -S //jam/dev2.3" reports <none> for the left hand file and the right hand file name is the old file name R.h before the rename to S.h on //jam/rel2.3/src/ p4 diff2 -S //jam/dev2.3 -q ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === The tagged output from "p4 -ztag diff2 -S //jam/dev2.3 -q" appears sensible: ... status right only ... depotFile2 //jam/main/src/R.h ... rev2 1 ... type2 text ... status left only ... depotFile //jam/dev2.3/src/S.h ... rev 1 ... type text ..but if we execute the same command using $p4->RunDiff2, for the 'right only' entry, we get array refs for rev,type and depotfile with the first 2 out of 3 elements empty (rather than the values being strings for the case without a rename) $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); print Dumper($diff2); [ { status => 'right only', rev => [ <<< rev value is array ref undef, <<< empty undef, <<< empty '1' ], type => [ <<< type is array ref undef, <<< empty undef, <<< empty 'text' ], depotFile => [ <<< depotFile is array ref undef, <<< empty undef, <<< empty '//jam/main/src/R.h' ] }, { status => 'left only', <<< this is "normal" with rev,type,depotFile keys having string values rev => '1', type => 'text', depotFile => '//jam/dev2.3/src/S.h' } ] If we set tagged to off with $p4->Tagged(0) the output appears much like the raw p4 equivalent; [ '==== <none> - //jam/main/src/R.h#1 ====', '==== //jam/dev2.3/src/S.h#1 - <none> ===' ] So the information is there but you'd have to check if rev,type and depotfile are array refs to get to them in this case. Test script follows: ##### Start of test script use P4; use Data::Dumper; my $p4 = new P4; $p4->SetClient( $clientname ); $p4->SetPort ( $p4port ); $p4->SetPassword( $p4password ); $p4->Connect() or die( "Failed to connect to Perforce Server" ); $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys=0; # Turn off tagging #$p4->Tagged( 0 ); # disabled # Execute diff2 $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); # Check command execution for errors (defined as sub) checkifError(); # Print out data structure print Dumper($diff2); # Check for execution for errors sub checkifError { if( $p4->ErrorCount() || $p4->WarningCount() ) { print "P4 Errors:\n\n" . $p4->Errors() . "\n" if $p4->ErrorCount(); print "P4 Warnings:\n\n" . $p4->Warnings() . "\n" if $p4->WarningCount(); $p4->Disconnect(); print "Exiting on P4 error!\n"; exit; } } ##### End of test script « | ||
10 years agoreg_smith modified job000161 for Calling a p4 diff2 command using P4Perl $p4->RunDiff2 against a depot path that contains a file that has been renamed/integrated/renamed again retu...rns the data structure in an unexpectedly different data structure. (referenced on p4prod:1666 by job077621) - In the case with no rename/integrate/rename, the hash values for the keys for rev,type and depotFile are strings as expected. - In the rename case the values are an array ref with 3 elements; the first 2 are empty and the last element is the expected value. It is specific to the case where the untagged output from diff2 contains <none> on the left hand side e.g.: ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === In my testing I renamed a file from Q.h to R.h on my //jam/main/src branch, and merge/copied the changes to //jam/rel2.3/src and then renamed the file from R.h to S.h on //jam/rel2.3/src. i.e. 1. rename //jam/main/src/Q.h to //jam/main/src/R.h 2. integrate //jam/main/src/R.h to //jam/rel2.3/src (so we have added //jam/rel2.3/src/R.h) 3. rename //jam/rel2.3/src/R.h to //jam/rel2.3/src/S.h The raw output from "p4 diff2 -S //jam/dev2.3" reports <none> for the left hand file and the right hand file name is the old file name R.h before the rename to S.h on //jam/rel2.3/src/ p4 diff2 -S //jam/dev2.3 -q ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === The tagged output from "p4 -ztag diff2 -S //jam/dev2.3 -q" appears sensible: ... status right only ... depotFile2 //jam/main/src/R.h ... rev2 1 ... type2 text ... status left only ... depotFile //jam/dev2.3/src/S.h ... rev 1 ... type text ..but if we execute the same command using $p4->RunDiff2, for the 'right only' entry, we get array refs for rev,type and depotfile with the first 2 out of 3 elements empty (rather than the values being strings for the case without a rename) $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); print Dumper($diff2); [ { status => 'right only', rev => [ <<< rev value is array ref undef, <<< empty undef, <<< empty '1' ], type => [ <<< type is array ref undef, <<< empty undef, <<< empty 'text' ], depotFile => [ <<< depotFile is array ref undef, <<< empty undef, <<< empty '//jam/main/src/R.h' ] }, { status => 'left only', <<< this is "normal" with rev,type,depotFile keys having string values rev => '1', type => 'text', depotFile => '//jam/dev2.3/src/S.h' } ] If we set tagged to off with $p4->Tagged(0) the output appears much like the raw p4 equivalent; [ '==== <none> - //jam/main/src/R.h#1 ====', '==== //jam/dev2.3/src/S.h#1 - <none> ===' ] So the information is there but you'd have to check if rev,type and depotfile are array refs to get to them in this case. Test script follows: ##### Start of test script use P4; use Data::Dumper; my $p4 = new P4; $p4->SetClient( $clientname ); $p4->SetPort ( $p4port ); $p4->SetPassword( $p4password ); $p4->Connect() or die( "Failed to connect to Perforce Server" ); $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys=0; # Turn off tagging #$p4->Tagged( 0 ); # disabled # Execute diff2 $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); # Check command execution for errors (defined as sub) checkifError(); # Print out data structure print Dumper($diff2); # Check for execution for errors sub checkifError { if( $p4->ErrorCount() || $p4->WarningCount() ) { print "P4 Errors:\n\n" . $p4->Errors() . "\n" if $p4->ErrorCount(); print "P4 Warnings:\n\n" . $p4->Warnings() . "\n" if $p4->WarningCount(); $p4->Disconnect(); print "Exiting on P4 error!\n"; exit; } } ##### End of test script « | ||
10 years agoreg_smith created job000161 for Calling a p4 diff2 command using P4Perl $p4->RunDiff2 against a depot path that contains a file that has been renamed/integrated/renamed again retu...rns the data structure in an unexpectedly different data structure. - In the case with no rename/integrate/rename, the hash values for the keys for rev,type and depotFile are strings as expected. - In the rename case the values are an array ref with 3 elements; the first 2 are empty and the last element is the expected value. It is specific to the case where the untagged output from diff2 contains <none> on the left hand side e.g.: ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === In my testing I renamed a file from Q.h to R.h on my //jam/main/src branch, and merge/copied the changes to //jam/rel2.3/src and then renamed the file from R.h to S.h on //jam/rel2.3/src. i.e. 1. rename //jam/main/src/Q.h to //jam/main/src/R.h 2. integrate //jam/main/src/R.h to //jam/rel2.3/src (so we have added //jam/rel2.3/src/R.h) 3. rename //jam/rel2.3/src/R.h to //jam/rel2.3/src/S.h The raw output from "p4 diff2 -S //jam/dev2.3" reports <none> for the left hand file and the right hand file name is the old file name R.h before the rename to S.h on //jam/rel2.3/src/ p4 diff2 -S //jam/dev2.3 -q ==== <none> - //jam/main/src/R.h#1 ==== ==== //jam/dev2.3/src/S.h#1 - <none> === The tagged output from "p4 -ztag diff2 -S //jam/dev2.3 -q" appears sensible: ... status right only ... depotFile2 //jam/main/src/R.h ... rev2 1 ... type2 text ... status left only ... depotFile //jam/dev2.3/src/S.h ... rev 1 ... type text ..but if we execute the same command using $p4->RunDiff2, for the 'right only' entry, we get array refs for rev,type and depotfile with the first 2 out of 3 elements empty (rather than the values being strings for the case without a rename) $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); print Dumper($diff2); [ { status => 'right only', rev => [ <<< rev value is array ref undef, <<< empty undef, <<< empty '1' ], type => [ <<< type is array ref undef, <<< empty undef, <<< empty 'text' ], depotFile => [ <<< depotFile is array ref undef, <<< empty undef, <<< empty '//jam/main/src/R.h' ] }, { status => 'left only', <<< this is "normal" with rev,type,depotFile keys having string values rev => '1', type => 'text', depotFile => '//jam/dev2.3/src/S.h' } ] If we set tagged to off with $p4->Tagged(0) the output appears much like the raw p4 equivalent; [ '==== <none> - //jam/main/src/R.h#1 ====', '==== //jam/dev2.3/src/S.h#1 - <none> ===' ] So the information is there but you'd have to check if rev,type and depotfile are array refs to get to them in this case. Test script follows: ##### Start of test script use P4; use Data::Dumper; my $p4 = new P4; $p4->SetClient( $clientname ); $p4->SetPort ( $p4port ); $p4->SetPassword( $p4password ); $p4->Connect() or die( "Failed to connect to Perforce Server" ); $Data::Dumper::Indent = 1; $Data::Dumper::Terse = 1; $Data::Dumper::Quotekeys=0; # Turn off tagging #$p4->Tagged( 0 ); # disabled # Execute diff2 $diff2=$p4->RunDiff2(-S => "//jam/dev2.3", '-q'); # Check command execution for errors (defined as sub) checkifError(); # Print out data structure print Dumper($diff2); # Check for execution for errors sub checkifError { if( $p4->ErrorCount() || $p4->WarningCount() ) { print "P4 Errors:\n\n" . $p4->Errors() . "\n" if $p4->ErrorCount(); print "P4 Warnings:\n\n" . $p4->Warnings() . "\n" if $p4->WarningCount(); $p4->Disconnect(); print "Exiting on P4 error!\n"; exit; } } ##### End of test script « | ||
Adjust when notifications are sent to you about reviews that you're associated with (as an author, reviewer, project member or moderator).