-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathflake.nix
More file actions
177 lines (162 loc) · 5.79 KB
/
flake.nix
File metadata and controls
177 lines (162 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
{
description = "Reusable Nix flake for building sbt projects with lockfile-based dependency management";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
let
# Library functions available for all systems
lib = {
# Build Coursier cache from a lockfile
# Args:
# pkgs: nixpkgs package set
# lockfilePath: path to deps.lock.json
# Returns: derivation containing the reconstructed cache
mkCoursierCache = { pkgs, lockfilePath }:
let
depsLock = builtins.fromJSON (builtins.readFile lockfilePath);
fetchDep = dep: pkgs.fetchurl {
url = dep.url;
sha256 = dep.sha256;
};
in
pkgs.runCommand "coursier-cache" { } ''
mkdir -p $out
${builtins.concatStringsSep "\n" (map (dep:
let
fetched = fetchDep dep;
cachePath = builtins.replaceStrings ["://"] ["/"] dep.url;
cacheDir = builtins.dirOf cachePath;
in ''
mkdir -p "$out/${cacheDir}"
cp ${fetched} "$out/${cachePath}"
''
) depsLock.artifacts)}
'';
# Generate sbt setup configuration for use in custom derivations
# Args:
# pkgs: nixpkgs package set
# coursierCache: derivation from mkCoursierCache
# jdk: JDK package to use (default: pkgs.jdk21)
# extraSbtOpts: additional SBT_OPTS
# Returns: attrset with:
# setupScript: shell script to set up sbt environment (call before running sbt)
# nativeBuildInputs: packages needed for building
# JAVA_HOME: path to JDK
mkSbtSetup =
{ pkgs
, coursierCache
, jdk ? pkgs.jdk21
, extraSbtOpts ? ""
}: {
# Shell script to set up sbt environment - call this in your buildPhase
setupScript = ''
export HOME=$(mktemp -d)
# On macOS, the nix build user's home is /var/empty which is read-only.
# The JVM resolves user.home from getpwuid(), not $HOME, so tools that
# use System.getProperty("user.home") try to write to /var/empty/Library.
# JAVA_TOOL_OPTIONS overrides user.home for regular JVM processes.
# GraalVM native images (e.g. scala-cli) ignore JAVA_TOOL_OPTIONS, so
# we override every directory env var they check to avoid the fallback
# to user.home + /Library/... entirely.
export JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Duser.home=\"$HOME\""
export SCALA_CLI_HOME="$HOME/.scala-cli"
export COURSIER_CACHE="$HOME/.cache/coursier"
export COURSIER_ARCHIVE_CACHE="$HOME/.cache/coursier-arc"
export COURSIER_BIN_DIR="$HOME/.local/bin/coursier"
export COURSIER_CONFIG_DIR="$HOME/.config/coursier"
export COURSIER_JVM_CACHE="$HOME/.cache/coursier-jvm"
# Set up Coursier cache - sbt uses .cache/coursier/https/...
mkdir -p "$HOME/.cache"
cp -r ${coursierCache} "$HOME/.cache/coursier"
chmod -R u+w "$HOME/.cache/coursier"
# Configure sbt for offline mode
export COURSIER_MODE=offline
export SBT_OPTS="-Dsbt.offline=true -Dsbt.boot.directory=$HOME/.sbt/boot ${extraSbtOpts}"
'';
# Packages needed for sbt builds
nativeBuildInputs = [
pkgs.sbt
jdk
pkgs.which
];
# Environment variable for JAVA_HOME
JAVA_HOME = jdk;
};
# Create a development shell for sbt projects
# Args:
# pkgs: nixpkgs package set
# jdk: JDK package to use (default: pkgs.jdk21)
# extraPackages: additional packages to include
# shellHook: additional shell hook commands
mkSbtShell =
{ pkgs
, jdk ? pkgs.jdk21
, extraPackages ? [ ]
, shellHook ? ""
}:
pkgs.mkShell {
buildInputs = [
pkgs.sbt
jdk
pkgs.coursier
pkgs.python3
] ++ extraPackages;
shellHook = ''
export JAVA_HOME=${jdk}
${shellHook}
'';
};
};
in
{
# Export library functions
lib = lib;
# Also provide overlays for convenience
overlays.default = final: prev: {
sbt-nix = lib;
};
} //
# Per-system outputs
flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
# Package the lockfile generator script
generateLockfile = pkgs.writeScriptBin "squish-lockfile" ''
#!${pkgs.python3}/bin/python3
${builtins.readFile ./scripts/generate-lockfile.py}
'';
in
{
packages = {
generate-lockfile = generateLockfile;
default = generateLockfile;
};
# Apps for easy execution
apps = {
generate-lockfile = {
type = "app";
program = "${generateLockfile}/bin/squish-lockfile";
};
default = {
type = "app";
program = "${generateLockfile}/bin/squish-lockfile";
};
};
# Development shell for working on this flake
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
python3
sbt
jdk21
coursier
nix
];
};
}
);
}