Search in sources :

Example 1 with DefaultTypeValidationContext

use of org.gradle.internal.reflect.DefaultTypeValidationContext in project gradle by gradle.

the class DefaultTransformationRegistrationFactory method create.

@Override
public ArtifactTransformRegistration create(ImmutableAttributes from, ImmutableAttributes to, Class<? extends TransformAction<?>> implementation, @Nullable TransformParameters parameterObject) {
    TypeMetadata actionMetadata = actionMetadataStore.getTypeMetadata(implementation);
    boolean cacheable = implementation.isAnnotationPresent(CacheableTransform.class);
    DefaultTypeValidationContext validationContext = DefaultTypeValidationContext.withoutRootType(documentationRegistry, cacheable);
    actionMetadata.visitValidationFailures(null, validationContext);
    // Should retain this on the metadata rather than calculate on each invocation
    Class<? extends FileNormalizer> inputArtifactNormalizer = null;
    Class<? extends FileNormalizer> dependenciesNormalizer = null;
    DirectorySensitivity artifactDirectorySensitivity = DirectorySensitivity.DEFAULT;
    DirectorySensitivity dependenciesDirectorySensitivity = DirectorySensitivity.DEFAULT;
    LineEndingSensitivity artifactLineEndingSensitivity = LineEndingSensitivity.DEFAULT;
    LineEndingSensitivity dependenciesLineEndingSensitivity = LineEndingSensitivity.DEFAULT;
    for (PropertyMetadata propertyMetadata : actionMetadata.getPropertiesMetadata()) {
        Class<? extends Annotation> propertyType = propertyMetadata.getPropertyType();
        if (propertyType.equals(InputArtifact.class)) {
            // Should ask the annotation handler to figure this out instead
            NormalizerCollectingVisitor visitor = new NormalizerCollectingVisitor();
            actionMetadata.getAnnotationHandlerFor(propertyMetadata).visitPropertyValue(propertyMetadata.getPropertyName(), null, propertyMetadata, visitor, null);
            inputArtifactNormalizer = visitor.normalizer;
            artifactDirectorySensitivity = visitor.directorySensitivity;
            artifactLineEndingSensitivity = visitor.lineEndingSensitivity;
            DefaultTransformer.validateInputFileNormalizer(propertyMetadata.getPropertyName(), inputArtifactNormalizer, cacheable, validationContext);
        } else if (propertyType.equals(InputArtifactDependencies.class)) {
            NormalizerCollectingVisitor visitor = new NormalizerCollectingVisitor();
            actionMetadata.getAnnotationHandlerFor(propertyMetadata).visitPropertyValue(propertyMetadata.getPropertyName(), null, propertyMetadata, visitor, null);
            dependenciesNormalizer = visitor.normalizer;
            dependenciesDirectorySensitivity = visitor.directorySensitivity;
            dependenciesLineEndingSensitivity = visitor.lineEndingSensitivity;
            DefaultTransformer.validateInputFileNormalizer(propertyMetadata.getPropertyName(), dependenciesNormalizer, cacheable, validationContext);
        }
    }
    ImmutableMap<String, Severity> validationMessages = validationContext.getProblems();
    if (!validationMessages.isEmpty()) {
        String formatString = validationMessages.size() == 1 ? "A problem was found with the configuration of %s." : "Some problems were found with the configuration of %s.";
        throw new DefaultMultiCauseException(String.format(formatString, ModelType.of(implementation).getDisplayName()), validationMessages.keySet().stream().sorted().map(InvalidUserDataException::new).collect(Collectors.toList()));
    }
    Transformer transformer = new DefaultTransformer(implementation, parameterObject, from, FileParameterUtils.normalizerOrDefault(inputArtifactNormalizer), FileParameterUtils.normalizerOrDefault(dependenciesNormalizer), cacheable, artifactDirectorySensitivity, dependenciesDirectorySensitivity, artifactLineEndingSensitivity, dependenciesLineEndingSensitivity, buildOperationExecutor, classLoaderHierarchyHasher, isolatableFactory, fileCollectionFactory, fileLookup, parametersPropertyWalker, actionInstantiationScheme, owner, calculatedValueContainerFactory, internalServices, documentationRegistry);
    return new DefaultArtifactTransformRegistration(from, to, new TransformationStep(transformer, transformerInvocationFactory, owner, inputFingerprinter));
}
Also used : LineEndingSensitivity(org.gradle.internal.fingerprint.LineEndingSensitivity) TypeMetadata(org.gradle.api.internal.tasks.properties.TypeMetadata) InputArtifactDependencies(org.gradle.api.artifacts.transform.InputArtifactDependencies) DirectorySensitivity(org.gradle.internal.fingerprint.DirectorySensitivity) Severity(org.gradle.internal.reflect.validation.Severity) DefaultMultiCauseException(org.gradle.internal.exceptions.DefaultMultiCauseException) InvalidUserDataException(org.gradle.api.InvalidUserDataException) DefaultTypeValidationContext(org.gradle.internal.reflect.DefaultTypeValidationContext) PropertyMetadata(org.gradle.internal.reflect.PropertyMetadata)

