Add option to hide whitepace changes in diffs

Co-authored-by: Florian Scholdei<florian.scholdei@cloudogu.com>
Co-authored-by: René Pfeuffer<rene.pfeuffer@cloudogu.com>


Reviewed-by: Florian Scholdei <florian.scholdei@cloudogu.com>
This commit is contained in:
Viktor Egorov
2024-05-14 11:33:48 +02:00
parent e5e2fd151c
commit c8ef99cf07
37 changed files with 688 additions and 498 deletions

View File

@@ -58,7 +58,7 @@ class DiffResultToDiffResultDtoMapper {
}
public DiffResultDto mapForIncoming(Repository repository, DiffResult result, String source, String target) {
String baseLink = resourceLinks.incoming().diffParsed(repository.getNamespace(), repository.getName(), source, target);
String baseLink = resourceLinks.incoming().diffParsed(repository.getNamespace(), repository.getName(), source, target) + "?ignoreWhitespace=" + result.getIgnoreWhitespace().name();
Links.Builder links = linkingTo().self(createSelfLink(result, baseLink));
appendNextChunkLinkIfNeeded(links, result, baseLink);
DiffResultDto dto = new DiffResultDto(links.build());
@@ -67,7 +67,7 @@ class DiffResultToDiffResultDtoMapper {
}
public DiffResultDto mapForRevision(Repository repository, DiffResult result, String revision) {
String baseLink = resourceLinks.diff().parsed(repository.getNamespace(), repository.getName(), revision);
String baseLink = resourceLinks.diff().parsed(repository.getNamespace(), repository.getName(), revision) + "?ignoreWhitespace=" + result.getIgnoreWhitespace().name();
Links.Builder links = linkingTo().self(createSelfLink(result, baseLink));
appendNextChunkLinkIfNeeded(links, result, baseLink);
DiffResultDto dto = new DiffResultDto(links.build());
@@ -96,25 +96,29 @@ class DiffResultToDiffResultDtoMapper {
private String createLinkWithLimitAndOffset(String baseLink, int offset, Integer limit) {
if (limit == null) {
return String.format("%s?offset=%s", baseLink, offset);
return String.format("%s&offset=%s", baseLink, offset);
} else {
return String.format("%s?offset=%s&limit=%s", baseLink, offset, limit);
return String.format("%s&offset=%s&limit=%s", baseLink, offset, limit);
}
}
private void setFiles(DiffResult result, DiffResultDto dto, Repository repository, String revision) {
List<DiffResultDto.FileDto> files = new ArrayList<>();
for (DiffFile file : result) {
files.add(mapFile(file, repository, revision));
files.add(mapFile(file, result, repository, revision));
}
dto.setFiles(files);
dto.setPartial(result.isPartial());
}
private DiffResultDto.FileDto mapFile(DiffFile file, Repository repository, String revision) {
private DiffResultDto.FileDto mapFile(DiffFile file, DiffResult result, Repository repository, String revision) {
Links.Builder links = linkingTo();
if (file.iterator().hasNext()) {
links.single(linkBuilder("lines", resourceLinks.source().content(repository.getNamespace(), repository.getName(), revision, file.getNewPath()) + "?start={start}&end={end}").build());
links.single(
linkBuilder(
"lines",
resourceLinks.source().content(repository.getNamespace(), repository.getName(), revision, file.getNewPath()) + "?ignoreWhitespace=" + result.getIgnoreWhitespace().name() + "&start={start}&end={end}").build()
);
}
if (!file.getChangeType().equals(DiffFile.ChangeType.ADD)) {
links.single(linkBuilder("oldFile", resourceLinks.source().content(repository.getNamespace(), repository.getName(), file.getOldRevision(), file.getOldPath())).build());

View File

@@ -44,6 +44,7 @@ import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.api.DiffCommandBuilder;
import sonia.scm.repository.api.DiffFormat;
import sonia.scm.repository.api.DiffResult;
import sonia.scm.repository.api.IgnoreWhitespaceLevel;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.util.HttpUtil;
@@ -99,13 +100,18 @@ public class DiffRootResource {
schema = @Schema(implementation = ErrorDto.class)
)
)
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("revision") String revision, @Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") @QueryParam("format") String format) throws IOException {
public Response get(@PathParam("namespace") String namespace,
@PathParam("name") String name,
@PathParam("revision") String revision,
@QueryParam("format") @Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") String format,
@QueryParam("ignoreWhitespace") @DefaultValue("NONE") IgnoreWhitespaceLevel ignoreWhitespace) throws IOException {
HttpUtil.checkForCRLFInjection(revision);
DiffFormat diffFormat = DiffFormat.valueOf(format);
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
DiffCommandBuilder.OutputStreamConsumer outputStreamConsumer = repositoryService.getDiffCommand()
.setRevision(revision)
.setFormat(diffFormat)
.setIgnoreWhitespace(ignoreWhitespace)
.retrieveContent();
return Response.ok((StreamingOutput) outputStreamConsumer::accept)
.header(HEADER_CONTENT_DISPOSITION, HttpUtil.createContentDispositionAttachmentHeader(String.format("%s-%s.diff", name, revision)))
@@ -147,6 +153,7 @@ public class DiffRootResource {
@PathParam("name") String name,
@PathParam("revision") String revision,
@QueryParam("limit") @Min(1) Integer limit,
@QueryParam("ignoreWhitespace") @DefaultValue("NONE") IgnoreWhitespaceLevel ignoreWhitespace,
@QueryParam("offset") @Min(0) Integer offset) throws IOException {
HttpUtil.checkForCRLFInjection(revision);
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
@@ -154,6 +161,7 @@ public class DiffRootResource {
.setRevision(revision)
.setLimit(limit)
.setOffset(offset)
.setIgnoreWhitespace(ignoreWhitespace)
.getDiffResult();
return parsedDiffMapper.mapForRevision(repositoryService.getRepository(), diffResult, revision);
}

View File

@@ -48,6 +48,7 @@ import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.repository.api.DiffCommandBuilder;
import sonia.scm.repository.api.DiffFormat;
import sonia.scm.repository.api.DiffResult;
import sonia.scm.repository.api.IgnoreWhitespaceLevel;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.util.HttpUtil;
@@ -192,9 +193,9 @@ public class IncomingRootResource {
@PathParam("name") String name,
@PathParam("source") String source,
@PathParam("target") String target,
@QueryParam("ignoreWhitespace") @DefaultValue("NONE") IgnoreWhitespaceLevel ignoreWhitespace,
@Pattern(regexp = DIFF_FORMAT_VALUES_REGEX) @DefaultValue("NATIVE") @QueryParam("format") String format) throws IOException {
HttpUtil.checkForCRLFInjection(source);
HttpUtil.checkForCRLFInjection(target);
DiffFormat diffFormat = DiffFormat.valueOf(format);
@@ -203,6 +204,7 @@ public class IncomingRootResource {
.setRevision(source)
.setAncestorChangeset(target)
.setFormat(diffFormat)
.setIgnoreWhitespace(ignoreWhitespace)
.retrieveContent();
return Response.ok((StreamingOutput) outputStreamConsumer::accept)
@@ -245,6 +247,7 @@ public class IncomingRootResource {
@PathParam("source") String source,
@PathParam("target") String target,
@QueryParam("limit") @Min(1) Integer limit,
@QueryParam("ignoreWhitespace") @DefaultValue("NONE") IgnoreWhitespaceLevel ignoreWhitespace,
@QueryParam("offset") @Min(0) Integer offset) throws IOException {
HttpUtil.checkForCRLFInjection(source);
HttpUtil.checkForCRLFInjection(target);
@@ -253,6 +256,7 @@ public class IncomingRootResource {
.setRevision(source)
.setAncestorChangeset(target)
.setLimit(limit)
.setIgnoreWhitespace(ignoreWhitespace)
.setOffset(offset)
.getDiffResult();
return Response.ok(parsedDiffMapper.mapForIncoming(repositoryService.getRepository(), diffResult, source, target)).build();