Remove single dir factorio install

This commit is contained in:
Cooldude2606 committed 2026-02-04 22:16:56 +00:00
1 parent 68a3c11d41
commit 1c7a32113a
11 files changed
+66 -65

No files matched your search

+26
View File
@@ -25,6 +25,7 @@ import * as lib from "@clusterio/lib";
import { ConsoleTransport, levels, logger } from "@clusterio/lib";
import Host from "./src/Host";
import { getFactorioVersion } from "./src/server";
let host: Host | undefined;
@@ -236,6 +237,31 @@ async function startHost() {
tlsCa = await fs.readFile(tlsCaPath, "utf8");
}
// Migrate from single factorio version to multiple
const factorioDir = hostConfig.get("host.factorio_directory");
const singleFactorioVersion = await getFactorioVersion(factorioDir);
if (singleFactorioVersion !== null) {
const dst = path.join(factorioDir, singleFactorioVersion);
logger.info(`Found single factorio version in ${factorioDir} moving to ${dst}`);
const stats = await fs.lstat(factorioDir);
if (stats.isSymbolicLink()) {
// For symlinks we want to move the file, but cant move it into itself so need a tmp move
const tmpPath = `${factorioDir}.tmp`;
await fs.move(factorioDir, tmpPath);
await fs.ensureDir(factorioDir);
await fs.move(tmpPath, dst);
} else {
// It is a directory here, otherwise no version would have been found
// We will only move known files in case a version was incorrectly installed in the dir
await fs.ensureDir(dst);
await Promise.all(
["bin", "data", "config-path.cfg"].map(name => (
fs.move(path.join(factorioDir, name), path.join(dst, name))
))
);
}
}
let hostConnector = new HostConnector(hostConfig, tlsCa, pluginInfos);
host = new Host(
hostConnector,
+18 -30
View File
@@ -14,11 +14,11 @@ import * as lib from "@clusterio/lib";
* Determines the version of Factorio the datadir is pointing to by
* reading the changelog.txt in it.
*
* @param changelogPath - Path to changelog.txt.
* @internal
* @param factorioDir - Path factorio dir containing data/changelog.txt.
*/
async function getVersion(changelogPath: string) {
export async function getFactorioVersion(factorioDir: string) {
let changelog;
const changelogPath = path.join(factorioDir, "data", "changelog.txt");
try {
changelog = await fs.readFile(changelogPath, "utf-8");
} catch (err: any) {
@@ -28,10 +28,10 @@ async function getVersion(changelogPath: string) {
throw err;
}
for (let line of changelog.split(/[\r\n]+/)) {
let index = line.indexOf(":");
for (const line of changelog.split(/[\r\n]+/)) {
const index = line.indexOf(":");
if (index !== -1) {
let name = line.slice(0, index).trim();
const name = line.slice(0, index).trim();
if (name.toLowerCase() === "version") {
return line.slice(index + 1).trim();
}
@@ -80,40 +80,29 @@ function versionOrder(a: string, b: string) {
* @internal
*/
async function findVersion(factorioDir: string, targetVersion: lib.TargetVersion): Promise<[string, lib.FullVersion]> {
// There are two supported setups: having the factorio dir be the actual
// install directory, and having the factorio dir be a folder containing
// multiple install directories
let simpleVersion = await getVersion(path.join(factorioDir, "data", "changelog.txt"));
if (simpleVersion !== null) {
if (simpleVersion === targetVersion || simpleVersion.startsWith(targetVersion) || targetVersion === "latest") {
if (lib.isFullVersion(simpleVersion)) {
return [path.join(factorioDir, "data"), simpleVersion];
const versions = new Map<lib.FullVersion, string>();
for (const name of await fs.readdir(factorioDir)) {
// We do not use withFileTypes or lstat because we want to follow symlinks
const fullPath = path.join(factorioDir, name);
try {
const stats = await fs.stat(fullPath);
if (!stats.isDirectory()) {
continue;
}
}
throw new Error(
`Factorio version ${targetVersion} was requested, but install directory contains ${simpleVersion}`
);
}
let versions = new Map<lib.FullVersion, string>();
for (let entry of await fs.readdir(factorioDir, { withFileTypes: true })) {
if (!entry.isDirectory()) {
} catch {
continue;
}
let version = await getVersion(path.join(factorioDir, entry.name, "data", "changelog.txt"));
const version = await getFactorioVersion(fullPath);
if (version === null || !lib.isFullVersion(version)) {
continue;
}
if (version === targetVersion) {
return [path.join(factorioDir, entry.name, "data"), version];
return [path.join(factorioDir, name, "data"), version];
}
versions.set(version, entry.name);
versions.set(version, name);
}
if (!versions.size) {
@@ -1421,7 +1410,6 @@ export class FactorioServer extends events.EventEmitter<FactorioServerEvents> {
// For testing only
export const _getVersion = getVersion;
export const _versionOrder = versionOrder;
export const _findVersion = findVersion;
export const _randomDynamicPort = randomDynamicPort;
File renamed without changes.
File renamed without changes.
View File
Whitespace-only changes.
Whitespace-only changes.
+18 -31
View File
@@ -11,17 +11,17 @@ const { testLines } = require("../lib/factorio/lines");
describe("host/server", function() {
describe("_getVersion()", function() {
describe("getFactorioVersion()", function() {
it("should get the version from a changelog", async function() {
let version = await hostServer._getVersion(path.join("test", "file", "changelog-test.txt"));
let version = await hostServer.getFactorioVersion(path.join("test", "file", "changelogs", "good"));
assert.equal(version, "0.1.1");
});
it("should return null if unable to find the version", async function() {
let version = await hostServer._getVersion(path.join("test", "file", "changelog-bad.txt"));
let version = await hostServer.getFactorioVersion(path.join("test", "file", "changelogs", "bad"));
assert.equal(version, null);
});
it("should return null if file does not exist", async function() {
let version = await hostServer._getVersion(path.join("test", "file", "does-not-exist.txt"));
let version = await hostServer.getFactorioVersion(path.join("test", "file", "changelogs", "not-exists"));
assert.equal(version, null);
});
});
@@ -38,46 +38,33 @@ describe("host/server", function() {
});
describe("_findVersion()", function() {
it("should find a given install dir with latest as target", async function() {
let installDir = path.join("test", "file", "factorio");
let [dir, version] = await hostServer._findVersion(installDir, "latest");
assert.equal(dir, path.join(installDir, "data"));
assert.equal(version, "0.1.1");
});
it("should find a given install dir with correct version as target", async function() {
let installDir = path.join("test", "file", "factorio");
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
assert.equal(dir, path.join(installDir, "data"));
assert.equal(version, "0.1.1");
});
it("should reject if the install dir version does not match target version", async function() {
let installDir = path.join("test", "file", "factorio");
await assert.rejects(
hostServer._findVersion(installDir, "0.1.2"),
new Error("Factorio version 0.1.2 was requested, but install directory contains 0.1.1")
);
});
it("should search given directory for latest Factorio install", async function() {
let installDir = path.join("test", "file");
let [dir, version] = await hostServer._findVersion(installDir, "latest");
assert.equal(dir, path.join(installDir, "factorio", "data"));
const installDir = path.join("test", "file", "factorio");
const [dir, version] = await hostServer._findVersion(installDir, "latest");
assert.equal(dir, path.join(installDir, "0.1.1", "data"));
assert.equal(version, "0.1.1");
});
it("should search given directory for given Factorio install", async function() {
let installDir = path.join("test", "file");
let [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
assert.equal(dir, path.join(installDir, "factorio", "data"));
const installDir = path.join("test", "file", "factorio");
const [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
assert.equal(dir, path.join(installDir, "0.1.1", "data"));
assert.equal(version, "0.1.1");
});
it("should search given directory for partly given Factorio install", async function() {
const installDir = path.join("test", "file", "factorio");
const [dir, version] = await hostServer._findVersion(installDir, "0.1");
assert.equal(dir, path.join(installDir, "0.1.1", "data"));
assert.equal(version, "0.1.1");
});
it("should reject if no factorio install with the given version was found", async function() {
let installDir = path.join("test", "file");
let installDir = path.join("test", "file", "factorio");
await assert.rejects(
hostServer._findVersion(installDir, "0.1.2"),
new Error("Unable to find Factorio version 0.1.2")
);
});
it("should reject if no factorio install was found", async function() {
let installDir = path.join("test", "file", "instances");
let installDir = path.join("test", "file");
await assert.rejects(
hostServer._findVersion(installDir, "latest"),
new Error(`Unable to find any Factorio install in ${installDir}`)
+4 -4
View File
@@ -5,14 +5,14 @@ const fs = require("fs-extra");
const path = require("path");
const lib = require("@clusterio/lib");
const { FactorioServer, _getVersion } = require("@clusterio/host/dist/node/src/server");
const { FactorioServer, getFactorioVersion } = require("@clusterio/host/dist/node/src/server");
const { logger } = lib;
const { slowTest, factorioDir } = require("./index");
describe("Integration of host/src/server", function() {
describe("_getVersion()", function() {
describe("getFactorioVersion()", function() {
it("should get a version from factorio's changelog.txt", async function() {
function checkVersion(version) {
if (!/^\d+\.\d+\.\d+$/.test(version)) {
@@ -20,7 +20,7 @@ describe("Integration of host/src/server", function() {
}
}
let version = await _getVersion(path.join(factorioDir, "data", "changelog.txt"));
let version = await getFactorioVersion(factorioDir);
if (version !== null) {
checkVersion(version);
} else {
@@ -30,7 +30,7 @@ describe("Integration of host/src/server", function() {
}
checkVersion(
await _getVersion(path.join(factorioDir, entry.name, "data", "changelog.txt"))
await getFactorioVersion(path.join(factorioDir, entry.name))
);
}
}