1
mirror of https://github.com/jakejarvis/hugo-extended.git synced 2025-04-26 09:05:20 -04:00

refactor directory structure and modularize a few common functions

This commit is contained in:
Jake Jarvis 2021-10-09 11:03:39 -04:00
parent 64f91f5b8e
commit 757a061ebe
Signed by: jake
GPG Key ID: 2B0C9CF251E69A39
9 changed files with 185 additions and 141 deletions

3
index.d.ts vendored
View File

@ -1,7 +1,8 @@
/// <reference types="node" />
/**
* @returns {string} Absolute path to the Hugo executable.
* @returns {string} Absolute path to the Hugo executable (`hugo.exe` on
* Windows, simply `hugo` otherwise).
*/
declare const hugo: string;
export = hugo;

View File

@ -1,5 +1,6 @@
import path from "path";
import { fileURLToPath } from "url";
import { getBinFilename } from "./lib/utils.js";
// https://gist.github.com/sindresorhus/a39789f98801d908bbc7ff3ecc99d99c#what-do-i-use-instead-of-__dirname-and-__filename
const __dirname = path.dirname(fileURLToPath(import.meta.url));
@ -7,7 +8,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
const hugo = path.join(
__dirname,
"vendor",
process.platform === "win32" ? "hugo.exe" : "hugo",
getBinFilename(),
);
// The only thing this module really exports is the absolute path to Hugo:

View File

@ -1,118 +0,0 @@
import path from "path";
import fs from "fs";
import { execFileSync } from "child_process";
import { readPackageUpAsync } from "read-pkg-up";
import downloader from "careful-downloader";
import chalk from "chalk";
installHugo()
.then((bin) => {
// try querying hugo's version via CLI
const stdout = execFileSync(bin, ["version"]);
return stdout.toString();
})
.then((version) => {
// print output of `hugo version` to console
console.log(chalk.green("✔ Hugo installed successfully!"));
console.log(version);
})
.catch((error) => {
// pass whatever error occured along the way to console
console.error(chalk.red("✖ Hugo installation failed. :("));
throw error;
});
async function installHugo() {
// this package's version number (should) always match the Hugo release we want
const { version } = (await readPackageUpAsync()).packageJson;
const downloadBaseUrl = `https://github.com/gohugoio/hugo/releases/download/v${version}/`;
const releaseFile = getArchiveFilename(version, process.platform, process.arch);
const checksumFile = `hugo_${version}_checksums.txt`;
const binFile = process.platform === "win32" ? "hugo.exe" : "hugo";
// stop here if there's nothing we can download
if (!releaseFile) {
throw new Error(`Are you sure this platform is supported? See: https://github.com/gohugoio/hugo/releases/tag/v${version}`);
}
// warn if platform doesn't support Hugo Extended, proceed with vanilla Hugo
if (!releaseFile.startsWith("hugo_extended_")) {
console.warn(chalk.yellow(" Hugo Extended isn't supported on this platform, downloading vanilla Hugo instead."));
}
const download = await downloader(
`${downloadBaseUrl}${releaseFile}`,
`${downloadBaseUrl}${checksumFile}`,
{
filename: releaseFile,
destDir: "vendor",
cleanDestDir: false,
algorithm: "sha256",
encoding: "binary",
extract: true,
},
);
// ensure hugo[.exe] is executable
fs.chmodSync(path.join(download, binFile), 0o755);
// return the full path to our Hugo binary
return path.join(download, binFile);
}
// Hugo Extended supports: macOS x64, macOS ARM64, Linux x64, Windows x64.
// all other combos fall back to vanilla Hugo. there are surely much better ways
// to do this but this is easy to read/update. :)
function getArchiveFilename(version, os, arch) {
const filename =
// macOS
os === "darwin" && arch === "x64" ?
`hugo_extended_${version}_macOS-64bit.tar.gz` :
os === "darwin" && arch === "arm64" ?
`hugo_extended_${version}_macOS-ARM64.tar.gz` :
// Windows
os === "win32" && arch === "x64" ?
`hugo_extended_${version}_Windows-64bit.zip` :
os === "win32" && arch.endsWith("32") ?
`hugo_${version}_Windows-32bit.zip` :
os === "win32" && "arm" ?
`hugo_${version}_Windows-ARM.zip` :
// Linux
os === "linux" && arch === "x64" ?
`hugo_extended_${version}_Linux-64bit.tar.gz` :
os === "linux" && arch.endsWith("32") ?
`hugo_${version}_Linux-32bit.tar.gz` :
os === "linux" && arch === "arm" ?
`hugo_${version}_Linux-ARM.tar.gz` :
os === "linux" && arch === "arm64" ?
`hugo_${version}_Linux-ARM64.tar.gz` :
// FreeBSD
os === "freebsd" && arch === "x64" ?
`hugo_${version}_FreeBSD-64bit.tar.gz` :
os === "freebsd" && arch.endsWith("32") ?
`hugo_${version}_FreeBSD-32bit.tar.gz` :
os === "freebsd" && arch === "arm" ?
`hugo_${version}_FreeBSD-ARM.tar.gz` :
os === "freebsd" && arch === "arm64" ?
`hugo_${version}_FreeBSD-ARM64.tar.gz` :
// OpenBSD
os === "openbsd" && arch === "x64" ?
`hugo_${version}_OpenBSD-64bit.tar.gz` :
os === "openbsd" && arch.endsWith("32") ?
`hugo_${version}_OpenBSD-32bit.tar.gz` :
os === "openbsd" && arch === "arm" ?
`hugo_${version}_OpenBSD-ARM.tar.gz` :
os === "openbsd" && arch === "arm64" ?
`hugo_${version}_OpenBSD-ARM64.tar.gz` :
// not gonna work :(
null;
return filename;
}
export { installHugo };

