about summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorTomaSajt <62384384+TomaSajt@users.noreply.github.com>2024-03-30 12:22:26 +0100
committerTomaSajt <62384384+TomaSajt@users.noreply.github.com>2024-04-03 12:32:08 +0200
commit92c8f64c5e0f98c5a721fb9188e71aa9c650514a (patch)
tree7aae40428a735810a7b3dbd90e15f851fb43c31a /pkgs
parente72670091620c725176d46ec44b6a6eb4bf86e37 (diff)
buildDubPackage, dub-to-nix: init
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/build-support/dlang/README.md7
-rw-r--r--pkgs/build-support/dlang/builddubpackage/default.nix124
-rw-r--r--pkgs/build-support/dlang/dub-support.nix5
-rw-r--r--pkgs/build-support/dlang/dub-to-nix/default.nix19
-rw-r--r--pkgs/build-support/dlang/dub-to-nix/dub-to-nix.py39
-rw-r--r--pkgs/build-support/fetchurl/mirrors.nix5
-rw-r--r--pkgs/top-level/all-packages.nix3
7 files changed, 202 insertions, 0 deletions
diff --git a/pkgs/build-support/dlang/README.md b/pkgs/build-support/dlang/README.md
new file mode 100644
index 0000000000000..bdd5fd2b60466
--- /dev/null
+++ b/pkgs/build-support/dlang/README.md
@@ -0,0 +1,7 @@
+# Build support for D
+
+Build utilities for the D language can be found in this directory.
+
+### Current maintainers
+- @TomaSajt
+- @jtbx
diff --git a/pkgs/build-support/dlang/builddubpackage/default.nix b/pkgs/build-support/dlang/builddubpackage/default.nix
new file mode 100644
index 0000000000000..9295445b0f7c7
--- /dev/null
+++ b/pkgs/build-support/dlang/builddubpackage/default.nix
@@ -0,0 +1,124 @@
+{
+  lib,
+  stdenv,
+  fetchurl,
+  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;
+      };
+    };
+
+  lockJson = if lib.isPath dubLock then lib.importJSON dubLock else dubLock;
+
+  lockedDeps = lib.mapAttrsToList (
+    pname: { version, sha256 }: makeDubDep { inherit pname version sha256; }
+  ) lockJson.dependencies;
+
+  # 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;
+    }) lockedDeps
+  );
+
+  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 dependencies
+        ${lib.concatMapStringsSep "\n" (dep: ''
+          dub fetch ${dep.pname}@${dep.version} --cache=user --skip-registry=standard --registry=file://${dubRegistryBase}/${dep.pname}
+        '') lockedDeps}
+
+        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 { };
+  }
+)
diff --git a/pkgs/build-support/dlang/dub-support.nix b/pkgs/build-support/dlang/dub-support.nix
new file mode 100644
index 0000000000000..879d59357d114
--- /dev/null
+++ b/pkgs/build-support/dlang/dub-support.nix
@@ -0,0 +1,5 @@
+{ callPackage }:
+{
+  buildDubPackage = callPackage ./builddubpackage { };
+  dub-to-nix = callPackage ./dub-to-nix { };
+}
diff --git a/pkgs/build-support/dlang/dub-to-nix/default.nix b/pkgs/build-support/dlang/dub-to-nix/default.nix
new file mode 100644
index 0000000000000..53a2e99c18df5
--- /dev/null
+++ b/pkgs/build-support/dlang/dub-to-nix/default.nix
@@ -0,0 +1,19 @@
+{
+  lib,
+  runCommand,
+  makeWrapper,
+  python3,
+  nix,
+}:
+
+runCommand "dub-to-nix"
+  {
+    nativeBuildInputs = [ makeWrapper ];
+    buildInputs = [ python3 ];
+  }
+  ''
+    install -Dm755 ${./dub-to-nix.py} "$out/bin/dub-to-nix"
+    patchShebangs "$out/bin/dub-to-nix"
+    wrapProgram "$out/bin/dub-to-nix" \
+        --prefix PATH : ${lib.makeBinPath [ nix ]}
+  ''
diff --git a/pkgs/build-support/dlang/dub-to-nix/dub-to-nix.py b/pkgs/build-support/dlang/dub-to-nix/dub-to-nix.py
new file mode 100644
index 0000000000000..48a9f241348a4
--- /dev/null
+++ b/pkgs/build-support/dlang/dub-to-nix/dub-to-nix.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+import sys
+import json
+import os
+import subprocess
+
+def eprint(text: str):
+    print(text, file=sys.stderr)
+
+if not os.path.exists("dub.selections.json"):
+    eprint("The file `dub.selections.json` does not exist in the current working directory")
+    eprint("run `dub upgrade --annotate` to generate it")
+    sys.exit(1)
+
+with open("dub.selections.json") as f:
+    selectionsJson = json.load(f)
+
+versionDict: dict[str, str] = selectionsJson["versions"]
+
+for pname in versionDict:
+    version = versionDict[pname]
+    if version.startswith("~"):
+        eprint(f'Package "{pname}" has a branch-type version "{version}", which doesn\'t point to a fixed version')
+        eprint("You can resolve it by manually changing the required version to a fixed one inside `dub.selections.json`")
+        eprint("When packaging, you might need to create a patch for `dub.sdl` or `dub.json` to accept the changed version")
+        sys.exit(1)
+
+lockedDependenciesDict: dict[str, dict[str, str]] = {}
+
+for pname in versionDict:
+    version = versionDict[pname]
+    eprint(f"Fetching {pname}@{version}")
+    url = f"https://code.dlang.org/packages/{pname}/{version}.zip"
+    command = ["nix-prefetch-url", "--type", "sha256", url]
+    sha256 = subprocess.run(command, check=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout.rstrip()
+    lockedDependenciesDict[pname] = {"version": version, "sha256": sha256}
+
+print(json.dumps({"dependencies": lockedDependenciesDict}, indent=2))
diff --git a/pkgs/build-support/fetchurl/mirrors.nix b/pkgs/build-support/fetchurl/mirrors.nix
index af0468b3e4944..a7e697c552154 100644
--- a/pkgs/build-support/fetchurl/mirrors.nix
+++ b/pkgs/build-support/fetchurl/mirrors.nix
@@ -312,6 +312,11 @@
     "https://backpan.perl.org/"  # for old releases
   ];
 
+  # D DUB
+  dub = [
+    "https://code.dlang.org/packages/"
+  ];
+
   # Haskell Hackage
   hackage = [
     "https://hackage.haskell.org/package/"
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index e88689aa7e508..d0d23a2f3c31e 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -7577,6 +7577,9 @@ with pkgs;
 
   dub = callPackage ../development/tools/build-managers/dub { };
 
+  inherit (import ../build-support/dlang/dub-support.nix { inherit callPackage; })
+    buildDubPackage dub-to-nix;
+
   duc = callPackage ../tools/misc/duc { };
 
   duff = callPackage ../tools/filesystems/duff {