Export without the graphics directory when it has no matching install

If host.factorio_graphics_directory had no install matching the major and
minor version of the instance, or did not exist, findVersion threw and the
whole export failed. Without the setting the same instance exports everything
except the base game icons, so it now logs a warning that names the setting
and exports without it.
This commit is contained in:
Danielv123 committed 2026-11-01 18:33:10 +01:00
1 parent 46fd7fcad4
commit 46c6153201
3 files changed
+49 -3

No files matched your search

+1
View File
@@ -363,6 +363,7 @@ Defaults to "factorio".
Directory to read the base game's icons from when exporting data.
The headless build of Factorio has no graphics, so instances running it export none of the base game's icons unless this points to a full install of Factorio.
Like `host.factorio_directory` this can either point to a Factorio directory, or to a directory containing multiple versions, in which case the latest one matching the major and minor version of the instance is used.
If there is no install matching the instance, a warning is logged and the data is exported without it.
Defaults to null.
+27 -2
View File
@@ -523,6 +523,31 @@ async function exportLocale(
return mergedLocales;
}
/**
* Find the data dir to read builtin mod graphics from
*
* @param server - The server the export runs on.
* @param graphicsDirectory - Full Factorio install, or directory of installs.
* @returns
* Data dir of the install matching the major and minor version of the
* server, or undefined if there is none.
* @internal
*/
async function findGraphicsDataDir(server: FactorioServer, graphicsDirectory: string) {
const majorMinor = server.version!.replace(/\.\d+$/, "") as lib.MajorMinorVersion;
try {
const [dataDir] = await findVersion(graphicsDirectory, majorMinor);
return dataDir;
} catch (err: any) {
// Without it the export still has everything but the base game icons
server._logger.warn(
`Unable to use host.factorio_graphics_directory for Factorio ${majorMinor}, exporting without it: ` +
`${err.message}`
);
return undefined;
}
}
/**
* Export locale, icons and metadata for the given factorio server
*
@@ -535,8 +560,7 @@ async function exportLocale(
export async function exportData(server: FactorioServer, graphicsDirectory?: string | null) {
const files: ExportFiles = { zipCache: new Map() };
if (graphicsDirectory) {
const majorMinor = server.version!.replace(/\.\d+$/, "") as lib.MajorMinorVersion;
[files.graphicsDataDir] = await findVersion(graphicsDirectory, majorMinor);
files.graphicsDataDir = await findGraphicsDataDir(server, graphicsDirectory);
}
try {
return await buildExport(server, files);
@@ -700,6 +724,7 @@ async function buildExport(server: FactorioServer, files: ExportFiles) {
export const _createSheetState = createSheetState;
export const _exportIcons = exportIcons;
export const _exportLocale = exportLocale;
export const _findGraphicsDataDir = findGraphicsDataDir;
export const _loadSimpleIcon = loadSimpleIcon;
export const _loadLayeredIcon = loadLayeredIcon;
export const _warnMissingBuiltinIcons = warnMissingBuiltinIcons;
+21 -1
View File
@@ -3,7 +3,8 @@ import path from "node:path";
import { FactorioServer } from "@clusterio/host/dist/node/src/server.js";
import {
_createSheetState, _exportIcons, _exportLocale, _loadLayeredIcon, _loadSimpleIcon, _warnMissingBuiltinIcons,
_createSheetState, _exportIcons, _exportLocale, _findGraphicsDataDir, _loadLayeredIcon, _loadSimpleIcon,
_warnMissingBuiltinIcons,
} from "@clusterio/host/dist/node/src/export.js";
@@ -121,6 +122,25 @@ describe("host/src/export", function() {
assert.equal(icon, null);
});
});
describe("findGraphicsDataDir()", function() {
const installs = path.join("test", "file", "factorio");
it("returns the data dir of the install matching the server version", async function() {
const dataDir = await _findGraphicsDataDir(testServer, installs);
assert.equal(dataDir, path.join(installs, "0.1.2", "data"));
assert.deepEqual(warnings, []);
});
it("warns and returns undefined when no install matches the server version", async function() {
const server = Object.create(testServer, { version: { value: "0.2.5" } });
assert.equal(await _findGraphicsDataDir(server, installs), undefined);
assert.equal(warnings.length, 1);
assert.match(warnings[0], /^Unable to use host\.factorio_graphics_directory for Factorio 0\.2, /);
});
it("warns and returns undefined when the directory does not exist", async function() {
assert.equal(await _findGraphicsDataDir(testServer, path.join("test", "file", "missing")), undefined);
assert.equal(warnings.length, 1);
assert.match(warnings[0], /^Unable to use host\.factorio_graphics_directory for Factorio 0\.1, .*ENOENT/);
});
});
describe("warnMissingBuiltinIcons()", function() {
it("warns once with the number of missing builtin files", function() {
_warnMissingBuiltinIcons(testServer, { zipCache: new Map() }, new Map([