} else {
if (p4UpstreamProject != null && p4UpstreamProject.length() > 0) {
log.println("Using last successful or unstable build of upstream project " + p4UpstreamProject);
Job job = Hudson.getInstance().getItemByFullName(p4UpstreamProject, Job.class);
if (job == null) {
throw new AbortException(
"Configured upstream job does not exist anymore: " + p4UpstreamProject + ". Please update your job configuration.");
}
Run upStreamRun = job.getLastSuccessfulBuild();
int lastUpStreamChange = getLastChangeNoFirstChange(upStreamRun);
if (lastUpStreamChange > 0) {
log.println("Using P4 revision " + lastUpStreamChange + " from upstream project " + p4UpstreamProject);
newestChange = lastUpStreamChange;
} else {
log.println("No P4 revision found in upstream project " + p4UpstreamProject);
throw new AbortException(
"Configured upstream job has not been run yet: " + p4UpstreamProject + ". Please run it once befor launching a new build.");
}
} else
if (p4Counter != null && !updateCounterValue) {
//use a counter
String counterName;
counterName = MacroStringHelper.substituteParameters(this.p4Counter, this, build, null);
Counter counter = depot.getCounters().getCounter(counterName);
newestChange = counter.getValue();
} else {
//use the latest submitted change from workspace, or depot
try {
List<Integer> workspaceChanges = depot.getChanges().getChangeNumbers(p4WorkspacePath, 0, 1);
if (workspaceChanges != null && workspaceChanges.size() > 0) {
newestChange = workspaceChanges.get(0);
} else {
List<Integer> depotChanges = depot.getChanges().getChangeNumbers("//...", 0, 1);
if (depotChanges != null && depotChanges.size() > 0) {
newestChange = depotChanges.get(0);
}
}
} catch (PerforceException e) {
//fall back onto 'change' counter value
log.println("Failed to get last submitted changeset in the view, falling back to change counter. Error was: " + e.getMessage());
Counter counter = depot.getCounters().getCounter("change");
newestChange = counter.getValue();
}
}
}
// Set newestChange down to the next available changeset if we're building one change at a time
if (oneChangelistOnly && build.getPreviousBuild() != null
&& lastChange > 0 && newestChange > lastChange) {
List<Integer> workspaceChanges = depot.getChanges().getChangeNumbersInRange(
p4workspace, lastChange+1, newestChange, viewMask, showIntegChanges);
for (int i = workspaceChanges.size()-1; i >= 0; --i) {
int changeNumber = workspaceChanges.get(i);
Changelist changelist = depot.getChanges().getChangelist(changeNumber, fileLimit);
if (!isChangelistExcluded(changelist, build.getProject(), build.getBuiltOn(), p4workspace.getViewsAsString(), log)) {
newestChange = changeNumber;
break;
}
log.println("Changelist "+changeNumber+" is composed of file(s) and/or user(s) that are excluded.");
}
log.println("Remaining changes: " + workspaceChanges);
log.println("Building next changeset in sequence: " + newestChange);
}
if (build instanceof MatrixRun) {
newestChange = getOrSetMatrixChangeSet(build, depot, newestChange, effectiveProjectPath, log);
}
if (lastChange <= 0) {
lastChange = newestChange - MAX_CHANGESETS_ON_FIRST_BUILD;
if (lastChange < 0) {
lastChange = 0;
}
}
// Get ChangeLog
if (!disableChangeLogOnly) {
int lastChangeToDisplay = lastChange+1;
if (lastChange > newestChange) {
// If we're building an older change, display it anyway
// TODO: This can be considered inconsistent behavior
lastChangeToDisplay = newestChange;
}
List<Integer> changeNumbersTo;
if (useViewMaskForChangeLog && useViewMask) {
changeNumbersTo = depot.getChanges().getChangeNumbersInRange(p4workspace, lastChangeToDisplay, newestChange, viewMask, showIntegChanges);
} else {
changeNumbersTo = depot.getChanges().getChangeNumbersInRange(p4workspace, lastChangeToDisplay, newestChange, showIntegChanges);
}
changes = depot.getChanges().getChangelistsFromNumbers(changeNumbersTo, fileLimit);
if (changes.size() > 0) {
// Save the changes we discovered.
PerforceChangeLogSet.saveToChangeLog(
new FileOutputStream(changelogFile), changes);
newestChange = changes.get(0).getChangeNumber();
// Get and store information about committers
retrieveUserInformation(depot, changes);
} else {
// No new changes discovered (though the definition of the workspace or label may have changed).
createEmptyChangeLog(changelogFile, listener, "changelog");
}
}
// Sync workspace
if (!disableSyncOnly) {
// Now we can actually do the sync process...
StringBuilder sbMessage = new StringBuilder("Sync'ing workspace to ");
StringBuilder sbSyncPath = new StringBuilder(p4WorkspacePath);
StringBuilder sbSyncPathSuffix = new StringBuilder();
sbSyncPathSuffix.append("@");
if (p4Label != null && !p4Label.trim().isEmpty()) {
sbMessage.append("label ");
sbMessage.append(p4Label);
sbSyncPathSuffix.append(p4Label);
} else {
sbMessage.append("changelist ");
sbMessage.append(newestChange);
sbSyncPathSuffix.append(newestChange);
}
sbSyncPath.append(sbSyncPathSuffix);
if (forceSync || alwaysForceSync)
sbMessage.append(" (forcing sync of unchanged files).");
else
sbMessage.append(".");
log.println(sbMessage.toString());
String syncPath = sbSyncPath.toString();
long startTime = System.currentTimeMillis();
if (useViewMaskForSyncing && useViewMask) {
for (String path : viewMask.replaceAll("\r", "").split("\n")) {
StringBuilder sbMaskPath = new StringBuilder(path);
sbMaskPath.append(sbSyncPathSuffix);
String maskPath = sbMaskPath.toString();
depot.getWorkspaces().syncTo(maskPath, forceSync || alwaysForceSync, dontUpdateServer);
}
} else {
depot.getWorkspaces().syncTo(syncPath, forceSync || alwaysForceSync, dontUpdateServer);
}
long endTime = System.currentTimeMillis();
long duration = endTime - startTime;
log.println("Sync complete, took " + duration + " ms");
}
boolean doSaveProject = false;
// reset one time use variables...
if (this.forceSync == true || this.firstChange != -1) {
this.forceSync = false;
this.firstChange = -1;
// save the one-time use variables...
doSaveProject = true;
}
// If we aren't managing the client views, update the current ones
// with those from perforce, and save them if they have changed.
if (!this.updateView && !effectiveProjectPath.equals(this.projectPath)) {
this.projectPath = effectiveProjectPath;
doSaveProject = true;
}
if (doSaveProject) {
build.getParent().save();
}
// Add tagging action that enables the user to create a label
// for this build.
build.addAction(new PerforceTagAction(
build, depot, newestChange, effectiveProjectPath, MacroStringHelper.substituteParameters(p4User, this, build, null)));
build.addAction(new PerforceSCMRevisionState(newestChange));
if (p4Counter != null && updateCounterValue) {
// Set or create a counter to mark this change
Counter counter = new Counter();
String counterName = MacroStringHelper.substituteParameters(this.p4Counter, this, build, null);
counter.setName(counterName);
counter.setValue(newestChange);
log.println("Updating counter " + counterName + " to " + newestChange);
depot.getCounters().saveCounter(counter);
}
// remember the p4Ticket if we were issued one
// otherwise keep the last one issued
if (depot.getP4Ticket() != null)
p4Ticket = depot.getP4Ticket();
return true;
} catch (PerforceException e) {
log.print("Caught exception communicating with perforce. " + e.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
pw.flush();
log.print(sw.toString());
throw new AbortException(
"Unable to communicate with perforce. " + e.getMessage());
} catch (InterruptedException e) {
throw new IOException(
"Unable to get hostname from slave. " + e.getMessage());
} catch (NullPointerException e) {
log.print("Caught exception in perforce-plugin. " + e.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
pw.flush();
log.print(sw.toString());
throw new AbortException(
"Caught exception in perfoce-plugin. " + e.getMessage());
}
}