{ 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 { }; } )