.getSourcePath does not return path of file with header. #5721
-
|
Hey, I am working on a header recipe something similar to licenseHeader recipe. final Path absolutePath = sourceFile.getSourcePath().toAbsolutePath();this only returns the fileName altho this works perfectly well for classes without any header. Please HELP OUT !! ///////////////////////////////////////////////////////////////////////////////////////////////
// checkstyle-openrewrite-recipes: Automatically fix Checkstyle violations with OpenRewrite.
// Copyright (C) 2025 The Checkstyle OpenRewrite Recipes Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////////////////////////
package org.checkstyle.autofix.recipe;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.Configuration;
import org.checkstyle.autofix.parser.CheckstyleViolation;
import org.openrewrite.*;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.tree.Comment;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaSourceFile;
import org.openrewrite.java.tree.Space;
public class Header extends Recipe {
private static final String HEADER_LITERAL = "header";
private static int VIOLATION_LINE = 0;
private List<CheckstyleViolation> violations;
private Configuration headerConfig;
public Header() {
this.violations = new ArrayList<>();
this.headerConfig = null;
}
public Header(List<CheckstyleViolation> violations, Configuration headerConfig) {
this.violations = violations;
this.headerConfig = headerConfig;
}
@Override
public String getDisplayName() {
return "Header recipe";
}
@Override
public String getDescription() {
return "Adds headers to Java source files when missing."
+ " Does not override existing license headers.";
}
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<>() {
@Override
public J visit(Tree tree, ExecutionContext ctx) {
final J result;
if (tree instanceof JavaSourceFile) {
JavaSourceFile sourceFile =
(JavaSourceFile) java.util.Objects.requireNonNull(tree);
final Path absolutePath = sourceFile.getSourcePath().toAbsolutePath();
if (sourceFile.getComments().isEmpty() && isAtViolation(absolutePath)) {
sourceFile = sourceFile.withPrefix(
Space.format(getLicenseHeader(headerConfig)
+ System.lineSeparator().repeat(2)));
}
else if (!sourceFile.getComments().isEmpty() && isAtViolation(absolutePath)) {
StringBuilder sourceHeaderBuilder = new StringBuilder();
for (Comment comment : sourceFile.getComments()) {
sourceHeaderBuilder.append(comment.printComment(getCursor()));
}
String sourceHeader = sourceHeaderBuilder.toString();
String actualHeader = getLicenseHeader(headerConfig);
String[] sourceLines = sourceHeader.split("\n");
String[] actualLines = actualHeader.split("\n");
sourceLines[VIOLATION_LINE] = actualLines[VIOLATION_LINE];
String newHeader = String.join("\n", sourceLines);
sourceFile = sourceFile.withComments(new ArrayList<>());
sourceFile = sourceFile.withPrefix(
Space.format(newHeader + System.lineSeparator().repeat(2)));
}
result = super.visit(sourceFile, ctx);
}
else {
result = super.visit(tree, ctx);
}
return result;
}
};
}
private static String getLicenseHeader(Configuration child) {
final String result;
final String[] propertyNames = child.getPropertyNames();
final boolean hasHeaderProperty = Arrays.asList(propertyNames).contains(HEADER_LITERAL);
try {
if (hasHeaderProperty) {
result = child.getProperty(HEADER_LITERAL);
}
else {
final String headerFile = child.getProperty("headerFile");
result = readHeaderFileContent(headerFile);
}
}
catch (CheckstyleException exception) {
throw new IllegalArgumentException("Failed to extract header from config", exception);
}
return result;
}
private static String readHeaderFileContent(String headerFilePath) {
try {
return Files.readString(Path.of(headerFilePath));
}
catch (IOException exception) {
throw new IllegalArgumentException("Failed to read: " + headerFilePath, exception);
}
}
private boolean isAtViolation(Path currentFileName) {
Iterator<CheckstyleViolation> iterator = violations.iterator();
while (iterator.hasNext()) {
CheckstyleViolation violation = iterator.next();
Path absolutePath = Path.of(violation.getFileName()).toAbsolutePath();
if (Objects.isNull(violation.getColumn()) && absolutePath.equals(currentFileName)) {
VIOLATION_LINE = violation.getLine();
iterator.remove(); // remove the violation before returning
return true;
}
}
return false;
}
} |
Beta Was this translation helpful? Give feedback.
Answered by
timtebeek
Jul 5, 2025
Replies: 1 comment 2 replies
-
|
As you've found |
Beta Was this translation helpful? Give feedback.
2 replies
Answer selected by
timtebeek
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
As you've found
getSourcePathonly give you the name of the file relative to the project root; it's not intended to give you the fill path on disk to that file. What exactly is the problem you're having when only seeing a relative path?