1
mirror of https://github.com/jakejarvis/hugo-extended.git synced 2026-06-24 10:25:57 -04:00

fix: update macOS installation process to extract Hugo binary without sudo (#184)

This commit is contained in:
2026-01-09 10:24:39 -05:00
committed by GitHub
parent b409823e55
commit db078597f6
10 changed files with 171 additions and 98 deletions
+7 -7
View File
@@ -1,5 +1,5 @@
import { execFileSync } from "node:child_process";
import { existsSync, lstatSync, readlinkSync, statSync } from "node:fs";
import { existsSync, lstatSync, statSync } from "node:fs";
import { beforeAll, describe, expect, it } from "vitest";
import hugo, { execWithOutput, getHugoBinary } from "../../src/hugo";
import {
@@ -59,13 +59,13 @@ describe("Hugo Installation E2E", () => {
);
it.skipIf(process.platform !== "darwin")(
"should be a symlink to /usr/local/bin/hugo on macOS",
"should be a regular file on macOS (not a symlink)",
() => {
const isSymlink = lstatSync(binaryPath).isSymbolicLink();
expect(isSymlink).toBe(true);
const target = readlinkSync(binaryPath);
expect(target).toBe("/usr/local/bin/hugo");
// Since v0.153.0, we extract the .pkg locally using pkgutil
// instead of running `sudo installer`, so the binary is a regular file
const stats = lstatSync(binaryPath);
expect(stats.isSymbolicLink()).toBe(false);
expect(stats.isFile()).toBe(true);
},
);
});
+55 -1
View File
@@ -1,6 +1,13 @@
import crypto from "node:crypto";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, assert, beforeEach, describe, expect, it } from "vitest";
import { getArchiveType, parseChecksumFile } from "../../src/lib/install";
import {
extractPkg,
getArchiveType,
parseChecksumFile,
} from "../../src/lib/install";
import { getReleaseFilename } from "../../src/lib/utils";
/**
@@ -165,6 +172,53 @@ f0e9d8c7b6a5432109876543210fedcba0987654321fedcba0987654321fedc hugo_extended_0
});
});
describe("extractPkg", () => {
it.skipIf(process.platform !== "darwin")(
"should throw error for non-existent .pkg file",
() => {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "hugo-test-"));
try {
const nonExistentPkg = path.join(tempDir, "nonexistent.pkg");
expect(() => extractPkg(nonExistentPkg, tempDir)).toThrow();
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
},
);
it.skipIf(process.platform !== "darwin")(
"should throw descriptive error when pkgutil fails on invalid pkg",
() => {
// Create a temporary directory with a fake .pkg file
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "hugo-test-"));
try {
// Create a fake .pkg file (just an empty file - pkgutil will fail to expand it)
const fakePkg = path.join(tempDir, "fake.pkg");
fs.writeFileSync(fakePkg, "not a real pkg");
expect(() => extractPkg(fakePkg, tempDir)).toThrow();
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
},
);
it.skipIf(process.platform === "darwin")(
"should not be available on non-macOS platforms (pkgutil is macOS-only)",
() => {
// On non-macOS platforms, pkgutil doesn't exist, so the function will fail
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "hugo-test-"));
try {
const fakePkg = path.join(tempDir, "fake.pkg");
fs.writeFileSync(fakePkg, "");
expect(() => extractPkg(fakePkg, tempDir)).toThrow();
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
},
);
});
describe("getReleaseFilename + getArchiveType integration", () => {
let originalPlatform: NodeJS.Platform;
let originalArch: NodeJS.Architecture;
+3 -3
View File
@@ -440,7 +440,7 @@ describe("utils", () => {
describe("warn", () => {
it("should log when not quiet", () => {
logger.warn("warning message");
expect(console.warn).toHaveBeenCalledWith("warning message");
expect(console.warn).toHaveBeenCalledWith("warning message");
});
it("should not log when HUGO_SILENT is set", () => {
@@ -453,13 +453,13 @@ describe("utils", () => {
describe("error", () => {
it("should always log errors", () => {
logger.error("error message");
expect(console.error).toHaveBeenCalledWith("error message");
expect(console.error).toHaveBeenCalledWith("error message");
});
it("should log errors even when quiet", () => {
process.env.HUGO_QUIET = "1";
logger.error("error message");
expect(console.error).toHaveBeenCalledWith("error message");
expect(console.error).toHaveBeenCalledWith("error message");
});
});
});