initial commit
This commit is contained in:
commit
1a55a11500
8 changed files with 270 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
.emacs*
|
||||||
|
.deno_cache
|
||||||
13
README.md
Normal file
13
README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Deno with packages
|
||||||
|
|
||||||
|
This flake provides utilities for managing Deno dependencies with Nix,
|
||||||
|
- reading multiple lock files
|
||||||
|
- creating a derivation per Deno dependency
|
||||||
|
- combining those into a single derivation
|
||||||
|
- installing shared cache into `DENO_DIR`
|
||||||
|
|
||||||
|
Currently only NPM dependencies are recognized.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
See `flake.nix`
|
||||||
32
deno.lock
generated
Normal file
32
deno.lock
generated
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
{
|
||||||
|
"version": "5",
|
||||||
|
"specifiers": {
|
||||||
|
"npm:@types/node@*": "22.13.4",
|
||||||
|
"npm:hjson@^3.2.2": "3.2.2",
|
||||||
|
"npm:jq-web@~0.6.2": "0.6.2"
|
||||||
|
},
|
||||||
|
"npm": {
|
||||||
|
"@types/node@22.13.4": {
|
||||||
|
"integrity": "sha512-ywP2X0DYtX3y08eFVx5fNIw7/uIv8hYUKgXoK8oayJlLnKcRfEYCxWMVE1XagUdVtCJlZT1AU4LXEABW+L1Peg==",
|
||||||
|
"dependencies": [
|
||||||
|
"undici-types"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hjson@3.2.2": {
|
||||||
|
"integrity": "sha512-MkUeB0cTIlppeSsndgESkfFD21T2nXPRaBStLtf3cAYA2bVEFdXlodZB0TukwZiobPD1Ksax5DK4RTZeaXCI3Q==",
|
||||||
|
"bin": true
|
||||||
|
},
|
||||||
|
"jq-web@0.6.2": {
|
||||||
|
"integrity": "sha512-+7XvjBYwTx4vP5PYkf6Q6orubO/v+UgMU6By1GritrmShr9QpT3UKa4ANzXWQfhdqtBnQYXsm7ZNbdIHT6tYpQ=="
|
||||||
|
},
|
||||||
|
"undici-types@6.20.0": {
|
||||||
|
"integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"dependencies": [
|
||||||
|
"npm:hjson@^3.2.2",
|
||||||
|
"npm:jq-web@~0.6.2"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1754214453,
|
||||||
|
"narHash": "sha256-Q/I2xJn/j1wpkGhWkQnm20nShYnG7TI99foDBpXm1SY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "5b09dc45f24cf32316283e62aec81ffee3c3e376",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
59
flake.nix
Normal file
59
flake.nix
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
description = "Builds a shared cache for Deno packages based on lock files";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in rec
|
||||||
|
{
|
||||||
|
lib = {
|
||||||
|
# Extract NPM dependencies from a single Deno lock file
|
||||||
|
denoLockfileToNpmDeps = import ./lib/lockfile-to-npm-deps.nix { self = lib; };
|
||||||
|
|
||||||
|
# Create a shared Deno cache from multiple lock files
|
||||||
|
denoSharedCache = import ./lib/shared-cache.nix { self = lib; };
|
||||||
|
|
||||||
|
# Install shared cache into DENO_DIR
|
||||||
|
installDenoCache = import ./lib/install-cache.nix;
|
||||||
|
|
||||||
|
denoNpmRegistryHostname = "registry.npmjs.org";
|
||||||
|
};
|
||||||
|
|
||||||
|
devShells.default = pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
deno
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook =
|
||||||
|
let
|
||||||
|
# Example
|
||||||
|
sharedCache = self.lib.${system}.denoSharedCache {
|
||||||
|
inherit pkgs;
|
||||||
|
lockfiles = [ ./deno.lock ]; # Add your lock files here
|
||||||
|
};
|
||||||
|
installScript = self.lib.${system}.installDenoCache {
|
||||||
|
inherit pkgs;
|
||||||
|
cache = sharedCache;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
''
|
||||||
|
export DENO_DIR="$PWD/.deno_cache"
|
||||||
|
|
||||||
|
if [ -d "${sharedCache}" ]; then
|
||||||
|
echo "Installing Deno shared cache..."
|
||||||
|
${installScript}/bin/install-deno-cache
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Deno development environment ready!"
|
||||||
|
echo "DENO_DIR is set to: $DENO_DIR"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
34
lib/install-cache.nix
Normal file
34
lib/install-cache.nix
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
{ pkgs, cache }:
|
||||||
|
|
||||||
|
pkgs.writeShellScriptBin "install-deno-cache" ''
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [ -z "''${DENO_DIR:-}" ]; then
|
||||||
|
echo "Error: DENO_DIR environment variable must be set" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Installing Deno cache to: $DENO_DIR"
|
||||||
|
|
||||||
|
# Remove existing cache if it exists
|
||||||
|
if [ -d "$DENO_DIR" ]; then
|
||||||
|
echo "Removing existing cache..."
|
||||||
|
rm -rf "$DENO_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy the shared cache, dereferencing symlinks
|
||||||
|
if [ -d "${cache}" ]; then
|
||||||
|
echo "Copying shared cache..."
|
||||||
|
mkdir -p "$(dirname "$DENO_DIR")"
|
||||||
|
cp -rL "${cache}" "$DENO_DIR"
|
||||||
|
chmod -R u+w "$DENO_DIR"
|
||||||
|
echo "Cache installed successfully!"
|
||||||
|
else
|
||||||
|
echo "No shared cache found at ${cache}"
|
||||||
|
mkdir -p "$DENO_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -d "$DENO_DIR/npm" ]; then
|
||||||
|
echo "NPM packages in cache: $(find "$DENO_DIR/npm" -name "package.json" | wc -l)"
|
||||||
|
fi
|
||||||
|
''
|
||||||
56
lib/lockfile-to-npm-deps.nix
Normal file
56
lib/lockfile-to-npm-deps.nix
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
{ self }:
|
||||||
|
{ pkgs, lockfile }:
|
||||||
|
let
|
||||||
|
registry = self.denoNpmRegistryHostname;
|
||||||
|
|
||||||
|
# Extract npm dependencies from a single lockfile
|
||||||
|
extractNpmDeps = lockfile:
|
||||||
|
let
|
||||||
|
lockJSON = builtins.fromJSON (builtins.readFile lockfile);
|
||||||
|
in
|
||||||
|
lockJSON.npm or {};
|
||||||
|
|
||||||
|
npmDeps = extractNpmDeps lockfile;
|
||||||
|
|
||||||
|
# Create tarball derivation for a package
|
||||||
|
mkTarballDrv = { name, version, integrity }:
|
||||||
|
let
|
||||||
|
tarballName =
|
||||||
|
if builtins.substring 0 1 name == "@"
|
||||||
|
then builtins.baseNameOf name # "@types/node" → "node"
|
||||||
|
else name;
|
||||||
|
in
|
||||||
|
pkgs.fetchurl {
|
||||||
|
url = "https://${registry}/${name}/-/${tarballName}-${version}.tgz";
|
||||||
|
hash = integrity;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Create derivation for a single npm package
|
||||||
|
mkNpmDep = key: value:
|
||||||
|
let
|
||||||
|
match = builtins.match "(.+)@(.+)" key;
|
||||||
|
name = builtins.elemAt match 0;
|
||||||
|
version = builtins.elemAt match 1;
|
||||||
|
in
|
||||||
|
pkgs.stdenv.mkDerivation {
|
||||||
|
pname = "deno-npm-${builtins.replaceStrings ["@" "/"] ["" "-"] name}";
|
||||||
|
version = version;
|
||||||
|
src = mkTarballDrv {
|
||||||
|
inherit name version;
|
||||||
|
inherit (value) integrity;
|
||||||
|
};
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
runHook preInstall
|
||||||
|
|
||||||
|
export OUT_PATH="$out/npm/${registry}/${name}/${version}"
|
||||||
|
|
||||||
|
mkdir -p $OUT_PATH
|
||||||
|
tar -xzf $src -C $OUT_PATH --strip-components=1
|
||||||
|
|
||||||
|
runHook postInstall
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
in
|
||||||
|
pkgs.lib.mapAttrsToList mkNpmDep npmDeps
|
||||||
13
lib/shared-cache.nix
Normal file
13
lib/shared-cache.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{ self }:
|
||||||
|
{ pkgs, lockfiles }:
|
||||||
|
let
|
||||||
|
allNpmDeps = builtins.concatMap
|
||||||
|
(lockfile:
|
||||||
|
self.denoLockfileToNpmDeps { inherit pkgs lockfile; })
|
||||||
|
lockfiles;
|
||||||
|
|
||||||
|
in
|
||||||
|
pkgs.symlinkJoin {
|
||||||
|
name = "deno-shared-cache";
|
||||||
|
paths = allNpmDeps;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue