mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 23:14:53 +09:00
Readd support for direct installs
This commit is contained in:
4 files changed
+103
-69
No files matched your search
@@ -25,7 +25,6 @@ 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;
|
||||
|
||||
@@ -237,31 +236,6 @@ 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,
|
||||
|
||||
+32
-12
@@ -18,7 +18,7 @@ const execFileAsync = util.promisify(child_process.execFile);
|
||||
*
|
||||
* @param factorioDir - Path factorio dir containing data/changelog.txt.
|
||||
*/
|
||||
export async function getFactorioVersion(factorioDir: string) {
|
||||
async function getFactorioVersion(factorioDir: string) {
|
||||
let changelog;
|
||||
const changelogPath = path.join(factorioDir, "data", "changelog.txt");
|
||||
try {
|
||||
@@ -35,7 +35,8 @@ export async function getFactorioVersion(factorioDir: string) {
|
||||
if (index !== -1) {
|
||||
const name = line.slice(0, index).trim();
|
||||
if (name.toLowerCase() === "version") {
|
||||
return line.slice(index + 1).trim();
|
||||
const version = line.slice(index + 1).trim();
|
||||
return lib.isFullVersion(version) ? version : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,6 +78,12 @@ function versionOrder(a: string, b: string) {
|
||||
async function listFactorioVersions(factorioDir: string) {
|
||||
const versions = new Set<lib.FullVersion>();
|
||||
|
||||
const directVersion = await getFactorioVersion(factorioDir);
|
||||
if (directVersion !== null) {
|
||||
versions.add(directVersion);
|
||||
return { direct: true, versions };
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -90,14 +97,14 @@ async function listFactorioVersions(factorioDir: string) {
|
||||
}
|
||||
|
||||
const version = await getFactorioVersion(fullPath);
|
||||
if (version === null || !lib.isFullVersion(version)) {
|
||||
if (version === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
versions.add(version);
|
||||
}
|
||||
|
||||
return versions;
|
||||
return { direct: false, versions };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,6 +185,16 @@ async function downloadAndExtractTar(url: string, targetDir: string) {
|
||||
* @internal
|
||||
*/
|
||||
async function findVersion(factorioDir: string, targetVersion: lib.TargetVersion): Promise<[string, lib.FullVersion]> {
|
||||
// Check if this is a direct installation dir
|
||||
const directVersion = await getFactorioVersion(factorioDir);
|
||||
if (directVersion !== null) {
|
||||
if (targetVersion === "latest" || directVersion === targetVersion || directVersion.startsWith(targetVersion)) {
|
||||
return [path.join(factorioDir, "data"), directVersion];
|
||||
}
|
||||
throw new Error(`Unable to find Factorio version ${targetVersion}`);
|
||||
}
|
||||
|
||||
// Otherwise assume it is a directory of multiple versions
|
||||
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
|
||||
@@ -192,7 +209,7 @@ async function findVersion(factorioDir: string, targetVersion: lib.TargetVersion
|
||||
}
|
||||
|
||||
const version = await getFactorioVersion(fullPath);
|
||||
if (version === null || !lib.isFullVersion(version)) {
|
||||
if (version === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -973,16 +990,18 @@ export class FactorioServer extends events.EventEmitter<FactorioServerEvents> {
|
||||
[0];
|
||||
|
||||
const installedVersions = await listFactorioVersions(this._factorioDir);
|
||||
if (!installedVersions.has(latestVersion.version)) {
|
||||
// Download the newer version
|
||||
if (!installedVersions.versions.has(latestVersion.version)) {
|
||||
const v = latestVersion.version;
|
||||
if (process.platform === "linux") {
|
||||
this._logger.info(`A newer version of factorio is available (${v}), starting download...`);
|
||||
const dst = path.join(this._factorioDir, latestVersion.version);
|
||||
await downloadAndExtractTar(latestVersion.headlessUrl, dst);
|
||||
} else {
|
||||
// Can't download if not linux or this is a direct install
|
||||
if (installedVersions.direct || process.platform !== "linux") {
|
||||
this._logger.info(`A newer version of factorio is available (${v}) but must be manually downloaded`);
|
||||
}
|
||||
|
||||
// Download the newer version
|
||||
this._logger.info(`A newer version of factorio is available (${v}), starting download...`);
|
||||
const dst = path.join(this._factorioDir, latestVersion.version);
|
||||
await downloadAndExtractTar(latestVersion.headlessUrl, dst);
|
||||
this._logger.info(`Downloaded factorio version ${v}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1536,6 +1555,7 @@ export class FactorioServer extends events.EventEmitter<FactorioServerEvents> {
|
||||
|
||||
|
||||
// For testing only
|
||||
export const _getFactorioVersion = getFactorioVersion;
|
||||
export const _versionOrder = versionOrder;
|
||||
export const _findVersion = findVersion;
|
||||
export const _listFactorioVersions = listFactorioVersions;
|
||||
|
||||
+68
-28
@@ -11,17 +11,17 @@ const { testLines } = require("../lib/factorio/lines");
|
||||
|
||||
|
||||
describe("host/server", function() {
|
||||
describe("getFactorioVersion()", function() {
|
||||
describe("_getFactorioVersion()", function() {
|
||||
it("should get the version from a changelog", async function() {
|
||||
let version = await hostServer.getFactorioVersion(path.join("test", "file", "changelogs", "good"));
|
||||
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.getFactorioVersion(path.join("test", "file", "changelogs", "bad"));
|
||||
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.getFactorioVersion(path.join("test", "file", "changelogs", "not-exists"));
|
||||
let version = await hostServer._getFactorioVersion(path.join("test", "file", "changelogs", "not-exists"));
|
||||
assert.equal(version, null);
|
||||
});
|
||||
});
|
||||
@@ -38,30 +38,59 @@ describe("host/server", function() {
|
||||
});
|
||||
|
||||
describe("_findVersion()", function() {
|
||||
it("should search given directory for latest Factorio install", async function() {
|
||||
const installDir = path.join("test", "file", "factorio");
|
||||
const [dir, version] = await hostServer._findVersion(installDir, "latest");
|
||||
assert.equal(dir, path.join(installDir, "0.1.2", "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
describe("direct install", function() {
|
||||
it("should search given directory for latest Factorio install", async function() {
|
||||
const installDir = path.join("test", "file", "factorio", "0.1.2");
|
||||
const [dir, version] = await hostServer._findVersion(installDir, "latest");
|
||||
assert.equal(dir, path.join(installDir, "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
});
|
||||
it("should search given directory for given Factorio install", async function() {
|
||||
const installDir = path.join("test", "file", "factorio", "0.1.1");
|
||||
const [dir, version] = await hostServer._findVersion(installDir, "0.1.1");
|
||||
assert.equal(dir, path.join(installDir, "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", "0.1.2");
|
||||
const [dir, version] = await hostServer._findVersion(installDir, "0.1");
|
||||
assert.equal(dir, path.join(installDir, "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
});
|
||||
it("should search given directory for latest Factorio install", async function() {
|
||||
const installDir = path.join("test", "file", "factorio");
|
||||
const [dir, version] = await hostServer._findVersion(installDir, "latest");
|
||||
assert.equal(dir, path.join(installDir, "0.1.2", "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
});
|
||||
});
|
||||
it("should search given directory for given Factorio install", async function() {
|
||||
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.2", "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
});
|
||||
it("should reject if no factorio install with the given version was found", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
await assert.rejects(
|
||||
hostServer._findVersion(installDir, "0.1.3"),
|
||||
new Error("Unable to find Factorio version 0.1.3")
|
||||
);
|
||||
describe("mutli install", function() {
|
||||
it("should reject if no factorio install with the given version was found", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
await assert.rejects(
|
||||
hostServer._findVersion(installDir, "0.1.3"),
|
||||
new Error("Unable to find Factorio version 0.1.3")
|
||||
);
|
||||
});
|
||||
it("should search given directory for given Factorio install", async function() {
|
||||
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.2", "data"));
|
||||
assert.equal(version, "0.1.2");
|
||||
});
|
||||
it("should reject if no factorio install with the given version was found", async function() {
|
||||
let installDir = path.join("test", "file", "factorio");
|
||||
await assert.rejects(
|
||||
hostServer._findVersion(installDir, "0.1.3"),
|
||||
new Error("Unable to find Factorio version 0.1.3")
|
||||
);
|
||||
});
|
||||
});
|
||||
it("should reject if no factorio install was found", async function() {
|
||||
let installDir = path.join("test", "file");
|
||||
@@ -73,10 +102,21 @@ describe("host/server", function() {
|
||||
});
|
||||
|
||||
describe("_listFactorioVersions()", function() {
|
||||
it("should list the version in a direct install", async function() {
|
||||
const installDir = path.join("test", "file", "factorio", "0.1.1");
|
||||
const installedVersions = await hostServer._listFactorioVersions(installDir);
|
||||
assert.deepEqual(installedVersions, {
|
||||
direct: true,
|
||||
versions: new Set(["0.1.1"]),
|
||||
});
|
||||
});
|
||||
it("should list all versions in a directory", async function() {
|
||||
const installDir = path.join("test", "file", "factorio");
|
||||
const installedVersions = await hostServer._listFactorioVersions(installDir);
|
||||
assert.deepEqual(installedVersions, new Set(["0.1.1", "0.1.2"]));
|
||||
assert.deepEqual(installedVersions, {
|
||||
direct: false,
|
||||
versions: new Set(["0.1.1", "0.1.2"]),
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ const fs = require("fs-extra");
|
||||
const path = require("path");
|
||||
|
||||
const lib = require("@clusterio/lib");
|
||||
const { FactorioServer, getFactorioVersion } = 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");
|
||||
@@ -20,7 +20,7 @@ describe("Integration of host/src/server", function() {
|
||||
}
|
||||
}
|
||||
|
||||
let version = await getFactorioVersion(factorioDir);
|
||||
let version = await _getFactorioVersion(factorioDir);
|
||||
if (version !== null) {
|
||||
checkVersion(version);
|
||||
} else {
|
||||
@@ -30,7 +30,7 @@ describe("Integration of host/src/server", function() {
|
||||
}
|
||||
|
||||
checkVersion(
|
||||
await getFactorioVersion(path.join(factorioDir, entry.name))
|
||||
await _getFactorioVersion(path.join(factorioDir, entry.name))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user