use of org.gradle.internal.hash.PrimitiveHasher in project gradle by gradle.
the class FileCacheBackedScriptClassCompiler method compile.
@Override
public <T extends Script, M> CompiledScript<T, M> compile(final ScriptSource source, final ClassLoaderScope targetScope, final CompileOperation<M> operation, final Class<T> scriptBaseClass, final Action<? super ClassNode> verifier) {
assert source.getResource().isContentCached();
if (source.getResource().getHasEmptyContent()) {
return emptyCompiledScript(operation);
}
ClassLoader classLoader = targetScope.getExportClassLoader();
HashCode sourceHashCode = source.getResource().getContentHash();
final String dslId = operation.getId();
HashCode classLoaderHash = classLoaderHierarchyHasher.getClassLoaderHash(classLoader);
if (classLoaderHash == null) {
throw new IllegalArgumentException("Unknown classloader: " + classLoader);
}
final RemappingScriptSource remapped = new RemappingScriptSource(source);
PrimitiveHasher hasher = Hashing.newPrimitiveHasher();
hasher.putString(dslId);
hasher.putHash(sourceHashCode);
hasher.putHash(classLoaderHash);
String key = hasher.hash().toCompactString();
// Caching involves 2 distinct caches, so that 2 scripts with the same (hash, classpath) do not get compiled twice
// 1. First, we look for a cache script which (path, hash) matches. This cache is invalidated when the compile classpath of the script changes
// 2. Then we look into the 2d cache for a "generic script" with the same hash, that will be remapped to the script class name
// Both caches can be closed directly after use because:
// For 1, if the script changes or its compile classpath changes, a different directory will be used
// For 2, if the script changes, a different cache is used. If the classpath changes, the cache is invalidated, but classes are remapped to 1. anyway so never directly used
final PersistentCache cache = cacheRepository.cache("scripts/" + key).withDisplayName(dslId + " generic class cache for " + source.getDisplayName()).withInitializer(new ProgressReportingInitializer(progressLoggerFactory, new CompileToCrossBuildCacheAction(remapped, classLoader, operation, verifier, scriptBaseClass), "Compiling " + source.getShortDisplayName())).open();
try {
File genericClassesDir = classesDir(cache, operation);
File metadataDir = metadataDir(cache);
ClassPath remappedClasses = remapClasses(genericClassesDir, remapped);
return scriptCompilationHandler.loadFromDir(source, sourceHashCode, targetScope, remappedClasses, metadataDir, operation, scriptBaseClass);
} finally {
cache.close();
}
}
use of org.gradle.internal.hash.PrimitiveHasher in project gradle by gradle.
the class CachingTextResource method maybeFetch.
private void maybeFetch() {
if (content == null) {
content = resource.getText();
PrimitiveHasher hasher = Hashing.newPrimitiveHasher();
hasher.putHash(SIGNATURE);
hasher.putString(content);
contentHash = hasher.hash();
}
}
use of org.gradle.internal.hash.PrimitiveHasher in project gradle by gradle.
the class StringTextResource method getContentHash.
@Override
public HashCode getContentHash() throws ResourceException {
if (contentHash == null) {
PrimitiveHasher hasher = Hashing.newPrimitiveHasher();
hasher.putHash(SIGNATURE);
hasher.putString(getText());
contentHash = hasher.hash();
}
return contentHash;
}
use of org.gradle.internal.hash.PrimitiveHasher in project gradle by gradle.
the class UriTextResource method getContentHash.
@Override
public HashCode getContentHash() throws ResourceException {
PrimitiveHasher hasher = Hashing.newPrimitiveHasher();
hasher.putHash(SIGNATURE);
hasher.putString(getText());
return hasher.hash();
}
use of org.gradle.internal.hash.PrimitiveHasher in project gradle by gradle.
the class LineEndingNormalizingInputStreamHasher method hash.
/**
* Returns empty if the file is detected to be a binary file
*/
private Optional<HashCode> hash(InputStream inputStream) throws IOException {
PrimitiveHasher hasher = Hashing.newPrimitiveHasher();
hasher.putHash(SIGNATURE);
try (BufferedInputStream input = new BufferedInputStream(new CloseShieldInputStream(inputStream), BUFFER_SIZE)) {
int peekAhead = -1;
while (true) {
// If there is something left over in the peekAhead buffer, use that
int next = peekAhead;
// If the peekAhead buffer is empty, get the next byte from the input stream
if (next != -1) {
peekAhead = -1;
} else {
next = input.read();
}
// If both the peekAhead buffer and the input stream are empty, we're done
if (next == -1) {
break;
}
// Bust out if we detect a binary file
if (isControlCharacter(next)) {
return Optional.empty();
}
// If the next bytes are '\r' or '\r\n', replace it with '\n'
if (next == '\r') {
peekAhead = input.read();
if (peekAhead == '\n') {
peekAhead = -1;
}
next = '\n';
}
hasher.putByte((byte) next);
}
}
return Optional.of(hasher.hash());
}
Aggregations