Skip to content

Commit

Permalink
Rework how artifact-compare works
Browse files Browse the repository at this point in the history
Fix #1871
  • Loading branch information
laeubi committed Dec 13, 2022
1 parent 742a4a1 commit d406c48
Show file tree
Hide file tree
Showing 14 changed files with 213 additions and 104 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,25 @@
*/
public interface ArtifactDelta {

/**
* A delta that represents no difference was found
*/
public static final ArtifactDelta NO_DIFFERENCE = null;

/**
* a default instance that indicates there is a difference but can't tell any further details
*/
public static final SimpleArtifactDelta DEFAULT = new SimpleArtifactDelta("different");
public static final ArtifactDelta DEFAULT = new SimpleArtifactDelta("different");

/**
* a default instance that indicate an item is only present in the baseline but no more details
*/
public static final SimpleArtifactDelta BASELINE_ONLY = new SimpleArtifactDelta("present in baseline only");
public static final ArtifactDelta BASELINE_ONLY = new SimpleArtifactDelta("present in baseline only");

/**
* a default instance that indicate an item is missing from what is found in the baseline
*/
public static final SimpleArtifactDelta MISSING_FROM_BASELINE = new SimpleArtifactDelta("not present in baseline");
public static final ArtifactDelta MISSING_FROM_BASELINE = new SimpleArtifactDelta("not present in baseline");

/**
* @return description of the delta, never null.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2022 Christoph Läubrich and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Läubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.artifactcomparator;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.Arrays;

import org.apache.commons.io.IOUtils;

/**
* Input stream to carry some important information for comparison and allows direct access to the
* underlying buffer.
*
* @author christoph
*
*/
public class ComparatorInputStream extends ByteArrayInputStream {

private final byte[] content;
private final String name;

public ComparatorInputStream(InputStream stream, String name) throws IOException {
this(IOUtils.toByteArray(stream), name);
}

public ComparatorInputStream(byte[] content, String name) {
super(content);
this.content = content;
this.name = name;
}

/**
*
* @return the total number of bytes of this stream
*/
public int size() {
return content.length;
}

/**
* @return a new stream backed by this stream data that could be read independently
*/
public InputStream asNewStream() {
return new ByteArrayInputStream(content);
}

/**
* @param charset
* @return the content of this stream as a string with the given charset
*/

public String asString(Charset charset) {
return new String(content, charset);
}

public byte[] asBytes() {
return content.clone();
}

/**
* Compares this stream directly to another stream on a by-by-byte basis, this is independent of
* the state of the streams, e.g number of bytes read, closing or mark state.
*
* @param other
* @return {@link ArtifactDelta#DEFAULT} if there is any difference or <code>null</code>
* otherwise.
*/
public ArtifactDelta compare(ComparatorInputStream other) {
if (Arrays.equals(content, other.content)) {
return null;
}
return ArtifactDelta.DEFAULT;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,16 @@
package org.eclipse.tycho.zipcomparator.internal;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;
Expand All @@ -40,24 +39,20 @@ public class ClassfileComparator implements ContentsComparator {
// which is not exported, so can't use this either.

@Override
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException {
byte[] baselineBytes = baseline.readAllBytes();
byte[] reactorBytes = reactor.readAllBytes();

String baselineDisassemble = null;
String reactorDisassemble = null;

public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException {
boolean equal;
try {
baselineDisassemble = disassemble(baselineBytes);
reactorDisassemble = disassemble(reactorBytes);
equal = baselineDisassemble.equals(reactorDisassemble);
String baselineDisassemble = disassemble(baseline.asBytes());
String reactorDisassemble = disassemble(reactor.asBytes());
if (baselineDisassemble.equals(reactorDisassemble)) {
return ArtifactDelta.NO_DIFFERENCE;
}
return new SimpleArtifactDelta("different", baselineDisassemble, reactorDisassemble);
} catch (RuntimeException e) {
// asm could not disassemble one of the classes, fallback to byte-to-byte comparison
equal = Arrays.equals(baselineBytes, reactorBytes);
return baseline.compare(reactor);
}

return !equal ? new SimpleArtifactDelta("different", baselineDisassemble, reactorDisassemble) : null;
}

private String disassemble(byte[] bytes) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,23 @@

import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;

public interface ContentsComparator {
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException;

/**
* Computes the delta for the given {@link InputStream}s, the streams passed will support
* mark/reset for repeated reads.
*
* @param baseline
* the baseline data
* @param reactor
* the reactor data or current project state
* @param data
* @return the {@link ArtifactDelta} or {@link ArtifactDelta#NO_DIFFERENCE} if the content is
* semantically the same
* @throws IOException
*/
public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@
package org.eclipse.tycho.zipcomparator.internal;

import java.io.IOException;
import java.io.InputStream;

import org.codehaus.plexus.component.annotations.Component;
import org.codehaus.plexus.util.IOUtil;
import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;

@Component(role = ContentsComparator.class, hint = DefaultContentsComparator.TYPE)
public class DefaultContentsComparator implements ContentsComparator {

public static final String TYPE = "default";

@Override
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException {
return !IOUtil.contentEquals(baseline, reactor) ? ArtifactDelta.DEFAULT : null;
public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException {
return baseline.compare(reactor);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.eclipse.tycho.zipcomparator.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeMap;
Expand All @@ -24,6 +23,7 @@
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;

@Component(role = ContentsComparator.class, hint = ManifestComparator.TYPE)
public class ManifestComparator implements ContentsComparator {
Expand All @@ -45,7 +45,8 @@ public class ManifestComparator implements ContentsComparator {
// TODO make it possible to disable default ignores and add custom ignore

@Override
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException {
public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException {
TreeMap<String, ArtifactDelta> result = new TreeMap<>();

Manifest manifest = new Manifest(baseline);
Expand Down Expand Up @@ -76,7 +77,7 @@ public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, Compari
}
}

return !result.isEmpty() ? new CompoundArtifactDelta("different", result) : null;
return !result.isEmpty() ? new CompoundArtifactDelta("different", result) : ArtifactDelta.NO_DIFFERENCE;
}

private void addDelta(TreeMap<String, ArtifactDelta> result, Name key, String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.eclipse.tycho.zipcomparator.internal;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
Expand All @@ -23,6 +22,7 @@
import org.eclipse.tycho.artifactcomparator.ArtifactComparator;
import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;

@Component(role = ContentsComparator.class, hint = NestedZipComparator.TYPE)
public class NestedZipComparator implements ContentsComparator {
Expand All @@ -32,7 +32,8 @@ public class NestedZipComparator implements ContentsComparator {
private ArtifactComparator zipComparator;

@Override
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException {
public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException {
Path baselineZip = Files.createTempFile("baseline", ".zip");
Path reactorZip = Files.createTempFile("reactor", ".zip");
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
package org.eclipse.tycho.zipcomparator.internal;

import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedHashSet;
import java.util.Map.Entry;
import java.util.Properties;
Expand All @@ -23,13 +22,15 @@
import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.tycho.artifactcomparator.ArtifactComparator.ComparisonData;
import org.eclipse.tycho.artifactcomparator.ArtifactDelta;
import org.eclipse.tycho.artifactcomparator.ComparatorInputStream;

@Component(role = ContentsComparator.class, hint = PropertiesComparator.TYPE)
public class PropertiesComparator implements ContentsComparator {
public static final String TYPE = "properties";

@Override
public ArtifactDelta getDelta(InputStream baseline, InputStream reactor, ComparisonData data) throws IOException {
public ArtifactDelta getDelta(ComparatorInputStream baseline, ComparatorInputStream reactor, ComparisonData data)
throws IOException {
TreeMap<String, ArtifactDelta> result = new TreeMap<>();

Properties props = new Properties();
Expand Down
Loading

0 comments on commit d406c48

Please sign in to comment.