Skip to content

Commit 7735f10

Browse files
committed
Update and fix search expressions for inclusion and exclusion of folders and files
1 parent a4c81d0 commit 7735f10

13 files changed

Lines changed: 252 additions & 222 deletions

File tree

README.md

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The property `explorviz.gitanalysis.run-mode` determines if the code-agent runs
1313
./gradlew quarkusDev
1414
```
1515
2. Visit [http://localhost:8078/](http://localhost:8078/). The new single-page UI is served directly from `src/main/resources/META-INF/resources/index.html`.
16-
3. Fill in either a local repository path or a remote URL (plus any optional parameters such as branch, source directories, credentials, metrics toggles, etc.).
16+
3. Fill in either a local repository path or a remote URL (plus any optional parameters such as branch,filters, credentials, metrics toggles, etc.).
1717
4. Hit **Run Analysis**. The page calls the existing REST endpoint at `/api/analysis/trigger` and streams the textual response back into the UI.
1818

1919
The form mirrors the fields of `AnalysisRequest`, so anything you can configure via JSON can now be triggered from the browser.
@@ -121,21 +121,19 @@ Type: Boolean or Empty (defaults to false)
121121
If a remote storage is used and this is set to true, the analysis data will be sent to the remote endpoint, if set to false, the analysis data will be stored as json on disc.
122122
The storage location will be printed on startup and is relative to the java working directory.
123123
124-
### explorviz.gitanalysis.source-directory
124+
### explorviz.gitanalysis.include-in-analysis-expressions
125125
126126
Type: String or empty
127127
128-
To detect java types successfully, the source directory should be specified.
129-
Source files are expected to be somewhere inside the given folders.
130-
Provide one or multiple [search expressions](#search-expressions).
128+
Only files contained in the folders matching one of the search expressions are analyzed.
129+
Provide one or multiple search expressions.
131130
132-
### explorviz.gitanalysis.restrict-analysis-to-folders
131+
### explorviz.gitanalysis.exclude-from-analysis-expressions
133132
134133
Type: String or empty
135134
136-
Only java files contained in the reachable folders from this search expression are analyzed.
137-
Type detection is not affected by this setting, any files reachable by the [source directory setting](#explorvizgitanalysissource-directory) are used to detect the correct type.
138-
Provide one or multiple [search expressions](#search-expressions).
135+
Only files with a filename matching one of the search expressions are analyzed.
136+
Provide one or multiple search expressions.
139137
140138
### explorviz.gitanalysis.start-commit-sha1
141139
@@ -182,29 +180,10 @@ If the folder location changes over the course of the development, it is possibl
182180
183181
Leading Wildcard:
184182
185-
E.g. the folder location `*/src/main/java` is searched in the repository everywhere, until some folder hierarchy matches `src/main/java` for example the path `project/javasources/src/main/java`.
183+
E.g. the folder location `**/src/main/java/**` is searched in the repository everywhere, until some folder hierarchy matches `src/main/java` for example the path `project/javasources/src/main/java`.
186184
The first match is used, if there are multiple matches, try to specify the path even more.
187185
Keep in mind to not use a line separator in front of or after the wildcard.
188186
189187
Infix Wildcards:
190188
191-
E.g. the folder location `/src/*/java` is searched in the repository starting with `src` and must end with `java`.
192-
The path `src/main/java` would match as well as `/src/some/deep/hierarchy/to/search/java`.
193-
If both folder structures would exist, one of these could be returned as the folders are not searched in a specific order.
194-
Make sure the folder is unambiguous.
195-
196-
Single wildcards do not guarantee a deeper folder level, the search string `/some/*/path` will match the folder `some/path` even if `some/other/path/` exists and might be the wanted.
197-
198-
Multiple consecutive wildcards e.g. `/some/*/*/path` enforce a depth of _number of wildcards - 1_.
199-
This search string matches `/some/other/path/`, `/some/deeper/other/path/` or even deeper but not `/some/path/`.
200-
201-
**WARNING: paths ending with wildcards are not allowed!**
202-
203-
<!-- The following can produce syntax errors
204-
#### Optional Paths
205-
206-
If a folder, like the test folder, is not present from the first commit onwards, it is possible to define these type of
207-
folders as optional. Optional folders are considered if they are found and ignored if not present.
208-
209-
To define a search expression as optional, simply put it in brackets: ``[\src\test\java]``. Wildcards are supported in
210-
optional search expressions. -->
189+
Multiple consecutive wildcards e.g. `/some/*/*/path` enforce a certain depth of the directories.

build.gradle

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -113,20 +113,3 @@ test {
113113
useJUnitPlatform()
114114
testLogging.showStandardStreams = true
115115
}
116-
117-
def registerGitHook = { taskName, hookFile, targetHook ->
118-
tasks.register(taskName, Copy) {
119-
from("code-analysis/${hookFile}")
120-
into(".git/hooks")
121-
rename { targetHook }
122-
}
123-
}
124-
125-
registerGitHook("registerPreCommitHook", "pre-commit", "pre-commit")
126-
registerGitHook("registerPreMergeCommitHook", "pre-commit", "pre-merge-commit")
127-
128-
tasks.named("quarkusGenerateCode") {
129-
dependsOn("registerPreCommitHook")
130-
dependsOn("registerPreMergeCommitHook")
131-
}
132-

src/main/java/net/explorviz/code/analysis/GitAnalysis.java

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,11 @@ public class GitAnalysis { // NOPMD
4949
@ConfigProperty(name = "explorviz.gitanalysis.branch")
5050
/* default */ Optional<String> repositoryBranchProperty; // NOCS
5151

52-
@ConfigProperty(name = "explorviz.gitanalysis.source-directory")
53-
/* default */ Optional<String> sourceDirectoryProperty; // NOCS
52+
@ConfigProperty(name = "explorviz.gitanalysis.include-in-analysis-expressions")
53+
/* default */ Optional<String> includeInAnalysisExpressionsProperty; // NOCS NOPMD
5454

55-
@ConfigProperty(name = "explorviz.gitanalysis.restrict-analysis-to-folders")
56-
/* default */ Optional<String> restrictAnalysisToFoldersProperty; // NOCS NOPMD
55+
@ConfigProperty(name = "explorviz.gitanalysis.exclude-from-analysis-expressions")
56+
/* default */ Optional<String> excludeFromAnalysisExpressionsProperty; // NOCS NOPMD
5757

5858
@ConfigProperty(name = "explorviz.gitanalysis.application-root")
5959
/* default */ Optional<String> applicationRootProperty; // NOCS
@@ -79,9 +79,6 @@ public class GitAnalysis { // NOPMD
7979
@ConfigProperty(name = "explorviz.gitanalysis.application-name")
8080
/* default */ String applicationNameProperty; // NOCS
8181

82-
@ConfigProperty(name = "explorviz.gitanalysis.code-analysis-excluded-file-extensions", defaultValue = "")
83-
/* default */ Optional<String> codeAnalysisExcludedFileExtensionsProperty; // NOCS
84-
8582
@Inject
8683
/* package */ GrpcExporter grpcExporter; // NOCS
8784

@@ -100,16 +97,15 @@ private AnalysisConfig createConfig() {
10097
.gitUsername(usernameProperty)
10198
.gitPassword(passwordProperty)
10299
.branch(repositoryBranchProperty)
103-
.sourceDirectory(sourceDirectoryProperty)
104-
.restrictAnalysisToFolders(restrictAnalysisToFoldersProperty)
100+
.includeInAnalysisExpressions(includeInAnalysisExpressionsProperty)
101+
.excludeFromAnalysisExpressions(excludeFromAnalysisExpressionsProperty)
105102
.applicationRoot(applicationRootProperty)
106103
.calculateMetrics(calculateMetricsProperty)
107104
.startCommit(startCommitProperty)
108105
.endCommit(endCommitProperty)
109106
.commitAnalysisLimit(commitAnalysisLimitProperty)
110107
.landscapeToken(landscapeTokenProperty)
111108
.applicationName(applicationNameProperty)
112-
.codeAnalysisExcludedFileExtensions(codeAnalysisExcludedFileExtensionsProperty.orElse(""))
113109
.build();
114110
}
115111

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

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ public class AnalysisRequest {
1414
private String username;
1515
private String password;
1616
private String branch;
17-
private String sourceDirectory;
18-
private String restrictAnalysisToFolders;
17+
private String includeInAnalysisExpressions;
18+
private String excludeFromAnalysisExpressions;
1919

2020
private boolean sendToRemote = true;
2121
private boolean calculateMetrics = true;
@@ -25,7 +25,6 @@ public class AnalysisRequest {
2525
private String landscapeToken = "mytokenvalue";
2626
private String applicationName = "";
2727
private String applicationRoot;
28-
private String codeAnalysisExcludedFileExtensions;
2928

3029
public AnalysisRequest() {
3130
}
@@ -70,20 +69,20 @@ public void setBranch(final String branch) {
7069
this.branch = branch;
7170
}
7271

73-
public String getSourceDirectory() {
74-
return sourceDirectory;
72+
public String getIncludeInAnalysisExpressions() {
73+
return includeInAnalysisExpressions;
7574
}
7675

77-
public void setSourceDirectory(final String sourceDirectory) {
78-
this.sourceDirectory = sourceDirectory;
76+
public void setIncludeInAnalysisExpressions(final String includeInAnalysisExpressions) {
77+
this.includeInAnalysisExpressions = includeInAnalysisExpressions;
7978
}
8079

81-
public String getRestrictAnalysisToFolders() {
82-
return restrictAnalysisToFolders;
80+
public String getExcludeFromAnalysisExpressions() {
81+
return excludeFromAnalysisExpressions;
8382
}
8483

85-
public void setRestrictAnalysisToFolders(final String restrictAnalysisToFolders) {
86-
this.restrictAnalysisToFolders = restrictAnalysisToFolders;
84+
public void setExcludeFromAnalysisExpressions(final String excludeFromAnalysisExpressions) {
85+
this.excludeFromAnalysisExpressions = excludeFromAnalysisExpressions;
8786
}
8887

8988
public String getApplicationRoot() {
@@ -142,7 +141,6 @@ public void setApplicationName(final String applicationName) {
142141
this.applicationName = applicationName;
143142
}
144143

145-
146144
public Integer getCommitAnalysisLimit() {
147145
return commitAnalysisLimit;
148146
}
@@ -151,14 +149,6 @@ public void setCommitAnalysisLimit(final Integer commitAnalysisLimit) {
151149
this.commitAnalysisLimit = commitAnalysisLimit;
152150
}
153151

154-
public String getCodeAnalysisExcludedFileExtensions() {
155-
return codeAnalysisExcludedFileExtensions;
156-
}
157-
158-
public void setCodeAnalysisExcludedFileExtensions(final String codeAnalysisExcludedFileExtensions) {
159-
this.codeAnalysisExcludedFileExtensions = codeAnalysisExcludedFileExtensions;
160-
}
161-
162152
/**
163153
* Converts this request to an AnalysisConfig.
164154
*
@@ -171,16 +161,15 @@ public AnalysisConfig toConfig() {
171161
.gitUsername(Optional.ofNullable(username))
172162
.gitPassword(Optional.ofNullable(password))
173163
.branch(Optional.ofNullable(branch))
174-
.sourceDirectory(Optional.ofNullable(sourceDirectory))
175-
.restrictAnalysisToFolders(Optional.ofNullable(restrictAnalysisToFolders))
164+
.includeInAnalysisExpressions(Optional.ofNullable(includeInAnalysisExpressions))
165+
.excludeFromAnalysisExpressions(Optional.ofNullable(excludeFromAnalysisExpressions))
176166
.calculateMetrics(calculateMetrics)
177167
.startCommit(Optional.ofNullable(startCommit))
178168
.endCommit(Optional.ofNullable(endCommit))
179169
.commitAnalysisLimit(Optional.ofNullable(commitAnalysisLimit))
180170
.landscapeToken((landscapeToken != null && !landscapeToken.isBlank()) ? landscapeToken : "mytokenvalue")
181171
.applicationName(applicationName != null ? applicationName : "")
182172
.applicationRoot(Optional.ofNullable(applicationRoot))
183-
.codeAnalysisExcludedFileExtensions(codeAnalysisExcludedFileExtensions)
184173
.build();
185174
}
186175
}

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

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,16 @@
11
package net.explorviz.code.analysis.git;
22

33
import java.io.IOException;
4-
import java.nio.file.FileSystems;
54
import java.nio.file.FileVisitResult;
65
import java.nio.file.Files;
76
import java.nio.file.Path;
8-
import java.nio.file.PathMatcher;
97
import java.nio.file.Paths;
108
import java.nio.file.SimpleFileVisitor;
119
import java.nio.file.attribute.BasicFileAttributes;
1210
import java.util.ArrayList;
13-
import java.util.HashMap;
1411
import java.util.HashSet;
1512
import java.util.List;
16-
import java.util.Map;
1713
import java.util.Set;
18-
import net.explorviz.code.analysis.exceptions.MalformedPathException;
1914
import net.explorviz.code.analysis.exceptions.NotFoundException;
2015
import org.slf4j.Logger;
2116
import org.slf4j.LoggerFactory;
@@ -26,26 +21,8 @@
2621
public final class DirectoryFinder {
2722

2823
private static final Logger LOGGER = LoggerFactory.getLogger(DirectoryFinder.class);
29-
private static final Map<String, List<String>> PATHS = new HashMap<>();
3024

3125
private DirectoryFinder() {
32-
33-
}
34-
35-
/**
36-
* Resets the given path entry, the saved value will be removed.
37-
*
38-
* @param path the search string for the path used to create it
39-
*/
40-
public static void resetDirectory(final String path) {
41-
PATHS.remove(path);
42-
}
43-
44-
/**
45-
* Resets the internal path storage.
46-
*/
47-
public static void reset() {
48-
PATHS.clear();
4926
}
5027

5128
/**
@@ -86,10 +63,15 @@ public static List<String> getDirectories(String root, List<String> searchPaths)
8663
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
8764
throws IOException {
8865
for (String searchPath : searchPaths) {
89-
PathMatcher matcher = FileSystems.getDefault().getPathMatcher("glob:" + searchPath);
66+
String glob = searchPath;
67+
if (!glob.startsWith("glob:") && !glob.startsWith("regex:")) {
68+
glob = "glob:" + glob;
69+
}
70+
java.nio.file.PathMatcher matcher = java.nio.file.FileSystems.getDefault().getPathMatcher(glob);
9071
if (matcher.matches(startPath.relativize(dir))) {
9172
pathSet.add(dir.toAbsolutePath().normalize()
9273
.toString()); // Normalize the path and add to the set
74+
LOGGER.atTrace().addArgument(dir).log("Directory matched glob and was added to set: {}");
9375
}
9476
}
9577
return FileVisitResult.CONTINUE;

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ private List<FileDescriptor> listFilesInCommit(final Repository repository, // N
536536
objectIdList.add(new FileDescriptor(treeWalk.getObjectId(0), treeWalk.getNameString(),
537537
treeWalk.getPathString()));
538538
}
539+
LOGGER.atDebug().addArgument(objectIdList.size()).log("Discovered {} files in commit tree");
539540
}
540541
return objectIdList;
541542

@@ -545,8 +546,10 @@ private TreeFilter getSourceFileTreeFilter(final List<String> pathRestrictions)
545546
throws NotFoundException {
546547
if (pathRestrictions.isEmpty() || pathRestrictions.size() == 1 && pathRestrictions.get(0)
547548
.isBlank()) {
549+
LOGGER.atInfo().log("No path restrictions provided. Analyzing all files.");
548550
return TreeFilter.ALL;
549551
} else {
552+
LOGGER.atInfo().addArgument(pathRestrictions).log("Applying path restrictions: {}");
550553
final List<String> pathList = DirectoryFinder.getRelativeDirectory(pathRestrictions,
551554
getCurrentRepositoryPath());
552555
final List<String> newPathList = new ArrayList<>();

0 commit comments

Comments
 (0)