diff --git a/src/main/kotlin/link/infra/packwiz/installer/DownloadTask.kt b/src/main/kotlin/link/infra/packwiz/installer/DownloadTask.kt index e5de0d2..917550a 100644 --- a/src/main/kotlin/link/infra/packwiz/installer/DownloadTask.kt +++ b/src/main/kotlin/link/infra/packwiz/installer/DownloadTask.kt @@ -21,6 +21,7 @@ import java.nio.file.StandardCopyOption internal class DownloadTask private constructor(val metadata: IndexFile.File, val index: IndexFile, private val downloadSide: Side) : IOptionDetails { var cachedFile: ManifestFile.File? = null + private set private var err: Exception? = null val exceptionDetails get() = err?.let { e -> ExceptionDetails(name, e) } @@ -28,10 +29,24 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va fun failed() = err != null var alreadyUpToDate = false + private set private var metadataRequired = true private var invalidated = false // If file is new or isOptional changed to true, the option needs to be presented again private var newOptional = true + var completionStatus = CompletionStatus.INCOMPLETE + private set + + enum class CompletionStatus { + INCOMPLETE, + DOWNLOADED, + ALREADY_EXISTS_CACHED, + ALREADY_EXISTS_VALIDATED, + SKIPPED_DISABLED, + SKIPPED_WRONG_SIDE, + DELETED_DISABLED, + DELETED_WRONG_SIDE; + } val isOptional get() = metadata.linkedFile?.option?.optional ?: false @@ -76,6 +91,7 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va if (currHash == cachedFile.hash) { // Already up to date alreadyUpToDate = true metadataRequired = false + completionStatus = CompletionStatus.ALREADY_EXISTS_CACHED } } if (cachedFile.isOptional) { @@ -143,6 +159,7 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va fileSource.buffer().readAll(blackholeSink()) if (hash == fileSource.hash) { alreadyUpToDate = true + completionStatus = CompletionStatus.ALREADY_EXISTS_VALIDATED // Update the manifest file cachedFile = (cachedFile ?: ManifestFile.File()).also { @@ -181,10 +198,18 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va if (it.cachedLocation != null) { // Ensure wrong-side or optional false files are removed try { - Files.deleteIfExists(it.cachedLocation!!.nioPath) + completionStatus = if (Files.deleteIfExists(it.cachedLocation!!.nioPath)) { + if (correctSide()) { CompletionStatus.DELETED_DISABLED } else { CompletionStatus.DELETED_WRONG_SIDE } + } else { + if (correctSide()) { CompletionStatus.SKIPPED_DISABLED } else { CompletionStatus.SKIPPED_WRONG_SIDE } + } } catch (e: IOException) { Log.warn("Failed to delete file", e) } + } else { + completionStatus = + if (correctSide()) { CompletionStatus.SKIPPED_DISABLED } + else { CompletionStatus.SKIPPED_WRONG_SIDE } } it.cachedLocation = null return @@ -284,6 +309,8 @@ internal class DownloadTask private constructor(val metadata: IndexFile.File, va } } } + + completionStatus = CompletionStatus.DOWNLOADED } companion object { diff --git a/src/main/kotlin/link/infra/packwiz/installer/UpdateManager.kt b/src/main/kotlin/link/infra/packwiz/installer/UpdateManager.kt index 389b898..1f1c2dc 100644 --- a/src/main/kotlin/link/infra/packwiz/installer/UpdateManager.kt +++ b/src/main/kotlin/link/infra/packwiz/installer/UpdateManager.kt @@ -247,31 +247,17 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse } ui.submitProgress(InstallProgress("Checking local files...")) - // TODO: use kotlin filtering/FP rather than an iterator? val it: MutableIterator> = manifest.cachedFiles.entries.iterator() while (it.hasNext()) { val (uri, file) = it.next() if (file.cachedLocation != null) { - var alreadyDeleted = false - // Delete if option value has been set to false - if (file.isOptional && !file.optionValue) { + if (indexFile.files.none { it.file.rebase(opts.packFolder) == uri }) { // File has been removed from the index try { Files.deleteIfExists(file.cachedLocation!!.nioPath) } catch (e: IOException) { - Log.warn("Failed to delete optional disabled file", e) - } - // Set to null, as it doesn't exist anymore - file.cachedLocation = null - alreadyDeleted = true - } - if (indexFile.files.none { it.file.rebase(opts.packFolder) == uri }) { // File has been removed from the index - if (!alreadyDeleted) { - try { - Files.deleteIfExists(file.cachedLocation!!.nioPath) - } catch (e: IOException) { - Log.warn("Failed to delete file removed from index", e) - } + Log.warn("Failed to delete file removed from index", e) } + Log.info("Deleted ${file.cachedLocation!!.filename} (removed from pack)") it.remove() } } @@ -401,7 +387,16 @@ class UpdateManager internal constructor(private val opts: Options, val ui: IUse val progress = if (exDetails != null) { "Failed to download ${exDetails.name}: ${exDetails.exception.message}" } else { - "Downloaded ${task.name}" + when (task.completionStatus) { + DownloadTask.CompletionStatus.INCOMPLETE -> "${task.name} pending (you should never see this...)" + DownloadTask.CompletionStatus.DOWNLOADED -> "Downloaded ${task.name}" + DownloadTask.CompletionStatus.ALREADY_EXISTS_CACHED -> "${task.name} already exists (cached)" + DownloadTask.CompletionStatus.ALREADY_EXISTS_VALIDATED -> "${task.name} already exists (validated)" + DownloadTask.CompletionStatus.SKIPPED_DISABLED -> "Skipped ${task.name} (disabled)" + DownloadTask.CompletionStatus.SKIPPED_WRONG_SIDE -> "Skipped ${task.name} (wrong side)" + DownloadTask.CompletionStatus.DELETED_DISABLED -> "Deleted ${task.name} (disabled)" + DownloadTask.CompletionStatus.DELETED_WRONG_SIDE -> "Deleted ${task.name} (wrong side)" + } } ui.submitProgress(InstallProgress(progress, i + 1, tasks.size))