From afc3e17c9754651300aacd03fba9fa9a61c12a38 Mon Sep 17 00:00:00 2001 From: SulfurNitride Date: Sun, 12 Apr 2026 15:22:06 -0500 Subject: Fix launcher sync copying unrelated files from extraction dir MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous sync ran `tar -cf - .` inside the launcher's HERE dir, which slurped anything sitting next to the fluorine-manager script. If a user extracted the release archive into ~/Downloads (alongside a 38 GB mod stash), the launcher happily copied the whole lot into ~/.local/share/fluorine/bin/ on first run. Write a `.fluorine-manifest` at build time listing the top-level entries that belong to Fluorine, then have the launcher copy only those entries. Also bail with a clear error if the manifest or ModOrganizer-core is missing — catches "launcher dropped into some random folder" before any damage is done. Co-Authored-By: Claude Opus 4.6 (1M context) --- docker/build-inner.sh | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'docker') diff --git a/docker/build-inner.sh b/docker/build-inner.sh index a53f79c..19227ce 100755 --- a/docker/build-inner.sh +++ b/docker/build-inner.sh @@ -363,6 +363,17 @@ BIN_DST="${FLUORINE_DATA}/bin" HERE_REAL="$(readlink -f "${HERE}")" DST_REAL="$(readlink -f "${BIN_DST}" 2>/dev/null || echo "")" if [ "${HERE_REAL}" != "${DST_REAL}" ]; then + # Manifest lists top-level entries that belong to Fluorine. Without it we + # can't distinguish our files from whatever else the user parked next to + # the launcher (e.g. extracted into ~/Downloads alongside their mods). + MANIFEST="${HERE}/.fluorine-manifest" + if [ ! -f "${MANIFEST}" ] || [ ! -f "${HERE}/ModOrganizer-core" ]; then + echo "ERROR: Fluorine launcher can't find its bundle files in ${HERE}." >&2 + echo "Extract the release archive into its own directory and run the" >&2 + echo "launcher from there — not from a folder containing other files." >&2 + exit 1 + fi + # Fingerprint from size+mtime (not inode) so re-extracting the same tarball # onto a different filesystem doesn't trigger a spurious full resync. CURRENT_VER="$(stat -c '%s:%Y' "${HERE}/ModOrganizer-core" 2>/dev/null || echo "unknown")" @@ -375,7 +386,14 @@ if [ "${HERE_REAL}" != "${DST_REAL}" ]; then STAGE="${BIN_DST}.new" rm -rf "${STAGE}" mkdir -p "${STAGE}" - (cd "${HERE}" && tar --exclude-vcs -cf - .) | (cd "${STAGE}" && tar -xf -) + # Copy only entries listed in the manifest — never the whole HERE dir, + # or we'd slurp any unrelated files sitting next to the launcher. + while IFS= read -r entry; do + [ -z "${entry}" ] && continue + [ -e "${HERE}/${entry}" ] || continue + cp -a "${HERE}/${entry}" "${STAGE}/" + done < "${MANIFEST}" + cp -a "${MANIFEST}" "${STAGE}/" rm -rf "${BIN_DST}" mv "${STAGE}" "${BIN_DST}" echo "${CURRENT_VER}" > "${MARKER}" @@ -440,6 +458,14 @@ cp -f /src/data/icons/com.fluorine.manager.desktop "${OUT_DIR}/icons/" cp -f /src/data/icons/com.fluorine.manager.png "${OUT_DIR}/icons/" cp -f /src/data/icons/com.fluorine.manager.metainfo.xml "${OUT_DIR}/icons/" +# ── Manifest of top-level entries ── +# The launcher's sync step copies only files listed here into +# ~/.local/share/fluorine/bin/. Without a manifest it would have to guess +# (previously: tar the whole extraction dir), and would slurp any unrelated +# files the user parked next to the launcher — e.g. 38 GB of mods in Downloads. +(cd "${OUT_DIR}" && ls -A | grep -v '^\.fluorine-manifest$') > "${OUT_DIR}/.fluorine-manifest" +echo "Wrote manifest: $(wc -l < "${OUT_DIR}/.fluorine-manifest") entries" + # ── Determine build mode ── # BUILD_MODE is passed from build.sh: tarball (default), installer, appimage, all BUILD_MODE="${BUILD_MODE:-tarball}" -- cgit v1.3.1