hugo-extended 0.154.2 → 0.154.3-sudoless.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,191 @@
1
+ import { getEnvConfig } from "./env.mjs";
2
+ import { execFileSync } from "node:child_process";
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ //#region src/lib/utils.ts
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ /**
10
+ * The first Hugo version that uses .pkg installers for macOS.
11
+ * Versions before this use .tar.gz archives.
12
+ *
13
+ * @see https://github.com/gohugoio/hugo/issues/14135
14
+ */
15
+ const MACOS_PKG_MIN_VERSION = "0.153.0";
16
+ /**
17
+ * Compares two semver version strings.
18
+ *
19
+ * @param a - First version string (e.g., "0.153.0")
20
+ * @param b - Second version string (e.g., "0.152.1")
21
+ * @returns -1 if a < b, 0 if a === b, 1 if a > b
22
+ */
23
+ function compareVersions(a, b) {
24
+ const partsA = a.split(".").map((n) => Number.parseInt(n, 10));
25
+ const partsB = b.split(".").map((n) => Number.parseInt(n, 10));
26
+ const maxLen = Math.max(partsA.length, partsB.length);
27
+ for (let i = 0; i < maxLen; i++) {
28
+ const numA = partsA[i] ?? 0;
29
+ const numB = partsB[i] ?? 0;
30
+ if (numA < numB) return -1;
31
+ if (numA > numB) return 1;
32
+ }
33
+ return 0;
34
+ }
35
+ /**
36
+ * Checks if a version uses .pkg installers for macOS.
37
+ * Hugo v0.153.0+ uses .pkg, earlier versions use .tar.gz.
38
+ *
39
+ * @param version - The Hugo version to check
40
+ * @returns true if the version uses .pkg installers on macOS
41
+ */
42
+ function usesMacOSPkg(version) {
43
+ return compareVersions(version, MACOS_PKG_MIN_VERSION) >= 0;
44
+ }
45
+ /**
46
+ * Gets the Hugo version to install.
47
+ *
48
+ * Resolution order:
49
+ * 1. HUGO_OVERRIDE_VERSION environment variable (if set)
50
+ * 2. `hugoVersion` field in package.json (for emergency overrides)
51
+ * 3. `version` field in package.json (should match Hugo release)
52
+ *
53
+ * @throws {Error} If package.json cannot be found and no override is set
54
+ * @returns The version string (e.g., "0.88.1")
55
+ */
56
+ function getPkgVersion() {
57
+ const envConfig = getEnvConfig();
58
+ if (envConfig.overrideVersion) return envConfig.overrideVersion;
59
+ const packageJsonPath = path.join(__dirname, "..", "..", "package.json");
60
+ try {
61
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
62
+ return packageJson.hugoVersion || packageJson.version;
63
+ } catch {
64
+ throw new Error(`Could not find or read package.json at ${packageJsonPath}`);
65
+ }
66
+ }
67
+ /**
68
+ * Generates the full URL to a Hugo release file.
69
+ *
70
+ * By default, downloads from GitHub releases. Can be overridden with
71
+ * HUGO_MIRROR_BASE_URL for mirrors or air-gapped environments.
72
+ *
73
+ * @param version - The Hugo version number (e.g., "0.88.1")
74
+ * @param filename - The release filename (e.g., "hugo_extended_0.88.1_darwin-universal.pkg")
75
+ * @returns The complete download URL for the release file
76
+ */
77
+ function getReleaseUrl(version, filename) {
78
+ const envConfig = getEnvConfig();
79
+ if (envConfig.downloadBaseUrl) return `${envConfig.downloadBaseUrl.replace(/\/$/, "")}/${filename}`;
80
+ return `https://github.com/gohugoio/hugo/releases/download/v${version}/${filename}`;
81
+ }
82
+ /**
83
+ * Gets the Hugo binary filename for the current platform.
84
+ *
85
+ * @returns "hugo.exe" on Windows, "hugo" on all other platforms
86
+ */
87
+ function getBinFilename() {
88
+ return process.platform === "win32" ? "hugo.exe" : "hugo";
89
+ }
90
+ /**
91
+ * Gets the absolute path to the Hugo binary.
92
+ *
93
+ * Resolution order:
94
+ * 1. HUGO_BIN_PATH environment variable (if set)
95
+ * 2. Local bin directory (./bin/hugo or ./bin/hugo.exe)
96
+ *
97
+ * @returns The absolute path to hugo binary
98
+ */
99
+ function getBinPath() {
100
+ const envConfig = getEnvConfig();
101
+ if (envConfig.binPath) return envConfig.binPath;
102
+ return path.join(__dirname, "..", "..", "bin", getBinFilename());
103
+ }
104
+ /**
105
+ * Executes the Hugo binary and returns its version string.
106
+ *
107
+ * @param bin - The absolute path to the Hugo binary
108
+ * @returns The version output string (e.g., "hugo v0.88.1-5BC54738+extended darwin/arm64 BuildDate=...")
109
+ * @throws {Error} If the binary cannot be executed
110
+ */
111
+ function getBinVersion(bin) {
112
+ return execFileSync(bin, ["version"]).toString().trim();
113
+ }
114
+ /**
115
+ * Checks if the Hugo binary exists at the specified path.
116
+ *
117
+ * @param bin - The absolute path to check for the Hugo binary
118
+ * @returns `true` if the file exists, `false` if it doesn't
119
+ * @throws {Error} If an unexpected error occurs (other than ENOENT)
120
+ */
121
+ function doesBinExist(bin) {
122
+ try {
123
+ if (fs.existsSync(bin)) return true;
124
+ } catch (error) {
125
+ if (error && typeof error === "object" && "code" in error && error.code !== "ENOENT") throw error;
126
+ return false;
127
+ }
128
+ return false;
129
+ }
130
+ /**
131
+ * Determines the correct Hugo release filename for the current platform and architecture.
132
+ *
133
+ * Hugo Extended is available for:
134
+ * - macOS: x64 and ARM64 (universal binaries as of v0.102.0)
135
+ * - Linux: x64 and ARM64
136
+ * - Windows: x64 only
137
+ *
138
+ * Other platform/architecture combinations fall back to vanilla Hugo where available.
139
+ * Set HUGO_NO_EXTENDED=1 to force vanilla Hugo even on platforms that support Extended.
140
+ *
141
+ * Note: macOS uses .pkg installers starting from v0.153.0. Earlier versions use .tar.gz.
142
+ *
143
+ * @param version - The Hugo version number (e.g., "0.88.1")
144
+ * @returns The release filename if supported (e.g., "hugo_extended_0.88.1_darwin-universal.pkg"),
145
+ * or `null` if the platform/architecture combination is not supported
146
+ */
147
+ function getReleaseFilename(version) {
148
+ const { platform, arch } = process;
149
+ const forceStandard = getEnvConfig().forceStandard;
150
+ const edition = (extended, standard) => forceStandard ? standard : extended;
151
+ if (platform === "darwin" && (arch === "x64" || arch === "arm64")) {
152
+ if (usesMacOSPkg(version)) return edition(`hugo_extended_${version}_darwin-universal.pkg`, `hugo_${version}_darwin-universal.pkg`);
153
+ return edition(`hugo_extended_${version}_darwin-universal.tar.gz`, `hugo_${version}_darwin-universal.tar.gz`);
154
+ }
155
+ return platform === "win32" && arch === "x64" ? edition(`hugo_extended_${version}_windows-amd64.zip`, `hugo_${version}_windows-amd64.zip`) : platform === "win32" && arch === "arm64" ? `hugo_${version}_windows-arm64.zip` : platform === "linux" && arch === "x64" ? edition(`hugo_extended_${version}_linux-amd64.tar.gz`, `hugo_${version}_linux-amd64.tar.gz`) : platform === "linux" && arch === "arm64" ? edition(`hugo_extended_${version}_linux-arm64.tar.gz`, `hugo_${version}_linux-arm64.tar.gz`) : platform === "freebsd" && arch === "x64" ? `hugo_${version}_freebsd-amd64.tar.gz` : platform === "openbsd" && arch === "x64" ? `hugo_${version}_openbsd-amd64.tar.gz` : null;
156
+ }
157
+ /**
158
+ * Generates the checksums filename for a given Hugo version.
159
+ *
160
+ * @param version - The Hugo version number (e.g., "0.88.1")
161
+ * @returns The checksums filename (e.g., "hugo_0.88.1_checksums.txt")
162
+ */
163
+ function getChecksumFilename(version) {
164
+ return `hugo_${version}_checksums.txt`;
165
+ }
166
+ /**
167
+ * Determines if a release filename corresponds to Hugo Extended or vanilla Hugo.
168
+ *
169
+ * @param releaseFile - The release filename to check (e.g., "hugo_extended_0.88.1_darwin-universal.pkg")
170
+ * @returns `true` if the release is Hugo Extended, `false` if it's vanilla Hugo
171
+ */
172
+ function isExtended(releaseFile) {
173
+ return releaseFile.startsWith("hugo_extended_");
174
+ }
175
+ /**
176
+ * Logger utility that respects the HUGO_QUIET setting.
177
+ */
178
+ const logger = {
179
+ info: (message) => {
180
+ if (!getEnvConfig().quiet) console.info(message);
181
+ },
182
+ warn: (message) => {
183
+ if (!getEnvConfig().quiet) console.warn(`⚠ ${message}`);
184
+ },
185
+ error: (message) => {
186
+ console.error(`✖ ${message}`);
187
+ }
188
+ };
189
+
190
+ //#endregion
191
+ export { compareVersions, doesBinExist, getBinFilename, getBinPath, getBinVersion, getChecksumFilename, getPkgVersion, getReleaseFilename, getReleaseUrl, isExtended, logger, usesMacOSPkg };
package/package.json CHANGED
@@ -1,50 +1,77 @@
1
1
  {
2
2
  "name": "hugo-extended",
3
- "version": "0.154.2",
3
+ "version": "0.154.3-sudoless.1",
4
+ "hugoVersion": "0.154.3",
4
5
  "description": "✏️ Plug-and-play binary wrapper for Hugo Extended, the awesomest static-site generator.",
5
6
  "license": "MIT",
6
- "homepage": "https://github.com/jakejarvis/hugo-extended",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/jakejarvis/hugo-extended.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/jakejarvis/hugo-extended/issues"
13
+ },
7
14
  "author": {
8
15
  "name": "Jake Jarvis",
9
16
  "email": "jake@jarv.is",
10
17
  "url": "https://github.com/jakejarvis"
11
18
  },
