Skip to content

Commit 45218b5

Browse files
committed
Merge branch 'contributor-activity' into 'main'
add contributor data extraction, GitHub social activity fetching See merge request ExplorViz/code/code-agent!13
2 parents 40f7d9a + 55218bb commit 45218b5

18 files changed

Lines changed: 927 additions & 5 deletions

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ dependencies {
2323
implementation 'io.quarkus:quarkus-rest-jackson'
2424
implementation 'io.quarkus:quarkus-grpc'
2525

26+
// GraphQL Client
27+
implementation 'io.quarkus:quarkus-smallrye-graphql-client'
28+
2629
implementation 'com.google.protobuf:protobuf-java-util'
2730

2831
// Java Parsing

src/main/java/net/explorviz/code/analysis/api/AnalysisRequest.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public void setRoot(final String root) {
5454
private String applicationRoot;
5555
private List<ApplicationSpec> applications;
5656

57+
private boolean fetchSocialData = false;
58+
private String fetchEndDate;
59+
private Integer socialDataTimeFrameDays;
60+
5761
public AnalysisRequest() {
5862
}
5963

@@ -185,6 +189,30 @@ public void setCommitAnalysisLimit(final Integer commitAnalysisLimit) {
185189
this.commitAnalysisLimit = commitAnalysisLimit;
186190
}
187191

192+
public boolean isFetchSocialData() {
193+
return fetchSocialData;
194+
}
195+
196+
public void setFetchSocialData(final boolean fetchSocialData) {
197+
this.fetchSocialData = fetchSocialData;
198+
}
199+
200+
public String getFetchEndDate() {
201+
return fetchEndDate;
202+
}
203+
204+
public void setFetchEndDate(final String fetchEndDate) {
205+
this.fetchEndDate = fetchEndDate;
206+
}
207+
208+
public Integer getSocialDataTimeFrameDays() {
209+
return socialDataTimeFrameDays;
210+
}
211+
212+
public void setSocialDataTimeFrameDays(final Integer socialDataTimeFrameDays) {
213+
this.socialDataTimeFrameDays = socialDataTimeFrameDays;
214+
}
215+
188216
/**
189217
* Converts this request to an AnalysisConfig.
190218
*
@@ -214,7 +242,11 @@ public AnalysisConfig toConfig() {
214242
.startCommit(Optional.ofNullable(startCommit))
215243
.endCommit(Optional.ofNullable(endCommit))
216244
.commitAnalysisLimit(Optional.ofNullable(commitAnalysisLimit))
217-
.landscapeToken((landscapeToken != null && !landscapeToken.isBlank()) ? landscapeToken : "mytokenvalue");
245+
.landscapeToken((landscapeToken != null && !landscapeToken.isBlank()) ? landscapeToken : "mytokenvalue")
246+
.applicationRoot(Optional.ofNullable(applicationRoot))
247+
.fetchSocialData(fetchSocialData)
248+
.socialDataTimeFrameDays(Optional.ofNullable(socialDataTimeFrameDays))
249+
.fetchEndDate(Optional.ofNullable(fetchEndDate).filter(s -> !s.isEmpty()));
218250

219251
if (!paths.isEmpty()) {
220252
builder.applicationPaths(paths);

src/main/java/net/explorviz/code/analysis/export/DataExporter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import java.util.Map;
44
import net.explorviz.code.proto.CommitData;
5+
import net.explorviz.code.proto.ContributorData;
56
import net.explorviz.code.proto.FileData;
67
import net.explorviz.code.proto.StateData;
8+
import net.explorviz.code.proto.TrackableResourceEvent;
79

810
/**
911
* A DataExporter handles the export of {@link FileData}, {@link CommitData} and request of {@link StateData}.
@@ -17,6 +19,8 @@ StateData getStateData(final String repositoryName, final String branchName, fin
1719

1820
void persistCommit(final CommitData commitData);
1921

22+
void persistTrackableResourceEvent(final TrackableResourceEvent trackableResourceEvent);
23+
2024
boolean isRemote();
2125

2226
boolean isInvalidCommitHash(final String hash);

src/main/java/net/explorviz/code/analysis/export/GrpcExporter.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55
import java.util.Map;
66
import net.explorviz.code.proto.CommitData;
77
import net.explorviz.code.proto.CommitServiceGrpc;
8+
import net.explorviz.code.proto.ContributorData;
9+
import net.explorviz.code.proto.ContributorServiceGrpc;
810
import net.explorviz.code.proto.FileData;
911
import net.explorviz.code.proto.FileDataServiceGrpc;
1012
import net.explorviz.code.proto.StateData;
1113
import net.explorviz.code.proto.StateDataRequest;
1214
import net.explorviz.code.proto.StateDataServiceGrpc;
15+
import net.explorviz.code.proto.TrackableResourceEvent;
16+
import net.explorviz.code.proto.TrackableResourceServiceGrpc;
1317
import org.eclipse.microprofile.config.inject.ConfigProperty;
1418
import org.slf4j.Logger;
1519
import org.slf4j.LoggerFactory;
@@ -32,6 +36,12 @@ public final class GrpcExporter implements DataExporter {
3236
//
3337
@GrpcClient(GRPC_CLIENT_NAME)
3438
/* package */ StateDataServiceGrpc.StateDataServiceBlockingStub stateDataGrpcClient;
39+
//
40+
@GrpcClient(GRPC_CLIENT_NAME)
41+
/* package */ ContributorServiceGrpc.ContributorServiceBlockingStub contributorDataGrpcClient;
42+
//
43+
@GrpcClient(GRPC_CLIENT_NAME)
44+
/* package */ TrackableResourceServiceGrpc.TrackableResourceServiceBlockingStub trackableResourceGrpcClient;
3545

3646
@ConfigProperty(name = "explorviz.landscape.token")
3747
/* default */ String landscapeTokenProperty;
@@ -92,7 +102,25 @@ public void persistCommit(final CommitData commitData) {
92102
LOGGER.error(e.getMessage());
93103
}
94104
}
105+
}
95106

