Files
2026-07-06 15:42:05 -07:00

327 lines
13 KiB
Ruby

# frozen_string_literal: true
# Generated by generate_tap.py for local/mirror
class Node < Formula
desc "Open-source, cross-platform JavaScript runtime environment"
homepage "https://nodejs.org/"
url "https://homebrew.hyprnet/sources/5d33401fe9f7bdf3f2fdec919770e11cf63b8c3693dd1cd5c6da40b16ee78850--node--26.4.0.x86_64_linux.bottle.tar.gz"
sha256 "9eceb3621024069d91035b5471d2ebe86aa04d22dbeba72a782eaf36ff9183ac"
license "MIT"
compatibility_version 1
head "https://github.com/nodejs/node.git", branch: "main"
livecheck do
url "https://nodejs.org/dist/"
regex(%r{href=["']?v?(\d+(?:\.\d+)+)/?["' >]}i)
end
bottle do
root_url "https://homebrew.hyprnet/bottles"
sha256 arm64_tahoe: "bbac60159fbed617a409fc241113a7d4824e115c6193df2661c9be6b6ed3f59f"
sha256 arm64_sequoia: "99cef8119eebd10eeedd277f9abd5ef22e1dabb7ee497c99fa4409c201ac9f4d"
sha256 arm64_sonoma: "c8797fda23595d84fa8a8e68cedd62c63c5ff50228ac8a9fa3f6528da83a9e65"
sha256 sonoma: "49a0dba0e9620845c2fb4a4eaec604ac90d013773e4e02945eca9e167d7e3be9"
sha256 arm64_linux: "3cf5b744223b997a37f12a87a5cdaf09308c0575ffe245af1b1ebb9cdfb80f28"
sha256 x86_64_linux: "4553aa69ff2ed12259d799b995fce3922861cf181db9c7ab51a868fe3fcefcef"
end
depends_on "pkgconf" => :build
depends_on "python@3.14" => :build
depends_on "ada-url"
depends_on "brotli"
depends_on "c-ares"
depends_on "hdrhistogram_c"
depends_on "icu4c@78"
depends_on "libffi" # System `libffi` is missing some definitions used by node
depends_on "libnghttp2"
depends_on "libnghttp3"
depends_on "libngtcp2"
depends_on "libuv"
depends_on "llhttp"
depends_on "merve"
depends_on "nbytes"
depends_on "openssl@3"
depends_on "simdjson"
depends_on "sqlite" # Fails with macOS sqlite.
depends_on "uvwasi"
depends_on "zstd"
uses_from_macos "python"
on_macos do
depends_on "llvm" => :build if DevelopmentTools.clang_build_version <= 1699
end
on_linux do
depends_on "zlib-ng-compat"
end
link_overwrite "bin/npm", "bin/npx"
# https://github.com/swiftlang/llvm-project/commit/078651b6de4b767b91e3e6a51e5df11a06d7bc4f
fails_with :clang do
build 1699
cause "needs SFINAE-friendly std::pointer_traits"
end
# https://github.com/nodejs/node/blob/main/BUILDING.md#supported-toolchains
# https://github.com/ada-url/ada?tab=readme-ov-file#requirements
fails_with :gcc do
version "12"
cause "needs GCC 13 or newer"
end
# We track major/minor from upstream Node releases.
# We will accept *important* npm patch releases when necessary.
resource "npm" do
url "https://registry.npmjs.org/npm/-/npm-11.17.0.tgz"
sha256 "b290bbb35b9e72c3ef84edbe041f28c4479c4d9ee79f555817b8caafe7ce4bba"
livecheck do
url "https://raw.githubusercontent.com/nodejs/node/refs/tags/v#{LATEST_VERSION}/deps/npm/package.json"
strategy :json do |json|
json["version"]
end
end
end
deny_network_access! [:build, :postinstall]
def install
# Backport fix for bundled LIEF's bundled spdlog's bundled fmt.
# Should be fixed when new LIEF version with following commit is released and used by node:
# https://github.com/lief-project/LIEF/commit/710637216b1f6f19569002d62e43fca201b9d91c
inreplace "deps/LIEF/third-party/spdlog/include/spdlog/fmt/bundled/format.h",
"#ifndef FMT_MODULE\n# include <cmath>",
"#ifndef FMT_MODULE\n# include <stdlib.h>\n# include <cmath>"
# make sure subprocesses spawned by make are using our Python 3
ENV["PYTHON"] = which("python3.14")
# Ensure Homebrew deps are used
rm_r(["deps/icu-small", "deps/npm"])
# Never install the bundled "npm", always prefer our
# installation from tarball for better packaging control.
args = %W[
--prefix=#{prefix}
--without-npm
--with-intl=system-icu
--shared
--openssl-use-def-ca-store
]
args << "--tag=head" if build.head?
# Devendor libraries available as formulae. The following maps the name
# used in configure (e.g. `--shared-<flag>`) to the bundled subdirectory
# and corresponding formula name as these can all differ.
{
# flag name sub-directory formula name
"ada" => ["ada", "ada-url"],
"brotli" => ["brotli", "brotli"],
"cares" => ["cares", "c-ares"],
"ffi" => ["libffi", "libffi"],
"hdr-histogram" => ["histogram", "hdrhistogram_c"],
"http-parser" => ["llhttp", "llhttp"],
"libuv" => ["uv", "libuv"],
"merve" => ["merve", "merve"],
"nbytes" => ["nbytes", "nbytes"],
"nghttp2" => ["nghttp2", "libnghttp2"],
"nghttp3" => ["ngtcp2/nghttp3", "libnghttp3"],
"ngtcp2" => ["ngtcp2", "libngtcp2"],
"openssl" => ["openssl/openssl", "openssl@3"],
"simdjson" => ["simdjson", "simdjson"],
"sqlite" => ["sqlite", "sqlite"],
"uvwasi" => ["uvwasi", "uvwasi"],
"zlib" => ["zlib", ("zlib-ng-compat" unless OS.mac?)],
"zstd" => ["zstd", "zstd"],
}.each do |flag, (subdir, formula)|
rm_r(buildpath/"deps"/subdir)
args << "--shared-#{flag}"
if formula
args << "--shared-#{flag}-includes=#{Formula[formula].include}"
args << "--shared-#{flag}-libpath=#{Formula[formula].lib}"
end
end
# TODO: Try to devendor these libraries.
# - `--shared-gtest` is only used for building the test suite, which we don't run here.
# - `--shared-simdutf` seems to result in build failures.
# - `--shared-temporal_capi` is only used when building with `--v8-enable-temporal-support`
# - `--shared-lief` is not available as dependency in Homebrew.
ignored_shared_flags = %w[
gtest
simdutf
temporal_capi
lief
].map { |library| "--shared-#{library}" }
configure_help = Utils.safe_popen_read("./configure", "--help")
shared_flag_regex = /\[(--shared-[^ \]]+)\]/
configure_help.scan(shared_flag_regex) do |matches|
matches.each do |flag|
next if args.include?(flag) || ignored_shared_flags.include?(flag)
message = "Unused `--shared-*` flag: #{flag}"
if build.head?
opoo message
else
odie message
end
end
end
# Enabling LTO errors on Linux with:
# terminate called after throwing an instance of 'std::out_of_range'
# macOS also can't build with LTO when using LLVM Clang
# LTO is unpleasant if you have to build from source.
# FIXME: re-enable me, currently crashes sequoia runner after 6 hours
# args << "--enable-lto" if OS.mac? && DevelopmentTools.clang_build_version > 1699 && build.bottle?
system "./configure", *args
system "make", "install"
# Allow npm to find Node before installation has completed.
ENV.prepend_path "PATH", bin
bootstrap = buildpath/"npm_bootstrap"
bootstrap.install resource("npm")
# These dirs must exists before npm install.
mkdir_p libexec/"lib"
system "node", bootstrap/"bin/npm-cli.js", "install", "-ddd", "--global",
"--prefix=#{libexec}", resource("npm").cached_download
# The `package.json` stores integrity information about the above passed
# in `cached_download` npm resource, which breaks `npm -g outdated npm`.
# This copies back over the vanilla `package.json` to fix this issue.
cp bootstrap/"package.json", libexec/"lib/node_modules/npm"
# These symlinks are never used & they've caused issues in the past.
rm_r libexec/"share" if (libexec/"share").exist?
# Create temporary npm and npx symlinks until post_install is done.
ln_s libexec/"lib/node_modules/npm/bin/npm-cli.js", bin/"npm"
ln_s libexec/"lib/node_modules/npm/bin/npx-cli.js", bin/"npx"
# Use the _npm completion included in Zsh rather than generating broken completion
generate_completions_from_executable(bin/"npm", "completion", shells: [:bash], shell_parameter_format: :none)
end
def post_install
node_modules = HOMEBREW_PREFIX/"lib/node_modules"
node_modules.mkpath
# Remove npm but preserve all other modules across node updates/upgrades.
rm_r node_modules/"npm" if (node_modules/"npm").exist?
cp_r libexec/"lib/node_modules/npm", node_modules
# This symlink doesn't hop into homebrew_prefix/bin automatically so
# we make our own. This is a small consequence of our
# bottle-npm-and-retain-a-private-copy-in-libexec setup
# All other installs **do** symlink to homebrew_prefix/bin correctly.
# We ln rather than cp this because doing so mimics npm's normal install.
ln_sf node_modules/"npm/bin/npm-cli.js", bin/"npm"
ln_sf node_modules/"npm/bin/npx-cli.js", bin/"npx"
ln_sf bin/"npm", HOMEBREW_PREFIX/"bin/npm"
ln_sf bin/"npx", HOMEBREW_PREFIX/"bin/npx"
# Create manpage symlinks (or overwrite the old ones)
%w[man1 man5 man7].each do |man|
# Dirs must exist first: https://github.com/Homebrew/legacy-homebrew/issues/35969
mkdir_p HOMEBREW_PREFIX/"share/man/#{man}"
# still needed to migrate from copied file manpages to symlink manpages
rm(Dir[HOMEBREW_PREFIX/"share/man/#{man}/{npm.,npm-,npmrc.,package.json.,npx.}*"])
ln_sf Dir[node_modules/"npm/man/#{man}/{npm,package-,shrinkwrap-,npx}*"], HOMEBREW_PREFIX/"share/man/#{man}"
end
(node_modules/"npm/npmrc").atomic_write("prefix = #{HOMEBREW_PREFIX}\n")
end
test do
path = testpath/"test.js"
path.write "console.log('hello');"
output = shell_output("#{bin}/node #{path}").strip
assert_equal "hello", output
output = shell_output("#{bin}/node -e 'console.log(new Intl.NumberFormat(\"en-EN\").format(1234.56))'").strip
assert_equal "1,234.56", output
output = shell_output("#{bin}/node -e 'console.log(new Intl.NumberFormat(\"de-DE\").format(1234.56))'").strip
assert_equal "1.234,56", output
# make sure npm can find node
ENV.prepend_path "PATH", opt_bin
ENV.delete "NVM_NODEJS_ORG_MIRROR"
assert_equal which("node"), opt_bin/"node"
assert_path_exists HOMEBREW_PREFIX/"bin/npm", "npm must exist"
assert_predicate HOMEBREW_PREFIX/"bin/npm", :executable?, "npm must be executable"
npm_args = ["-ddd", "--cache=#{HOMEBREW_CACHE}/npm_cache", "--build-from-source"]
system HOMEBREW_PREFIX/"bin/npm", *npm_args, "install", "npm@latest"
system HOMEBREW_PREFIX/"bin/npm", *npm_args, "install", "nan"
assert_path_exists HOMEBREW_PREFIX/"bin/npx", "npx must exist"
assert_predicate HOMEBREW_PREFIX/"bin/npx", :executable?, "npx must be executable"
assert_match "< hello >", shell_output("#{HOMEBREW_PREFIX}/bin/npx --yes cowsay hello")
# Test `uvwasi` is linked correctly
(testpath/"wasi-smoke-test.mjs").write <<~JAVASCRIPT
import { WASI } from 'node:wasi';
// Minimal WASM that:
// - imports wasi proc_exit(i32)->()
// - exports memory (required by Node's WASI binding)
// - exports _start which calls proc_exit(42)
const wasmBytes = new Uint8Array([
// \0asm + version
0x00,0x61,0x73,0x6d, 0x01,0x00,0x00,0x00,
// Type section: 2 types: (i32)->() and ()->()
0x01,0x08, 0x02,
0x60,0x01,0x7f,0x00,
0x60,0x00,0x00,
// Import section: wasi_snapshot_preview1.proc_exit : func(type 0)
0x02,0x24, 0x01,
0x16, // module name len = 22
0x77,0x61,0x73,0x69,0x5f,0x73,0x6e,0x61,0x70,0x73,0x68,0x6f,0x74,0x5f,0x70,0x72,0x65,0x76,0x69,0x65,0x77,0x31,
0x09, // name len = 9
0x70,0x72,0x6f,0x63,0x5f,0x65,0x78,0x69,0x74,
0x00, // import kind = func
0x00, // type index 0
// Function section: 1 function (type index 1 = ()->())
0x03,0x02, 0x01, 0x01,
// Memory section: one memory with min=1 page; export later
0x05,0x03, 0x01, 0x00, 0x01,
// Export section: export "_start" (func 1) and "memory" (mem 0)
0x07,0x13, 0x02,
0x06, 0x5f,0x73,0x74,0x61,0x72,0x74, 0x00, 0x01,
0x06, 0x6d,0x65,0x6d,0x6f,0x72,0x79, 0x02, 0x00,
// Code section: body for func 1: i32.const 42; call 0; end
0x0a,0x08, 0x01,
0x06, 0x00, 0x41,0x2a, 0x10,0x00, 0x0b
]);
const wasi = new WASI({
version: 'preview1',
returnOnExit: true
});
const { instance } = await WebAssembly.instantiate(wasmBytes, wasi.getImportObject());
// This should return 42 if uvwasi is correctly linked & wired.
const rc = wasi.start(instance);
if (rc === 42) {
console.log('PASS: uvwasi proc_exit(42) worked (exitCode=42)');
process.exit(0);
} else {
console.error('FAIL: unexpected return', rc);
process.exit(2);
}
JAVASCRIPT
system bin/"node", "wasi-smoke-test.mjs"
end
end