Example 2 with DefaultTypeValidationContext

use of org.gradle.internal.reflect.DefaultTypeValidationContext in project gradle by gradle.

the class DefaultTransformer method fingerprintParameters.

private static void fingerprintParameters(DocumentationRegistry documentationRegistry, InputFingerprinter inputFingerprinter, FileCollectionFactory fileCollectionFactory, PropertyWalker propertyWalker, Hasher hasher, Object parameterObject, boolean cacheable) {
    DefaultTypeValidationContext validationContext = DefaultTypeValidationContext.withoutRootType(documentationRegistry, cacheable);
    InputFingerprinter.Result result = inputFingerprinter.fingerprintInputProperties(ImmutableSortedMap.of(), ImmutableSortedMap.of(), ImmutableSortedMap.of(), ImmutableSortedMap.of(), visitor -> propertyWalker.visitProperties(parameterObject, validationContext, new PropertyVisitor.Adapter() {

        @Override
        public void visitInputProperty(String propertyName, PropertyValue value, boolean optional) {
            try {
                Object preparedValue = InputParameterUtils.prepareInputParameterValue(value);
                if (preparedValue == null && !optional) {
                    reportValueNotSet(propertyName, validationContext);
                }
                visitor.visitInputProperty(propertyName, () -> preparedValue);
            } catch (Throwable e) {
                throw new InvalidUserDataException(String.format("Error while evaluating property '%s' of %s", propertyName, getParameterObjectDisplayName(parameterObject)), e);
            }
        }

        @Override
        public void visitInputFileProperty(String propertyName, boolean optional, boolean skipWhenEmpty, DirectorySensitivity directorySensitivity, LineEndingSensitivity lineEndingNormalization, boolean incremental, @Nullable Class<? extends FileNormalizer> fileNormalizer, PropertyValue value, InputFilePropertyType filePropertyType) {
            validateInputFileNormalizer(propertyName, fileNormalizer, cacheable, validationContext);
            visitor.visitInputFileProperty(propertyName, incremental ? InputFingerprinter.InputPropertyType.INCREMENTAL : InputFingerprinter.InputPropertyType.NON_INCREMENTAL, new FileValueSupplier(value, fileNormalizer == null ? AbsolutePathInputNormalizer.class : fileNormalizer, directorySensitivity, lineEndingNormalization, () -> FileParameterUtils.resolveInputFileValue(fileCollectionFactory, filePropertyType, value)));
        }

        @Override
        public void visitOutputFileProperty(String propertyName, boolean optional, PropertyValue value, OutputFilePropertyType filePropertyType) {
            validationContext.visitPropertyProblem(problem -> problem.withId(ValidationProblemId.ARTIFACT_TRANSFORM_SHOULD_NOT_DECLARE_OUTPUT).reportAs(Severity.ERROR).forProperty(propertyName).withDescription("declares an output").happensBecause("is annotated with an output annotation").addPossibleSolution("Remove the output property and use the TransformOutputs parameter from transform(TransformOutputs) instead").documentedAt("validation_problems", "artifact_transform_should_not_declare_output"));
        }
    }));
    ImmutableMap<String, Severity> validationMessages = validationContext.getProblems();
    if (!validationMessages.isEmpty()) {
        throw new DefaultMultiCauseException(String.format(validationMessages.size() == 1 ? "A problem was found with the configuration of the artifact transform parameter %s." : "Some problems were found with the configuration of the artifact transform parameter %s.", getParameterObjectDisplayName(parameterObject)), validationMessages.keySet().stream().sorted().map(InvalidUserDataException::new).collect(Collectors.toList()));
    }
    for (Map.Entry<String, ValueSnapshot> entry : result.getValueSnapshots().entrySet()) {
        hasher.putString(entry.getKey());
        entry.getValue().appendToHasher(hasher);
    }
    for (Map.Entry<String, CurrentFileCollectionFingerprint> entry : result.getFileFingerprints().entrySet()) {
        hasher.putString(entry.getKey());
        hasher.putHash(entry.getValue().getHash());
    }
}
Also used : LineEndingSensitivity(org.gradle.internal.fingerprint.LineEndingSensitivity) ValueSnapshot(org.gradle.internal.snapshot.ValueSnapshot) FileValueSupplier(org.gradle.internal.execution.fingerprint.InputFingerprinter.FileValueSupplier) FileNormalizer(org.gradle.api.tasks.FileNormalizer) OutputFilePropertyType(org.gradle.api.internal.tasks.properties.OutputFilePropertyType) DefaultTypeValidationContext(org.gradle.internal.reflect.DefaultTypeValidationContext) DirectorySensitivity(org.gradle.internal.fingerprint.DirectorySensitivity) PropertyValue(org.gradle.api.internal.tasks.properties.PropertyValue) InputFilePropertyType(org.gradle.api.internal.tasks.properties.InputFilePropertyType) Severity(org.gradle.internal.reflect.validation.Severity) DefaultMultiCauseException(org.gradle.internal.exceptions.DefaultMultiCauseException) InputFingerprinter(org.gradle.internal.execution.fingerprint.InputFingerprinter) InvalidUserDataException(org.gradle.api.InvalidUserDataException) CurrentFileCollectionFingerprint(org.gradle.internal.fingerprint.CurrentFileCollectionFingerprint) DslObject(org.gradle.api.internal.plugins.DslObject) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) ImmutableSortedMap(com.google.common.collect.ImmutableSortedMap) Nullable(javax.annotation.Nullable)