107+
@Override
108+
public void persistTrackableResourceEvent(final TrackableResourceEvent trackableResourceEvent) {
109+
LOGGER.info(
110+
"Sending TrackableResourceEvent {} for {} #{}",
111+
trackableResourceEvent.getAnnotationType(),
112+
trackableResourceEvent.getResourceType(),
113+
trackableResourceEvent.getResourceId()
114+
);
115+
try {
116+
trackableResourceGrpcClient.persistTrackableResourceEvent(trackableResourceEvent);
117+
} catch (final Exception e) {
118+
if (LOGGER.isErrorEnabled()) {
119+
LOGGER.error("Failed to send trackable resource event {}: {}", trackableResourceEvent.getAnnotationId(),
120+
e.getMessage());
121+
LOGGER.debug("Detailed event data: {}", trackableResourceEvent);
122+
}
123+
}
96124
}
97125

98126
@Override

src/main/java/net/explorviz/code/analysis/export/JsonExporter.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@
66
import java.nio.file.Paths;
77
import java.util.Map;
88
import net.explorviz.code.proto.CommitData;
9+
import net.explorviz.code.proto.ContributorData;
910
import net.explorviz.code.proto.FileData;
1011
import net.explorviz.code.proto.StateData;
1112
import net.explorviz.code.proto.StateDataRequest;
13+
import net.explorviz.code.proto.TrackableResourceEvent;
1214
import org.slf4j.Logger;
1315
import org.slf4j.LoggerFactory;
1416

@@ -174,6 +176,17 @@ public void persistCommit(final CommitData commitData) {
174176
this.commitCount++;
175177
}
176178

179+
@Override
180+
public void persistTrackableResourceEvent(final TrackableResourceEvent trackableResourceEvent) {
181+
try {
182+
final String json = unescapeHtml(JsonFormat.printer().print(trackableResourceEvent));
183+
final String fileName = "TrackableResourceEvent" + trackableResourceEvent.getResourceId() + JSON_FILE_EXTENSION;
184+
Files.write(Paths.get(storageDirectory, fileName), json.getBytes());
185+
} catch (IOException e) { // NOPMD
186+
throw new RuntimeException(e); // NOPMD
187+
}
188+
}
189+
177190
@Override
178191
public boolean isRemote() {
179192
return false;

src/main/java/net/explorviz/code/analysis/export/VoidExporter.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import java.util.Map;
44
import net.explorviz.code.proto.CommitData;
5+
import net.explorviz.code.proto.ContributorData;
56
import net.explorviz.code.proto.FileData;
67
import net.explorviz.code.proto.StateData;
8+
import net.explorviz.code.proto.TrackableResourceEvent;
79

810
/**
911
* Dummy to dump the data into void.
@@ -27,6 +29,11 @@ public void persistCommit(final CommitData commitData) {
2729
// DO NOTHING
2830
}
2931

32+
@Override
33+
public void persistTrackableResourceEvent(final TrackableResourceEvent trackableResourceEvent) {
34+
// DO NOTHING
35+
}
36+
3037
@Override
3138
public boolean isRemote() {
3239
return false;

src/main/java/net/explorviz/code/analysis/git/GitMetricCollector.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import net.explorviz.code.analysis.handler.AbstractFileDataHandler;
44
import net.explorviz.code.analysis.types.FileDescriptor;
5+
import net.explorviz.code.proto.ContributorData;
6+
import net.explorviz.code.proto.ContributorData.Builder;
57
import org.eclipse.jgit.revwalk.RevCommit;
68
import org.slf4j.Logger;
79
import org.slf4j.LoggerFactory;
@@ -62,4 +64,30 @@ public static void addFileGitMetrics(final AbstractFileDataHandler fileDataHandl
6264
}
6365
}
6466
}
67+
68+
/**
69+
* Creates a ContributorData object based on the given commit, landscape token and repository name.
70+
*
71+
* @param commit the commit to extract contributor information from
72+
* @param landscapeToken the landscape token to set in the ContributorData
73+
* @param repositoryName the repository name to set in the ContributorData
74+
* @return a ContributorData object containing the contributor information
75+
*/
76+
public static ContributorData createContributorData(
77+
final RevCommit commit,
78+
final String landscapeToken,
79+
final String repositoryName
80+
81+
) {
82+
String name = commit.getAuthorIdent().getName();
83+
String email = commit.getAuthorIdent().getEmailAddress();
84+
85+
Builder builder = ContributorData.newBuilder()
86+
.setGitUsername(name)
87+
.setEmail(email)
88+
.setLandscapeToken(landscapeToken)
89+
.setRepositoryName(repositoryName);
90+
91+
return builder.build();
92+
}
6593
}

