Search in sources :

Example 1 with ValueSnapshot

use of org.gradle.internal.snapshot.ValueSnapshot 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 2 with ValueSnapshot

use of org.gradle.internal.snapshot.ValueSnapshot in project gradle by gradle.

the class CaptureStateBeforeExecutionStep method captureExecutionStateWithOutputs.

private BeforeExecutionState captureExecutionStateWithOutputs(UnitOfWork work, PreviousExecutionContext context, ImmutableSortedMap<String, FileSystemSnapshot> unfilteredOutputSnapshots) {
    Optional<PreviousExecutionState> previousExecutionState = context.getPreviousExecutionState();
    ImplementationsBuilder implementationsBuilder = new ImplementationsBuilder(classLoaderHierarchyHasher);
    work.visitImplementations(implementationsBuilder);
    ImplementationSnapshot implementation = implementationsBuilder.getImplementation();
    ImmutableList<ImplementationSnapshot> additionalImplementations = implementationsBuilder.getAdditionalImplementations();
    if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Implementation for {}: {}", work.getDisplayName(), implementation);
        LOGGER.debug("Additional implementations for {}: {}", work.getDisplayName(), additionalImplementations);
    }
    ImmutableSortedMap<String, ValueSnapshot> previousInputProperties = previousExecutionState.map(InputExecutionState::getInputProperties).orElse(ImmutableSortedMap.of());
    ImmutableSortedMap<String, ? extends FileCollectionFingerprint> previousInputFileFingerprints = previousExecutionState.map(InputExecutionState::getInputFileProperties).orElse(ImmutableSortedMap.of());
    ImmutableSortedMap<String, FileSystemSnapshot> previousOutputSnapshots = previousExecutionState.map(PreviousExecutionState::getOutputFilesProducedByWork).orElse(ImmutableSortedMap.of());
    OverlappingOutputs overlappingOutputs;
    switch(work.getOverlappingOutputHandling()) {
        case DETECT_OVERLAPS:
            overlappingOutputs = overlappingOutputDetector.detect(previousOutputSnapshots, unfilteredOutputSnapshots);
            break;
        case IGNORE_OVERLAPS:
            overlappingOutputs = null;
            break;
        default:
            throw new AssertionError();
    }
    InputFingerprinter.Result newInputs = work.getInputFingerprinter().fingerprintInputProperties(previousInputProperties, previousInputFileFingerprints, context.getInputProperties(), context.getInputFileProperties(), work::visitRegularInputs);
    return new DefaultBeforeExecutionState(implementation, additionalImplementations, newInputs.getAllValueSnapshots(), newInputs.getAllFileFingerprints(), unfilteredOutputSnapshots, overlappingOutputs);
}
Also used : ValueSnapshot(org.gradle.internal.snapshot.ValueSnapshot) DefaultBeforeExecutionState(org.gradle.internal.execution.history.impl.DefaultBeforeExecutionState) OverlappingOutputs(org.gradle.internal.execution.history.OverlappingOutputs) PreviousExecutionState(org.gradle.internal.execution.history.PreviousExecutionState) FileSystemSnapshot(org.gradle.internal.snapshot.FileSystemSnapshot) InputFingerprinter(org.gradle.internal.execution.fingerprint.InputFingerprinter) ImplementationSnapshot(org.gradle.internal.snapshot.impl.ImplementationSnapshot)

Example 3 with ValueSnapshot

use of org.gradle.internal.snapshot.ValueSnapshot in project gradle by gradle.

the class SnapshotSerializer method read.

