Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add nix flake support #1157

Open
wants to merge 21 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
{
pkgs ? import <nixpkgs> {},
system ? builtins.currentSystem,
sha256 ? null,
}: let
packageJson = builtins.fromJSON (builtins.readFile ./package.json);
nodeVersion = builtins.replaceStrings ["^" "~"] ["" ""] packageJson.engines.node;
pnpmVersion = builtins.head (builtins.match "pnpm@([0-9.]+).*" packageJson.packageManager);

getPlatformString = platform:
if platform == "nodejs"
then
if pkgs.stdenv.isDarwin
then
if pkgs.stdenv.isAarch64
then "darwin-arm64"
else "darwin-x64"
else if pkgs.stdenv.isAarch64
then "linux-arm64"
else "linux-x64"
else if pkgs.stdenv.isDarwin
then
if pkgs.stdenv.isAarch64
then "macos-arm64"
else "macos-x64"
else if pkgs.stdenv.isAarch64
then "linux-arm64"
else "linux-x64";
in rec {
buildNodePackages = pkgs: {
nodejs = pkgs.stdenv.mkDerivation {
name = "nodejs-${nodeVersion}";
src = pkgs.fetchurl {
url = "https://nodejs.org/dist/v${nodeVersion}/node-v${nodeVersion}-${getPlatformString "nodejs"}.tar.xz";
inherit sha256;
};
buildInputs = [pkgs.python3];
sourceRoot = ".";
dontUnpack = false;
dontBuild = true;
installPhase = ''
mkdir -p $out
mv node-v${nodeVersion}-* node
cp -r node/* $out/
chmod +x $out/bin/node
ln -s $out/bin/node $out/bin/nodejs
'';
};

pnpm = pkgs.stdenv.mkDerivation {
name = "pnpm-${pnpmVersion}";
src = pkgs.fetchurl {
url = "https://github.com/pnpm/pnpm/releases/download/v${pnpmVersion}/pnpm-${getPlatformString "pnpm"}";
inherit sha256;
};
dontUnpack = true;
dontStrip = true;
installPhase = ''
mkdir -p $out/bin
cp $src $out/bin/pnpm
chmod +x $out/bin/pnpm
'';
};
};
}
60 changes: 60 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
{
description = "Node.js development environment with NVM and PNPM";

inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};

outputs = {
self,
nixpkgs,
flake-utils,
}:
flake-utils.lib.eachDefaultSystem (system: let
pkgs = nixpkgs.legacyPackages.${system};
fallbackNodeVersion = "23.3.0";
fallbackPnpmVersion = "9.14.4";

# Read and parse package.json
packageJson = let
path = ./package.json;
in
if builtins.pathExists path
then builtins.fromJSON (builtins.readFile path)
else {
engines = {node = fallbackNodeVersion;};
packageManager = "pnpm@${fallbackPnpmVersion}";
}; # Default if no package.json

# Extract Node.js version from engines field
nodeVersion = let
engineVersion = packageJson.engines.node or fallbackNodeVersion;
cleanVersion = builtins.replaceStrings ["^" ">" "=" "~" " "] ["" "" "" "" ""] engineVersion;
in
cleanVersion;

# Extract PNPM version from packageManager field
# Handles format: "[email protected]+sha512..." or "[email protected]"
pnpmVersion = let
packageManager = packageJson.packageManager or "pnpm@${fallbackPnpmVersion}";
# First split on '+' to remove SHA, then extract version
withoutSha = builtins.head (builtins.split "[+]" packageManager);
versionMatch = builtins.match "pnpm@([0-9]+[.][0-9]+[.][0-9]+).*" withoutSha;
in
if versionMatch == null
then fallbackPnpmVersion
else builtins.head versionMatch;
in {
devShell = pkgs.mkShell {
buildInputs = with pkgs; [
curl
git
];

shellHook = ''
# Install nvm if it's not already installed
export NVM_DIR="$HOME/.nvm"
if [ ! -d "$NVM_DIR" ]; then
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
fi

# Load nvm
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

# Install and use the specified version if not already installed
if ! nvm ls ${nodeVersion} >/dev/null 2>&1; then
nvm install ${nodeVersion}
fi
nvm use ${nodeVersion}

# Enable and configure corepack for PNPM
corepack enable
corepack prepare pnpm@${pnpmVersion} --activate

# Setup PNPM environment
export PNPM_HOME="$HOME/.local/share/pnpm"
export PATH="$PNPM_HOME:$PATH"

# Get clean versions for comparison
NODE_ACTUAL=$(node --version | sed 's/^v//')
PNPM_ACTUAL=$(pnpm --version)

echo "🤖 Development environment loaded 🚀"
echo "------------------------------------------"
echo "package.json version(s) = environment:"

if [ "$NODE_ACTUAL" = "${nodeVersion}" ]; then
echo "✅ Node.js (v${nodeVersion})"
else
echo "❌ Node.js (v${nodeVersion} != v$NODE_ACTUAL)"
fi

if [ "$PNPM_ACTUAL" = "${pnpmVersion}" ]; then
echo "✅ PNPM (v${pnpmVersion})"
else
echo "❌ PNPM (v${pnpmVersion} != v$PNPM_ACTUAL)"
fi

echo """
🏗️ Quickstart Guide:
--------------------
┌─> 1. pnpm i (Install dependencies)
│ 2. pnpm build (Build project)
└─ 3. pnpm clean (Clear Artifacts, for a fresh start)
4. pnpm test (Run tests)

For more commands, run: pnpm --help
"""
'';
};
});
}
Loading