Example 3 with DefaultTypeValidationContext

use of org.gradle.internal.reflect.DefaultTypeValidationContext in project gradle by gradle.

the class ValidateAction method collectValidationProblems.

private static void collectValidationProblems(Class<?> topLevelBean, Map<String, Boolean> problems, boolean enableStricterValidation) {
    DefaultTypeValidationContext validationContext;
    if (Task.class.isAssignableFrom(topLevelBean)) {
        validationContext = createValidationContextAndValidateCacheableAnnotations(topLevelBean, CacheableTask.class, enableStricterValidation);
    } else if (TransformAction.class.isAssignableFrom(topLevelBean)) {
        validationContext = createValidationContextAndValidateCacheableAnnotations(topLevelBean, CacheableTransform.class, enableStricterValidation);
    } else {
        validationContext = createValidationContext(topLevelBean, enableStricterValidation);
    }
    PropertyValidationAccess.collectValidationProblems(topLevelBean, validationContext);
    validationContext.getProblems().forEach((message, severity) -> problems.put(message, severity == ERROR));
}
Also used : DefaultTypeValidationContext(org.gradle.internal.reflect.DefaultTypeValidationContext) TransformAction(org.gradle.api.artifacts.transform.TransformAction) CacheableTask(org.gradle.api.tasks.CacheableTask)

Example 4 with DefaultTypeValidationContext

use of org.gradle.internal.reflect.DefaultTypeValidationContext in project gradle by gradle.

the class ValidateAction method createValidationContextAndValidateCacheableAnnotations.

private static DefaultTypeValidationContext createValidationContextAndValidateCacheableAnnotations(Class<?> topLevelBean, Class<? extends Annotation> cacheableAnnotationClass, boolean enableStricterValidation) {
    boolean cacheable = topLevelBean.isAnnotationPresent(cacheableAnnotationClass);
    DefaultTypeValidationContext validationContext = createValidationContext(topLevelBean, cacheable || enableStricterValidation);
    if (enableStricterValidation) {
        validateCacheabilityAnnotationPresent(topLevelBean, cacheable, cacheableAnnotationClass, validationContext);
    }
    return validationContext;
}
Also used : DefaultTypeValidationContext(org.gradle.internal.reflect.DefaultTypeValidationContext)

Aggregations

DefaultTypeValidationContext (org.gradle.internal.reflect.DefaultTypeValidationContext)4 InvalidUserDataException (org.gradle.api.InvalidUserDataException)2 DefaultMultiCauseException (org.gradle.internal.exceptions.DefaultMultiCauseException)2 DirectorySensitivity (org.gradle.internal.fingerprint.DirectorySensitivity)2 LineEndingSensitivity (org.gradle.internal.fingerprint.LineEndingSensitivity)2 Severity (org.gradle.internal.reflect.validation.Severity)2 ImmutableMap (com.google.common.collect.ImmutableMap)1 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)1 Map (java.util.Map)1 Nullable (javax.annotation.Nullable)1 InputArtifactDependencies (org.gradle.api.artifacts.transform.InputArtifactDependencies)1 TransformAction (org.gradle.api.artifacts.transform.TransformAction)1 DslObject (org.gradle.api.internal.plugins.DslObject)1 InputFilePropertyType (org.gradle.api.internal.tasks.properties.InputFilePropertyType)1 OutputFilePropertyType (org.gradle.api.internal.tasks.properties.OutputFilePropertyType)1 PropertyValue (org.gradle.api.internal.tasks.properties.PropertyValue)1 TypeMetadata (org.gradle.api.internal.tasks.properties.TypeMetadata)1 CacheableTask (org.gradle.api.tasks.CacheableTask)1 FileNormalizer (org.gradle.api.tasks.FileNormalizer)1 InputFingerprinter (org.gradle.internal.execution.fingerprint.InputFingerprinter)1