View File

@ -1,7 +1,7 @@
#!/usr/bin/env node
import { spawn } from "child_process";
import hugo from "./index.js";
import hugo from "../index.js";
const args = process.argv.slice(2);

57
lib/install.js Normal file
View File

@ -0,0 +1,57 @@
import path from "path";
import fs from "fs";
import downloader from "careful-downloader";
import logSymbols from "log-symbols";
import { getPkgVersion, getReleaseUrl, getReleaseFilename, getBinFilename, getBinVersion, getChecksumFilename, isExtended } from "./utils.js";
installHugo()
.then((bin) =>
// try querying hugo's version via CLI
getBinVersion(bin),
)
.then((version) => {
// print output of `hugo version` to console
console.log(`${logSymbols.success} Hugo installed successfully!`);
console.log(version);
})
.catch((error) => {
// pass whatever error occured along the way to console
console.error(`${logSymbols.error} Hugo installation failed. :(`);
throw error;
});
async function installHugo() {
const version = getPkgVersion();
const releaseFile = getReleaseFilename(version);
const checksumFile = getChecksumFilename(version);
const binFile = getBinFilename();
// stop here if there's nothing we can download
if (!releaseFile) {
throw new Error(`Are you sure this platform is supported? See: https://github.com/gohugoio/hugo/releases/tag/v${version}`);
}
// warn if platform doesn't support Hugo Extended, proceed with vanilla Hugo
if (!isExtended(releaseFile)) {
console.warn(`${logSymbols.info} Hugo Extended isn't supported on this platform, downloading vanilla Hugo instead.`);
}
const download = await downloader(
getReleaseUrl(version, releaseFile),
getReleaseUrl(version, checksumFile),
{
filename: releaseFile,
destDir: "vendor",
cleanDestDir: false,
algorithm: "sha256",
encoding: "binary",
extract: true,
},
);
// ensure hugo[.exe] is executable
fs.chmodSync(path.join(download, binFile), 0o755);
// return the full path to our Hugo binary
return path.join(download, binFile);
}

92
lib/utils.js Normal file
View File

