Skip to content

Commit

Permalink
feat(pattern): ✨ Persist spoon pattern results and expose them in the…
Browse files Browse the repository at this point in the history
… API (#725)
  • Loading branch information
MartinWitt authored Jun 10, 2023
1 parent d39076d commit 74feb39
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package xyz.keksdose.spoon.code_solver.analyzer.spoon;

import com.google.common.flogger.FluentLogger;
import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
Expand All @@ -14,11 +13,11 @@ public class SpoonAnalyzer {

private static final FluentLogger logger = FluentLogger.forEnclosingClass();

public List<AnalyzerResult> analyze(Path path) {
public List<SpoonAnalyzerResult> analyze(Path path) {

logger.atInfo().log("Received request for SpoonAnalyzer with path %s", path.toString());
CtModel model = buildModel(path);
List<AnalyzerResult> list = model.getAllTypes().stream()
List<SpoonAnalyzerResult> list = model.getAllTypes().stream()
.flatMap(v -> analyzeType(v).stream())
.collect(Collectors.toList());
logger.atInfo().log("SpoonAnalyzer finished with %d results", list.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
@Name("BadSmell")
public class BadSmellGraphQLDto {

private String analyzer;
private String identifier;
private String name;
private String messageMarkdown;
Expand All @@ -29,6 +30,7 @@ public BadSmellGraphQLDto(BadSmell badSmell) {
this.commitHashes = List.of(badSmell.getCommitHash());
this.filePath = badSmell.filePath();
this.position = badSmell.position();
this.analyzer = badSmell.getAnalyzer();
}

/**
Expand Down Expand Up @@ -142,4 +144,17 @@ public Position getPosition() {
public void setPosition(Position position) {
this.position = position;
}

/**
* @return the analyzer
*/
public String getAnalyzer() {
return analyzer;
}
/**
* @param analyzer the analyzer to set
*/
public void setAnalyzer(String analyzer) {
this.analyzer = analyzer;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package io.github.martinwitt.laughing_train.data;

import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult;
import java.io.Serializable;
import java.util.List;
import xyz.keksdose.spoon.code_solver.analyzer.spoon.SpoonAnalyzerResult;

public sealed interface SpoonPatternAnalyzerResult extends Serializable {
record Success(List<AnalyzerResult> result, Project project) implements SpoonPatternAnalyzerResult {}
record Success(List<SpoonAnalyzerResult> result, Project project) implements SpoonPatternAnalyzerResult {}

record Failure(String message) implements SpoonPatternAnalyzerResult {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import java.util.Queue;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.apache.commons.io.FileUtils;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
Expand Down Expand Up @@ -133,12 +134,13 @@ private void mineRandomRepo() {
private void saveSpoonResults(Success spoonSuccess) {
spoonSuccess.project().runInContext(() -> {
try {
List<AnalyzerResult> results = spoonSuccess.result();
List<? extends AnalyzerResult> results = spoonSuccess.result();
if (results.isEmpty()) {
logger.atInfo().log("No results for %s", spoonSuccess);
return Optional.empty();
}
String content = printFormattedResults(spoonSuccess, results);
var list = results.stream().map(v -> (AnalyzerResult) v).collect(Collectors.toList());
String content = printFormattedResults(spoonSuccess, list);
var laughingRepo = getLaughingRepo();
updateOrCreateContent(laughingRepo, spoonSuccess.project().name(), content);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.flogger.FluentLogger;
import io.github.martinwitt.laughing_train.data.Project;
import io.github.martinwitt.laughing_train.data.QodanaResult;
import io.github.martinwitt.laughing_train.data.SpoonPatternAnalyzerResult;
import io.github.martinwitt.laughing_train.persistence.BadSmell;
import io.github.martinwitt.laughing_train.persistence.repository.BadSmellRepository;
import io.smallrye.mutiny.Multi;
Expand Down Expand Up @@ -30,8 +31,26 @@ void persistResults(QodanaResult result) {
.collect()
.with(Collectors.counting())
.subscribe()
.with(badSmell ->
logger.atInfo().log("Persisted %d bad smells for project %s", badSmell, project.name()));
.with(badSmell -> logger.atInfo().log(
"Persisted %d qodana bad smells for project %s", badSmell, project.name()));
}
}

void persistResults(SpoonPatternAnalyzerResult result) {
if (result instanceof SpoonPatternAnalyzerResult.Success success) {
Project project = success.project();
Multi.createFrom()
.iterable(success.result())
.map(badSmell -> new BadSmell(badSmell, project.name(), project.url(), project.commitHash()))
.filter(v -> badSmellRepository
.findByIdentifier(v.getIdentifier())
.isEmpty())
.map(badSmellRepository::save)
.collect()
.with(Collectors.counting())
.subscribe()
.with(badSmell -> logger.atInfo().log(
"Persisted %d spoon bad smells for project %s", badSmell, project.name()));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,10 @@ public SpoonPatternAnalyzerResult analyze(AnalyzerRequest request) {
if (request instanceof AnalyzerRequest.WithProject project) {
SpoonAnalyzer analyzer = new SpoonAnalyzer();

return new SpoonPatternAnalyzerResult.Success(
SpoonPatternAnalyzerResult.Success success = new SpoonPatternAnalyzerResult.Success(
analyzer.analyze(project.project().folder().toPath()), project.project());
persistResults(success);
return success;
} else {
return new SpoonPatternAnalyzerResult.Failure("Unknown request type");
}
Expand All @@ -45,6 +47,10 @@ public SpoonPatternAnalyzerResult analyze(AnalyzerRequest request) {
}
}

private void persistResults(SpoonPatternAnalyzerResult result) {
analyzerResultPersistenceService.persistResults(result);
}

@Readiness
@ApplicationScoped
private static class HealthCheck implements AsyncHealthCheck {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClientBuilder;
import jakarta.inject.Inject;
import java.util.regex.Pattern;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

@QuarkusTest
Expand Down Expand Up @@ -59,7 +58,6 @@ private BadSmell createWithMessage(String ruleID) {
}

@Test
@Disabled("Only for local testing")
void getBadSmellFromLive() throws Exception {
client = DynamicGraphQLClientBuilder.newBuilder()
.url("https://laughing-train.keksdose.xyz/graphql")
Expand All @@ -69,11 +67,11 @@ void getBadSmellFromLive() throws Exception {
OperationType.QUERY,
field(
"byRuleID",
Argument.args(Argument.arg("ruleID", "InnerClassMayBeStatic")),
Argument.args(Argument.arg("ruleID", "UNNECESSARY_TOSTRING_CALL")),
field("ruleID"),
field("message"),
field("projectName"),
field("filePath"),
field("name"),
field("identifier"),
field("messageMarkdown"),
field("position", field("startLine")))));
Response response = client.executeSync(document);
System.out.println(response.getData().toString().replaceAll(Pattern.quote("},{"), "\n"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,19 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import io.github.martinwitt.laughing_train.domain.entity.AnalyzerResult;
import io.github.martinwitt.laughing_train.domain.value.Position;
import io.github.martinwitt.laughing_train.utils.TestAnalyzerResult;
import java.util.List;
import org.instancio.Instancio;
import org.junit.jupiter.api.Test;
import xyz.keksdose.spoon.code_solver.analyzer.spoon.SpoonAnalyzerResult;

public class SpoonPatternAnalyzerResultTest {

@Test
public void testSuccessRecord() {
Project project = new Project("test-owner", "test-name", null, "test-url", "#9999");
AnalyzerResult result1 = new TestAnalyzerResult("test-rule-1", new Position(0, 0, 0, 0, 0, 0));
AnalyzerResult result2 = new TestAnalyzerResult("test-rule-2", new Position(0, 0, 0, 0, 0, 0));
List<AnalyzerResult> results = List.of(result1, result2);
SpoonAnalyzerResult result1 = Instancio.create(SpoonAnalyzerResult.class);
SpoonAnalyzerResult result2 = Instancio.create(SpoonAnalyzerResult.class);
List<SpoonAnalyzerResult> results = List.of(result1, result2);
SpoonPatternAnalyzerResult.Success success = new SpoonPatternAnalyzerResult.Success(results, project);
assertEquals(results, success.result());
assertEquals(project, success.project());
Expand Down

0 comments on commit 74feb39

Please sign in to comment.