{ pkgs ? import <nixpkgs> {},
  stdenv ? pkgs.stdenv,
  lib ? pkgs.lib,
  ldc ? null,
  dcompiler ? pkgs.ldc,
  dub ? pkgs.dub
}:
assert dcompiler != null;
with (
  with lib;
  let
    filterDub = name: type: let baseName = baseNameOf (toString name); in ! ( # filter function to remove the .dub package folder from src
      type == "directory" && baseName == ".dub"
    );
    targetOf = package: "${package.targetPath or "."}/${package.targetName or package.name}";
    # remove reference to build tools and library sources
    disallowedReferences = deps: [ dcompiler dub ];
    removeExpr = refs: ''remove-references-to ${lib.concatMapStrings (ref: " -t ${ref}") refs}'';
  in {
    mkDubDerivation = lib.makeOverridable ({
      src,
      nativeBuildInputs ? [],
      dubJSON ? src + "/dub.json",
      passthru ? {},
      package ? lib.importJSON dubJSON,
      ...
    } @ attrs: stdenv.mkDerivation (attrs // {
      pname = package.name;
      nativeBuildInputs = [ dcompiler dub pkgs.removeReferencesTo ] ++ nativeBuildInputs;
      disallowedReferences = disallowedReferences deps;
      passthru = passthru // {
        inherit dub dcompiler pkgs;
      };
      src = lib.cleanSourceWith {
        filter = filterDub;
        src = lib.cleanSource src;
      };
      preFixup = ''
        find $out/bin -type f -exec ${removeExpr (disallowedReferences deps)} '{}' + || true
      '';
      buildPhase = ''
        runHook preBuild
        HOME="$PWD"
        DFLAGS="-O2 -inline"
        for DC_ in dmd ldmd2 gdmd; do
          echo "- check for D compiler $DC_"
          DC=$(type -P $DC_ || echo "")
          if [ ! "$DC" == "" ]; then
            break
          fi
        done
        if [ "$DC" == "" ]; then
          exit "Error: could not find D compiler"
        fi
        echo "$DC_ used as D compiler to build $pname"
        dub build --compiler=$DC --build=release --combined --skip-registry=all
        runHook postBuild
      '';
      checkPhase = ''
        runHook preCheck
        HOME="$PWD"
        dub test --combined --skip-registry=all
        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;
      } // attrs.meta or {};
    } // lib.optionalAttrs (!(attrs ? version)) {
      name = package.name; # use name from dub.json, unless pname and version are specified
    }));
  }
);
mkDubDerivation rec {
  pname         = "spine";
  version       = "0.12.0";
  src           = ./.;
  nativeBuildInputs = with pkgs; [ dub ldc ];
  buildInputs = with pkgs; [ nixVersions.unstable sqlite ];
  meta = with pkgs.lib; {
    description = "A sisu like parser and document generator";
    longDescription = ''
      A sisu like parser and document generator
    '';
    homepage    = "https://sisudoc.org";
    license     = licenses.agpl3Plus;
    platforms   = platforms.linux;
    maintainers = [ "RalphAmissah" ];
  };
}