@Override
public ValueSnapshot read(Decoder decoder) throws Exception {
    int type = decoder.readSmallInt();
    int size;
    String className;
    switch(type) {
        case NULL_SNAPSHOT:
            return NullValueSnapshot.INSTANCE;
        case TRUE_SNAPSHOT:
            return BooleanValueSnapshot.TRUE;
        case FALSE_SNAPSHOT:
            return BooleanValueSnapshot.FALSE;
        case STRING_SNAPSHOT:
            return new StringValueSnapshot(decoder.readString());
        case INTEGER_SNAPSHOT:
            return new IntegerValueSnapshot(decoder.readInt());
        case LONG_SNAPSHOT:
            return new LongValueSnapshot(decoder.readLong());
        case SHORT_SNAPSHOT:
            return new ShortValueSnapshot((short) decoder.readInt());
        case HASH_SNAPSHOT:
            return new HashCodeSnapshot(HashCode.fromBytes(decoder.readBinary()));
        case FILE_SNAPSHOT:
            return new FileValueSnapshot(decoder.readString());
        case ENUM_SNAPSHOT:
            return new EnumValueSnapshot(decoder.readString(), decoder.readString());
        case EMPTY_ARRAY_SNAPSHOT:
            return ArrayValueSnapshot.EMPTY;
        case ARRAY_SNAPSHOT:
            size = decoder.readSmallInt();
            ImmutableList<ValueSnapshot> arrayElements = readList(decoder, size);
            return new ArrayValueSnapshot(arrayElements);
        case EMPTY_LIST_SNAPSHOT:
            return ListValueSnapshot.EMPTY;
        case LIST_SNAPSHOT:
            size = decoder.readSmallInt();
            ImmutableList<ValueSnapshot> listElements = readList(decoder, size);
            return new ListValueSnapshot(listElements);
        case SET_SNAPSHOT:
            size = decoder.readSmallInt();
            ImmutableSet.Builder<ValueSnapshot> setBuilder = ImmutableSet.builder();
            for (int i = 0; i < size; i++) {
                setBuilder.add(read(decoder));
            }
            return new SetValueSnapshot(setBuilder.build());
        case MAP_SNAPSHOT:
            size = decoder.readSmallInt();
            ImmutableList.Builder<MapEntrySnapshot<ValueSnapshot>> mapBuilder = ImmutableList.builderWithExpectedSize(size);
            for (int i = 0; i < size; i++) {
                mapBuilder.add(new MapEntrySnapshot<>(read(decoder), read(decoder)));
            }
            return new MapValueSnapshot(mapBuilder.build());
        case MANAGED_SNAPSHOT:
            className = decoder.readString();
            ValueSnapshot state = read(decoder);
            return new ManagedValueSnapshot(className, state);
        case IMMUTABLE_MANAGED_SNAPSHOT:
            className = decoder.readString();
            String value = decoder.readString();
            return new ImmutableManagedValueSnapshot(className, value);
        case IMPLEMENTATION_SNAPSHOT:
            return implementationSnapshotSerializer.read(decoder);
        case ATTRIBUTE:
            return new AttributeDefinitionSnapshot(Attribute.of(decoder.readString(), classFromContextLoader(decoder.readString())), classLoaderHasher);
        case GRADLE_SERIALIZED_SNAPSHOT:
            return new GradleSerializedValueSnapshot(decoder.readBoolean() ? serializer.read(decoder) : null, decoder.readBinary());
        case DEFAULT_SNAPSHOT:
            return new JavaSerializedValueSnapshot(decoder.readBoolean() ? serializer.read(decoder) : null, decoder.readBinary());
        default:
            throw new IllegalArgumentException("Don't know how to deserialize a snapshot with type tag " + type);
    }
}
Also used : ValueSnapshot(org.gradle.internal.snapshot.ValueSnapshot) ImmutableList(com.google.common.collect.ImmutableList) ImmutableSet(com.google.common.collect.ImmutableSet)

Example 4 with ValueSnapshot

use of org.gradle.internal.snapshot.ValueSnapshot in project gradle by gradle.

the class SnapshotSerializer method write.

