<!--
Copyright (c) Perforce Software, Inc., 1997-2010. All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE
SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
User contributed content on the Perforce Public Depot is not supported by Perforce,
although it may be supported by its author. This applies to all contributions
even those submitted by Perforce employees.
-->
<html>
<head>
<title>Pending Integrations</title>
<link rel="stylesheet" type="text/css" href="applets.css" />
<script type="text/javascript">
function defaultUser() {
document.getElementById('branchuser').value = P4JsApi.encodeForHTMLAttribute(P4JsApi.getUser());
} // defaultUser
function getPendingIntegs() {
var maxFiles = document.getElementById('maxfiles').value;
var maxBranches = document.getElementById('maxbranches').value;
P4JsApi.setWebKitDeveloperExtrasEnabled(true);
var table = document.getElementById('pendingintegs');
for(var i = table.rows.length; i > 1;i--) {
table.deleteRow(i -1);
}
// get all branch specs owned by current user
var branchuser = document.getElementById('branchuser').value;
var branchfilter = document.getElementById('branchfilter').value;
var branchescmd = 'branches';
if(branchuser != '') {
branchescmd = branchescmd + ' -u ' + branchuser;
}
if(branchfilter != '') {
branchescmd = branchescmd + ' -e "' + branchfilter + '"';
}
var branches = P4JsApi.p4(branchescmd);
for (var i = 0; i < branches.size && i < maxBranches; 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));
var fullview = '<b>View</b><br>' + branchspec.data[0].View0;
var k = 1;
while(typeof branchspec.data[0]["View" + k] != "undefined") {
fullview = fullview
+ "<br>"
+ branchspec.data[0]["View" + k];
k++;
} // complete view
var fullviewdiv = document.createElement("div");
fullviewdiv.id = 'tooltip_' + i;
fullviewdiv.className = 'tooltip';
fullviewdiv.innerHTML = fullview;
document.getElementById('thebody').appendChild(fullviewdiv);
// get pending forward integs (changelists)
var fpendingCL = P4JsApi.p4("interchanges -b " + branch.Branch);
var found = 0;
var fpendingCLlist = '<ul>';
for (var j = 0; j < fpendingCL.size && j < maxFiles; j++) {
if(fpendingCL.data[j].change) {
found = 1;
fpendingCLlist = fpendingCLlist
+ "<li>" + P4JsApi.encodeForHTML(fpendingCL.data[j].change) + ": " + getJobsFixed(fpendingCL.data[j].change, branch.Branch, '');
}
} // all forward pending integs
if(fpendingCL.size > maxFiles) {
fpendingCLlist = fpendingCLlist
+ "<br><i>... and " + (fpendingCL.size - maxFiles)+ " more</i>";
} // more than max files to show
fpendingCLlist = fpendingCLlist + "</ul>";
if(found == 0) {
fpendingCLlist = "<i>None found</i>";
}
console.log(fpendingCLlist);
// get pending reverse integs
var rpendingCL = P4JsApi.p4("interchanges -r -b " + branch.Branch);
found = 0;
var rpendingCLlist = '<ul>';
for (var j = 0; j < rpendingCL.size && j < maxFiles; j++) {
if(rpendingCL.data[j].change) {
found = 1;
rpendingCLlist = rpendingCLlist
+ "<li>" + P4JsApi.encodeForHTML(rpendingCL.data[j].change) + ": " + getJobsFixed(rpendingCL.data[j].change, branch.Branch, '-r');
}
} // all reverse pending integs
if(rpendingCL.size > maxFiles) {
rpendingCLlist = rpendingCLlist
+ "<br><i>... and " + (rpendingCL.size - maxFiles)+ " more</i>";
} // more than max files to show
rpendingCLlist = rpendingCLlist + "</ul>";
if(found == 0) {
rpendingCLlist = "<i>None found</i>";
}
console.log(rpendingCLlist);
// get pending forward integs
var fpending = P4JsApi.p4("integrate -n -b " + branch.Branch);
var fpendinglist = '';
for (var j = 0; j < fpending.size && j < maxFiles; j++) {
fpendinglist = fpendinglist
+ P4JsApi.encodeForHTML(fpending.data[j].depotFile)
+ "<br>";
} // all forward pending integs
if(fpending.size > maxFiles) {
fpendinglist = fpendinglist
+ "<i>... and " + (fpending.size - maxFiles)+ " more</i>";
} // more than max files to show
console.log(fpendinglist);
// get pending reverse integs
var rpending = P4JsApi.p4("integrate -n -r -b " + branch.Branch);
var rpendinglist = '';
for (var j = 0; j < rpending.size && j < maxFiles; j++) {
rpendinglist = rpendinglist
+ P4JsApi.encodeForHTML(rpending.data[j].depotFile)
+ "<br>";
} // all reverse pending integs
if(rpending.size > maxFiles) {
rpendinglist = rpendinglist
+ "<i>... and " + (rpending.size - maxFiles)+ " more</i>";
} // more than max files to show
console.log(rpendinglist);
// add branch to table
var row = document.createElement("tr");
row.innerHTML = "<td class='applet colone'>"
+ P4JsApi.encodeForHTML(branch.Branch)
+ "</td>"
+ "<td id='tdview_" + i + "' class='applet coltwo' onmouseover='tooltip_show(\"tooltip_" + i + "\", \"tdview_" + i + "\");' onmouseout='tooltip_hide(\"tooltip_" + i + "\");'>"
+ view
+ "</td>"
+ "<td class='applet colinterchanges'>"
+ "<div class='interchanges'>"
+ fpendingCLlist
+ "</div>"
+ "</td>"
+ "<td class='applet colinterchanges'>"
+ "<div class='interchanges'>"
+ rpendingCLlist
+ "</div>"
+ "</td>"
+ "<td class='applet colinteg'>"
+ "<div class='integ'>"
+ fpendinglist
+ "</div>"
+ "</td>"
+ "<td class='applet colinteg'>"
+ "<div class='integ'>"
+ rpendinglist
+ "</div>"
+ "</td>";
table.appendChild(row);
} // all branches owned by user
} // getPendingIntegs
function getJobsFixed(cl, branch, direction) {
var jobs = P4JsApi.p4("fixes -c " + cl);
var joblist = '';
for (var j = 0; j < jobs.size; j++) {
joblist = joblist
+ "<a href='#' onclick='integJob(\"" + jobs.data[j].Job + "\", \"" + branch + "\", \"" + direction + "\")'>"
+ P4JsApi.encodeForHTML(jobs.data[j].Job) + "</a>"
+ ", ";
} // all jobs
return joblist;
} // getJobsFixed
function logObject(o) {
for(var k in o) {
console.log(k, o[k]);
}
} // logObject
function integJob(jobId, branch, direction) {
var cls = P4JsApi.p4("fixes -j " + jobId);
var results = '';
var found = 0;
for (var j = (cls.size - 1); j >= 0; j--) {
var cl = cls.data[j].Change;
found = 1;
var integCmd = "integ " + direction + " -b " + branch + " //...@" + cl + ",@" + cl;
results = results + "> " + integCmd + "\r\n";
var result = P4JsApi.p4(integCmd);
if(result.data[0].action) {
results = results + ">> " + result.size + " files integrated\r\n";
}
else {
results = results + ">> " + result.data[0].p4ERROR.message + "\r\n";
}
logObject(result.data[0]);
} // all changelists
if(found > 0) {
results = "Now review any pending files in the default changelist, resolve, and submit!\r\nLog:\r\n" + results;
}
document.getElementById('jobintegresults').innerHTML = P4JsApi.encodeForHTML(results);
} // integJob
function tooltip_findPosX(obj)
{
var curleft = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curleft += obj.offsetLeft
obj = obj.offsetParent;
}
}
else if (obj.x)
curleft += obj.x;
return curleft;
} // tooltip_findPosX
function tooltip_findPosY(obj)
{
var curtop = 0;
if (obj.offsetParent)
{
while (obj.offsetParent)
{
curtop += obj.offsetTop
obj = obj.offsetParent;
}
}
else if (obj.y)
curtop += obj.y;
return curtop;
} // tooltip_findPosY
function tooltip_show(tooltipId, parentId)
{
it = document.getElementById(tooltipId);
if ((it.style.top == '' || it.style.top == 0)
&& (it.style.left == '' || it.style.left == 0))
{
// need to fixate default size (MSIE problem)
it.style.width = it.offsetWidth + 'px';
it.style.height = it.offsetHeight + 'px';
img = document.getElementById(parentId);
// if tooltip is too wide, shift left to be within parent
x = tooltip_findPosX(img);
y = tooltip_findPosY(img);
it.style.top = y + 'px';
it.style.left = x + 'px';
}
it.style.visibility = 'visible';
} // tooltip_show
function tooltip_hide(id)
{
it = document.getElementById(id);
it.style.visibility = 'hidden';
} // tooltip_hide
</script>
</head>
<body onload="defaultUser(); getPendingIntegs();" id="thebody">
<table class="eighty applet">
<tr>
<th class="filter">User</th>
<th class="filter">Filter</th>
<th class="filter">Max Branches</th>
<th class="filter">Max Files</th>
</tr>
<tr>
<td class="filter"><input type="text" value="" id="branchuser"/></td>
<td class="filter"><input type="text" value="" id="branchfilter"/></td>
<td class="filter"><input type="text" value="10" id="maxbranches"/></td>
<td class="filter"><input type="text" value="20" id="maxfiles"/></td>
</tr>
<tr>
<td class="filter" align="center" colspan="4"><input type="button" value="Load" onclick="getPendingIntegs();"/></td>
</tr>
</table>
<br>
<table id="pendingintegs" class="applet interchanges">
<tr>
<th scope="col" class="applet colone">Branch</th>
<th scope="col" class="applet coltwo">View (first line)</th>
<th scope="col" class="applet colinterchanges">Pending Changelists and Jobs</th>
<th scope="col" class="applet colinterchanges">Reverse Pending Changelists and Jobs</th>
<th scope="col" class="applet colinteg">Pending Files</th>
<th scope="col" class="applet colinteg">Reverse Pending Files</th>
</tr>
</table>
<br>
<textarea class="results" id="jobintegresults" readonly="readonly">
</textarea>
</body>
</html>
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #5 | 7957 | Randy DeFauw |
Added a very simple promote-by-job function. Added interchanges output. REQUIRES 2011.1 P4V. |
||
| #4 | 7725 | Randy DeFauw |
New features: CSS for style Documentation applet Provide flexible branch filtering Display full branch view in tool-tip Limit number of branches/files displayed |
||
| #3 | 7681 | Randy DeFauw | add copyright and license info | ||
| #2 | 7672 | Randy DeFauw | Use scroll bars when the list of pending file integs is long | ||
| #1 | 7669 | Randy DeFauw | Adding example P4JsApi applet showing pending integrations |