about summary refs log tree commit diff
path: root/pkgs/build-support/dlang/builddubpackage/default.nix
blob: 31454d5cd69bf7c426446d0580afdfc34fcfef51 (plain) (blame)
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
{
  lib,
  stdenv,
  fetchurl,
  fetchgit,
  linkFarm,
  dub,
  ldc,
  removeReferencesTo,
}:

# See https://nixos.org/manual/nixpkgs/unstable#dlang for more detailed usage information

{
  # A lockfile generated by `dub-to-nix` from the source of the package.
  # Can be either a path to the file, or an attrset already parsed with `lib.importJSON`.
  dubLock,
  # The build type to pass to `dub build` as a value for the `--build=` flag.
  dubBuildType ? "release",
  # The flags to pass to `dub build` and `dub test`.
  dubFlags ? [ ],
  # The flags to pass to `dub build`.
  dubBuildFlags ? [ ],
  # The flags to pass to `dub test`.
  dubTestFlags ? [ ],
  # The D compiler to be used by `dub`.
  compiler ? ldc,
  ...
}@args:

let
  makeDubDep =
    {
      pname,
      version,
      sha256,
    }:
    {
      inherit pname version;
      src = fetchurl {
        name = "dub-${pname}-${version}.zip";
        url = "mirror://dub/${pname}/${version}.zip";
        inherit sha256;
      };
    };

  makeGitDep =
    {
      pname,
      version,
      repository,
      sha256,
    }:
    {
      inherit pname version;
      src = fetchgit {
        url = repository;
        rev = version;
        inherit sha256;
      };
    };

  lockJson = if lib.isPath dubLock then lib.importJSON dubLock else dubLock;
  depsRaw = lib.mapAttrsToList (pname: args: { inherit pname; } // args) lockJson.dependencies;

  dubDeps = map makeDubDep (lib.filter (args: !(args ? repository)) depsRaw);
  gitDeps = map makeGitDep (lib.filter (args: args ? repository) depsRaw);

  # a directory with multiple single element registries
  # one big directory with all .zip files leads to version parsing errors
  # when the name of a package is a prefix of the name of another package
  dubRegistryBase = linkFarm "dub-registry-base" (
    map (dep: {
      name = "${dep.pname}/${dep.pname}-${dep.version}.zip";
      path = dep.src;
    }) dubDeps
  );

  combinedFlags = "--skip-registry=all --compiler=${lib.getExe compiler} ${toString dubFlags}";
  combinedBuildFlags = "${combinedFlags} --build=${dubBuildType} ${toString dubBuildFlags}";
  combinedTestFlags = "${combinedFlags} ${toString dubTestFlags}";
in
stdenv.mkDerivation (
  builtins.removeAttrs args [ "dubLock" ]
  // {
    strictDeps = args.strictDeps or true;

    nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [
      dub
      compiler
      removeReferencesTo
    ];

    configurePhase =
      args.configurePhase or ''
        runHook preConfigure

        export DUB_HOME="$NIX_BUILD_TOP/.dub"
        mkdir -p "$DUB_HOME"

        # register dub dependencies
        ${lib.concatMapStringsSep "\n" (dep: ''
          dub fetch ${dep.pname}@${dep.version} --cache=user --skip-registry=standard --registry=file://${dubRegistryBase}/${dep.pname}
        '') dubDeps}

        # register git dependencies
        ${lib.concatMapStringsSep "\n" (dep: ''
          mkdir -p "$DUB_HOME/packages/${dep.pname}/${dep.version}"
          cp -r --no-preserve=all ${dep.src} "$DUB_HOME/packages/${dep.pname}/${dep.version}/${dep.pname}"
        '') gitDeps}

        runHook postConfigure
      '';

    buildPhase =
      args.buildPhase or ''
        runHook preBuild

        dub build ${combinedBuildFlags}

        runHook postBuild
      '';

    doCheck = args.doCheck or false;

    checkPhase =
      args.checkPhase or ''
        runHook preCheck

        dub test ${combinedTestFlags}

        runHook postCheck
      '';

    preFixup = ''
      ${args.preFixup or ""}

      find "$out" -type f -exec remove-references-to -t ${compiler} '{}' +
    '';

    disallowedReferences = [ compiler ];

    meta = {
      platforms = dub.meta.platforms;
    } // args.meta or { };
  }
)