Skip to content

Commit

Permalink
Add support for diffing of templates.
Browse files Browse the repository at this point in the history
Resolves issue #143

Added ability to pass `status:PROVIDED` (and other status types) to
template locator in the REST API.

Added diffing page to web-ui which shows differences between template
contents.

Added link to edit template page to show diffs if template is
USER_OVERRIDDEN.
  • Loading branch information
netwolfuk committed Jul 20, 2019
1 parent 7917986 commit 5c1a56d
Show file tree
Hide file tree
Showing 17 changed files with 6,035 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,22 @@ public WebHookPayloadTemplate getTemplate(String formatShortname){
}
}

public WebHookTemplateConfig getTemplateConfig(String formatShortname){
public WebHookTemplateConfig getTemplateConfig(String formatShortname, TemplateState templateState){
synchronized (orderedTemplateCollection) {
if (xmlConfigTemplates.containsKey(formatShortname)){
if (springTemplates.containsKey(formatShortname)
&& xmlConfigTemplates.containsKey(formatShortname)
&& TemplateState.PROVIDED.equals(templateState))
{
return WebHookTemplateConfigBuilder.buildConfig(springTemplates.get(formatShortname).getAsEntity());
}
if (xmlConfigTemplates.containsKey(formatShortname)
&& ( TemplateState.BEST.equals(templateState) || getTemplateState(formatShortname, templateState).equals(templateState)))
{
return WebHookTemplateConfigBuilder.buildConfig(xmlConfigTemplates.get(formatShortname).getAsEntity());
}
if (springTemplates.containsKey(formatShortname)){
if (springTemplates.containsKey(formatShortname)
&& ( TemplateState.BEST.equals(templateState) || TemplateState.PROVIDED.equals(templateState) || getTemplateState(formatShortname, templateState).equals(templateState)))
{
return WebHookTemplateConfigBuilder.buildConfig(springTemplates.get(formatShortname).getAsEntity());
}
return null;
Expand Down Expand Up @@ -190,8 +200,8 @@ public List<WebHookPayloadTemplate> findAllTemplatesForFormat(String formatShort
return matchingTemplates;
}

public TemplateState getTemplateState(String template){
if (springTemplates.containsKey(template) && xmlConfigTemplates.containsKey(template)){
public TemplateState getTemplateState(String template, TemplateState templateState){
if ((TemplateState.BEST.equals(templateState) || TemplateState.USER_OVERRIDDEN.equals(templateState)) && springTemplates.containsKey(template) && xmlConfigTemplates.containsKey(template)){
return TemplateState.USER_OVERRIDDEN;
} else if (springTemplates.containsKey(template)){
return TemplateState.PROVIDED;
Expand All @@ -205,6 +215,7 @@ public static enum TemplateState {
PROVIDED ("Template bundled with tcWebhooks"),
USER_DEFINED ("User defined template"),
USER_OVERRIDDEN ("Overridden by user defined template"),
BEST ("Template in its most specific state"), // Only used for finding. Template will never actually be in this state.
UNKNOWN ("Unknown origin");

private final String description;
Expand Down Expand Up @@ -232,6 +243,10 @@ public boolean isStateUnknown()
{
return TemplateState.UNKNOWN.equals(this);
}
public boolean isStateAny()
{
return TemplateState.BEST.equals(this);
}
}

public void setConfigFilePath(String configFilePath) {
Expand Down
11 changes: 9 additions & 2 deletions tcwebhooks-rest-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- <plugin>
Expand Down Expand Up @@ -297,6 +297,13 @@
<version>1.1</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.0</version>
</dependency>

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import jetbrains.buildServer.serverSide.SBuildServer;
import webhook.teamcity.payload.WebHookPayloadManager;
import webhook.teamcity.payload.WebHookTemplateManager;
import webhook.teamcity.payload.WebHookTemplateManager.TemplateState;
import webhook.teamcity.server.rest.util.webhook.WebHookManager;
import webhook.teamcity.settings.config.WebHookTemplateConfig;

Expand Down Expand Up @@ -52,7 +53,7 @@ public List<WebHookTemplateConfigWrapper> getWebHookTemplates(){
List<WebHookTemplateConfigWrapper> templates = new ArrayList<>();
for (WebHookTemplateConfig template : this.myTemplateManager.getRegisteredTemplateConfigs()){
templates.add(new WebHookTemplateConfigWrapper(template,
this.myTemplateManager.getTemplateState(template.getId()),
this.myTemplateManager.getTemplateState(template.getId(), TemplateState.BEST),
WebHookTemplateStates.build(template)
)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import jetbrains.buildServer.server.rest.errors.NotFoundException;
import jetbrains.buildServer.util.StringUtil;
import webhook.teamcity.payload.WebHookTemplateManager;
import webhook.teamcity.payload.WebHookTemplateManager.TemplateState;
import webhook.teamcity.server.rest.data.WebHookTemplateItemConfigWrapper.WebHookTemplateItemRest;
import webhook.teamcity.settings.config.WebHookTemplateConfig;
import webhook.teamcity.settings.config.WebHookTemplateConfig.WebHookTemplateBranchText;
Expand Down Expand Up @@ -35,7 +36,7 @@ public WebHookTemplateConfigWrapper findTemplateById(String templateLocator) {
throw new BadRequestException("Empty template locator is not supported.");
}

final Locator locator = new Locator(templateLocator, "id", "name",
final Locator locator = new Locator(templateLocator, "id", "name", "type",
Locator.LOCATOR_SINGLE_VALUE_UNUSED_NAME);

if (locator.isSingleValue()) {
Expand All @@ -44,52 +45,60 @@ public WebHookTemplateConfigWrapper findTemplateById(String templateLocator) {
WebHookTemplateConfig template = null;
@NotNull
final String singleValue = locator.getSingleValue();
template = myTemplateManager.getTemplateConfig(singleValue);
template = myTemplateManager.getTemplateConfig(singleValue, TemplateState.BEST);
if (template != null) {
return new WebHookTemplateConfigWrapper(template,
myTemplateManager.getTemplateState(template.getId()),
myTemplateManager.getTemplateState(template.getId(), TemplateState.BEST),
WebHookTemplateStates.build(template));
}
throw new NotFoundException(
"No template found by name '"
"No template found by id '"
+ singleValue + "'.");

} else if (locator.getSingleDimensionValue("id") != null){
WebHookTemplateConfig template = null;
@NotNull
final String templateId = locator.getSingleDimensionValue("id");
template = myTemplateManager.getTemplateConfig(templateId);
@NotNull final String templateId = locator.getSingleDimensionValue("id");
@NotNull final TemplateState templateState = getTemplateStateDimension(locator);
template = myTemplateManager.getTemplateConfig(templateId, templateState);
if (template != null) {
return new WebHookTemplateConfigWrapper(template,
myTemplateManager.getTemplateState(template.getId()),
myTemplateManager.getTemplateState(template.getId(), templateState),
WebHookTemplateStates.build(template)
);
}
throw new NotFoundException(
"No template found by id '"
+ templateId + "'.");
+ templateId + "' and state '"+ templateState.toString() +"'.");

} else if (locator.getSingleDimensionValue("name") != null){
WebHookTemplateConfig template = null;
@NotNull
final String templateName = locator.getSingleDimensionValue("name");
template = myTemplateManager.getTemplateConfig(templateName);
@NotNull final String templateName = locator.getSingleDimensionValue("name");
@NotNull final TemplateState templateState = getTemplateStateDimension(locator);

template = myTemplateManager.getTemplateConfig(templateName, templateState);
if (template != null) {
return new WebHookTemplateConfigWrapper(template,
myTemplateManager.getTemplateState(template.getId()),
myTemplateManager.getTemplateState(template.getId(), templateState),
WebHookTemplateStates.build(template)
);
}
throw new NotFoundException(
"No template found by name '"
+ templateName + "'.");
+ templateName + "' and state '"+ templateState.toString() +"'.");

}

throw new BadRequestException("Sorry: Searching for multiple template is not supported.");

}

private TemplateState getTemplateStateDimension(Locator locator) {
if (locator.getSingleDimensionValue("status") != null) {
return TemplateState.valueOf(locator.getSingleDimensionValue("status"));
}
return TemplateState.BEST;
}

public WebHookTemplateItemConfigWrapper findTemplateByIdAndTemplateContentById(String templateLocator, String templateContentLocator) {

WebHookTemplateConfigWrapper templateConfigWrapper = findTemplateById(templateLocator);
Expand Down Expand Up @@ -153,4 +162,5 @@ private WebHookTemplateItemConfigWrapper buildWebHookTemplateItemConfigWrapper(
"No templateItem found by id '"
+ templateId + "'.");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import com.intellij.openapi.util.text.StringUtil;

import jetbrains.buildServer.server.rest.errors.BadRequestException;
import jetbrains.buildServer.server.rest.errors.NotFoundException;
import jetbrains.buildServer.server.rest.model.Fields;
import jetbrains.buildServer.server.rest.util.ValueWithDefault;
Expand All @@ -27,9 +24,7 @@
import lombok.Setter;
import webhook.teamcity.BuildStateEnum;
import webhook.teamcity.payload.WebHookTemplateManager;
import webhook.teamcity.payload.template.WebHookTemplateFromXml;
import webhook.teamcity.server.rest.WebHookWebLinks;
import webhook.teamcity.server.rest.data.DataProvider;
import webhook.teamcity.server.rest.data.TemplateFinder;
import webhook.teamcity.server.rest.data.WebHookTemplateConfigWrapper;
import webhook.teamcity.server.rest.data.WebHookTemplateItemConfigWrapper.WebHookTemplateItemRest;
Expand Down
Loading

0 comments on commit 5c1a56d

Please sign in to comment.