12
- "repository": {
13
- "type": "git",
14
- "url": "git+https://github.com/jakejarvis/hugo-extended.git"
15
- },
16
19
  "publishConfig": {
17
20
  "access": "public"
18
21
  },
22
+ "type": "module",
23
+ "main": "./dist/hugo.mjs",
24
+ "module": "./dist/hugo.mjs",
25
+ "types": "./dist/hugo.d.mts",
26
+ "bin": {
27
+ "hugo": "dist/cli.mjs",
28
+ "hugo-extended": "dist/cli.mjs"
29
+ },
30
+ "exports": {
31
+ ".": {
32
+ "types": "./dist/hugo.d.mts",
33
+ "import": "./dist/hugo.mjs",
34
+ "default": "./dist/hugo.mjs"
35
+ },
36
+ "./types": {
37
+ "types": "./dist/generated/types.d.mts",
38
+ "default": "./dist/generated/types.mjs"
39
+ }
40
+ },
19
41
  "files": [
20
- "index.js",
21
- "index.d.ts",
22
- "postinstall.js",
23
- "lib"
42
+ "dist",
43
+ "postinstall.js"
24
44
  ],
25
- "bin": {
26
- "hugo": "lib/cli.js",
27
- "hugo-extended": "lib/cli.js"
45
+ "scripts": {
46
+ "build": "tsdown",
47
+ "dev": "tsdown --watch",
48
+ "generate-types": "bun scripts/generate-types.ts",
49
+ "lint": "biome check",
50
+ "lint:fix": "biome check --write",
51
+ "typecheck": "tsc --noEmit",
52
+ "test": "vitest run",
53
+ "test:watch": "vitest",
54
+ "test:unit": "vitest run tests/unit",
55
+ "test:integration": "vitest run tests/integration",
56
+ "test:e2e": "vitest run tests/e2e",
57
+ "test:coverage": "vitest run --coverage",
58
+ "postinstall": "node postinstall.js",
59
+ "prepublishOnly": "npm run generate-types && npm run build"
28
60
  },
29
- "type": "module",
30
- "exports": "./index.js",
31
- "types": "./index.d.ts",
32
61
  "dependencies": {
33
62
  "adm-zip": "^0.5.16",
34
- "log-symbols": "^7.0.1",
35
- "read-package-up": "^12.0.0",
36
63
  "tar": "^7.5.2"
37
64
  },
38
65
  "devDependencies": {
66
+ "@biomejs/biome": "^2.3.11",
39
67
  "@types/adm-zip": "^0.5.7",
40
- "del": "^8.0.1",
41
- "eslint": "^9.39.2",
42
- "globals": "^16.5.0",
43
- "mocha": "^11.7.5"
44
- },
45
- "scripts": {
46
- "postinstall": "node postinstall.js",
47
- "test": "eslint . && mocha"
68
+ "@types/node": "^25.0.3",
69
+ "@types/tar": "^6.1.13",
70
+ "@vitest/coverage-v8": "^4.0.16",
71
+ "tinyexec": "^1.0.2",
72
+ "tsdown": "^0.19.0-beta.5",
73
+ "typescript": "^5.9.3",
74
+ "vitest": "^4.0.16"
48
75
  },
49
76
  "engines": {
50
77
  "node": ">=18.17"
package/postinstall.js CHANGED
@@ -1,4 +1,58 @@
1
- import install from "./lib/install.js";
1
+ #!/usr/bin/env node
2
2
 
3
- // Install Hugo right off the bat.
4
- (async () => await install())();
3
+ import { existsSync } from "node:fs";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+
7
+ /**
8
+ * Postinstall wrapper script that properly handles errors during Hugo binary installation.
9
+ * This script imports and executes the install function, logging any errors with full stack traces
10
+ * and exiting with a non-zero code on failure.
11
+ *
12
+ * During development/CI (before build), the dist folder won't exist and this script will exit gracefully.
13
+ * For published packages, the dist folder is included and installation will proceed.
14
+ *
15
+ * Environment variables:
16
+ * - HUGO_SKIP_DOWNLOAD: Skip installation entirely (useful for CI caching, Docker layers)
17
+ */
18
+
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const installPath = join(__dirname, "dist", "lib", "install.mjs");
21
+
22
+ /**
23
+ * Check if an environment variable is set to a truthy value.
24
+ * @param {string} name - Environment variable name
25
+ * @returns {boolean}
26
+ */
27
+ function isEnvTruthy(name) {
28
+ const value = process.env[name];
29
+ if (!value) return false;
30
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase().trim());
31
+ }
32
+
33
+ async function run() {
34
+ // Skip installation if HUGO_SKIP_DOWNLOAD is set
35
+ if (isEnvTruthy("HUGO_SKIP_DOWNLOAD")) {
36
+ console.log("Skipping Hugo installation (HUGO_SKIP_DOWNLOAD is set)");
37
+ process.exit(0);
38
+ }
39
+
40
+ // Skip installation if dist folder doesn't exist (development/CI environment)
41
+ if (!existsSync(installPath)) {
42
+ console.log(
43
+ "Skipping Hugo installation (dist not found - likely in CI or development environment)",
44
+ );
45
+ process.exit(0);
46
+ }
47
+
48
+ try {
49
+ const m = await import("./dist/lib/install.mjs");
50
+ await m.default();
51
+ } catch (error) {
52
+ console.error("Hugo installation failed:");
53
+ console.error(error);
54
+ process.exit(1);
55
+ }
56
+ }
57
+
58
+ run();
package/index.d.ts DELETED
@@ -1,7 +0,0 @@
1
- /// <reference types="node" />
2
-
3
- /**
4
- * @returns A promise of the absolute path to the Hugo executable (`hugo.exe` on
5
- * Windows, simply `hugo` otherwise) once it's installed.
6
- */
7
- export default function hugo(): Promise<string>;
package/index.js DELETED
@@ -1,22 +0,0 @@
1
- import logSymbols from "log-symbols";
2
- import install from "./lib/install.js";
3
- import { getBinPath, doesBinExist } from "./lib/utils.js";
4
-
5
- const hugo = async () => {
6
- const bin = getBinPath();
7
-
8
- // A fix for fleeting ENOENT errors, where Hugo seems to disappear. For now,
9
- // just reinstall Hugo when it's missing and then continue normally like
10
- // nothing happened.
11
- // See: https://github.com/jakejarvis/hugo-extended/issues/81
12
- if (!doesBinExist(bin)) {
13
- // Hugo isn't there for some reason. Try re-installing.
14
- console.info(`${logSymbols.info} Hugo is missing, reinstalling now...`);
15
- await install();
16
- }
17
-
18
- return bin;
19
- };
20
-
21
- // The only thing this module really exports is the absolute path to Hugo:
22
- export default hugo;
package/lib/cli.js DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawn } from "child_process";
4
- import hugo from "../index.js";
5
-
6
- (async () => {
7
- const args = process.argv.slice(2);
8
- const bin = await hugo();
9
-
10
- spawn(bin, args, { stdio: "inherit" })
11
- .on("exit", (code) => {
12
- // forward Hugo's exit code so this module itself reports success/failure
13
- process.exitCode = code;
14
- });
15
- })();
package/lib/install.js DELETED
@@ -1,144 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { fileURLToPath } from "url";
4
- import { spawnSync } from "child_process";
5
- import { pipeline } from "stream/promises";
6
- import crypto from "crypto";
7
- import * as tar from "tar";
8
- import AdmZip from "adm-zip";
9
- import logSymbols from "log-symbols";
10
- import {
11
- getPkgVersion,
12
- getReleaseUrl,
13
- getReleaseFilename,
14
- getBinFilename,
15
- getBinVersion,
16
- getChecksumFilename,
17
- isExtended,
18
- } from "./utils.js";
19
-
20
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
21
-
22
- async function downloadFile(url, dest) {
23
- const response = await fetch(url);
24
- if (!response.ok) {
25
- throw new Error(`Failed to download ${url}: ${response.statusText}`);
26
- }
27
- await pipeline(response.body, fs.createWriteStream(dest));
28
- }
29
-
30
- async function verifyChecksum(filePath, checksumUrl, filename) {
31
- const response = await fetch(checksumUrl);
32
- if (!response.ok) {
33
- throw new Error(`Failed to download checksums: ${response.statusText}`);
34
- }
35
- const checksums = await response.text();
36
-
37
- // checksums file format: "sha256 filename"
38
- const expectedChecksum = checksums
39
- .split("\n")
40
- .find((line) => line.endsWith(filename))
41
- ?.split(/\s+/)[0];
42
-
43
- if (!expectedChecksum) {
44
- throw new Error(`Checksum for ${filename} not found in checksums file.`);
45
- }
46
-
47
- const fileBuffer = fs.readFileSync(filePath);
48
- const hash = crypto.createHash("sha256");
49
- hash.update(fileBuffer);
50
- const actualChecksum = hash.digest("hex");
51
-
52
- if (actualChecksum !== expectedChecksum) {
53
- throw new Error(`Checksum mismatch! Expected ${expectedChecksum}, got ${actualChecksum}`);
54
- }
55
- }
56
-
57
- async function install() {
58
- try {
59
- const version = getPkgVersion();
60
- const releaseFile = getReleaseFilename(version);
61
- const checksumFile = getChecksumFilename(version);
62
- const binFile = getBinFilename();
63
-
64
- if (!releaseFile) {
65
- throw new Error(`Are you sure this platform is supported? See: https://github.com/gohugoio/hugo/releases/tag/v${version}`);
66
- }
67
-
68
- if (!isExtended(releaseFile)) {
69
- console.warn(`${logSymbols.info} Hugo Extended isn't supported on this platform, downloading vanilla Hugo instead.`);
70
- }
71
-
72
- // Prepare vendor directory
73
- const vendorDir = path.join(__dirname, "..", "vendor");
74
- if (!fs.existsSync(vendorDir)) {
75
- fs.mkdirSync(vendorDir, { recursive: true });
76
- }
77
-
78
- const releaseUrl = getReleaseUrl(version, releaseFile);
79
- const checksumUrl = getReleaseUrl(version, checksumFile);
80
- const downloadPath = path.join(vendorDir, releaseFile);
81
-
82
- console.info(`${logSymbols.info} Downloading ${releaseFile}...`);
83
- await downloadFile(releaseUrl, downloadPath);
84
-
85
- console.info(`${logSymbols.info} Verifying checksum...`);
86
- await verifyChecksum(downloadPath, checksumUrl, releaseFile);
87
-
88
- if (process.platform === "darwin") {
89
- console.info(`${logSymbols.info} Installing ${releaseFile} (requires sudo)...`);
90
- // Run MacOS installer
91
- const result = spawnSync("sudo", ["installer", "-pkg", downloadPath, "-target", "/"], {
92
- stdio: "inherit",
93
- });
94
-
95
- if (result.error) throw result.error;
96
- if (result.status !== 0) {
97
- throw new Error(`Installer failed with exit code ${result.status}`);
98
- }
99
-
100
- // Cleanup downloaded pkg
101
- fs.unlinkSync(downloadPath);
102
- } else {
103
- console.info(`${logSymbols.info} Extracting...`);
104
-
105
- if (releaseFile.endsWith(".zip")) {
106
- const zip = new AdmZip(downloadPath);
107
- zip.extractAllTo(vendorDir, true);
108
-
109
- // Cleanup zip
110
- fs.unlinkSync(downloadPath);
111
- } else if (releaseFile.endsWith(".tar.gz")) {
112
- await tar.x({
113
- file: downloadPath,
114
- cwd: vendorDir,
115
- });
116
-
117
- // Cleanup tar.gz
118
- fs.unlinkSync(downloadPath);
119
- }
120
-
121
- const binPath = path.join(vendorDir, binFile);
122
- if (fs.existsSync(binPath)) {
123
- fs.chmodSync(binPath, 0o755);
124
- }
125
- }
126
-
127
- console.info(`${logSymbols.success} Hugo installed successfully!`);
128
-
129
- // Check version
130
- if (process.platform === "darwin") {
131
- console.info(getBinVersion("/usr/local/bin/hugo"));
132
- return "/usr/local/bin/hugo";
133
- } else {
134
- const binPath = path.join(vendorDir, binFile);
135
- console.info(getBinVersion(binPath));
136
- return binPath;
137
- }
138
- } catch (error) {
139
- console.error(`${logSymbols.error} Hugo installation failed. :(`);
140
- throw error;
141
- }
142
- }
143
-
144
- export default install;
package/lib/utils.js DELETED
@@ -1,109 +0,0 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { fileURLToPath } from "url";
4
- import { execFileSync } from "child_process";
5
- import { readPackageUpSync } from "read-package-up";
6
-
7
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
-
9
- // This package's version number (should) always match the Hugo release we want.
10
- // We check for a `hugoVersion` field in package.json just in case it doesn't
11
- // match in the future (from pushing an emergency package update, etc.).
12
- export function getPkgVersion() {
13
- const { packageJson } = readPackageUpSync({ cwd: __dirname });
14
- return packageJson.hugoVersion || packageJson.version;
15
- }
16
-
17
- // Generate the full GitHub URL to a given release file.
18
- export function getReleaseUrl(version, filename) {
19
- return `https://github.com/gohugoio/hugo/releases/download/v${version}/${filename}`;
20
- }
21
-
22
- // Binary is named `hugo.exe` on Windows, and simply `hugo` otherwise.
23
- export function getBinFilename() {
24
- return process.platform === "win32" ? "hugo.exe" : "hugo";
25
- }
26
-
27
- // Simple shortcut to ./vendor/hugo[.exe] from package root.
28
- export function getBinPath() {
29
- if (process.platform === "darwin") return "/usr/local/bin/hugo";
30
-
31
- return path.join(
32
- __dirname,
33
- "..",
34
- "vendor",
35
- getBinFilename()
36
- );
37
- }
38
-
39
- // Returns the output of the `hugo version` command, i.e.:
40
- // "hugo v0.88.1-5BC54738+extended darwin/arm64 BuildDate=..."
41
- export function getBinVersion(bin) {
42
- const stdout = execFileSync(bin, ["version"]);
43
- return stdout.toString().trim();
44
- }
45
-
46
- // Simply detect if the given file exists.
47
- export function doesBinExist(bin) {
48
- try {
49
- if (fs.existsSync(bin)) {
50
- return true;
51
- }
52
- } catch (error) {
53
- // something bad happened besides Hugo not existing
54
- if (error.code !== "ENOENT") {
55
- throw error;
56
- }
57
-
58
- return false;
59
- }
60
- }
61
-
62
- // Hugo Extended supports: macOS x64 / ARM64, Linux x64 / ARM64, Windows x64.
63
- // All other combos fall back to vanilla Hugo. There are surely much better ways
64
- // to do this but this is easy to read/update. :)
65
- export function getReleaseFilename(version) {
66
- const { platform, arch } = process;
67
-
68
- const filename =
69
- // macOS: as of 0.102.0, binaries are universal
70
- platform === "darwin" && arch === "x64"
71
- ? `hugo_extended_${version}_darwin-universal.pkg`
72
- : platform === "darwin" && arch === "arm64"
73
- ? `hugo_extended_${version}_darwin-universal.pkg`
74
-
75
- // Windows
76
- : platform === "win32" && arch === "x64"
77
- ? `hugo_extended_${version}_windows-amd64.zip`
78
- : platform === "win32" && arch === "arm64"
79
- ? `hugo_${version}_windows-arm64.zip`
80
-
81
- // Linux
82
- : platform === "linux" && arch === "x64"
83
- ? `hugo_extended_${version}_linux-amd64.tar.gz`
84
- : platform === "linux" && arch === "arm64"
85
- ? `hugo_extended_${version}_linux-arm64.tar.gz`
86
-
87
- // FreeBSD
88
- : platform === "freebsd" && arch === "x64"
89
- ? `hugo_${version}_freebsd-amd64.tar.gz`
90
-
91
- // OpenBSD
92
- : platform === "openbsd" && arch === "x64"
93
- ? `hugo_${version}_openbsd-amd64.tar.gz`
94
-
95
- // not gonna work :(
96
- : null;
97
-
98
- return filename;
99
- }
100
-
101
- // Simple formula for the checksums.txt file.
102
- export function getChecksumFilename(version) {
103
- return `hugo_${version}_checksums.txt`;
104
- }
105
-
106
- // Check if Hugo extended is being downloaded (as opposed to plain Hugo) based on the release filename.
107
- export function isExtended(releaseFile) {
108
- return releaseFile.startsWith("hugo_extended_");
109
- }
File without changes