Skip to content

Commit

Permalink
vcs: add DiffComparator for comparing diffs
Browse files Browse the repository at this point in the history
Reviewed-by: rwestberg
  • Loading branch information
edvbld committed Nov 11, 2020
1 parent 2e35aff commit 0a8b1e7
Show file tree
Hide file tree
Showing 2 changed files with 107 additions and 84 deletions.
92 changes: 8 additions & 84 deletions bots/pr/src/main/java/org/openjdk/skara/bots/pr/CheckRun.java
Expand Up @@ -248,93 +248,17 @@ private void updateReadyForReview(PullRequestCheckIssueVisitor visitor, List<Str
}

private boolean updateClean(Commit commit) {
var backportDiff = commit.parentDiffs().get(0);
var prDiff = pr.diff();
var isClean = DiffComparator.areFuzzyEqual(backportDiff, prDiff);
var hasCleanLabel = labels.contains("clean");
var originalPatches = new HashMap<String, Patch>();
for (var patch : commit.parentDiffs().get(0).patches()) {
originalPatches.put(patch.toString(), patch);
}
var prPatches = new HashMap<String, Patch>();
for (var patch : pr.diff().patches()) {
prPatches.put(patch.toString(), patch);
}

if (originalPatches.size() != prPatches.size()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}

var descriptions = new HashSet<>(originalPatches.keySet());
descriptions.removeAll(prPatches.keySet());
if (!descriptions.isEmpty()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}

for (var desc : originalPatches.keySet()) {
var original = originalPatches.get(desc).asTextualPatch();
var backport = prPatches.get(desc).asTextualPatch();
if (original.hunks().size() != backport.hunks().size()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
if (original.additions() != backport.additions()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
if (original.deletions() != backport.deletions()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
for (var i = 0; i < original.hunks().size(); i++) {
var originalHunk = original.hunks().get(i);
var backportHunk = backport.hunks().get(i);

if (originalHunk.source().lines().size() != backportHunk.source().lines().size()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
var sourceLines = new HashSet<>(originalHunk.source().lines());
sourceLines.removeAll(backportHunk.source().lines());
if (!sourceLines.isEmpty()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}

if (originalHunk.target().lines().size() != backportHunk.target().lines().size()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
var targetLines = new HashSet<>(originalHunk.target().lines());
targetLines.removeAll(backportHunk.target().lines());
if (!targetLines.isEmpty()) {
if (hasCleanLabel) {
pr.removeLabel("clean");
}
return false;
}
}
}

if (!hasCleanLabel) {
if (isClean && !hasCleanLabel) {
pr.addLabel("clean");
}
return true;
if (!isClean && hasCleanLabel) {
pr.removeLabel("clean");
}
return isClean;
}

private Optional<HostedCommit> backportedFrom() {
Expand Down
99 changes: 99 additions & 0 deletions vcs/src/main/java/org/openjdk/skara/vcs/DiffComparator.java
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.openjdk.skara.vcs;

import java.io.*;
import java.nio.file.*;
import java.util.*;

public class DiffComparator {
public static boolean areFuzzyEqual(Diff a, Diff b) {
var aPatches = new HashMap<String, Patch>();
for (var patch : a.patches()) {
aPatches.put(patch.toString(), patch);
}
var bPatches = new HashMap<String, Patch>();
for (var patch : b.patches()) {
bPatches.put(patch.toString(), patch);
}

if (aPatches.size() != bPatches.size()) {
return false;
}
var onlyInA = new HashSet<>(aPatches.keySet());
onlyInA.removeAll(bPatches.keySet());
if (!onlyInA.isEmpty()) {
return false;
}
var onlyInB = new HashSet<>(bPatches.keySet());
onlyInB.removeAll(aPatches.keySet());
if (!onlyInB.isEmpty()) {
return false;
}

for (var key : aPatches.keySet()) {
var aPatch = aPatches.get(key).asTextualPatch();
var bPatch = bPatches.get(key).asTextualPatch();
if (!areFuzzyEqual(aPatch, bPatch)) {
return false;
}
}

return true;
}

private static boolean areFuzzyEqual(Patch a, Patch b) {
var aHunks = a.asTextualPatch().hunks();
var bHunks = b.asTextualPatch().hunks();
if (aHunks.size() != bHunks.size()) {
return false;
}
for (var i = 0; i < aHunks.size(); i++) {
var aHunk = aHunks.get(i);
var bHunk = bHunks.get(i);

if (aHunk.source().lines().size() != bHunk.source().lines().size()) {
return false;
}
for (var j = 0; j < aHunk.source().lines().size(); j++) {
var aLine = aHunk.source().lines().get(i);
var bLine = bHunk.source().lines().get(i);
if (!aLine.equals(bLine)) {
return false;
}
}

if (aHunk.target().lines().size() != bHunk.target().lines().size()) {
return false;
}
for (var j = 0; j < aHunk.target().lines().size(); j++) {
var aLine = aHunk.target().lines().get(i);
var bLine = bHunk.target().lines().get(i);
if (!aLine.equals(bLine)) {
return false;
}
}
}
return true;
}
}

1 comment on commit 0a8b1e7

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.