mirror of
https://github.com/C4illin/ConvertX.git
synced 2026-09-12 09:57:46 +02:00
fix: version printing (#606)
Co-authored-by: Emrik Östling <emrik.ostling@gmail.com>
This commit is contained in:
@@ -62,6 +62,7 @@ RUN apt-get update && apt-get install -y \
|
||||
libreoffice \
|
||||
libva2 \
|
||||
libvips-tools \
|
||||
libemail-address-perl \
|
||||
libemail-outlook-message-perl \
|
||||
lmodern \
|
||||
mupdf-tools \
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"heif-info",
|
||||
"potrace",
|
||||
"soffice",
|
||||
"msgconvert"
|
||||
"perl"
|
||||
],
|
||||
"tailwind": {
|
||||
"entry": ["src/main.css"]
|
||||
|
||||
@@ -8,6 +8,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
readFile("/etc/os-release", "utf8", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Not running on docker, this is not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -18,6 +19,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("pandoc -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Pandoc is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -28,6 +30,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("ffmpeg -version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("FFmpeg is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -38,6 +41,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("vips -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Vips is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -48,6 +52,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("magick --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("ImageMagick is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -58,6 +63,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("gm version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("GraphicsMagick is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -68,6 +74,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("inkscape --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Inkscape is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -78,6 +85,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("djxl --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("libjxl-tools is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -85,19 +93,21 @@ if (process.env.NODE_ENV === "production") {
|
||||
}
|
||||
});
|
||||
|
||||
exec("dasel --version", (error, stdout) => {
|
||||
exec("dasel version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("dasel is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
console.log(`dasel ${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("xelatex -version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Tex Live with XeTeX is not installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -108,36 +118,30 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("resvg -V", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("resvg is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
// stdout may contain the command plus version (e.g. "resvg -V v1.0.0").
|
||||
// Extract the last token and print it as version to avoid duplication.
|
||||
const firstLine = (stdout || "").split("\n")[0] || "";
|
||||
const lastToken = (firstLine.split(" ").filter(Boolean).pop() ?? "").toString();
|
||||
console.log(`resvg ${lastToken}`);
|
||||
console.log(`resvg v${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("assimp version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("assimp is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
// assimp prints its version on a specific line in real output; if the
|
||||
// expected line isn't present (e.g. in tests/mocks), fall back to the
|
||||
// first non-empty line. Then extract the last token as version.
|
||||
const lines = (stdout || "").split("\n").filter(Boolean);
|
||||
const candidate = (lines[5] ?? lines[0] ?? "").toString();
|
||||
const lastToken = (candidate.split(" ").filter(Boolean).pop() ?? "").toString();
|
||||
console.log(`assimp ${lastToken}`);
|
||||
const firstLines = stdout.split("\n");
|
||||
console.log(`assimp ${firstLines[5] || firstLines[0] || ""}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("ebook-convert --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("ebook-convert (calibre) is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -148,6 +152,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("heif-info -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("libheif is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -158,6 +163,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("potrace -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("potrace is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -168,6 +174,7 @@ if (process.env.NODE_ENV === "production") {
|
||||
exec("soffice --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("libreoffice is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
@@ -175,28 +182,29 @@ if (process.env.NODE_ENV === "production") {
|
||||
}
|
||||
});
|
||||
|
||||
exec("msgconvert --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("msgconvert (libemail-outlook-message-perl) is not installed");
|
||||
}
|
||||
// msgconvert has no version flag, so read the version of the perl module providing it
|
||||
exec(
|
||||
"perl -MEmail::Outlook::Message -e 'print $Email::Outlook::Message::VERSION'",
|
||||
(error, stdout) => {
|
||||
if (error) {
|
||||
console.error("msgconvert (libemail-outlook-message-perl) is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
if (stdout) {
|
||||
console.log(`msgconvert v${stdout.split("\n")[0]}`);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
exec("bun -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Bun is not installed. wait what");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
// stdout may include the command itself (e.g. "bun -v v1.0.0"). Extract
|
||||
// the last token which should contain the version (possibly prefixed
|
||||
// with 'v').
|
||||
const firstLine = (stdout || "").split("\n")[0] || "";
|
||||
const lastToken = (firstLine.split(" ").filter(Boolean).pop() ?? "").toString();
|
||||
console.log(`Bun ${lastToken}`);
|
||||
console.log(`Bun v${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { test, expect, mock, spyOn, afterEach } from "bun:test";
|
||||
import { afterEach, expect, mock, spyOn, test } from "bun:test";
|
||||
import { exec } from "node:child_process";
|
||||
import { readFile } from "node:fs";
|
||||
|
||||
@@ -12,11 +12,38 @@ mock.module("node:child_process", () => ({
|
||||
const shouldError = (process.env.MOCK_EXEC_ERROR || "")
|
||||
.split(",")
|
||||
.some((p) => p && cmd.includes(p));
|
||||
|
||||
if (shouldError) {
|
||||
cb(new Error(`${cmd} not found`), "");
|
||||
} else {
|
||||
cb(null, `${cmd} v1.0.0\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
// resvg, bun, heif-info, dasel, and the perl one-liner (msgconvert) print just
|
||||
// the bare version number — the source code itself prepends the tool name as a label.
|
||||
if (
|
||||
cmd.startsWith("resvg") ||
|
||||
cmd.startsWith("bun") ||
|
||||
cmd.startsWith("heif-info") ||
|
||||
cmd.startsWith("dasel") ||
|
||||
cmd.startsWith("perl")
|
||||
) {
|
||||
cb(null, "1.0.0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// assimp's real output is multi-line; the source reads line index 5.
|
||||
if (cmd.startsWith("assimp")) {
|
||||
cb(null, "l1\nl2\nl3\nl4\nl5\nVersion 1.0.0 (GIT commit abc123)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// magick prefixes its version line with "Version: ".
|
||||
if (cmd.startsWith("magick")) {
|
||||
cb(null, "Version: ImageMagick v1.0.0\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cb(null, `${cmd} v1.0.0\n`);
|
||||
}),
|
||||
}));
|
||||
|
||||
@@ -79,8 +106,8 @@ test("prints system information and tool versions in production mode", async ()
|
||||
|
||||
test("logs error paths when tools are missing", async () => {
|
||||
process.env.NODE_ENV = "production";
|
||||
// Trigger a few error paths
|
||||
process.env.MOCK_EXEC_ERROR = "pandoc,resvg,bun";
|
||||
// Trigger a few error paths ("perl" is the msgconvert version lookup)
|
||||
process.env.MOCK_EXEC_ERROR = "pandoc,resvg,bun,perl";
|
||||
consoleLogSpy = spyOn(console, "log");
|
||||
consoleErrorSpy = spyOn(console, "error");
|
||||
|
||||
@@ -91,6 +118,9 @@ test("logs error paths when tools are missing", async () => {
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Pandoc is not installed.");
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("resvg is not installed");
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith("Bun is not installed. wait what");
|
||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
||||
"msgconvert (libemail-outlook-message-perl) is not installed",
|
||||
);
|
||||
});
|
||||
|
||||
test("processes output parsing correctly and logs no errors in the success case", async () => {
|
||||
@@ -108,6 +138,8 @@ test("processes output parsing correctly and logs no errors in the success case"
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("ffmpeg -version v1.0.0");
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("resvg v1.0.0");
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("Bun v1.0.0");
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("dasel 1.0.0");
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("msgconvert v1.0.0");
|
||||
|
||||
// make sure that error paths have not been triggered
|
||||
expect(consoleErrorSpy).not.toHaveBeenCalled();
|
||||
|
||||
Reference in New Issue
Block a user