<html> <STYLE type="text/css"> H1 {border-width: 1; border: solid} </STYLE> <title>Scripting Column as of $Date: 2004/08/20 $</title> <h1><center>Monthly Scripting Column for January</center></h1> <table border=0 width="100%"> <tr><td width="70%"> <p>Greetings! This begins a series of bulletins, in which we introduce one of the scripts that will be in a future release. <td> <table border=1 width="100%"> <tr><td><i><font color="blue">Tip: Maybe it was there all along, but you needed the "-Ztag" decoder ring to actually see it?</font></i> </table> </tr> </table> <hr> <h2>Today's script</h2> <p>It's easy to sing the praises of shell scripts. <p>Sometimes, however, you need to store away or parse something for later in the same script. In Perl, with the Perforce API enabled, the parsing is easy. <p>As an example, we notice that sometimes people want to see the local pathname for their opened files. <bl> <li>The simplest option might be to invoke "p4 where" for each file - but the extra calls don't make sense. <li>It's useful to notice that "p4 -Ztag opened" returned many more fields than we're used to seeing. Each of those can be used, and the "clientFile" field is suspiciously close to what we need. </bl> <p>We introduce "p4opened.p4perl", which is another of a line of simple (and dumb, but helpful) scripts. This variant, below, is an example of P4Perl; the full source code is <a href="examples/p4opened.p4perl">here</a> and at the end of this page. <blockquote> Note for reading any code on this page: <font color="green">Green text</font> is what you'll cut/paste when you make your own P4Perl script. </blockquote> <p>Comments should indicate the flow: <ol><li> Get a list of opened files from 'p4 opened' (with tagged output) <li> For each of those files, print the clientFile field of the output. (Err, massage it first, mapping "//clientname" to the client root directory.) </ol> <hr> <h3>First step: Setting up P4 object</h3> <p> If you're using P4Perl, which is the Perforce hook for Perl, then you'll need to initialize your Perforce connection: <pre> <font color="green">use P4; my $p4 = new P4; $p4->ParseForms(); $p4->Init() or die "Failed to initialize 'p4' object!"; $p4->Tagged(); </font> </pre> <p> Note that we copy this block into most of our P4Perl programs. The other calls are handy because they foist the parsing off to someone else: <ol><li> The 'ParseForms' call make it easy to process any specs (client specs, etc),<li>and the 'Tagged' call makes it easy to process the 'opened' output. </ol> <h3>Second step: retrieving information from a client spec</h3> <p> Note how easy certain things are. "Retrieve a client spec" boils down to this: <pre> <font color="green">my $info = $p4->FetchClient();</font> $cl_name = $info->{"Client"}; $cl_root = $info->{"Root"}; </pre> <p> If we'd wanted to update it and stash it back into the database, we'd use a call to 'SaveClient'. <pre> <font color="green">my $info = $p4->FetchClient();</font> $cl_name = $info->{"Client"}; $info->{"Root"} = "/tmp/herman"; print "Setting root of $cl_name to $info->{'Root'}\n"; <font color="green">$ret = $p4->SaveClient($info);</font> </pre> <p> <h3>Third step: getting information about what's opened</h3> <p> We chose to run: <pre> <font color="green">@ret = $p4->Opened();</font> </pre> <p> This, in turn, runs "p4 opened". <p> From there, it's a matter of writing out the correct field from each filename returned in <tt>@ret</tt>. <hr> <center>Reminder: <font color="green">Green text</font> for P4Perl hooks.</center> <hr> <pre> # Task: output list of 'opened' files, using local pathnames. # # status: tested on Win/NT using perl 5.6 with p4perl API <font color="green"># num of calls to 'p4': 2</font> # room for optimization/improvement: add getopts call # # Copyright 2004 Perforce Corporation, Inc. All rights reserved. <font color="green">use P4; my $p4 = new P4; $p4->ParseForms(); $p4->Init() or die "Failed to initialize 'p4' object!"; $p4->Tagged();</font> #----------------------------------------------------------- # first call to P4: 'p4 client -o' # Note that it's easier to get the client root dir from # the 'client spec', hence the "FetchClient" call. #----------------------------------------------------------- <font color="green">my $info = $p4->FetchClient();</font> $cl_name = $info->{"Client"}; $cl_root = $info->{"Root"}; #----------------------------------------------------------- # second call to P4: 'p4 opened' #----------------------------------------------------------- <font color="green">@ret = $p4->Opened();</font> #----------------------------------------------------------- # Now, loop through the output of 'p4 opened'. The tagged # output gives us a client-syntax version of the name # in the form "//clientName/rest-of-local-path", # so we substitute the client root dir before printing. #----------------------------------------------------------- $oldtag = "//$cl_name"; foreach $h (@ret) { $localFile = $h->{'clientFile'}; $localFile =~ s/$oldtag/$cl_root/; print "$localFile\n"; } </pre> <hr> <small><p>Note: all the programs shown in these columns have been written four times: in Perl, in P4Perl, in Python, and in P4Ruby. Look into the Perforce example database for the other versions.</small> <i><small>$Id: //guest/jeff_bowles/scripts/0130p4perl.html#1 $ <br>© 2004 Perforce Corporation, Inc.</small></i> <br><em> </html>
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 4420 | Jeff Bowles |
adding the beginnings of example "columns" for scripting examples. |