src/main/java/net/explorviz/code/analysis/handler/CommitReportHandler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.List;
77
import net.explorviz.code.analysis.types.FileDescriptor;
88
import net.explorviz.code.proto.CommitData;
9+
import net.explorviz.code.proto.ContributorData;
910
import net.explorviz.code.proto.FileIdentifier;
1011

1112
/**
@@ -18,13 +19,15 @@ public class CommitReportHandler { // NOPMD
1819
private final List<FileIdentifier> deletedFiles = new ArrayList<>();
1920
private final List<FileIdentifier> modifiedFiles = new ArrayList<>();
2021
private CommitData.Builder builder;
22+
private ContributorData.Builder contributorBuilder;
2123

2224
/**
2325
* Creates a blank handler, use
2426
* {@link CommitReportHandler#init(String, String, String)} to initialize it.
2527
*/
2628
public CommitReportHandler() {
2729
this.builder = CommitData.newBuilder();
30+
this.contributorBuilder = ContributorData.newBuilder();
2831
}
2932

3033
/**
@@ -33,6 +36,7 @@ public CommitReportHandler() {
3336
*/
3437
public void clear() {
3538
this.builder = CommitData.newBuilder();
39+
this.contributorBuilder = ContributorData.newBuilder();
3640
this.addedFiles.clear();
3741
this.deletedFiles.clear();
3842
this.modifiedFiles.clear();
@@ -96,6 +100,10 @@ public void setCommitDate(final Timestamp commitDate) {
96100
builder.setCommitDate(commitDate);
97101
}
98102

103+
public void setAuthor(final ContributorData contributorData) {
104+
builder.setAuthor(contributorData);
105+
}
106+
99107
/**
100108
* Returns the commit data. * * @return commit data object
101109
*/

src/main/java/net/explorviz/code/analysis/service/AnalysisConfig.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package net.explorviz.code.analysis.service;
22

3+
import java.sql.Date;
4+
import java.time.Instant;
5+
import java.util.Collections;
36
import java.util.LinkedHashMap;
47
import java.util.List;
58
import java.util.Map;
@@ -17,7 +20,8 @@ public record AnalysisConfig(Optional<String> repoPath, Optional<String> repoRem
1720
boolean calculateMetrics,
1821
Optional<String> startCommit, Optional<String> endCommit,
1922
Optional<Integer> commitAnalysisLimit,
20-
String landscapeToken) {
23+
String landscapeToken,
24+
boolean fetchSocialData, Optional<String> fetchEndDate, Optional<Integer> socialDataTimeFrameDays) {
2125

2226
/**
2327
* Path filter passed to Git diffs: union of all application roots, or global filters when appropriate.
@@ -91,6 +95,11 @@ public static class Builder {
9195
private String applicationName = "";
9296
private List<ApplicationPath> explicitApplicationPaths;
9397

98+
// Social data analysis
99+
private boolean fetchSocialData = false;
100+
private Optional<String> fetchEndDate = Optional.empty();
101+
private Optional<Integer> socialDataTimeFrameDays = Optional.empty();
102+
94103
public Builder repoPath(final Optional<String> repoPath) {
95104
this.repoPath = repoPath;
96105
return this;
@@ -161,6 +170,21 @@ public Builder applicationName(final String applicationName) {
161170
return this;
162171
}
163172

173+
public Builder fetchSocialData(final boolean fetchSocialData) {
174+
this.fetchSocialData = fetchSocialData;
175+
return this;
176+
}
177+
178+
public Builder fetchEndDate(final Optional<String> fetchEndDate) {
179+
this.fetchEndDate = fetchEndDate;
180+
return this;
181+
}
182+
183+
public Builder socialDataTimeFrameDays(final Optional<Integer> socialDataTimeFrameDays) {
184+
this.socialDataTimeFrameDays = socialDataTimeFrameDays;
185+
return this;
186+
}
187+
164188
public Builder applicationPaths(final List<ApplicationPath> paths) {
165189
this.explicitApplicationPaths = paths;
166190
return this;
@@ -188,7 +212,10 @@ public AnalysisConfig build() {
188212
startCommit,
189213
endCommit,
190214
commitAnalysisLimit,
191-
landscapeToken);
215+
landscapeToken,
216+
fetchSocialData,
217+
fetchEndDate,
218+
socialDataTimeFrameDays);
192219
}
193220
}
194221

0 commit comments

Comments
 (0)