-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmkDub.nix
137 lines (106 loc) · 4 KB
/
mkDub.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
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
{ pkgs ? import <nixpkgs> {},
stdenv ? pkgs.stdenv,
lib ? pkgs.lib,
dtools ? pkgs.dtools or pkgs.rdmd,
dmd ? pkgs.dmd,
dcompiler ? dmd,
dub ? pkgs.dub }:
with stdenv;
let
# Filter function to remove the .dub package folder from src
filterDub = name: type: let baseName = baseNameOf (toString name); in ! (
type == "directory" && baseName == ".dub"
);
# Convert a GIT rev string (tag) to a simple semver version
rev-to-version = builtins.replaceStrings ["v" "refs/tags/v"] ["" ""];
dep2src = dubDep: pkgs.fetchgit { inherit (dubDep.fetch) url rev sha256 fetchSubmodules; };
# Fetch a dependency (source only for now)
fromDub = dubDep: mkDerivation rec {
name = "${src.name}-${version}";
version = rev-to-version dubDep.fetch.rev;
nativeBuildInputs = [ dcompiler dtools dub ];
src = dep2src dubDep;
buildPhase = ''
runHook preBuild
export HOME=$PWD
dub build -b=release
runHook postBuild
'';
# outputs = [ "lib" ];
# installPhase = ''
# runHook preInstall
# mkdir -p $out/bin
# runHook postInstall
# '';
};
# Adds a local package directory (e.g. a git repository) to Dub
dub-add-local = dubDep: "dub add-local ${(fromDub dubDep).src.outPath} ${rev-to-version dubDep.fetch.rev}";
# The target output of the Dub package
targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}";
# Remove reference to build tools and library sources
disallowedReferences = deps: [ dcompiler dtools dub ] ++ builtins.map dep2src deps;
removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
# Like split, but only keep the matches
matches = regex: str: builtins.filter lib.isList (builtins.split regex str);
# Very primitive parsing of SDL files, but suffices for name, description, homepage, etc.
importSDL = path: builtins.foldl' (a: l: a // {"${lib.elemAt l 1}"=lib.elemAt l 2;}) {} (matches "(^|\n)([a-z]+) \"([^\"]+)\"" (builtins.readFile path));
importPackage = sdl: json: if builtins.pathExists sdl then importSDL sdl else lib.importJSON json;
in {
inherit fromDub;
mkDubDerivation = lib.makeOverridable ({
src,
nativeBuildInputs ? [],
dubJSON ? src + "/dub.json",
dubSDL ? src + "/dub.sdl",
buildType ? "release",
dubFlags ? "--combined",
extraDubFlags ? "",
selections ? src + "/dub.selections.nix",
deps ? import selections,
package ? importPackage dubSDL dubJSON,
passthru ? {},
...
} @ attrs: stdenv.mkDerivation ((removeAttrs attrs ["package" "deps" "selections" "dubJSON" "dubSDL"]) // {
pname = package.name;
nativeBuildInputs = [ dcompiler dtools dub pkgs.removeReferencesTo ] ++ nativeBuildInputs;
disallowedReferences = disallowedReferences deps;
passthru = passthru // {
inherit dub dcompiler dtools pkgs;
};
src = lib.cleanSourceWith {
filter = filterDub;
src = lib.cleanSource src;
};
preFixup = ''
find $out/bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true
'';
buildPhase = ''
runHook preBuild
export HOME=$PWD
${lib.concatMapStringsSep "\n" dub-add-local deps}
dub build -b ${buildType} ${dubFlags} --skip-registry=all ${extraDubFlags}
runHook postBuild
'';
checkPhase = ''
runHook preCheck
export HOME=$PWD
${lib.concatMapStringsSep "\n" dub-add-local deps}
dub test ${dubFlags} --skip-registry=all ${extraDubFlags}
runHook postCheck
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp -r "${targetOf package}" $out/bin
runHook postInstall
'';
meta = lib.optionalAttrs (package ? description) {
description = package.description;
} // lib.optionalAttrs (package ? homepage) {
homepage = package.homepage;
} // attrs.meta or {};
} // lib.optionalAttrs (!(attrs ? version)) {
# Use name from dub.json, unless pname and version are specified
name = package.name;
}));
}