Skip to content

Commit

Permalink
Add other possible solution for OUTPUT_FILE_VALIDATOR
Browse files Browse the repository at this point in the history
Signed-off-by: Björn Kautler <Bjoern@Kautler.net>
  • Loading branch information
Vampire committed Feb 1, 2022
1 parent 8c85f70 commit 97a681a
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ task someTask(type: SomeTask) {
expect:
fails "test"
failureDescriptionContains(cannotWriteToFile {
failureDescriptionContains(cannotWriteFileToDirectory {
property('output')
.file(outputDir)
.isNotFile()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.gradle.api.internal.GeneratedSubclass;
import org.gradle.api.internal.tasks.TaskValidationContext;
import org.gradle.internal.reflect.problems.ValidationProblemId;
import org.gradle.internal.reflect.validation.PropertyProblemBuilder;
import org.gradle.internal.typeconversion.UnsupportedNotationException;
import org.gradle.model.internal.type.ModelType;

Expand Down Expand Up @@ -84,13 +85,13 @@ public void doValidate(String propertyName, Object value, TaskValidationContext
validateNotInReservedFileSystemLocation(propertyName, context, file);
if (file.exists()) {
if (file.isDirectory()) {
reportCannotWriteToFile(propertyName, context, "'" + file + "' is not a file");
reportCannotWriteFileToDirectory(propertyName, context, file);
}
// else, assume we can write to anything that exists and is not a directory
} else {
for (File candidate = file.getParentFile(); candidate != null && !candidate.isDirectory(); candidate = candidate.getParentFile()) {
if (candidate.exists() && !candidate.isDirectory()) {
reportCannotWriteToFile(propertyName, context, "'" + file + "' ancestor '" + candidate + "' is not a directory");
reportCannotCreateParentDirectories(propertyName, context, file, candidate);
break;
}
}
Expand Down Expand Up @@ -183,18 +184,32 @@ private static void reportFileTreeWithFileRoot(String propertyName, TaskValidati
);
}

private static void reportCannotWriteToFile(String propertyName, TaskValidationContext context, String cause) {
context.visitPropertyProblem(problem ->
problem.withId(ValidationProblemId.CANNOT_WRITE_OUTPUT)
.reportAs(ERROR)
.forProperty(propertyName)
.withDescription(() -> "is not writable because " + cause)
.happensBecause(() -> "Cannot write a file to a location pointing at a directory")
.addPossibleSolution(() -> "Configure '" + propertyName + "' to point to a file, not a directory")
.documentedAt("validation_problems", "cannot_write_output")
private static void reportCannotWriteFileToDirectory(String propertyName, TaskValidationContext context, File file) {
context.visitPropertyProblem(problem -> {
PropertyProblemBuilder problemBuilder = problem.withId(ValidationProblemId.CANNOT_WRITE_OUTPUT)
.reportAs(ERROR)
.forProperty(propertyName)
.withDescription(() -> "is not writable because '" + file + "' is not a file")
.happensBecause(() -> "Cannot write a file to a location pointing at a directory")
.addPossibleSolution(() -> "Configure '" + propertyName + "' to point to a file, not a directory")
.addPossibleSolution(() -> "Annotate '" + propertyName + "' with @OutputDirectory instead of @OutputFiles")
.documentedAt("validation_problems", "cannot_write_output");
}
);
}

private static void reportCannotCreateParentDirectories(String propertyName, TaskValidationContext context, File file, File ancestor) {
context.visitPropertyProblem(problem -> {
PropertyProblemBuilder problemBuilder = problem.withId(ValidationProblemId.CANNOT_WRITE_OUTPUT)
.reportAs(ERROR)
.forProperty(propertyName)
.withDescription(() -> "is not writable because '" + file + "' ancestor '" + ancestor + "' is not a directory")
.happensBecause(() -> "Cannot create parent directories that are existing as file")
.addPossibleSolution(() -> "Configure '" + propertyName + "' to point to the correct location")
.documentedAt("validation_problems", "cannot_write_output");
}
);
}

private static String actualKindOf(File input) {
if (input.isFile()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ class AnnotationProcessingTaskFactoryTest extends AbstractProjectBuilderSpec imp

then:
def e = thrown WorkValidationException
validateException(task, e, cannotWriteToFile {
validateException(task, e, cannotWriteFileToDirectory {
property('outputFile')
.file(task.outputFile)
.isNotFile()
Expand All @@ -478,7 +478,7 @@ class AnnotationProcessingTaskFactoryTest extends AbstractProjectBuilderSpec imp

then:
def e = thrown WorkValidationException
validateException(task, e, cannotWriteToFile {
validateException(task, e, cannotWriteFileToDirectory {
property('outputFiles')
.file(task.outputFiles[0])
.isNotFile()
Expand All @@ -499,7 +499,7 @@ class AnnotationProcessingTaskFactoryTest extends AbstractProjectBuilderSpec imp

then:
def e = thrown WorkValidationException
validateException(task, e, cannotWriteToFile {
validateException(task, e, cannotCreateParentDirectories {
property('outputFile')
.file(task.outputFile)
.ancestorIsNotDirectory(task.outputFile.parentFile)
Expand All @@ -520,7 +520,7 @@ class AnnotationProcessingTaskFactoryTest extends AbstractProjectBuilderSpec imp

then:
def e = thrown WorkValidationException
validateException(task, e, cannotWriteToFile {
validateException(task, e, cannotCreateParentDirectories {
property('outputFiles')
.file(task.outputFiles[0])
.ancestorIsNotDirectory(task.outputFiles[0].parentFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ Please refer to https://docs.gradle.org/current/userguide/validation_problems.ht
def ancestor = dummyLocation('/tmp/foo')

when:
render cannotWriteToFile {
render cannotWriteFileToDirectory {
type('Writer').property('output')
file(location)
isNotFile()
Expand All @@ -576,13 +576,15 @@ Type 'Writer' property 'output' is not writable because '${location}' is not a f
Reason: Cannot write a file to a location pointing at a directory.
Possible solution: Configure 'output' to point to a file, not a directory.
Possible solutions:
1. Configure 'output' to point to a file, not a directory.
2. Annotate 'output' with @OutputDirectory instead of @OutputFiles.
Please refer to https://docs.gradle.org/current/userguide/validation_problems.html#cannot_write_output for more details about this problem.
"""

when:
render cannotWriteToFile {
render cannotCreateParentDirectories {
type('Writer').property('output')
file(location)
ancestorIsNotDirectory(ancestor)
Expand All @@ -593,9 +595,9 @@ Please refer to https://docs.gradle.org/current/userguide/validation_problems.ht
outputEquals """
Type 'Writer' property 'output' is not writable because '${location}' ancestor '${ancestor}' is not a directory.
Reason: Cannot write a file to a location pointing at a directory.
Reason: Cannot create parent directories that are existing as file.
Possible solution: Configure 'output' to point to a file, not a directory.
Possible solution: Configure 'output' to point to the correct location.
Please refer to https://docs.gradle.org/current/userguide/validation_problems.html#cannot_write_output for more details about this problem.
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,26 @@ trait ValidationMessageChecker {
@ValidationTestFor(
ValidationProblemId.CANNOT_WRITE_OUTPUT
)
String cannotWriteToFile(@DelegatesTo(value = CannotWriteToFile, strategy = Closure.DELEGATE_FIRST) Closure<?> spec = {}) {
String cannotWriteFileToDirectory(@DelegatesTo(value = CannotWriteToFile, strategy = Closure.DELEGATE_FIRST) Closure<?> spec = {}) {
def config = display(CannotWriteToFile, 'cannot_write_output', spec)
config.description("is not writable because '${config.file}' ${config.reason}")

def cannotWriteToFile = config.description("is not writable because '${config.file}' ${config.reason}")
.reason("Cannot write a file to a location pointing at a directory")
.solution("Configure '${config.property}' to point to a file, not a directory")
.render()
.solution("Annotate '${config.property}' with @OutputDirectory instead of @OutputFiles.")
cannotWriteToFile.render()
}

@ValidationTestFor(
ValidationProblemId.CANNOT_WRITE_OUTPUT
)
String cannotCreateParentDirectories(@DelegatesTo(value = CannotWriteToFile, strategy = Closure.DELEGATE_FIRST) Closure<?> spec = {}) {
def config = display(CannotWriteToFile, 'cannot_write_output', spec)

def cannotWriteToFile = config.description("is not writable because '${config.file}' ${config.reason}")
.reason("Cannot create parent directories that are existing as file")
.solution("Configure '${config.property}' to point to the correct location")
cannotWriteToFile.render()
}

@ValidationTestFor(
Expand Down

0 comments on commit 97a681a

Please sign in to comment.