Skip to content

Commit

Permalink
Migrating files
Browse files Browse the repository at this point in the history
  • Loading branch information
frankreyesgarcia committed Aug 23, 2024
1 parent 857134e commit d17dd4f
Show file tree
Hide file tree
Showing 32 changed files with 977 additions and 245 deletions.
76 changes: 68 additions & 8 deletions src/main/java/se/kth/BreakingGood.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
package se.kth;

import se.kth.breaking_changes.ApiMetadata;
import se.kth.log_Analyzer.MavenErrorLog;
import se.kth.core.ChangesBetweenVersions;
import se.kth.explaining.ExplanationTemplate;
import se.kth.explaining.JavaVersionIncompatibilityTemplate;
import se.kth.java_version.JavaIncompatibilityAnalyzer;
import se.kth.java_version.JavaVersionFailure;
import se.kth.java_version.JavaVersionIncompatibility;
import se.kth.java_version.VersionFinder;
import se.kth.log_Analyzer.MavenLogAnalyzer;
import se.kth.spoon_compare.Client;
import se.kth.werror.WError;
import spoon.reflect.CtModel;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class BreakingGood {
Expand All @@ -22,17 +31,19 @@ public class BreakingGood {
* @return The error log
* @throws IOException If the log could not be read
*/
public static MavenErrorLog parseLog(Path logPath, Path client) throws IOException {
public static MavenLogAnalyzer parseLog(File logPath, Path client) throws IOException {
Path mavenLog = null;
// Parse log
if (!Files.exists(logPath)) {
if (logPath == null || !Files.exists(logPath.toPath())) {
String log = executeMvnCleanTest(client);
if (log != null) {
logPath = Path.of(log);
mavenLog = Path.of(log);
}
} else {
mavenLog = logPath.toPath();
}
MavenLogAnalyzer mavenLogAnalyzer = new MavenLogAnalyzer(
new File(logPath.toString()));
return mavenLogAnalyzer.analyzeCompilationErrors();
return new MavenLogAnalyzer(
new File(mavenLog.toString()));
}


Expand Down Expand Up @@ -60,7 +71,7 @@ private static String executeMvnCleanTest(Path directory) {
processBuilder.redirectOutput(tempFile);
Process process = processBuilder.start();
int exitCode = process.waitFor();
if (exitCode != 0) {
if (exitCode == 0) {
System.out.println("Maven clean test command failed with exit code " + exitCode);
return null;
} else {
Expand All @@ -74,4 +85,53 @@ private static String executeMvnCleanTest(Path directory) {
}


public static void wErrorAnalysis(String logPath, String client, ApiMetadata oldApiVersion, ApiMetadata newApiVersion) throws IOException {

ChangesBetweenVersions changes = new ChangesBetweenVersions(oldApiVersion, newApiVersion);
WError werror = new WError("Explanation.md");
try {
werror.analyzeWerror(logPath, client, changes);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

/**
* Generate the explanation for a Java version incompatibility error
*
* @param project The project path
* @param logFile The log file path
* @param oldApiVersion The old API version
* @param newApiVersion The new API version
* @throws IOException If the explanation could not be generated
*/
public static void javaVersionIncompatibilityErrorExplanation(Path project, Path logFile, ApiMetadata oldApiVersion, ApiMetadata newApiVersion) throws IOException {
ChangesBetweenVersions changes = new ChangesBetweenVersions(oldApiVersion, newApiVersion);
Client client = new Client(project);

VersionFinder versionFinder = new VersionFinder();

// generateVersionExplanation(changes, client.getSourcePath().toString(), client.getSourcePath().toString() + "/%s.log".formatted(breakingUpdate.breakingCommit()));

Map<String, List<Integer>> javaVersions = versionFinder.findJavaVersions(client.getSourcePath().toString());
JavaIncompatibilityAnalyzer javaIncompatibilityAnalyzer = new JavaIncompatibilityAnalyzer();
Set<String> errorList = javaIncompatibilityAnalyzer.parseErrors(logFile.toString());

Map<JavaVersionIncompatibility, Set<String>> versionFailures = JavaIncompatibilityAnalyzer.extractVersionErrors(errorList);

JavaVersionFailure javaVersionFailure = new JavaVersionFailure();
javaVersionFailure.setJavaInWorkflowFiles(javaVersions);
javaVersionFailure.setDiffVersionErrors(versionFailures);
javaVersionFailure.setErrorMessages(errorList);
javaVersionFailure.setIncompatibilityVersion();


ExplanationTemplate explanationTemplate = new JavaVersionIncompatibilityTemplate(
changes, "JavaVersionIncompatibility.md",
javaVersionFailure
);
explanationTemplate.generateTemplate();
}


}
78 changes: 62 additions & 16 deletions src/main/java/se/kth/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
import picocli.CommandLine;
import se.kth.breaking_changes.ApiChange;
import se.kth.breaking_changes.ApiMetadata;
import se.kth.breaking_changes.BreakingGoodOptions;
import se.kth.breaking_changes.JApiCmpAnalyze;
import se.kth.core.Changes;
import se.kth.core.ChangesBetweenVersions;
import se.kth.core.CombineResults;
import se.kth.data.JsonUtils;
import se.kth.explaining.CompilationErrorTemplate;
import se.kth.explaining.ExplanationTemplate;
import se.kth.japianalysis.BreakingChange;
import se.kth.log_Analyzer.MavenErrorLog;
import se.kth.log_Analyzer.MavenLogAnalyzer;
import se.kth.sponvisitors.BreakingChangeVisitor;
import se.kth.spoon_compare.Client;
import se.kth.transitive_changes.CompareTransitiveDependency;
import se.kth.transitive_changes.Dependency;
Expand All @@ -19,8 +25,12 @@
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.Set;

import static se.kth.BreakingGood.javaVersionIncompatibilityErrorExplanation;
import static se.kth.BreakingGood.wErrorAnalysis;

public class Main {
public static void main(String[] args) {
int exitCode = new CommandLine(new CLIEntryPoint()).execute(args);
Expand Down Expand Up @@ -56,25 +66,58 @@ public void run() {

ApiMetadata oldApiMetadata = new ApiMetadata(oldDependency.toFile().getName(), oldDependency);
ApiMetadata newApiMetadata = new ApiMetadata(newDependency.toFile().getName(), newDependency);
Client client = new Client(project);

JApiCmpAnalyze jApiCmpAnalyze = new JApiCmpAnalyze(oldApiMetadata, newApiMetadata);

Set<ApiChange> apiChanges = jApiCmpAnalyze.useJApiCmp();

try {
MavenErrorLog errorLog = BreakingGood.parseLog(mavenLog.toPath(), project);

CtModel model = BreakingGood.spoonAnalyzer(client, oldApiMetadata, project);
MavenLogAnalyzer mavenLogAnalyzer = BreakingGood.parseLog(mavenLog, project);


// Check if the log contains the -Werror flag
boolean isWerror = mavenLogAnalyzer.isWerror(mavenLogAnalyzer.getLogFile().getAbsolutePath());

if (isWerror) {
// If the log contain the -Werror flag, analyze the log and generate a new log with the -Werror flag
System.out.println("The log contains the -Werror flag");
wErrorAnalysis(mavenLogAnalyzer.getLogFile().getAbsolutePath(), project.toString(), oldApiMetadata, newApiMetadata);
} else {
// Check if the log contains a Java version incompatibility error
boolean isJavaVersionIncompatibility = mavenLogAnalyzer.isJavaVersionIncompatibilityError(mavenLogAnalyzer.getLogFile().getAbsolutePath());

if (isJavaVersionIncompatibility) {
System.out.println("The log file contains a Java version incompatibility error.");
javaVersionIncompatibilityErrorExplanation(
project,
mavenLog.toPath(),
oldApiMetadata,
newApiMetadata);
} else {

CombineResults combineResults = new CombineResults(apiChanges, oldApiMetadata, newApiMetadata, errorLog, model);
//remove project name folder
combineResults.setProject(project.toString().substring(0, project.toString().lastIndexOf("/")));
Changes changes = combineResults.analyze();
JApiCmpAnalyze jApiCmpAnalyze = new JApiCmpAnalyze(oldApiMetadata, newApiMetadata);
Set<ApiChange> apiChanges = jApiCmpAnalyze.useJApiCmp();
List<BreakingChange> breakingChanges = jApiCmpAnalyze.useJApiCmp_v2();
Client client = new Client(project);
client.setClasspath(List.of(oldDependency));
CtModel model = client.createModel();

// ExplanationTemplate explanationTemplate = new CompilationErrorTemplate(changes, "Explanations/" + project.toFile().getName() + ".md");
// explanationTemplate.generateTemplate();
MavenErrorLog errorLog = mavenLogAnalyzer.analyzeCompilationErrors();

CombineResults combineResults = new CombineResults(apiChanges, oldApiMetadata, newApiMetadata, errorLog, model);
//remove project name folder
combineResults.setProject(project.toString().substring(0, project.toString().lastIndexOf("/")));

List<BreakingChangeVisitor> visitors = jApiCmpAnalyze.getVisitors(breakingChanges);
BreakingGoodOptions options = new BreakingGoodOptions();

ChangesBetweenVersions changesV2 = combineResults.analyze_v2(visitors, options);

if (!changesV2.brokenChanges().isEmpty()) {
ExplanationTemplate explanationTemplate = new CompilationErrorTemplate(changesV2, "Explanation.md");
explanationTemplate.generateTemplate();
}

}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
Expand All @@ -95,15 +138,18 @@ public void run() {
ApiMetadata oldApiMetadata = new ApiMetadata(oldDependency.toFile().getName(), oldDependency);
ApiMetadata newApiMetadata = new ApiMetadata(newDependency.toFile().getName(), newDependency);

Set<Dependency> v1 = MavenTree.read(oldApiMetadata);
Set<Dependency> v2 = MavenTree.read(newApiMetadata);
Dependency o = new Dependency("com.google.guava", "guava", "30.1-jre", "jar", "compile");
Dependency n = new Dependency("com.google.guava", "guava", "30.1.1-jre", "jar", "compile");

Set<Dependency> v1 = MavenTree.read(oldApiMetadata, o);
Set<Dependency> v2 = MavenTree.read(newApiMetadata, n);

Set<PairTransitiveDependency> transitiveDependencies = MavenTree.diff(v1, v2);

for (PairTransitiveDependency pair : transitiveDependencies) {
try {
CompareTransitiveDependency compareTransitiveDependency = new CompareTransitiveDependency(pair.newVersion(), pair.oldVersion());
compareTransitiveDependency.compareDependency();
compareTransitiveDependency.getChangesBetweenDependencies();
System.out.println("Breaking changes for " + pair.newVersion() + " and " + pair.oldVersion());
System.out.println("Breaking Changes amount: " + compareTransitiveDependency.getBreakingChanges().size());

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/se/kth/breaking_changes/ApiMetadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
@lombok.Getter
public class ApiMetadata {

private static final Logger log = LoggerFactory.getLogger(ApiMetadata.class);


String name;

Expand Down Expand Up @@ -90,7 +90,7 @@ private List<String> buildClasspath() {
}

private List<String> buildClasspathFromPom(Path pom) {
System.out.println("Building classpath from " + pom);

try {
if (pom.toFile().exists()) {
SpoonPom spoonPom = new SpoonPom(
Expand All @@ -110,7 +110,7 @@ private List<String> buildClasspathFromPom(Path pom) {
return Collections.emptyList();
}

public Path extractPomFromJar(Path toSave) {
public Path extractPomFromJar(Path toSave) {
try (JarFile jarFile = new JarFile(file.toFile())) {
List<JarEntry> poms = jarFile.stream().filter(e -> e.getName().endsWith("pom.xml")).toList();

Expand Down
88 changes: 83 additions & 5 deletions src/main/java/se/kth/breaking_changes/Download.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class Download {

Expand Down Expand Up @@ -69,19 +68,98 @@ private static String getUrlOfRequestedJar(String indexPageContent, String index
}
}

public static File getJarFile(String groupId, String artifactId, String version, Path directory)
private static String getUrlOfRequestedPom(String indexPageContent, String indexPageUrl) {
List<String> candidates = Jsoup.parse(indexPageContent).select("a").stream()
.map(e -> e.attr("href"))
.toList();

Optional<String> artifactJar;
if (indexPageUrl.contains("https://repo.jenkins-ci.org/artifactory/releases")) {
artifactJar = candidates.stream()
.filter(c -> c.endsWith(".pom"))
.findFirst();
} else {
artifactJar = candidates.stream()
.filter(c -> c.endsWith(".pom"))
.filter(c -> !c.contains("sources"))
.filter(c -> !c.contains("javadoc"))
.filter(c -> !c.contains("tests"))
.filter(c -> !c.contains("test"))
.filter(c -> !c.contains("config"))
.findFirst();
}

// Optional<String> artifactJar = candidates.stream()
// .filter(c -> c.endsWith(".pom"))
// .filter(c -> !c.contains("sources"))
// .filter(c -> !c.contains("javadoc"))
// .filter(c -> !c.contains("tests"))
// .filter(c -> !c.contains("test"))
// .filter(c -> !c.contains("config"))
// .findFirst();

if (artifactJar.isPresent()) {
String artifactJarName = artifactJar.get();
// java.net.URI has the worst APIs ever
if (artifactJarName.startsWith("https://") || artifactJarName.startsWith("http://")) {
return artifactJarName;
}
return indexPageUrl + artifactJarName;
} else {
System.err.println("Could not find jar for " + indexPageUrl);
return null;
}
}

private static String getUrlOfRequestedSource(String indexPageContent, String indexPageUrl) {
List<String> candidates = Jsoup.parse(indexPageContent).select("a").stream()
.map(e -> e.attr("href"))
.toList();

Optional<String> artifactJar = candidates.stream()
.filter(c -> c.endsWith("-sources.jar"))
.filter(c -> c.contains("sources"))
.filter(c -> !c.contains("javadoc"))
.filter(c -> !c.contains("tests"))
.filter(c -> !c.contains("test"))
.filter(c -> !c.contains("config"))
.findFirst();

if (artifactJar.isPresent()) {
String artifactJarName = artifactJar.get();
// java.net.URI has the worst APIs ever
if (artifactJarName.startsWith("https://") || artifactJarName.startsWith("http://")) {
return artifactJarName;
}
return indexPageUrl + artifactJarName;
} else {
System.err.println("Could not find jar for " + indexPageUrl);
return null;
}
}

public static File getJarFile(String groupId, String artifactId, String version, Path directory, String extension)
throws IOException, InterruptedException {
for (String repositoryUrl : repositoryUrls.values()) {
String url = getArtifactUrl(groupId, artifactId, version, repositoryUrl);
String indexPageContent = getIndexPageOfRepository(url);
if (indexPageContent != null) {
String jarUrl = getUrlOfRequestedJar(indexPageContent, url);

String jarUrl = "";
if (extension.equals("jar"))
jarUrl = getUrlOfRequestedJar(indexPageContent, url);
else if (extension.equals("sources"))
jarUrl = getUrlOfRequestedSource(indexPageContent, url);
else if (extension.equals("pom"))
jarUrl = getUrlOfRequestedPom(indexPageContent, url);
if (jarUrl != null) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest.newBuilder().uri(URI.create(jarUrl)).build();

final var resolve = directory.resolve(String.format("%s-%s", artifactId, version) + ".jar");
String fileExtension = extension.equals("pom") ? "xml" : extension;
if (extension.equals("sources"))
fileExtension = "zip";
final var resolve = directory.resolve(String.format("%s-%s", artifactId, version) + "." + fileExtension);
HttpResponse<Path> result = client.send(request, HttpResponse.BodyHandlers.ofFile(resolve));
return result.body().toFile();
}
Expand Down
2 changes: 0 additions & 2 deletions src/main/java/se/kth/breaking_changes/JApiCmpAnalyze.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@
@lombok.Setter
@lombok.Getter
public class JApiCmpAnalyze {
private static final Logger log = LoggerFactory.getLogger(JApiCmpAnalyze.class);


private final ApiMetadata oldJar;
private final ApiMetadata newJar;
Expand Down
Loading

0 comments on commit d17dd4f

Please sign in to comment.