@ -0,0 +1,92 @@
import { readPackageUpSync } from "read-pkg-up";
import { execFileSync } from "child_process";
// This package's version number (should) always match the Hugo release we want.
export function getPkgVersion() {
const { packageJson } = readPackageUpSync();
return packageJson.version;
}
// Generate the full GitHub URL to a given release file.
export function getReleaseUrl(version, filename) {
return `https://github.com/gohugoio/hugo/releases/download/v${version}/${filename}`;
}
// Binary is named `hugo.exe` on Windows, and simply `hugo` otherwise.
export function getBinFilename() {
return process.platform === "win32" ? "hugo.exe" : "hugo";
}
// Returns the output of the `hugo version` command, i.e.:
// "hugo v0.88.1-5BC54738+extended darwin/arm64 BuildDate=..."
export function getBinVersion(bin) {
const stdout = execFileSync(bin, ["version"]);
return stdout.toString();
}
// Hugo Extended supports: macOS x64, macOS ARM64, Linux x64, Windows x64.
// all other combos fall back to vanilla Hugo. There are surely much better ways
// to do this but this is easy to read/update. :)
export function getReleaseFilename(version) {
const { platform, arch } = process;
const filename =
// macOS
platform === "darwin" && arch === "x64" ?
`hugo_extended_${version}_macOS-64bit.tar.gz` :
platform === "darwin" && arch === "arm64" ?
`hugo_extended_${version}_macOS-ARM64.tar.gz` :
// Windows
platform === "win32" && arch === "x64" ?
`hugo_extended_${version}_Windows-64bit.zip` :
platform === "win32" && arch.endsWith("32") ?
`hugo_${version}_Windows-32bit.zip` :
platform === "win32" && "arm" ?
`hugo_${version}_Windows-ARM.zip` :
// Linux
platform === "linux" && arch === "x64" ?
`hugo_extended_${version}_Linux-64bit.tar.gz` :
platform === "linux" && arch.endsWith("32") ?
`hugo_${version}_Linux-32bit.tar.gz` :
platform === "linux" && arch === "arm" ?
`hugo_${version}_Linux-ARM.tar.gz` :
platform === "linux" && arch === "arm64" ?
`hugo_${version}_Linux-ARM64.tar.gz` :
// FreeBSD
platform === "freebsd" && arch === "x64" ?
`hugo_${version}_FreeBSD-64bit.tar.gz` :
platform === "freebsd" && arch.endsWith("32") ?
`hugo_${version}_FreeBSD-32bit.tar.gz` :
platform === "freebsd" && arch === "arm" ?
`hugo_${version}_FreeBSD-ARM.tar.gz` :
platform === "freebsd" && arch === "arm64" ?
`hugo_${version}_FreeBSD-ARM64.tar.gz` :
// OpenBSD
platform === "openbsd" && arch === "x64" ?
`hugo_${version}_OpenBSD-64bit.tar.gz` :
platform === "openbsd" && arch.endsWith("32") ?
`hugo_${version}_OpenBSD-32bit.tar.gz` :
platform === "openbsd" && arch === "arm" ?
`hugo_${version}_OpenBSD-ARM.tar.gz` :
platform === "openbsd" && arch === "arm64" ?
`hugo_${version}_OpenBSD-ARM64.tar.gz` :
// not gonna work :(
null;
return filename;
}
// Simple formula for the checksums.txt file.
export function getChecksumFilename(version) {
return `hugo_${version}_checksums.txt`;
}
// Check if Hugo extended is being downloaded (as opposed to plain Hugo) based on the release filename.
export function isExtended(releaseFile) {
return releaseFile.startsWith("hugo_extended_");
}

View File