@Override
public void write(Encoder encoder, ValueSnapshot snapshot) throws Exception {
    if (snapshot == NullValueSnapshot.INSTANCE) {
        encoder.writeSmallInt(NULL_SNAPSHOT);
    } else if (snapshot instanceof StringValueSnapshot) {
        StringValueSnapshot stringSnapshot = (StringValueSnapshot) snapshot;
        encoder.writeSmallInt(STRING_SNAPSHOT);
        encoder.writeString(stringSnapshot.getValue());
    } else if (snapshot instanceof ListValueSnapshot) {
        ListValueSnapshot listSnapshot = (ListValueSnapshot) snapshot;
        if (listSnapshot.getElements().isEmpty()) {
            encoder.writeSmallInt(EMPTY_LIST_SNAPSHOT);
        } else {
            encoder.writeSmallInt(LIST_SNAPSHOT);
            encoder.writeSmallInt(listSnapshot.getElements().size());
            for (ValueSnapshot valueSnapshot : listSnapshot.getElements()) {
                write(encoder, valueSnapshot);
            }
        }
    } else if (snapshot == BooleanValueSnapshot.TRUE) {
        encoder.writeSmallInt(TRUE_SNAPSHOT);
    } else if (snapshot == BooleanValueSnapshot.FALSE) {
        encoder.writeSmallInt(FALSE_SNAPSHOT);
    } else if (snapshot instanceof IntegerValueSnapshot) {
        IntegerValueSnapshot integerSnapshot = (IntegerValueSnapshot) snapshot;
        encoder.writeSmallInt(INTEGER_SNAPSHOT);
        encoder.writeInt(integerSnapshot.getValue());
    } else if (snapshot instanceof LongValueSnapshot) {
        LongValueSnapshot longSnapshot = (LongValueSnapshot) snapshot;
        encoder.writeSmallInt(LONG_SNAPSHOT);
        encoder.writeLong(longSnapshot.getValue());
    } else if (snapshot instanceof ShortValueSnapshot) {
        ShortValueSnapshot shortSnapshot = (ShortValueSnapshot) snapshot;
        encoder.writeSmallInt(SHORT_SNAPSHOT);
        encoder.writeInt(shortSnapshot.getValue());
    } else if (snapshot instanceof HashCodeSnapshot) {
        HashCodeSnapshot hashSnapshot = (HashCodeSnapshot) snapshot;
        encoder.writeSmallInt(HASH_SNAPSHOT);
        encoder.writeBinary(hashSnapshot.getValue().toByteArray());
    } else if (snapshot instanceof FileValueSnapshot) {
        FileValueSnapshot fileSnapshot = (FileValueSnapshot) snapshot;
        encoder.writeSmallInt(FILE_SNAPSHOT);
        encoder.writeString(fileSnapshot.getValue());
    } else if (snapshot instanceof EnumValueSnapshot) {
        EnumValueSnapshot enumSnapshot = (EnumValueSnapshot) snapshot;
        encoder.writeSmallInt(ENUM_SNAPSHOT);
        encoder.writeString(enumSnapshot.getClassName());
        encoder.writeString(enumSnapshot.getName());
    } else if (snapshot instanceof SetValueSnapshot) {
        SetValueSnapshot setSnapshot = (SetValueSnapshot) snapshot;
        encoder.writeSmallInt(SET_SNAPSHOT);
        encoder.writeSmallInt(setSnapshot.getElements().size());
        for (ValueSnapshot valueSnapshot : setSnapshot.getElements()) {
            write(encoder, valueSnapshot);
        }
    } else if (snapshot instanceof ImplementationSnapshot) {
        ImplementationSnapshot implementationSnapshot = (ImplementationSnapshot) snapshot;
        encoder.writeSmallInt(IMPLEMENTATION_SNAPSHOT);
        implementationSnapshotSerializer.write(encoder, implementationSnapshot);
    } else if (snapshot instanceof AttributeDefinitionSnapshot) {
        AttributeDefinitionSnapshot valueSnapshot = (AttributeDefinitionSnapshot) snapshot;
        encoder.writeSmallInt(ATTRIBUTE);
        encoder.writeString(valueSnapshot.getValue().getName());
        encoder.writeString(valueSnapshot.getValue().getType().getName());
    } else if (snapshot instanceof GradleSerializedValueSnapshot) {
        GradleSerializedValueSnapshot valueSnapshot = (GradleSerializedValueSnapshot) snapshot;
        encoder.writeSmallInt(GRADLE_SERIALIZED_SNAPSHOT);
        if (valueSnapshot.getImplementationHash() == null) {
            encoder.writeBoolean(false);
        } else {
            encoder.writeBoolean(true);
            serializer.write(encoder, valueSnapshot.getImplementationHash());
        }
        encoder.writeBinary(valueSnapshot.getValue());
    } else if (snapshot instanceof JavaSerializedValueSnapshot) {
        JavaSerializedValueSnapshot valueSnapshot = (JavaSerializedValueSnapshot) snapshot;
        encoder.writeSmallInt(DEFAULT_SNAPSHOT);
        if (valueSnapshot.getImplementationHash() == null) {
            encoder.writeBoolean(false);
        } else {
            encoder.writeBoolean(true);
            serializer.write(encoder, valueSnapshot.getImplementationHash());
        }
        encoder.writeBinary(valueSnapshot.getValue());
    } else if (snapshot instanceof MapValueSnapshot) {
        MapValueSnapshot mapSnapshot = (MapValueSnapshot) snapshot;
        encoder.writeSmallInt(MAP_SNAPSHOT);
        encoder.writeSmallInt(mapSnapshot.getEntries().size());
        for (MapEntrySnapshot<ValueSnapshot> entry : mapSnapshot.getEntries()) {
            write(encoder, entry.getKey());
            write(encoder, entry.getValue());
        }
    } else if (snapshot instanceof ArrayValueSnapshot) {
        ArrayValueSnapshot arraySnapshot = (ArrayValueSnapshot) snapshot;
        if (arraySnapshot.getElements().isEmpty()) {
            encoder.writeSmallInt(EMPTY_ARRAY_SNAPSHOT);
        } else {
            encoder.writeSmallInt(ARRAY_SNAPSHOT);
            encoder.writeSmallInt(arraySnapshot.getElements().size());
            for (ValueSnapshot valueSnapshot : arraySnapshot.getElements()) {
                write(encoder, valueSnapshot);
            }
        }
    } else if (snapshot instanceof ImmutableManagedValueSnapshot) {
        encoder.writeSmallInt(IMMUTABLE_MANAGED_SNAPSHOT);
        ImmutableManagedValueSnapshot valueSnapshot = (ImmutableManagedValueSnapshot) snapshot;
        encoder.writeString(valueSnapshot.getClassName());
        encoder.writeString(valueSnapshot.getValue());
    } else if (snapshot instanceof ManagedValueSnapshot) {
        encoder.writeSmallInt(MANAGED_SNAPSHOT);
        ManagedValueSnapshot managedTypeSnapshot = (ManagedValueSnapshot) snapshot;
        encoder.writeString(managedTypeSnapshot.getClassName());
        write(encoder, managedTypeSnapshot.getState());
    } else {
        throw new IllegalArgumentException("Don't know how to serialize a value of type " + snapshot.getClass().getSimpleName());
    }
}
Also used : ValueSnapshot(org.gradle.internal.snapshot.ValueSnapshot)

