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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
{ depot, pkgs, lib, ... }:

let
  #   bins = depot.nix.getBins pkgs.sqlite ["sqlite3"];

  whatcd-resolver = pkgs.haskellPackages.mkDerivation {
    pname = "whatcd-resolver";
    version = "0.1.0";

    src = depot.users.Profpatsch.exactSource ./. [
      ./whatcd-resolver.cabal
      ./Main.hs
      ./src/WhatcdResolver.hs
      ./src/AppT.hs
      ./src/Bencode.hs
      ./src/JsonLd.hs
      ./src/Optional.hs
      ./src/Html.hs
      ./src/Http.hs
      ./src/Transmission.hs
      ./src/Redacted.hs
    ];

    libraryHaskellDepends = [
      depot.users.Profpatsch.my-prelude
      depot.users.Profpatsch.my-webstuff
      pkgs.haskellPackages.pa-label
      depot.users.Profpatsch.my-prelude
      pkgs.haskellPackages.pa-error-tree
      pkgs.haskellPackages.pa-run-command
      pkgs.haskellPackages.aeson-better-errors
      pkgs.haskellPackages.bencode
      pkgs.haskellPackages.blaze-html
      pkgs.haskellPackages.hs-opentelemetry-sdk
      pkgs.haskellPackages.http-conduit
      pkgs.haskellPackages.http-types
      pkgs.haskellPackages.ihp-hsx
      pkgs.haskellPackages.monad-logger
      pkgs.haskellPackages.resource-pool
      pkgs.haskellPackages.postgresql-simple
      pkgs.haskellPackages.tmp-postgres
      pkgs.haskellPackages.unliftio
      pkgs.haskellPackages.wai-extra
      pkgs.haskellPackages.warp
      pkgs.haskellPackages.punycode
    ];

    isExecutable = true;
    isLibrary = false;
    license = lib.licenses.mit;
  };

  bins = depot.nix.getBins whatcd-resolver [ "whatcd-resolver" ];

  # ─────────────────────────────────────────────────────────────────────────
  # The Go port.
  #
  # It lives in the same directory as the Haskell implementation above but
  # shares no files with it except ./static. Both builds list their sources
  # explicitly (exactSource above, srcs below), so neither sees the other's
  # files.
  # ─────────────────────────────────────────────────────────────────────────

  goDeps = import ./go-deps.nix { inherit depot pkgs; };

  # Sources, templates and static files are staged into one directory because
  # //go:embed resolves its patterns relative to the directory of the first
  # `srcs` entry; passing path literals would place each file in its own store
  # path and the templates would silently embed as empty.
  # See `man ./nix/buildGo/buildGo.7`, section EMBEDDING FILES.
  goSrc = pkgs.runCommandLocal "whatcd-resolver-go-src" { } ''
    mkdir -p $out/templates $out/static $out/resources
    cp ${./main.go} $out/main.go
    cp ${./db.go} $out/db.go
    cp ${./otel.go} $out/otel.go
    cp ${./redacted.go} $out/redacted.go
    cp ${./releasetype.go} $out/releasetype.go
    cp ${./transmission.go} $out/transmission.go
    cp ${./bencode.go} $out/bencode.go
    cp ${./coverart.go} $out/coverart.go
    cp ${./queries.go} $out/queries.go
    cp ${./handlers.go} $out/handlers.go
    cp ${./assets.go} $out/assets.go
    cp ${./templates}/*.html $out/templates/
    cp ${./static}/progress-player.js $out/static/
    cp ${./resources}/stylize.css $out/resources/
  '';

  whatcd-resolver-go-unwrapped = depot.nix.buildGo.program {
    name = "whatcd-resolver-go";
    srcs = [
      "${goSrc}/main.go"
      "${goSrc}/db.go"
      "${goSrc}/otel.go"
      "${goSrc}/redacted.go"
      "${goSrc}/releasetype.go"
      "${goSrc}/transmission.go"
      "${goSrc}/bencode.go"
      "${goSrc}/coverart.go"
      "${goSrc}/queries.go"
      "${goSrc}/handlers.go"
      "${goSrc}/assets.go"
    ];
    deps = [
      goDeps.jackc-pgx.pgxpool
      goDeps.jackc-pgx
      goDeps.otel
      goDeps.otel.attribute
      goDeps.otel.codes
      goDeps.otel.sdk.resource
      goDeps.otel.sdk.trace
      goDeps.otel.semconv."v1.43.0"
      goDeps.otel.trace
      goDeps.golang-x-sync.errgroup
    ];
  };

in
{
  whatcd-resolver = depot.nix.writeExecline "whatcd-resolver-wrapped" { } [
    "importas"
    "-i"
    "PATH"
    "PATH"
    "export"
    "PATH"
    # TODO: figure out how to automatically migrate to a new postgres version with tmp_postgres (dump?)
    "${pkgs.postgresql_14}/bin:$${PATH}"
    "export"
    # Frontend resources that cannot be fetched at runtime any more, because
    # their upstream disappeared. See ./resources/README.md.
    "WHATCD_RESOLVER_RESOURCES"
    "${./resources}"
    "export"
    "WHATCD_RESOLVER_TOOLS"
    (pkgs.linkFarm "whatcd-resolver-tools" [
      {
        name = "pg_format";
        path = "${pkgs.pgformatter}/bin/pg_format";
      }
      {
        name = "exiftool";
        path = "${pkgs.exiftool}/bin/exiftool";
      }
    ])
    bins.whatcd-resolver
  ];

  # The Go port. Unlike the Haskell version it does not start its own
  # PostgreSQL, so no postgresql package is put on its PATH; it only needs
  # exiftool, for cover art embedded in audio file tags.
  whatcd-resolver-go = pkgs.symlinkJoin {
    name = "whatcd-resolver-go";
    outputs = [ "out" "man" ];
    paths = [ whatcd-resolver-go-unwrapped ];
    postBuild = ''
      mkdir -p $man/share/man/man1
      cp ${./whatcd-resolver.1} $man/share/man/man1/whatcd-resolver.1
    '';
  };

  static-directory = ./static;
}