try {
// keep projectPath local so any modifications for slaves don't get saved
String effectiveProjectPath= getEffectiveProjectPath(build,
build.getProject(), build.getBuiltOn(), log, depot);
Workspace p4workspace = getPerforceWorkspace(build.getProject(), effectiveProjectPath, depot, build.getBuiltOn(), build, launcher, workspace, listener, false);
boolean dirtyWorkspace = p4workspace.isDirty();
saveWorkspaceIfDirty(depot, p4workspace, log);
//Wipe/clean workspace
String p4config;
WipeWorkspaceExcludeFilter wipeFilter;
try {
p4config = MacroStringHelper.substituteParameters("${P4CONFIG}", this, build, null);
wipeFilter = new WipeWorkspaceExcludeFilter(".p4config",p4config);
} catch (ParameterSubstitutionException ex) {
wipeFilter = new WipeWorkspaceExcludeFilter();
}
if (wipeBeforeBuild || quickCleanBeforeBuild) {
long cleanStartTime = System.currentTimeMillis();
if (wipeRepoBeforeBuild) {
log.println("Clear workspace includes .repository ...");
} else {
log.println("Note: .repository directory in workspace (if exists) is skipped during clean.");
wipeFilter.exclude(".repository");
}
if (wipeBeforeBuild) {
log.println("Wiping workspace...");
List<FilePath> workspaceDirs = workspace.list(wipeFilter);
for (FilePath dir : workspaceDirs) {
dir.deleteRecursive();
}
log.println("Wiped workspace.");
forceSync = true;
}
if (quickCleanBeforeBuild) {
QuickCleaner quickCleaner = new QuickCleaner(depot.getExecutable(), depot.getP4Ticket(), launcher, depot, workspace, wipeFilter);
log.println("Quickly cleaning workspace...");
quickCleaner.doClean();
log.println("Workspace is clean.");
if (restoreChangedDeletedFiles) {
log.println("Restoring changed and deleted files...");
quickCleaner.doRestore();
log.println("Files restored.");
}
}
long cleanEndTime = System.currentTimeMillis();
long cleanDuration = cleanEndTime - cleanStartTime;
log.println("Clean complete, took " + cleanDuration + " ms");
}
// In case of a stream depot, we want Perforce to handle the client views. So let's re-initialize
// the p4workspace object if it was changed since the last build. Also, populate projectPath with
// the current view from Perforce. We need it for labeling.
if (useStreamDepot) {
if (dirtyWorkspace) {
// Support for concurrent builds
String p4Client = getConcurrentClientName(workspace, getEffectiveClientName(build, null));
p4workspace = depot.getWorkspaces().getWorkspace(p4Client, p4Stream);
}
effectiveProjectPath = p4workspace.getTrimmedViewsAsString();
}
// If we're not managing the view, populate the projectPath with the current view from perforce
// This is both for convenience, and so the labeling mechanism can operate correctly
if (!updateView) {
effectiveProjectPath = p4workspace.getTrimmedViewsAsString();
}
String p4WorkspacePath = "//" + p4workspace.getName() + "/...";
int lastChange = getLastChange((Run)build.getPreviousBuild());
log.println("Last build changeset: " + lastChange);
// Determine changeset number
int newestChange = lastChange;
List<Changelist> changes;
if (p4Label != null && !p4Label.trim().isEmpty()) {
newestChange = depot.getChanges().getHighestLabelChangeNumber(p4workspace, p4Label.trim(), p4WorkspacePath);
} 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.");
}