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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
{ depot, pkgs, ... }:

# Go dependencies for the Go port of whatcd-resolver.
#
# See `man ./nix/buildGo/buildGo.7`: versions here are what actually gets built;
# the go.mod beside it exists only for editor tooling and `go test`. The two can
# disagree silently, so they are kept in sync by hand.
#
# Deliberately absent: go.opentelemetry.io/otel/exporters/otlp/…. The official
# OTLP exporter imports go.opentelemetry.io/proto/otlp, which drags in grpc,
# genproto and grpc-gateway — roughly 45 packages — even when only the HTTP
# transport is used. otel.go writes the OTLP/JSON payload directly instead,
# which Jaeger accepts on the same endpoint, so none of that is needed.

let
  sharedDeps = import ../go-deps.nix { inherit depot pkgs; };
in
sharedDeps // rec {

  # golang.org/x/sync - errgroup (bounded concurrency for the paged API fetches)
  # and semaphore (a pgx dependency). Not in the shared go-deps.nix yet.
  golang-x-sync = depot.nix.buildGo.external {
    path = "golang.org/x/sync";
    src = pkgs.fetchFromGitHub {
      owner = "golang";
      repo = "sync";
      rev = "v0.17.0";
      sha256 = "0bga9sfiwqxs7g913p7b355hg30agw58h5f5k7rzgpsai37nbkik";
    };
  };

  # ══════════════════════════════════════════════════════════
  # PostgreSQL driver
  # ══════════════════════════════════════════════════════════

  # github.com/jackc/pgpassfile - ~/.pgpass parsing (pgx dependency)
  jackc-pgpassfile = depot.nix.buildGo.external {
    path = "github.com/jackc/pgpassfile";
    src = pkgs.fetchFromGitHub {
      owner = "jackc";
      repo = "pgpassfile";
      rev = "v1.0.0";
      sha256 = "1crw06lzksgimbmr1a3sr00azg2v7l4qkvjra1cpmzzq5mncaj8z";
    };
  };

  # github.com/jackc/pgservicefile - pg_service.conf parsing (pgx dependency)
  jackc-pgservicefile = depot.nix.buildGo.external {
    path = "github.com/jackc/pgservicefile";
    src = pkgs.fetchFromGitHub {
      owner = "jackc";
      repo = "pgservicefile";
      rev = "5a60cdf6a761";
      sha256 = "0z8ndfdxx5r4dpjbjn9caq9w56lrzwm6nh8jwwk0gnq0n2q4cfhi";
    };
  };

  # github.com/jackc/puddle - the generic resource pool behind pgxpool
  jackc-puddle = depot.nix.buildGo.external {
    path = "github.com/jackc/puddle/v2";
    src = pkgs.fetchFromGitHub {
      owner = "jackc";
      repo = "puddle";
      rev = "v2.2.2";
      sha256 = "0agbk4nnja0fahi8mjp1y5ac9vjsjhldjwx9zshw0zjqhaxmsk11";
    };
    deps = [
      golang-x-sync.semaphore
    ];
  };

  # github.com/jackc/pgx - PostgreSQL driver.
  #
  # Chosen over lib/pq because the queries use JSONB, int[] and nullable
  # parameters throughout, which pgx maps to Go types without a wrapper type per
  # column.
  jackc-pgx = depot.nix.buildGo.external {
    path = "github.com/jackc/pgx/v5";
    src = pkgs.fetchFromGitHub {
      owner = "jackc";
      repo = "pgx";
      rev = "v5.10.0";
      sha256 = "10km2l44721rxbmm22sfvq2vhga8l25s9ykywxwjbxasg98s4aba";
    };
    deps = [
      jackc-pgpassfile
      jackc-pgservicefile
      jackc-puddle
      sharedDeps.golang-x-crypto.pbkdf2
      sharedDeps.golang-x-text.cases
      sharedDeps.golang-x-text.secure.precis
      sharedDeps.golang-x-text.unicode.norm
      golang-x-sync.semaphore
    ];
  };

  # ══════════════════════════════════════════════════════════
  # OpenTelemetry
  # ══════════════════════════════════════════════════════════

  # github.com/go-logr/logr - the logging interface the otel SDK logs through.
  go-logr = depot.nix.buildGo.external {
    path = "github.com/go-logr/logr";
    src = pkgs.fetchFromGitHub {
      owner = "go-logr";
      repo = "logr";
      rev = "v1.4.3";
      sha256 = "1m9v04wkrbm89vhlzfm99vxg3lnjsqqsqp871zv3r2sa92x38a88";
    };
  };

  # github.com/go-logr/stdr - logr backed by the standard log package.
  go-logr-stdr = depot.nix.buildGo.external {
    path = "github.com/go-logr/stdr";
    src = pkgs.fetchFromGitHub {
      owner = "go-logr";
      repo = "stdr";
      rev = "v1.2.2";
      sha256 = "1dl2rzvjacwqlnvw7azrxqbh4jvzaq8v399f6drs146l39ss21c1";
    };
    deps = [ go-logr go-logr.funcr ];
  };

  # github.com/cespare/xxhash - hashing used by otel's attribute set.
  cespare-xxhash = depot.nix.buildGo.external {
    path = "github.com/cespare/xxhash/v2";
    src = pkgs.fetchFromGitHub {
      owner = "cespare";
      repo = "xxhash";
      rev = "v2.3.0";
      sha256 = "1fhpn8iwb0p44sqi1hflgxpvy83krpi8gd0dd66m7756wszy3g6r";
    };
  };

  # The otel source, shared by the two external() calls below.
  otelSrc = pkgs.fetchFromGitHub {
    owner = "open-telemetry";
    repo = "opentelemetry-go";
    rev = "v1.45.0";
    sha256 = "0nhv8fcjjs1qlvghifih9d9d4gx6fc4hzvfz6gz0nq70qs5ajl8c";
  };

  # Since v1.33.0 there is a dependency cycle between the two otel
  # repositories, at the level buildGo works at:
  #
  #   go.opentelemetry.io/otel/internal/global  ->  go.opentelemetry.io/auto/sdk
  #   go.opentelemetry.io/auto/sdk              ->  go.opentelemetry.io/otel/{attribute,codes,trace,…}
  #
  # Go itself is fine with this, because no *package* is part of a cycle, only
  # the repositories are mutually dependent. buildGo.external, however, takes
  # one `deps` list per repository.
  #
  # It is nonetheless expressible, because the analyser output is consumed
  # lazily: buildGo only errors about a missing foreign dependency when the
  # particular sub-package that imports it is actually evaluated. So we build
  # the otel source twice:
  #
  #   otel-base  without auto/sdk. Every package except internal/global builds;
  #              touching internal/global from here would throw.
  #   otel       with auto/sdk (itself built against otel-base). Complete, and
  #              the one consumers should use.
  #
  # Only the attributes actually taken from each are ever forced, so the cycle
  # never has to be resolved.
  otel-base = depot.nix.buildGo.external {
    path = "go.opentelemetry.io/otel";
    src = otelSrc;
    deps = [
      go-logr
      go-logr-stdr
      cespare-xxhash
      sharedDeps.google-uuid
      sharedDeps.golang-x-sys.unix
    ];
  };

  # go.opentelemetry.io/auto/sdk - the in-process side of the
  # auto-instrumentation support, imported unconditionally by otel's global
  # tracer provider. The importable package is the `sdk` subdirectory; the
  # repository root is the instrumentation agent, which we do not build.
  otel-auto-sdk = depot.nix.buildGo.external {
    path = "go.opentelemetry.io/auto";
    src = pkgs.fetchFromGitHub {
      owner = "open-telemetry";
      repo = "opentelemetry-go-instrumentation";
      rev = "sdk/v1.2.1";
      sha256 = "1g90g8sijdlxy77am3m2xdvl94ldgyb0cl2jaw4cy0dkpwwk7yv5";
    };
    deps = [
      otel-base.attribute
      otel-base.codes
      otel-base.trace
      otel-base.trace.noop
      otel-base.semconv."v1.37.0"
    ];
  };

  # go.opentelemetry.io/otel - the API, SDK, trace and metric packages all live
  # in this one repository; the individual ones are navigated to in default.nix.
  otel = depot.nix.buildGo.external {
    path = "go.opentelemetry.io/otel";
    src = otelSrc;
    deps = [
      go-logr
      go-logr-stdr
      otel-auto-sdk.sdk
      cespare-xxhash
      sharedDeps.google-uuid
      sharedDeps.golang-x-sys.unix
    ];
  };
}