package org.jfrog.bamboo.release.vcs.perforce;
import com.atlassian.bamboo.build.logger.BuildLogger;
import com.atlassian.bamboo.builder.BuildState;
import com.atlassian.bamboo.credentials.CredentialsAccessor;
import com.atlassian.bamboo.v2.build.BuildContext;
import com.atlassian.bamboo.v2.build.CurrentBuildResult;
import com.atlassian.bamboo.variable.CustomVariableContext;
import org.jfrog.bamboo.context.AbstractBuildContext;
import org.jfrog.bamboo.release.vcs.AbstractVcsCoordinator;
import java.io.File;
import java.io.IOException;
import java.util.Map;
/**
* Perforce coordinator that will perform SCM operations that are specific to the Perforce SCM.
*
* @author Shay Yaakov
*/
public class PerforceCoordinator extends AbstractVcsCoordinator {
private PerforceManager perforce;
private final Map<String, String> configuration;
private boolean tagCreated;
private int currentChangeListId;
public PerforceCoordinator(BuildContext context, Map<String, String> configuration, BuildLogger buildLogger,
CustomVariableContext customVariableContext, CredentialsAccessor credentialsAccessor) {
super(context, buildLogger, customVariableContext, credentialsAccessor);
this.configuration = configuration;
}
@Override
public void prepare() throws IOException {
perforce = new PerforceManager(context, buildLogger);
perforce.prepare();
}
@Override
public void beforeReleaseVersionChange() throws IOException {
currentChangeListId = perforce.createNewChangeList();
}
@Override
public void afterSuccessfulReleaseVersionBuild() throws IOException, InterruptedException {
AbstractBuildContext context = AbstractBuildContext.createContextFromMap(configuration);
AbstractBuildContext.ReleaseManagementContext releaseManagementContext = context.releaseManagementContext;
String labelChangeListId = configuration.get("repository.revision.number");
if (modifiedFilesForReleaseVersion) {
log("Submitting release version changes");
labelChangeListId = currentChangeListId + "";
perforce.commitWorkingCopy(currentChangeListId, releaseManagementContext.getTagComment());
} else {
safeRevertWorkingCopy();
currentChangeListId = perforce.getDefaultChangeListId();
}
if (releaseManagementContext.isCreateVcsTag()) {
log("Creating label: '" + releaseManagementContext.getTagUrl() + "' with change list id: " + labelChangeListId);
perforce.createTag(releaseManagementContext.getTagUrl(), releaseManagementContext.getTagComment(),
labelChangeListId);
tagCreated = true;
}
}
@Override
public void beforeDevelopmentVersionChange() throws IOException {
currentChangeListId = perforce.getDefaultChangeListId();
}
@Override
public void afterDevelopmentVersionChange(boolean modified) throws IOException, InterruptedException {
super.afterDevelopmentVersionChange(modified);
AbstractBuildContext context = AbstractBuildContext.createContextFromMap(configuration);
AbstractBuildContext.ReleaseManagementContext releaseManagementContext = context.releaseManagementContext;
if (modified) {
log("Submitting next development version changes");
perforce.commitWorkingCopy(currentChangeListId, releaseManagementContext.getNextDevelopmentComment());
} else {
safeRevertWorkingCopy();
currentChangeListId = perforce.getDefaultChangeListId();
}
}
@Override
public void edit(File file) throws IOException, InterruptedException {
log("Opening file: '" + file.getAbsolutePath() + "' for editing");
perforce.edit(currentChangeListId, file);
}
@Override
public void buildCompleted(BuildContext buildContext) throws IOException, InterruptedException {
AbstractBuildContext context = AbstractBuildContext.createContextFromMap(configuration);
CurrentBuildResult result = buildContext.getBuildResult();
if (!BuildState.SUCCESS.equals(result.getBuildState())) {
safeRevertWorkingCopy();
if (tagCreated) {
safeDeleteLabel(context.releaseManagementContext.getTagUrl());
}
} else {
log("Closing connection to perforce server");
perforce.closeConnection();
}
}
private void safeRevertWorkingCopy() {
log("Reverting local changes");
try {
perforce.revertWorkingCopy(currentChangeListId);
} catch (Exception e) {
log("Failed to revert: " + e.getLocalizedMessage());
}
}
private void safeDeleteLabel(String label) throws IOException {
log("Deleting label '" + label + "'");
try {
perforce.deleteLabel(label);
} catch (Exception e) {
log("Failed to delete label: " + e.getLocalizedMessage());
}
}
@Override
public String getRemoteUrlForPom() {
return null;
}
@Override
public boolean isSubversion() {
return false;
}
@Override
public int getCurrentChangeListId() {
return currentChangeListId;
}
@Override
public void setCurrentChangeListId(int currentChangeListId) {
this.currentChangeListId = currentChangeListId;
}
}