func downloadAndPopulateCache()

in Sources/PackageRegistry/RegistryDownloadsManager.swift [133:235]


    func downloadAndPopulateCache(
        package: PackageIdentity,
        version: Version,
        packagePath: AbsolutePath,
        observabilityScope: ObservabilityScope,
        delegateQueue: DispatchQueue,
        callbackQueue: DispatchQueue,
        completion: @escaping  (Result<FetchDetails, Error>) -> Void
    ) {
        if let cachePath = self.cachePath {
            do {
                let relativePath = try package.downloadPath(version: version)
                let cachedPacakgePath = cachePath.appending(relativePath)

                try self.initializeCacheIfNeeded(cachePath: cachePath)
                try self.fileSystem.withLock(on: cachedPacakgePath, type: .exclusive) {
                    // download the package into the cache unless already exists
                    if try self.fileSystem.validPackageDirectory(cachedPacakgePath) {
                        // extra validation to defend from racy edge cases?
                        if self.fileSystem.exists(packagePath) {
                            throw StringError("\(packagePath) already exists unexpectedly")
                        }
                        // copy the package from the cache into the package path.
                        try self.fileSystem.createDirectory(packagePath.parentDirectory, recursive: true)
                        try self.fileSystem.copy(from: cachedPacakgePath, to: packagePath)
                        completion(.success(.init(fromCache: true, updatedCache: false)))
                    } else {
                        // it is possible that we already created the directory before from failed attempts, so clear leftover data if present.
                        try? self.fileSystem.removeFileTree(cachedPacakgePath)
                        // download the package from the registry
                        self.registryClient.downloadSourceArchive(
                            package: package,
                            version: version,
                            fileSystem: self.fileSystem,
                            destinationPath: cachedPacakgePath,
                            checksumAlgorithm: self.checksumAlgorithm,
                            progressHandler: updateDownloadProgress,
                            observabilityScope: observabilityScope,
                            callbackQueue: callbackQueue
                        ) { result in
                            completion(result.tryMap {
                                // extra validation to defend from racy edge cases?
                                if self.fileSystem.exists(packagePath) {
                                    throw StringError("\(packagePath) already exists unexpectedly")
                                }
                                // copy the package from the cache into the package path.
                                try self.fileSystem.createDirectory(packagePath.parentDirectory, recursive: true)
                                try self.fileSystem.copy(from: cachedPacakgePath, to: packagePath)
                                return FetchDetails(fromCache: true, updatedCache: true)
                            })
                        }
                    }
                }
            } catch {
                // download without populating the cache in the case of an error.
                observabilityScope.emit(warning: "skipping cache due to an error: \(error)")
                // it is possible that we already created the directory from failed attempts, so clear leftover data if present.
                try? self.fileSystem.removeFileTree(packagePath)
                //try self.provider.fetch(repository: handle.repository, to: repositoryPath, progressHandler: updateFetchProgress(progress:))
                self.registryClient.downloadSourceArchive(
                    package: package,
                    version: version,
                    fileSystem: self.fileSystem,
                    destinationPath: packagePath,
                    checksumAlgorithm: self.checksumAlgorithm,
                    progressHandler: updateDownloadProgress,
                    observabilityScope: observabilityScope,
                    callbackQueue: callbackQueue
                ) { result in
                    completion(result.map{ FetchDetails(fromCache: false, updatedCache: false) })
                }
            }
        } else {
            // it is possible that we already created the directory from failed attempts, so clear leftover data if present.
            try? self.fileSystem.removeFileTree(packagePath)
            // download without populating the cache when no `cachePath` is set.
            self.registryClient.downloadSourceArchive(
                package: package,
                version: version,
                fileSystem: self.fileSystem,
                destinationPath: packagePath,
                checksumAlgorithm: self.checksumAlgorithm,
                progressHandler: updateDownloadProgress,
                observabilityScope: observabilityScope,
                callbackQueue: callbackQueue
            ) { result in
                completion(result.map{ FetchDetails(fromCache: false, updatedCache: false) })
            }
        }

        // utility to update progress

        func updateDownloadProgress(downloaded: Int64, total: Int64?) -> Void {
            delegateQueue.async {
                self.delegate?.fetching(
                    package: package,
                    version: version,
                    downloaded: downloaded,
                    total: total
                )
            }
        }
    }