@ -15,20 +15,19 @@
},
"files": [
"index.js",
"install.js",
"cli.js",
"index.d.ts"
"index.d.ts",
"lib"
],
"bin": {
"hugo": "cli.js",
"hugo-extended": "cli.js"
"hugo": "lib/cli.js",
"hugo-extended": "lib/cli.js"
},
"type": "module",
"exports": "./index.js",
"types": "./index.d.ts",
"dependencies": {
"careful-downloader": "^1.3.1",
"chalk": "^4.1.2",
"careful-downloader": "^1.3.2",
"log-symbols": "^5.0.0",
"read-pkg-up": "^8.0.0"
},
"devDependencies": {
@ -37,7 +36,7 @@
"mocha": "^9.1.2"
},
"scripts": {
"postinstall": "node install.js",
"postinstall": "node lib/install.js",
"test": "eslint . && mocha"
},
"engines": {

View File

@ -1,5 +1,4 @@
/* eslint-env node, mocha */
import { execFile } from "child_process";
import assert from "assert";
import hugo from "../index.js";

View File

@ -10,9 +10,9 @@
"@babel/highlight" "^7.10.4"
"@babel/code-frame@^7.0.0":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb"
integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==
version "7.15.8"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503"
integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==
dependencies:
"@babel/highlight" "^7.14.5"
@ -399,10 +399,10 @@ caniuse-lite@^1.0.30001251, caniuse-lite@^1.0.30001264:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001265.tgz#0613c9e6c922e422792e6fcefdf9a3afeee4f8c3"
integrity sha512-YzBnspggWV5hep1m9Z6sZVLOt7vrju8xWooFAgN6BA5qvy98qPAPb7vNUzypFaoh2pb3vlfzbDO8tB57UPGbtw==
careful-downloader@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/careful-downloader/-/careful-downloader-1.3.1.tgz#885452db0fdeb0cc4c178d6fc348203a41779de2"
integrity sha512-22B44PheR54zFdxB9PP1h4yNhZap/3E9bWom8PBxUCGgW93kg8rbjZn4kGjVH9FXsIvgcGrrVq6BYwawmMwz1w==
careful-downloader@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/careful-downloader/-/careful-downloader-1.3.2.tgz#ef142f302f6bb9d1af54b4550e16467667f3a684"
integrity sha512-7hLwtEZCz0WwkZBnP1hfZWIYnRgpSR5jan3Pm5QchAgO9e3LJFgOjh+duSF+bWjVdIMKjt69LyAL/l2qQWFYiw==
dependencies:
decompress "^4.2.1"
fs-extra "^10.0.0"
@ -421,7 +421,7 @@ chalk@^2.0.0:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2:
chalk@^4.0.0, chalk@^4.1.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@ -669,9 +669,9 @@ doctrine@^3.0.0:
esutils "^2.0.2"
electron-to-chromium@^1.3.857:
version "1.3.860"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.860.tgz#d612e54ed75fa524c12af8da3ad8121ebfe2802b"
integrity sha512-gWwGZ+Wv4Mou2SJRH6JQzhTPjL5f95SX7n6VkLTQ/Q/INsZLZNQ1vH2GlZjozKyvT0kkFuCmWTwIoCj+/hUDPw==
version "1.3.864"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.864.tgz#6a993bcc196a2b8b3df84d28d5d4dd912393885f"
integrity sha512-v4rbad8GO6/yVI92WOeU9Wgxc4NA0n4f6P1FvZTY+jyY7JHEhw3bduYu60v3Q1h81Cg6eo4ApZrFPuycwd5hGw==
emoji-regex@^8.0.0:
version "8.0.0"
@ -1437,6 +1437,11 @@ is-unicode-supported@^0.1.0:
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
is-unicode-supported@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-1.1.0.tgz#9127b71f9fa82f52ca5c20e982e7bec0ee31ee1e"
integrity sha512-lDcxivp8TJpLG75/DpatAqNzOpDPSpED8XNtrpBHTdQ2InQ1PbW78jhwSxyxhhu+xbVSast2X38bwj8atwoUQA==
is-weakref@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2"
@ -1593,6 +1598,14 @@ log-symbols@4.1.0:
chalk "^4.1.0"
is-unicode-supported "^0.1.0"
log-symbols@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-5.0.0.tgz#7720d3c6a56c365e1f658916069ba18d941092ca"
integrity sha512-zBsSKauX7sM0kcqrf8VpMRPqcWzU6a/Wi7iEl0QlVSCiIZ4CctaLdfVdiZUn6q2/nenyt392qJqpw9FhNAwqxQ==
dependencies:
chalk "^4.1.0"
is-unicode-supported "^1.0.0"
lowercase-keys@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"