June 21, 2010

Pending Integrations Preview Dashboard

Flexible Workflows

One of the duties of a branch curator (usually a senior developer or project manager) is periodically refreshing her branch with changes from an upstream branch. For example, if she is curating a development branch, she will need to periodically pick up changes from the MAIN or INTEGRATION branch.

When I've had this responsibility, I constantly looked for ways to remind myself to run the integrations frequently. I really wanted to see a list of pending integrations in a tool that I used every day. I've tried using widgets in wikis and intranets, scripts that sent pending integrations weekly via email, and a few other methods.

Now, with the 2010.1 beta release, there's a better way. Using the Perforce Javascript API (P4JsApi) (PDF), we can put our own tabs (applets) in P4V, which is the tool I always have open when I work in Perforce.

In order to create a Branch Curator's Dashboard, let's start by making a Pending Integrations tab (applet). This tab will show me, for each branch spec that I own, all pending integrations, using the forward and reverse view mapping. (I always use branch specs to manage integration activities.)

The source code and a README file with more complete installation instructions are available in the Public Depot. Here's a brief description of how the tab works.

  • Implement the tab The tab (applet) is implemented in a file called interchanges.html, which we check in as //depot/jsapi/interchanges.html. More on this file later; the name came from my hope that the undoc interchanges command would be available in P4JsApi.
  • Register the tab We create a centralsettings.js file that defines our tab as a P4V applet. We check in this file as //depot/jsapi/centralsettings.js. The relevant part of the file is:
    function settings(key) {
        if (key == "p4v_mainTabs")  {
            return ["p4:///files/depot/jsapi/interchanges.html"];
  • Enable the tab for a group We add a protections table entry specifying that the centralsettings.js file should be used for the group BranchCurators.G:
    list group BranchCurators.G centralsettings
    Of course, we could use any user or group here, and define different settings files for different users or groups. See the P4JsApi guide for more details.
  • Start using it We have our users enable applets in P4V, as described in the P4JsApi guide. After restarting P4V, the View menu has a new entry called Pending Integrations.Here's a screen shot of the tab in action in P4V.


    The interchanges.html implementation file uses the P4JsApi to execute a series of Perforce commands. It gathers a list of branches owned by the current user, then runs a preview integration (p4 integ -n) for each branch. The data is put into an HTML table for display to the user. The snippet below shows the most interesting bits of the file.

    // get all branch specs owned by current user
    var branches = P4JsApi.p4("branches -u " + P4JsApi.getUser());
    for (var i = 0; i < branches.size; i++) {
        var branch = branches.data[i];
        // get view
        var branchspec = P4JsApi.p4("branch -o " + branch.Branch);
        var origview = branchspec.data[0].View0;
        var indexofdiv = origview.lastIndexOf("//");
        var view = P4JsApi.encodeForHTML(origview.substring(0,indexofdiv))
            + "<br>   "
            + P4JsApi.encodeForHTML(origview.substring(indexofdiv));
        // get pending forward integs
        var fpending = P4JsApi.p4("integrate -n -b " + branch.Branch);
        var fpendinglist = '';
        for (var j = 0; j < fpending.size; j++) {
            fpendinglist = fpendinglist
                + P4JsApi.encodeForHTML(fpending.data[j].depotFile)
                + "<br>";
        } // all forward pending integs
        // get pending reverse integs
        var rpending = P4JsApi.p4("integrate -n -r -b " + branch.Branch);
        var rpendinglist = '';
        for (var j = 0; j < rpending.size; j++) {
            rpendinglist = rpendinglist
                + P4JsApi.encodeForHTML(rpending.data[j].depotFile)
                + "<br>";
        } // all reverse pending integs
        // add branch to table
        // ... use HTML DOM to insert rows ...

    The README file has a list of possible future enhancements. Probably the most useful enhancement is the ability to let a user choose which branch specs to view in the tab, rather than using the branch specs they own. Feel free to customize interchanges.html if you want to use different criteria for selecting branch specs of interest.

    The P4JsApi opens up all sorts of interesting possibilities for making custom dashboards and views in P4V. Hopefully, applets like this one will provide the building blocks for a richer P4V experience. There are other examples in the Public Depot as well.