use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.
the class ChangeFinderTest method testChangesByBuildIdFromDependenciesHaveDescriptor.
@Test
@TestFor(issues = "TW-60774")
public void testChangesByBuildIdFromDependenciesHaveDescriptor() {
final BuildTypeImpl buildConf1 = registerBuildType("buildConf1", "project");
final BuildTypeImpl buildConf2 = registerBuildType("buildConf2", "project");
createDependencyChain(buildConf2, buildConf1);
MockVcsSupport vcs = new MockVcsSupport("vcs");
vcs.setDAGBased(true);
myFixture.getVcsManager().registerVcsSupport(vcs);
SVcsRootEx parentRoot1 = myFixture.addVcsRoot(vcs.getName(), "", buildConf1);
SVcsRootEx parentRoot2 = myFixture.addVcsRoot(vcs.getName(), "", buildConf2);
VcsRootInstance root1 = buildConf1.getVcsRootInstanceForParent(parentRoot1);
VcsRootInstance root2 = buildConf2.getVcsRootInstanceForParent(parentRoot2);
assert root1 != null;
assert root2 != null;
setBranchSpec(root1, "+:*");
setBranchSpec(root2, "+:*");
SVcsModification m1 = myFixture.addModification(modification().in(root1).version("1").parentVersions("0"));
SVcsModification m2 = myFixture.addModification(modification().in(root2).version("2").parentVersions("0"));
SQueuedBuild qb1 = build().in(buildConf1).onModifications(m1).addToQueue();
SQueuedBuild qb2 = build().in(buildConf2).onModifications(m2).snapshotDepends(qb1.getBuildPromotion()).addToQueue();
SFinishedBuild build1 = finishBuild(myFixture.flushQueueAndWait(), false);
SFinishedBuild build2 = finishBuild(myFixture.flushQueueAndWait(), false);
List<SVcsModificationOrChangeDescriptor> items = getFinder().getItems("build:" + build2.getBuildId() + ",changesFromDependencies:true,vcsRoot:(id:" + root1.getExternalId() + ")").myEntries;
assertEquals("There is exactly one change coming from dependency.", 1, items.size());
ChangeDescriptor descriptor = items.get(0).getChangeDescriptor();
assertNotNull("Change descriptor must be present when looking for changes using build id.", descriptor);
assertEquals(ChangeDescriptorConstants.SNAPSHOT_DEPENDENCY_VCS_CHANGE, descriptor.getType());
SVcsModification modification = items.get(0).getSVcsModification();
assertEquals("1", modification.getDisplayVersion());
}
use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.
the class ChangeRequest method serveChanges.
// todo: use locator here, like for builds with limitLookup, changes from dependencies flag, etc.
// todo: mark changes from dependencies
/**
* Lists changes by the specified locator
* @param locator Change locator
* @param projectLocator Deprecated, use "locator" parameter instead
* @param buildTypeLocator Deprecated, use "locator" parameter instead
* @param buildLocator Deprecated, use "locator" parameter instead
* @param vcsRootInstanceLocator Deprecated, use "locator" parameter instead. Note that corresponding locator dimension is "vcsRootInstance"
* @param sinceChangeLocator Deprecated, use "locator" parameter instead
* @param start Deprecated, use "locator" parameter instead
* @param count Deprecated, use "locator" parameter instead
* @param uriInfo Deprecated, use "locator" parameter instead
* @param request Deprecated, use "locator" parameter instead
* @return
*/
@GET
@Produces({ "application/xml", "application/json" })
@ApiOperation(value = "Get all changes.", nickname = "getAllChanges")
public Changes serveChanges(@ApiParam(hidden = true) @QueryParam("project") String projectLocator, @ApiParam(hidden = true) @QueryParam("buildType") String buildTypeLocator, @ApiParam(hidden = true) @QueryParam("build") String buildLocator, @ApiParam(hidden = true) @QueryParam("vcsRoot") String vcsRootInstanceLocator, @ApiParam(hidden = true) @QueryParam("sinceChange") String sinceChangeLocator, @ApiParam(hidden = true) @QueryParam("start") Long start, @ApiParam(hidden = true) @QueryParam("count") Integer count, @ApiParam(format = LocatorName.CHANGE) @QueryParam("locator") String locator, @QueryParam("fields") String fields, @Context UriInfo uriInfo, @Context HttpServletRequest request) {
Locator actualLocator = locator == null ? Locator.createEmptyLocator() : new Locator(locator);
if (!actualLocator.isSingleValue()) {
updateLocatorDimension(actualLocator, "project", projectLocator);
updateLocatorDimension(actualLocator, "buildType", buildTypeLocator);
updateLocatorDimension(actualLocator, "build", buildLocator);
updateLocatorDimension(actualLocator, "vcsRootInstance", vcsRootInstanceLocator);
updateLocatorDimension(actualLocator, "sinceChange", sinceChangeLocator);
updateLocatorDimension(actualLocator, "start", start != null ? String.valueOf(start) : null);
updateLocatorDimension(actualLocator, "count", count != null ? String.valueOf(count) : null);
}
final String locatorText = actualLocator.isEmpty() ? null : actualLocator.getStringRepresentation();
PagedSearchResult<SVcsModificationOrChangeDescriptor> buildModifications = myChangeFinder.getItems(locatorText);
final UriBuilder requestUriBuilder = uriInfo.getRequestUriBuilder();
requestUriBuilder.replaceQueryParam("count", null);
requestUriBuilder.replaceQueryParam("start", null);
return new Changes(buildModifications.myEntries, new PagerData(requestUriBuilder, request.getContextPath(), buildModifications, locatorText, "locator"), new Fields(fields), myBeanContext);
}
use of jetbrains.buildServer.server.rest.data.change.SVcsModificationOrChangeDescriptor in project teamcity-rest by JetBrains.
the class ChangeFinder method getFilter.
@NotNull
@Override
public ItemFilter<SVcsModificationOrChangeDescriptor> getFilter(@NotNull final Locator locator) {
final MultiCheckerFilter<SVcsModification> result = new MultiCheckerFilter<>();
// myBuildType, myProject and myBranchName are handled on getting initial collection to filter
final String vcsRootInstanceLocator = locator.getSingleDimensionValue(VCS_ROOT_INSTANCE);
if (vcsRootInstanceLocator != null) {
final VcsRootInstance vcsRootInstance = myVcsRootInstanceFinder.getItem(vcsRootInstanceLocator);
result.add(item -> {
// todo: check personal change applicability to the root
return !item.isPersonal() && vcsRootInstance.getId() == item.getVcsRoot().getId();
});
}
final String vcsRootLocator = locator.getSingleDimensionValue(VCS_ROOT);
if (vcsRootLocator != null) {
final VcsRoot vcsRoot = myVcsRootFinder.getItem(vcsRootLocator);
result.add(item -> {
// todo: check personal change applicability to the root
return !item.isPersonal() && vcsRoot.getId() == item.getVcsRoot().getParent().getId();
});
}
// todo: deprecate this
final String sinceChangeLocator = locator.getSingleDimensionValue(SINCE_CHANGE);
if (sinceChangeLocator != null) {
final long sinceChangeId = getChangeIdBySinceChangeLocator(sinceChangeLocator);
result.add(item -> sinceChangeId < item.getId());
}
if (locator.isUnused(USERNAME)) {
final String username = locator.getSingleDimensionValue(USERNAME);
if (username != null) {
result.add(item -> {
// todo: is ignoreCase is right here?
return username.equalsIgnoreCase(item.getUserName());
});
}
}
if (locator.getUnusedDimensions().contains(USER)) {
final String userLocator = locator.getSingleDimensionValue(USER);
if (userLocator != null) {
final SUser user = myUserFinder.getItem(userLocator);
result.add(item -> item.getCommitters().contains(user));
}
}
// TeamCity API: exclude "fake" personal changes created by TeamCity for personal builds without personal changes
result.add(item -> {
if (!item.isPersonal())
return true;
return item.getChanges().size() > 0;
});
final Boolean personal = locator.getSingleDimensionValueAsBoolean(PERSONAL);
if (personal != null) {
result.add(item -> FilterUtil.isIncludedByBooleanFilter(personal, item.isPersonal()));
}
if (personal != null && personal) {
// initial collection can contain changes from any buildType/project
final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
if (buildTypeLocator != null) {
final SBuildType buildType = myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
result.add(item -> isPersonalChangeMatchesBuildType(item, buildType));
}
}
if (locator.getUnusedDimensions().contains(BUILD)) {
final String buildLocator = locator.getSingleDimensionValue(BUILD);
if (buildLocator != null) {
final Set<Long> buildChanges = getBuildChangeDescriptors(myBuildFinder.getBuildPromotion(null, buildLocator), locator).map(mord -> mord.getRelatedVcsChange().getId()).collect(Collectors.toSet());
result.add(item -> buildChanges.contains(item.getId()));
}
}
// pre-9.0 dimension compatibility
if (locator.getUnusedDimensions().contains(PROMOTION)) {
final Long promotionLocator = locator.getSingleDimensionValueAsLong(PROMOTION);
if (promotionLocator != null) {
@SuppressWarnings("ConstantConditions") final Set<Long> buildChanges = getBuildChangeDescriptors(BuildFinder.getBuildPromotion(promotionLocator, myServiceLocator.findSingletonService(BuildPromotionManager.class)), null).map(mord -> mord.getRelatedVcsChange().getId()).collect(Collectors.toSet());
result.add(item -> buildChanges.contains(item.getId()));
}
}
if (locator.isUnused(BUILD_TYPE)) {
// todo: support multiple buildTypes here
final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
if (buildTypeLocator != null) {
SBuildType buildType = myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
// todo: this does not include "show changes from dependencies", relates to https://youtrack.jetbrains.com/issue/TW-63704
result.add(item -> item.getRelatedConfigurations().contains(buildType));
}
}
final String projectLocator = locator.getSingleDimensionValue(PROJECT);
if (projectLocator != null) {
final SProject project = myProjectFinder.getItem(projectLocator);
Set<String> btIds = project.getOwnBuildTypes().stream().map(BuildTypeDescriptor::getBuildTypeId).collect(Collectors.toSet());
result.add(item -> {
List<String> itemBtIds = ((VcsModificationEx) item).getRelatedConfigurationIds(false);
for (String itemBtId : itemBtIds) {
String finalId = RemoteBuildTypeIdUtil.isValidRemoteBuildTypeId(itemBtId) ? RemoteBuildTypeIdUtil.getParentBuildTypeId(itemBtId) : itemBtId;
if (btIds.contains(finalId)) {
return true;
}
}
return false;
});
}
if (locator.isUnused(INTERNAL_VERSION)) {
final String internalVersion = locator.getSingleDimensionValue(INTERNAL_VERSION);
if (internalVersion != null) {
result.add(item -> internalVersion.equals(item.getVersion()));
}
}
if (locator.isUnused(VERSION)) {
final String displayVersion = locator.getSingleDimensionValue(VERSION);
ValueCondition condition = ParameterCondition.createValueCondition(displayVersion);
if (displayVersion != null) {
result.add(item -> condition.matches(item.getDisplayVersion()));
}
}
final String commentLocatorText = locator.getSingleDimensionValue(COMMENT);
if (commentLocatorText != null) {
final String containsText = new Locator(commentLocatorText).getSingleDimensionValue("contains");
// Preserve legacy behaviour
if (containsText != null) {
result.add(item -> item.getDescription().contains(containsText));
// todo: check unprocessed dimensions
} else {
ValueCondition condition = ParameterCondition.createValueCondition(commentLocatorText);
result.add(item -> condition.matches(item.getDescription()));
}
}
if (locator.getUnusedDimensions().contains(PENDING)) {
final Boolean pending = locator.getSingleDimensionValueAsBoolean(PENDING);
if (pending != null) {
// todo: support multiple buildTypes here
final String buildTypeLocator = locator.getSingleDimensionValue(BUILD_TYPE);
final SBuildType buildType = buildTypeLocator == null ? null : myBuildTypeFinder.getBuildType(null, buildTypeLocator, false);
final Set<SVcsModification> pendingChanges = getPendingChanges(buildType, locator).map(mcd -> mcd.getSVcsModification()).collect(Collectors.toSet());
result.add(item -> FilterUtil.isIncludedByBooleanFilter(pending, pendingChanges.contains(item)));
}
}
final String fileLocator = locator.getSingleDimensionValue(FILE);
if (fileLocator != null) {
// todo: use conditions here
final String pathLocatorText = new Locator(fileLocator).getSingleDimensionValue("path");
// todo: check unknown locator dimensions
if (pathLocatorText != null) {
final String containsText = new Locator(pathLocatorText).getSingleDimensionValue("contains");
if (containsText != null) {
result.add(item -> {
for (VcsFileModification vcsFileModification : item.getChanges()) {
if (vcsFileModification.getFileName().contains(containsText)) {
return true;
}
}
return false;
});
// todo: check unknown locator dimensions
} else {
ValueCondition condition = ParameterCondition.createValueCondition(pathLocatorText);
result.add(item -> item.getChanges().stream().map(m -> m.getFileName()).anyMatch(condition::matches));
}
}
}
if (TeamCityProperties.getBoolean("rest.request.changes.check.enforceChangeViewPermission")) {
result.add(myPermissionChecker::checkCanView);
}
return new UnwrappingFilter<>(result, SVcsModificationOrChangeDescriptor::getSVcsModification);
}
Aggregations