patch absolute paths

This commit is contained in:
olcxja 2026-09-26 15:45:11 +02:00
commit b442363f38
3 changed files with 21 additions and 10 deletions

View file

@ -6,8 +6,8 @@
"main": "src/main.js", "main": "src/main.js",
"scripts": { "scripts": {
"start": "electron .", "start": "electron .",
"test": "node test/import.test.js && node test/icons.test.js && node test/shortcuts.test.js", "test": "node test/import.test.js && node test/icons.test.js && node test/shortcuts.test.js && node test/wines-portable.test.js",
"smoke": "node test/import.test.js && node test/icons.test.js && node test/shortcuts.test.js" "smoke": "node test/import.test.js && node test/icons.test.js && node test/shortcuts.test.js && node test/wines-portable.test.js"
}, },
"devDependencies": { "devDependencies": {
"@electron/asar": "^3.4.1", "@electron/asar": "^3.4.1",

View file

@ -576,7 +576,7 @@ function renderWines() {
</div> </div>
` `
row.querySelector('.title').textContent = w.label row.querySelector('.title').textContent = w.label
row.querySelector('.sub').textContent = w.path || t('wines.systemHint') row.querySelector('.sub').textContent = displayPath(w.path) || t('wines.systemHint')
row.querySelector('.sub').title = row.querySelector('.sub').textContent row.querySelector('.sub').title = row.querySelector('.sub').textContent
const defBtn = row.querySelector('[data-act=default]') const defBtn = row.querySelector('[data-act=default]')
defBtn.textContent = t('wines.makeDefault') defBtn.textContent = t('wines.makeDefault')

View file

@ -3,7 +3,7 @@
const fs = require('fs') const fs = require('fs')
const fsp = fs.promises const fsp = fs.promises
const path = require('path') const path = require('path')
const { DIRS, readJson, writeJson } = require('./paths') const { DIRS, readJson, writeJson, toPortablePath, resolvePortablePath } = require('./paths')
const { dedupeDir } = require('./fsutil') const { dedupeDir } = require('./fsutil')
const WINES_DIR = DIRS.WINES const WINES_DIR = DIRS.WINES
@ -106,7 +106,7 @@ async function refreshWines() {
} catch { } catch {
found = [] found = []
} }
const prev = readJson(REGISTRY, []) const prev = readJson(REGISTRY, []).map(wineAbs)
const prevById = new Map(prev.map(w => [w.id, w])) const prevById = new Map(prev.map(w => [w.id, w]))
// A build whose path changed since last scan was moved (or the launcher // A build whose path changed since last scan was moved (or the launcher
// itself was) - rewire its absolute symlinks to the current location. // itself was) - rewire its absolute symlinks to the current location.
@ -120,12 +120,22 @@ async function refreshWines() {
} }
const disabled = new Set(prev.filter(w => w.disabled).map(w => w.id)) const disabled = new Set(prev.filter(w => w.disabled).map(w => w.id))
for (const w of found) if (disabled.has(w.id)) w.disabled = true for (const w of found) if (disabled.has(w.id)) w.disabled = true
writeJson(REGISTRY, found) writeJson(REGISTRY, found.map(wineRel))
return found return found
} }
// Stored relative to FILES (portable), resolved to absolute for use - same
// scheme as the game registry. `id`, `name`, `label`, `version`, `type` pass through.
function wineAbs(w) {
return { ...w, path: resolvePortablePath(w.path), wineBin: resolvePortablePath(w.wineBin) }
}
function wineRel(w) {
return { ...w, path: toPortablePath(w.path), wineBin: toPortablePath(w.wineBin) }
}
function getWines() { function getWines() {
return readJson(REGISTRY, []) return readJson(REGISTRY, []).map(wineAbs)
} }
function getWine(id) { function getWine(id) {
@ -137,7 +147,7 @@ function setWineDisabled(id, disabled) {
const w = wines.find(x => x.id === id) const w = wines.find(x => x.id === id)
if (w) { if (w) {
w.disabled = !!disabled w.disabled = !!disabled
writeJson(REGISTRY, wines) writeJson(REGISTRY, wines.map(wineRel))
} }
return wines return wines
} }
@ -160,7 +170,7 @@ function deleteWine(id) {
try { try {
fs.rmSync(w.path, { recursive: true, force: true }) fs.rmSync(w.path, { recursive: true, force: true })
} catch {} } catch {}
writeJson(REGISTRY, wines.filter(x => x.id !== id)) writeJson(REGISTRY, wines.filter(x => x.id !== id).map(wineRel))
if (getDefaultWine() === id) require('./library').saveSettings({ defaultWine: 'system' }) if (getDefaultWine() === id) require('./library').saveSettings({ defaultWine: 'system' })
return { ok: true } return { ok: true }
} }
@ -262,7 +272,8 @@ async function importWineFolder(srcDir) {
symlinksFixed = await fixBuildSymlinks(dst) symlinksFixed = await fixBuildSymlinks(dst)
} catch {} } catch {}
await refreshWines() await refreshWines()
return { ok: true, path: dst, symlinksFixed } // the toast shows a portable-looking path (files/...) like everywhere else
return { ok: true, path: toPortablePath(dst), symlinksFixed }
} }
module.exports = { refreshWines, getWines, getWine, setWineDisabled, getDefaultWine, setDefaultWine, deleteWine, importWineFolder, findWineBinary, detectType, fixBuildSymlinks } module.exports = { refreshWines, getWines, getWine, setWineDisabled, getDefaultWine, setDefaultWine, deleteWine, importWineFolder, findWineBinary, detectType, fixBuildSymlinks }