Example 5 with ValueSnapshot

use of org.gradle.internal.snapshot.ValueSnapshot in project gradle by gradle.

the class ListValueSnapshot method processList.

private ValueSnapshot processList(Object value, ValueSnapshotter snapshotter) {
    if (!(value instanceof List)) {
        return snapshotter.snapshot(value);
    }
    // Find first position where values are different
    List<?> list = (List<?>) value;
    int pos = 0;
    int len = Math.min(elements.size(), list.size());
    ValueSnapshot newElement = null;
    for (; pos < len; pos++) {
        ValueSnapshot element = elements.get(pos);
        newElement = snapshotter.snapshot(list.get(pos), element);
        if (element != newElement) {
            break;
        }
        newElement = null;
    }
    if (pos == elements.size() && pos == list.size()) {
        // Same size and no differences
        return this;
    }
    // Copy the snapshots whose values are the same, then snapshot remaining values
    ImmutableList.Builder<ValueSnapshot> newElements = ImmutableList.builderWithExpectedSize(list.size());
    for (int i = 0; i < pos; i++) {
        newElements.add(elements.get(i));
    }
    if (pos < list.size()) {
        // If we broke out of the comparison because there was a difference, we can reuse the snapshot of the new element
        if (newElement != null) {
            newElements.add(newElement);
            pos++;
        }
        // Anything left over only exists in the new list
        for (int i = pos; i < list.size(); i++) {
            newElements.add(snapshotter.snapshot(list.get(i)));
        }
    }
    return new ListValueSnapshot(newElements.build());
}
Also used : ValueSnapshot(org.gradle.internal.snapshot.ValueSnapshot) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList)

Aggregations

ValueSnapshot (org.gradle.internal.snapshot.ValueSnapshot)10 ImmutableList (com.google.common.collect.ImmutableList)5 ImmutableSortedMap (com.google.common.collect.ImmutableSortedMap)4 CurrentFileCollectionFingerprint (org.gradle.internal.fingerprint.CurrentFileCollectionFingerprint)4 List (java.util.List)3 PreviousExecutionState (org.gradle.internal.execution.history.PreviousExecutionState)3 ImplementationSnapshot (org.gradle.internal.snapshot.impl.ImplementationSnapshot)3 File (java.io.File)2 Map (java.util.Map)2 Optional (java.util.Optional)2 OriginMetadata (org.gradle.caching.internal.origin.OriginMetadata)2 UnitOfWork (org.gradle.internal.execution.UnitOfWork)2 WorkValidationContext (org.gradle.internal.execution.WorkValidationContext)2 InputFingerprinter (org.gradle.internal.execution.fingerprint.InputFingerprinter)2 BeforeExecutionState (org.gradle.internal.execution.history.BeforeExecutionState)2 ExecutionHistoryStore (org.gradle.internal.execution.history.ExecutionHistoryStore)2 FileCollectionFingerprint (org.gradle.internal.fingerprint.FileCollectionFingerprint)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 ImmutableCollection (com.google.common.collect.ImmutableCollection)1