forked from reposense/RepoSense
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ReportGenerator.java
158 lines (137 loc) · 6.96 KB
/
ReportGenerator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package reposense.report;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.google.gson.JsonSyntaxException;
import reposense.RepoSense;
import reposense.authorship.AuthorshipReporter;
import reposense.authorship.model.AuthorshipSummary;
import reposense.commits.CommitsReporter;
import reposense.commits.model.CommitContributionSummary;
import reposense.git.GitClone;
import reposense.git.GitCloneException;
import reposense.git.GitShortlog;
import reposense.model.Author;
import reposense.model.RepoConfiguration;
import reposense.model.StandaloneConfig;
import reposense.parser.StandaloneConfigJsonParser;
import reposense.system.LogsManager;
import reposense.util.FileUtil;
public class ReportGenerator {
private static final String REPOSENSE_CONFIG_FOLDER = "_reposense";
private static final String REPOSENSE_CONFIG_FILE = "config.json";
private static final Logger logger = LogsManager.getLogger(ReportGenerator.class);
// zip file which contains all the dashboard template files
private static final String TEMPLATE_FILE = "/templateZip.zip";
private static final String MESSAGE_INVALID_CONFIG_JSON = "%s Ignoring the config provided by this repository.";
/**
* Generates the authorship and commits JSON file for each repo in {@code configs} at {@code outputPath}, as
* well as the summary JSON file of all the repos.
*
* @throws IOException if templateZip.zip does not exists in jar file.
*/
public static void generateReposReport(List<RepoConfiguration> configs, String outputPath,
String generationDate) throws IOException {
InputStream is = RepoSense.class.getResourceAsStream(TEMPLATE_FILE);
FileUtil.copyTemplate(is, outputPath);
for (RepoConfiguration config : configs) {
Path repoReportDirectory;
try {
GitClone.clone(config);
repoReportDirectory = Paths.get(outputPath, config.getDisplayName());
FileUtil.createDirectory(repoReportDirectory);
} catch (GitCloneException gde) {
logger.log(Level.WARNING,
"Exception met while trying to clone the repo, will skip this repo.", gde);
repoReportDirectory = Paths.get(outputPath, config.getDisplayName());
FileUtil.createDirectory(repoReportDirectory);
generateEmptyRepoReport(repoReportDirectory.toString());
continue;
} catch (IOException ioe) {
logger.log(Level.WARNING,
"Error has occurred while creating repo directory, will skip this repo.", ioe);
continue;
} catch (RuntimeException rte) {
logger.log(Level.SEVERE, "Error has occurred during analysis, will skip this repo.", rte);
continue;
}
// preprocess the config and repo
updateRepoConfig(config);
updateAuthorList(config);
CommitContributionSummary commitSummary = CommitsReporter.generateCommitSummary(config);
AuthorshipSummary authorshipSummary = AuthorshipReporter.generateAuthorshipSummary(config);
generateIndividualRepoReport(commitSummary, authorshipSummary, repoReportDirectory.toString());
try {
FileUtil.deleteDirectory(FileUtil.REPOS_ADDRESS);
} catch (IOException ioe) {
logger.log(Level.WARNING, "Error deleting report directory.", ioe);
}
}
FileUtil.writeJsonFile(new SummaryReportJson(configs, generationDate), getSummaryResultPath(outputPath));
logger.info("The report is generated at " + outputPath);
}
/**
* Updates {@code config} with configuration provided by repository if exists.
*/
public static void updateRepoConfig(RepoConfiguration config) {
Path configJsonPath =
Paths.get(config.getRepoRoot(), REPOSENSE_CONFIG_FOLDER, REPOSENSE_CONFIG_FILE).toAbsolutePath();
if (!Files.exists(configJsonPath)) {
logger.info(String.format("%s does not contain a standalone config file.", config.getLocation()));
return;
}
if (config.isStandaloneConfigIgnored()) {
logger.info(String.format("Ignoring standalone config file in %s.", config.getLocation()));
return;
}
try {
StandaloneConfig standaloneConfig = new StandaloneConfigJsonParser().parse(configJsonPath);
config.update(standaloneConfig);
} catch (JsonSyntaxException jse) {
logger.warning(String.format("%s/%s/%s is malformed.",
config.getDisplayName(), REPOSENSE_CONFIG_FOLDER, REPOSENSE_CONFIG_FILE));
} catch (IllegalArgumentException iae) {
logger.warning(String.format(MESSAGE_INVALID_CONFIG_JSON, iae.getMessage()));
} catch (IOException ioe) {
throw new AssertionError(
"This exception should not happen as we have performed the file existence check.");
}
}
/**
* Find and update {@code config} with all the author identities if author list is empty.
*/
private static void updateAuthorList(RepoConfiguration config) {
if (config.getAuthorList().isEmpty()) {
logger.info(String.format(
"%s has no authors specified, using all authors by default.", config.getDisplayName()));
List<Author> authorList = GitShortlog.getAuthors(config);
config.setAuthorList(authorList);
}
}
private static void generateIndividualRepoReport(
CommitContributionSummary commitSummary, AuthorshipSummary authorshipSummary, String repoReportDirectory) {
CommitReportJson commitReportJson = new CommitReportJson(commitSummary, authorshipSummary);
FileUtil.writeJsonFile(commitReportJson, getIndividualCommitsPath(repoReportDirectory));
FileUtil.writeJsonFile(authorshipSummary.getFileResults(), getIndividualAuthorshipPath(repoReportDirectory));
}
private static void generateEmptyRepoReport(String repoReportDirectory) {
CommitReportJson emptyCommitReportJson = new CommitReportJson();
FileUtil.writeJsonFile(emptyCommitReportJson, getIndividualCommitsPath(repoReportDirectory));
FileUtil.writeJsonFile(Collections.emptyList(), getIndividualAuthorshipPath(repoReportDirectory));
}
private static String getSummaryResultPath(String targetFileLocation) {
return targetFileLocation + "/summary.json";
}
private static String getIndividualAuthorshipPath(String repoReportDirectory) {
return repoReportDirectory + "/authorship.json";
}
private static String getIndividualCommitsPath(String repoReportDirectory) {
return repoReportDirectory + "/commits.json";
}
}