-
Notifications
You must be signed in to change notification settings - Fork 3
/
createHome.nix
110 lines (93 loc) · 3.46 KB
/
createHome.nix
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
# Creates a home directory populated with caches in ~/.m2
# (for maven dependencies) and ~/.gitlibs (for git dependencies) according
# to a lockfile generated with ./locker.py
{ pkgs, src, mavenRepos, lockfile }:
let
lib = pkgs.lib;
# Fall back to no dependencies if the lockfile hasn't been generated yet
# Useful when your nix-shell evaluates this code, but the nix-shell also
# provides the binary to produce the lockfile
contents =
if builtins.pathExists (src + "/${lockfile}")
then lib.importJSON (src + "/${lockfile}")
else { maven = {}; git = {}; };
fetchMaven = file: sha256: {
name = file;
path = pkgs.fetchurl {
# Try to fetch this maven dependency from all given maven repositories
urls = map (repo: repo + file) mavenRepos;
inherit sha256;
};
};
handleGit = path: { url, rev, sha256, common_dir, ... }: {
name = path;
path = pkgs.fetchgit {
inherit url rev sha256;
};
};
# Corresponds to the ~/.m2/repository directory
mavenRepoCache = pkgs.linkFarm "maven-repo-cache" (lib.mapAttrsToList fetchMaven contents.maven);
unpreppedGitWorkTrees = lib.mapAttrsToList handleGit contents.git;
# This corresponds to the ~/.gitlibs/libs directory, containing git worktrees
gitWorktreeCache = gitWorkTrees: pkgs.linkFarm "git-worktree-cache" gitWorkTrees;
# This corresponds to the ~/.gitlibs/_repos directory, containing git directories for the above worktrees
gitFakeRepoCache = pkgs.runCommandNoCC "git-fake-repo-cache" {}
# We don't actually need these, however clojure has a check for the existence of a
# `config` file in these directories, so let's create empty ones
# Note that we aren't using `linkFarm` for this because that would
# give collisions for multiple entries at the same path
((lib.concatMapStringsSep "\n" (item: ''
mkdir -p "$out"/${lib.escapeShellArg item.common_dir}
touch "$out"/${lib.escapeShellArg item.common_dir}/config
'') (lib.attrValues contents.git)) +
# just so we don't fail in the 0-gitlibs case
"mkdir -p $out");
# Provides a ~/.clojure directory which clojure will accept read-only
configDir = pkgs.runCommandNoCC "config-dir" {} ''
mkdir -p $out/tools
echo '{}' > $out/deps.edn
echo '{}' > $out/tools/tools.edn
'';
# Creates a home directory for Clojure, combining all parts together
clojureHome = gitWorkTrees:
pkgs.linkFarm "clojure-home" [
{
name = ".m2/repository";
path = mavenRepoCache;
}
{
name = ".gitlibs/libs";
path = gitWorktreeCache gitWorkTrees;
}
{
name = ".gitlibs/_repos";
path = gitFakeRepoCache;
}
{
name = ".clojure";
path = configDir;
}
];
unpreppedHome = clojureHome unpreppedGitWorkTrees;
utils = import ./utils.nix { inherit pkgs; };
prepLib = { path, name }: spec:
if spec ? prep then
let prep = spec.prep; in
pkgs.runCommand "${name}-prepped"
{ nativeBuildInputs = [ (utils.wrapClojure unpreppedHome pkgs.clojure) ]; }
''
cp -r ${path} $out
chmod -R +w $out
cd $out
clojure -X:${prep.alias} ${prep.fn}
''
else
path;
prepGitWorkTree = { name, ... }@wt:
{
inherit name;
path = prepLib wt (lib.getAttr name contents.git);
};
preppedGitWorkTrees = builtins.map prepGitWorkTree unpreppedGitWorkTrees;
preppedHome = clojureHome preppedGitWorkTrees;
in preppedHome