show progress for imports and deletions

This commit is contained in:
olcxja 2026-10-02 15:19:00 +02:00
commit 5e342b6fe5
13 changed files with 343 additions and 115 deletions

View file

@ -4,7 +4,7 @@ const fs = require('fs')
const fsp = fs.promises
const path = require('path')
const { DIRS, readJson, writeJson, toPortablePath, resolvePortablePath } = require('./paths')
const { dedupeDir } = require('./fsutil')
const { dedupeDir, copyTree, treeSize, removeTree } = require('./fsutil')
const { normalizeLabel } = require('./names')
const { rewireSymlinks, restoreExecutableBits, EXEC_NAMES } = require('./symlinks')
@ -210,13 +210,18 @@ function setDefaultWine(id) {
return { ok: true, defaultWine: id }
}
function deleteWine(id) {
// Same measured removal as a prefix (staging, then a bar driven by the files
// walking out): a build folder is multi-GB.
async function deleteWine(id, onProgress) {
const wines = getWines()
const w = wines.find(x => x.id === id)
if (!w || w.system) return { ok: false, error: w ? 'isSystem' : 'notFound' }
try {
fs.rmSync(w.path, { recursive: true, force: true })
} catch {}
const emit = (phase, detail) => {
if (onProgress) onProgress({ phase, label: w.label || w.name || id, ...detail })
}
emit('count', { files: 0, bytes: 0 })
const total = await treeSize(w.path)
await removeTree(w.path, p => emit('remove', { files: p.files, bytes: p.bytes, totalFiles: total.files, totalBytes: total.bytes }))
writeJson(REGISTRY, wines.filter(x => x.id !== id).map(wineRel))
if (getDefaultWine() === id) require('./library').saveSettings({ defaultWine: 'system' })
return { ok: true }
@ -281,7 +286,7 @@ function buildAuditFailed(root, wineBin) {
return false
}
async function importWineFolder(srcDir) {
async function importWineFolder(srcDir, onProgress) {
const type = detectType(srcDir)
let copySrc = srcDir
if (!type) {
@ -294,7 +299,14 @@ async function importWineFolder(srcDir) {
if (build) copySrc = path.join(srcDir, build.name)
}
const dst = dedupeDir(WINES_DIR, path.basename(copySrc))
await fsp.cp(copySrc, dst, { recursive: true, verbatimSymlinks: true })
// a wine/proton build is big enough that the copy needs a real bar: count it
// first (staging), then report bytes as they land while it copies
const emit = (phase, detail) => {
if (onProgress) onProgress({ phase, label: path.basename(dst), ...detail })
}
emit('count', { files: 0, bytes: 0 })
const total = await treeSize(copySrc)
await copyTree(copySrc, dst, p => emit('copy', { files: p.done, bytes: p.bytes, totalFiles: total.files, totalBytes: total.bytes }))
let healed = { links: 0, executables: 0 }
try {
healed = await healBuild(dst)