October 17, 2013

Simplify your P4 scripts with P4.Iterate

Traceability

Motivation

A typical use case for a P4 script is to process some or all spec objects such as client workspaces, labels or changes. For example, I might want to change the options of all existing client workspaces from normdir to rmdir. The workflow would then be:

  1. Retrieve some or all spec objects, here p4.run_clients()
  2. Iterate through the result
    1. Retrieve the name of the spec object via a key, here “client”
    2. Load the spec form for the name, p4.fetch_client()
    3. Modify the options in the form
    4. Save the form back to the Perforce Server

The operation to show some or all clients workspaces, “p4 clients”, does not contain all information about each client; views and options, for example, are missing. So I need to retrieve the spec form first.

The tricky part is 2a. For each spec the key is different and mostly inconsistent. Here is the full table (as of 2013.1):

Command to list all specs      Command to access one spec      Object key
p4 clients                     p4 client                       client
p4 labels 		       p4 label			       label
p4 branches 		       p4 branch 		       branch
p4 changes 		       p4 change                       change
p4 streams 		       p4 stream                       Stream
p4 jobs 		       p4 job 			       Job
p4 users  		       p4 user 			       User
p4 groups 		       p4 group 		       group
p4 depots 		       p4 depot 		       name
p4 servers 		       p4 server 		       Name

This makes writing generic scripts more difficult than necessary.

Solution

To solve the conundrum, I wrote a little extension called iterate_spec for P4Python, which knows the object name for each spec. With this extension, the operation becomes simpler:

      for client in p4.iterate_clients():
        client._options = clients._options.replace(“normdir”, “rmdir”)
        p4.save_client(client)

Not only did I not have to remember the key of each spec, I also saved one line of code which can only be a good thing.

P4.iterate is available for P4Python, P4Perl and P4Ruby from 2012.2 onwards. Try it out!

Happy hacking.