Skip to content

Commit 5653718

Browse files
committed
Revert FileAdjustor
1 parent 19afaf1 commit 5653718

File tree

4 files changed

+241
-1
lines changed

4 files changed

+241
-1
lines changed

community-rust-plugin/src/main/java/org/elegoff/plugins/communityrust/clippy/ClippySensor.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
import java.util.List;
2828
import java.util.Set;
2929
import java.util.stream.Collectors;
30+
import javax.annotation.CheckForNull;
3031
import org.elegoff.plugins.communityrust.language.RustLanguage;
3132
import org.slf4j.Logger;
3233
import org.slf4j.LoggerFactory;
34+
import org.sonar.api.batch.fs.InputFile;
3335
import org.sonar.api.batch.fs.TextRange;
3436
import org.sonar.api.batch.rule.Severity;
3537
import org.sonar.api.batch.sensor.Sensor;
@@ -52,13 +54,21 @@ public class ClippySensor implements Sensor {
5254
private static final Long DEFAULT_CONSTANT_DEBT_MINUTES = 5L;
5355
private static final int MAX_LOGGED_FILE_NAMES = 20;
5456

57+
private FileAdjustor fileAdjustor;
58+
59+
@CheckForNull
60+
private InputFile inputFile(SensorContext context, String filePath) {
61+
String relativePath = fileAdjustor.relativePath(filePath);
62+
return context.fileSystem().inputFile(context.fileSystem().predicates().hasPath(relativePath));
63+
}
64+
5565
private void saveIssue(SensorContext context, ClippyJsonReportReader.ClippyIssue clippyIssue, Set<String> unresolvedInputFiles) {
5666
if (isEmpty(clippyIssue.ruleKey) || isEmpty(clippyIssue.filePath) || isEmpty(clippyIssue.message)) {
5767
LOG.debug("Missing information for ruleKey:'{}', filePath:'{}', message:'{}'", clippyIssue.ruleKey, clippyIssue.filePath, clippyIssue.message);
5868
return;
5969
}
6070

61-
var inputFile = context.fileSystem().inputFile(context.fileSystem().predicates().hasPath(clippyIssue.filePath));
71+
InputFile inputFile = inputFile(context, clippyIssue.filePath);
6272

6373
if (inputFile == null) {
6474
unresolvedInputFiles.add(clippyIssue.filePath);
@@ -99,6 +109,7 @@ private static org.sonar.api.batch.rule.Severity toSonarQubeSeverity(String seve
99109
@Override
100110
public void execute(SensorContext context) {
101111
Set<String> unresolvedInputFiles = new HashSet<>();
112+
fileAdjustor = FileAdjustor.create(context);
102113
List<File> reportFiles = ExternalReportProvider.getReportFiles(context, reportPathKey());
103114
reportFiles.forEach(report -> importReport(report, context, unresolvedInputFiles));
104115
logUnresolvedInputFiles(unresolvedInputFiles);
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Community Rust Plugin
3+
* Copyright (C) 2021-2025 Vladimir Shelkovnikov
4+
* mailto:community-rust AT pm DOT me
5+
* http://github.com/C4tWithShell/community-rust
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU Lesser General Public
9+
* License as published by the Free Software Foundation; either
10+
* version 3 of the License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this program; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20+
*/
21+
package org.elegoff.plugins.communityrust.clippy;
22+
23+
import java.io.File;
24+
import java.nio.file.Path;
25+
import org.sonar.api.batch.fs.FileSystem;
26+
import org.sonar.api.batch.sensor.SensorContext;
27+
28+
/**
29+
* Adjust file paths from clippy reports into a path relative to the project.
30+
* The context in which the report was created and the analyzer context may possibly be different.
31+
*/
32+
public class FileAdjustor {
33+
34+
private final FileSystem fileSystem;
35+
36+
private int relativePathOffset = 0;
37+
38+
private FileAdjustor(FileSystem fileSystem) {
39+
this.fileSystem = fileSystem;
40+
}
41+
42+
public static FileAdjustor create(SensorContext context) {
43+
return new FileAdjustor(context.fileSystem());
44+
}
45+
46+
public String relativePath(String fileName) {
47+
48+
if (isKnown(fileName)) {
49+
return fileName;
50+
}
51+
52+
String normalizedPath = chooseSeparator(fileName);
53+
if (normalizedPath == null) {
54+
return fileName;
55+
}
56+
57+
Path path = Path.of(normalizedPath);
58+
int pathNameCount = path.getNameCount();
59+
60+
if (relativePathOffset > 0) {
61+
if (path.getNameCount() > relativePathOffset) {
62+
path = path.subpath(relativePathOffset, pathNameCount);
63+
if (isKnown(path)) {
64+
return path.toString();
65+
}
66+
}
67+
return fileName;
68+
}
69+
70+
for (int i = 1; i < pathNameCount; i++) {
71+
Path subpath = path.subpath(i, pathNameCount);
72+
if (isKnown(subpath)) {
73+
relativePathOffset = i;
74+
return subpath.toString();
75+
}
76+
}
77+
78+
return fileName;
79+
}
80+
81+
private static String chooseSeparator(String path) {
82+
return isWindows() ? windowsSeparators(path) : unixSeparators(path);
83+
}
84+
85+
private static boolean isWindows() {
86+
return File.separatorChar == '\\';
87+
}
88+
89+
private static String unixSeparators(String path) {
90+
return path.indexOf(92) != -1 ? path.replace('\\', '/') : path;
91+
}
92+
93+
private static String windowsSeparators(String path) {
94+
return path.indexOf(47) != -1 ? path.replace('/', '\\') : path;
95+
}
96+
97+
private boolean isKnown(Path path) {
98+
return isKnown(path.toString());
99+
}
100+
101+
private boolean isKnown(String path) {
102+
return fileSystem.hasFiles(fileSystem.predicates().hasPath(path));
103+
}
104+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Community Rust Plugin
3+
* Copyright (C) 2021-2025 Vladimir Shelkovnikov
4+
* mailto:community-rust AT pm DOT me
5+
* http://github.com/C4tWithShell/community-rust
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU Lesser General Public
9+
* License as published by the Free Software Foundation; either
10+
* version 3 of the License, or (at your option) any later version.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
* Lesser General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU Lesser General Public License
18+
* along with this program; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20+
*/
21+
package org.elegoff.plugins.communityrust.clippy;
22+
23+
import java.nio.file.Path;
24+
import java.nio.file.Paths;
25+
import java.util.Arrays;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
29+
import org.sonar.api.batch.sensor.internal.SensorContextTester;
30+
31+
32+
import static org.assertj.core.api.Assertions.assertThat;
33+
34+
class FileAdjustorTest {
35+
36+
private static final Path PROJECT_DIR = Paths.get("src", "test", "resources", "FileAdjustor");
37+
private static final String MODULE_KEY = "FileAdjustor";
38+
39+
private FileAdjustor fileAdjustor;
40+
41+
private SensorContextTester context;
42+
43+
@BeforeEach
44+
void setup() {
45+
context = SensorContextTester.create(PROJECT_DIR);
46+
addInputFiles("main.rs", "subfolder/main.rs");
47+
fileAdjustor = FileAdjustor.create(context);
48+
}
49+
50+
@Test
51+
void should_return_relative_path_when_all_files_are_known() {
52+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "main.rs"))).isEqualTo("main.rs");
53+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "subfolder", "main.rs"))).isEqualTo(path("subfolder", "main.rs"));
54+
}
55+
56+
@Test
57+
void should_return_relative_path_when_first_file_is_in_subfolder() {
58+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "subfolder", "main.rs"))).isEqualTo(path("subfolder", "main.rs"));
59+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "main.rs"))).isEqualTo("main.rs");
60+
}
61+
62+
@Test
63+
void should_not_return_relative_when_files_are_unknown() {
64+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "unknown.rs"))).isEqualTo(path("foo", "bar", "FileAdjustor", "unknown.rs"));
65+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "subfolder", "unknown.rs"))).isEqualTo(path("foo", "bar", "FileAdjustor", "subfolder", "unknown.rs"));
66+
}
67+
68+
@Test
69+
void should_return_relative_when_first_file_is_unknown() {
70+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "unknown.rs"))).isEqualTo(path("foo", "bar", "FileAdjustor", "unknown.rs"));
71+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "subfolder", "main.rs"))).isEqualTo(path("subfolder", "main.rs"));
72+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "main.rs"))).isEqualTo("main.rs");
73+
}
74+
75+
@Test
76+
void should_return_relative_path_when_already_relative() {
77+
assertThat(fileAdjustor.relativePath("main.rs")).isEqualTo("main.rs");
78+
assertThat(fileAdjustor.relativePath(path("subfolder", "main.rs"))).isEqualTo(path("subfolder", "main.rs"));
79+
}
80+
81+
@Test
82+
void test() {
83+
assertThat(fileAdjustor.relativePath(path("unknown", "main.rs"))).isEqualTo(path("main.rs"));
84+
assertThat(fileAdjustor.relativePath("main.rs")).isEqualTo("main.rs");
85+
}
86+
87+
@Test
88+
void should_return_relative_path_for_second_file_when_unknown() {
89+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileHandler", "main.rs"))).isEqualTo("main.rs");
90+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileHandler", "subfolder", "unknown.rs"))).isEqualTo(path("foo", "bar", "FileHandler", "subfolder", "unknown.rs"));
91+
}
92+
93+
@Test
94+
void should_return_relative_path_for_unix_path() {
95+
assertThat(fileAdjustor.relativePath("/foo/bar/FileAdjustor/main.rs")).isEqualTo("main.rs");
96+
assertThat(fileAdjustor.relativePath("/foo/bar/FileAdjustor/subfolder/main.rs")).isEqualTo(path("subfolder", "main.rs"));
97+
}
98+
99+
@Test
100+
void should_return_relative_path_for_fqn_windows_path() {
101+
assertThat(fileAdjustor.relativePath("C:\\foo\\bar\\FileAdjustor\\main.rs")).isEqualTo("main.rs");
102+
assertThat(fileAdjustor.relativePath("C:\\foo\\bar\\FileAdjustor\\subfolder\\main.rs")).isEqualTo(path("subfolder", "main.rs"));
103+
}
104+
105+
@Test
106+
void should_return_relative_path_for_relative_windows_path() {
107+
assertThat(fileAdjustor.relativePath("main.rs")).isEqualTo("main.rs");
108+
assertThat(fileAdjustor.relativePath("subfolder\\main.rs")).isEqualTo("subfolder\\main.rs");
109+
}
110+
111+
@Test
112+
void should_return_handle_shorter_path() {
113+
assertThat(fileAdjustor.relativePath(path("foo", "bar", "FileAdjustor", "main.rs"))).isEqualTo("main.rs");
114+
assertThat(fileAdjustor.relativePath(path("bar", "main.rs"))).isEqualTo(path("bar", "main.rs"));
115+
}
116+
117+
private void addInputFiles(String... paths) {
118+
Arrays.stream(paths).forEach(path -> context.fileSystem().add(TestInputFileBuilder.create(MODULE_KEY, path).build()));
119+
}
120+
121+
private static String path(String first, String... more) {
122+
return Path.of(first, more).toString();
123+
}
124+
125+
}

community-rust-plugin/src/test/resources/FileAdjustor/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)