From 2d62506a97b2ba80c378756c78bdebba0ab6be89 Mon Sep 17 00:00:00 2001 From: TomaSajt <62384384+TomaSajt@users.noreply.github.com> Date: Sun, 3 Aug 2025 12:16:35 +0200 Subject: [PATCH] buildDubPackage: split into hooks and into importDubLock --- .../dlang/builddubpackage/default.nix | 165 +++++------------- .../dlang/builddubpackage/hooks/default.nix | 26 +++ .../builddubpackage/hooks/dub-build-hook.sh | 13 ++ .../builddubpackage/hooks/dub-check-hook.sh | 13 ++ .../builddubpackage/hooks/dub-setup-hook.sh | 19 ++ .../dlang/builddubpackage/import-dub-lock.nix | 81 +++++++++ pkgs/build-support/dlang/dub-support.nix | 5 +- .../dlang/dub-to-nix/dub-to-nix.py | 0 pkgs/top-level/all-packages.nix | 6 +- 9 files changed, 205 insertions(+), 123 deletions(-) create mode 100644 pkgs/build-support/dlang/builddubpackage/hooks/default.nix create mode 100644 pkgs/build-support/dlang/builddubpackage/hooks/dub-build-hook.sh create mode 100644 pkgs/build-support/dlang/builddubpackage/hooks/dub-check-hook.sh create mode 100644 pkgs/build-support/dlang/builddubpackage/hooks/dub-setup-hook.sh create mode 100644 pkgs/build-support/dlang/builddubpackage/import-dub-lock.nix mode change 100644 => 100755 pkgs/build-support/dlang/dub-to-nix/dub-to-nix.py diff --git a/pkgs/build-support/dlang/builddubpackage/default.nix b/pkgs/build-support/dlang/builddubpackage/default.nix index 2a32b4d17fc3f..8c9937ef50a9f 100644 --- a/pkgs/build-support/dlang/builddubpackage/default.nix +++ b/pkgs/build-support/dlang/builddubpackage/default.nix @@ -1,148 +1,71 @@ { lib, stdenv, - fetchurl, - fetchgit, - linkFarm, dub, + importDubLock, + dubSetupHook, + dubBuildHook, + dubCheckHook, ldc, removeReferencesTo, }: -# See https://nixos.org/manual/nixpkgs/unstable#dlang for more detailed usage information +lib.extendMkDerivation { + constructDrv = stdenv.mkDerivation; -{ - # 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: + excludeDrvArgNames = [ + "dubLock" + "compiler" + ]; -let - makeDubDep = - { - pname, - version, - sha256, - }: + extendDrvArgs = + finalAttrs: { - inherit pname version; - src = fetchurl { - name = "dub-${pname}-${version}.zip"; - url = "mirror://dub/${pname}/${version}.zip"; - inherit sha256; - }; - }; + # 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, + compiler ? ldc, + ... + }@args: - makeGitDep = - { - pname, - version, - repository, - sha256, - }: { - inherit pname version; - src = fetchgit { - url = repository; - rev = version; - inherit sha256; + dubDeps = importDubLock { + inherit (finalAttrs) pname version; + lock = dubLock; }; - }; - - 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 - ); + strictDeps = args.strictDeps or true; - 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 [ ] ++ [ + dubSetupHook + (dubBuildHook.override { inherit dub; }) + compiler + removeReferencesTo + ]; - nativeBuildInputs = args.nativeBuildInputs or [ ] ++ [ - dub - compiler - removeReferencesTo - ]; - - configurePhase = - args.configurePhase or '' + configurePhase = '' 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} - + dubFlags+=("--compiler=${lib.getExe compiler}") runHook postConfigure ''; - buildPhase = - args.buildPhase or '' - runHook preBuild - - dub build ${combinedBuildFlags} - - runHook postBuild - ''; - - doCheck = args.doCheck or false; + doCheck = args.doCheck or false; - checkPhase = - args.checkPhase or '' - runHook preCheck + nativeCheckInputs = [ + (dubCheckHook.override { inherit dub; }) + ]; - dub test ${combinedTestFlags} + preFixup = '' + ${args.preFixup or ""} - runHook postCheck + find "$out" -type f -exec remove-references-to -t ${compiler} '{}' + ''; - preFixup = '' - ${args.preFixup or ""} - - find "$out" -type f -exec remove-references-to -t ${compiler} '{}' + - ''; + disallowedReferences = args.disallowedReferences or [ compiler ]; - disallowedReferences = [ compiler ]; - - meta = { - platforms = dub.meta.platforms; - } - // args.meta or { }; - } -) + meta = { + platforms = dub.meta.platforms; + } + // args.meta or { }; + }; +} diff --git a/pkgs/build-support/dlang/builddubpackage/hooks/default.nix b/pkgs/build-support/dlang/builddubpackage/hooks/default.nix new file mode 100644 index 0000000000000..b407d24fae4ea --- /dev/null +++ b/pkgs/build-support/dlang/builddubpackage/hooks/default.nix @@ -0,0 +1,26 @@ +{ callPackage }: + +{ + dubSetupHook = callPackage ( + { makeSetupHook }: + makeSetupHook { + name = "dub-setup-hook"; + } ./dub-setup-hook.sh + ) { }; + + dubBuildHook = callPackage ( + { makeSetupHook, dub }: + makeSetupHook { + name = "dub-build-hook"; + propagatedBuildInputs = [ dub ]; + } ./dub-build-hook.sh + ) { }; + + dubCheckHook = callPackage ( + { makeSetupHook, dub }: + makeSetupHook { + name = "dub-check-hook"; + propagatedBuildInputs = [ dub ]; + } ./dub-check-hook.sh + ) { }; +} diff --git a/pkgs/build-support/dlang/builddubpackage/hooks/dub-build-hook.sh b/pkgs/build-support/dlang/builddubpackage/hooks/dub-build-hook.sh new file mode 100644 index 0000000000000..400d7bcfc6329 --- /dev/null +++ b/pkgs/build-support/dlang/builddubpackage/hooks/dub-build-hook.sh @@ -0,0 +1,13 @@ +dubBuildHook() { + runHook preBuild + echo "Executing dubBuildHook" + + dub build --skip-registry=all --build="${dubBuildType-"release"}" "${dubBuildFlags[@]}" "${dubFlags[@]}" + + echo "Finished dubBuildHook" + runHook postBuild +} + +if [[ -z "${dontDubBuild-}" && -z "${buildPhase-}" ]]; then + buildPhase=dubBuildHook +fi diff --git a/pkgs/build-support/dlang/builddubpackage/hooks/dub-check-hook.sh b/pkgs/build-support/dlang/builddubpackage/hooks/dub-check-hook.sh new file mode 100644 index 0000000000000..99ffd4ae1cb92 --- /dev/null +++ b/pkgs/build-support/dlang/builddubpackage/hooks/dub-check-hook.sh @@ -0,0 +1,13 @@ +dubCheckHook() { + runHook preCheck + echo "Executing dubCheckHook" + + dub test --skip-registry=all "${dubTestFlags[@]}" "${dubFlags[@]}" + + echo "Finished dubCheckHook" + runHook postCheck +} + +if [[ -z "${dontDubCheck-}" && -z "${checkPhase-}" ]]; then + checkPhase=dubCheckHook +fi diff --git a/pkgs/build-support/dlang/builddubpackage/hooks/dub-setup-hook.sh b/pkgs/build-support/dlang/builddubpackage/hooks/dub-setup-hook.sh new file mode 100644 index 0000000000000..57bf00dbd05a2 --- /dev/null +++ b/pkgs/build-support/dlang/builddubpackage/hooks/dub-setup-hook.sh @@ -0,0 +1,19 @@ +dubSetupHook() { + echo "Executing dubSetupHook" + + if [ -z "${dubDeps-}" ]; then + echo "Error: 'dubDeps' must be set when using dubSetupHook." + exit 1 + fi + + export DUB_HOME="$NIX_BUILD_TOP"/.dub + echo "Configuring \$DUB_HOME ($DUB_HOME)" + cp -Tr "$dubDeps"/.dub "$NIX_BUILD_TOP"/.dub + chmod -R +w "$DUB_HOME" + + echo "Finished dubSetupHook" +} + +if [ -z "${dontDubSetup-}" ]; then + postPatchHooks+=(dubSetupHook) +fi diff --git a/pkgs/build-support/dlang/builddubpackage/import-dub-lock.nix b/pkgs/build-support/dlang/builddubpackage/import-dub-lock.nix new file mode 100644 index 0000000000000..121d21df9d990 --- /dev/null +++ b/pkgs/build-support/dlang/builddubpackage/import-dub-lock.nix @@ -0,0 +1,81 @@ +{ + lib, + runCommand, + linkFarm, + fetchurl, + fetchgit, + dub, +}: + +{ + pname, + version, + lock, +}: + +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 lock then lib.importJSON lock else lock; + 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 + ); + +in +runCommand "${pname}-${version}-dub-deps" + { + nativeBuildInputs = [ dub ]; + } + '' + export DUB_HOME="$out/.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} + '' diff --git a/pkgs/build-support/dlang/dub-support.nix b/pkgs/build-support/dlang/dub-support.nix index 879d59357d114..083b318ecd886 100644 --- a/pkgs/build-support/dlang/dub-support.nix +++ b/pkgs/build-support/dlang/dub-support.nix @@ -1,5 +1,8 @@ { callPackage }: + { - buildDubPackage = callPackage ./builddubpackage { }; dub-to-nix = callPackage ./dub-to-nix { }; + importDubLock = callPackage ./builddubpackage/import-dub-lock.nix { }; + buildDubPackage = callPackage ./builddubpackage { }; } +// import ./builddubpackage/hooks { inherit callPackage; } 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 old mode 100644 new mode 100755 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 19ea2ce1706d5..d85517640f4fe 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -2803,8 +2803,12 @@ with pkgs; dsview = libsForQt5.callPackage ../applications/science/electronics/dsview { }; inherit (import ../build-support/dlang/dub-support.nix { inherit callPackage; }) - buildDubPackage dub-to-nix + importDubLock + buildDubPackage + dubSetupHook + dubBuildHook + dubCheckHook ; duff = callPackage ../tools/filesystems/duff { };