[Native] Lazily create dependency & cache directories. (#4627)
Previously initializing the DependencyProcessor will result in file IO. In a fully-hermetic environment where all dependencies are local, this IO is redundant and may require the build system (e.g. Bazel) to do extra setup to ensure there is a local writable directory specified for these directories. This change will instead cause the dependency processor to bail early and skip downloading dependencies if all are local anyway. Prior to this change kicking off a clean build with local dependencies would result in: ``` rm -rf ~/.konan/cache; fswatch -ax ~/.konan ~/.konan/cache Created IsDir ~/.konan/cache/.lock Created IsFile ``` After the change no FS operations are performed.
This commit is contained in:
+21
-8
@@ -96,10 +96,17 @@ class DependencyProcessor(dependenciesRoot: File,
|
||||
private val deleteArchives: Boolean = true,
|
||||
private val archiveType: ArchiveType = ArchiveType.systemDefault) {
|
||||
|
||||
private val dependenciesDirectory = dependenciesRoot.apply { mkdirs() }
|
||||
private val cacheDirectory = homeDependencyCache.apply { mkdirs() }
|
||||
private val dependenciesDirectory by lazy {
|
||||
dependenciesRoot.apply { mkdirs() }
|
||||
}
|
||||
|
||||
private val lockFile = File(cacheDirectory, ".lock").apply { if (!exists()) createNewFile() }
|
||||
private val cacheDirectory by lazy {
|
||||
homeDependencyCache.apply { mkdirs() }
|
||||
}
|
||||
|
||||
private val lockFile by lazy {
|
||||
File(cacheDirectory, ".lock").apply { if (!exists()) createNewFile() }
|
||||
}
|
||||
|
||||
var showInfo = true
|
||||
private var isInfoShown = false
|
||||
@@ -289,18 +296,24 @@ class DependencyProcessor(dependenciesRoot: File,
|
||||
// String literals are internalized so we create a new instance to avoid synchronization on a shared object.
|
||||
java.lang.String("lock")
|
||||
}
|
||||
|
||||
val remoteDependencies = resolvedDependencies.mapNotNull { (dependency, candidate) ->
|
||||
when (candidate) {
|
||||
is DependencySource.Local -> null
|
||||
is DependencySource.Remote -> dependency to candidate
|
||||
}
|
||||
}
|
||||
if (remoteDependencies.isEmpty()) { return }
|
||||
|
||||
synchronized(lock) {
|
||||
RandomAccessFile(lockFile, "rw").channel.lock().use {
|
||||
resolvedDependencies.forEach { (dependency, candidate) ->
|
||||
remoteDependencies.forEach { (dependency, candidate) ->
|
||||
val baseUrl = when (candidate) {
|
||||
is DependencySource.Local -> null
|
||||
DependencySource.Remote.Public -> dependenciesUrl
|
||||
DependencySource.Remote.Internal -> InternalServer.url
|
||||
}
|
||||
// TODO: consider using different caches for different remotes.
|
||||
if (baseUrl != null) {
|
||||
downloadDependency(dependency, baseUrl)
|
||||
}
|
||||
downloadDependency(dependency, baseUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user