Skip to content

Commit 39a2fa0

Browse files
committed
Add reproduction for cargo pgrx install --config (issue #2135) for reproducing issue.
1 parent 3e78514 commit 39a2fa0

11 files changed

Lines changed: 251 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Reproduction: why `cargo pgrx install --config` is needed (issue #2135)
2+
3+
A self-contained, Docker-based reproduction of the real-world scenario PR #2343
4+
fixes: a pgrx extension that depends on an **internal crate from a private
5+
registry**, in a monorepo where the registry is declared only in the
6+
extension's own `.cargo/config.toml`.
7+
8+
## Why it's real
9+
10+
Companies run a **private registry** (Artifactory, ktra, a crates.io mirror, …)
11+
for internal crates, declared per-repo in `.cargo/config.toml`. A pgrx extension
12+
lives as one submodule/subfolder of a larger monorepo. Cargo resolves
13+
`.cargo/config.toml` **from the current directory upward**, so building the
14+
extension from the monorepo root inherits the *parent* config — which does not
15+
know the private registry — and `cargo pgrx install` dies at its first step,
16+
`cargo metadata`. `cargo build` lets you fix this with `--config`; this PR gives
17+
`cargo pgrx install` the same.
18+
19+
## Layout (everything is a real file — nothing is generated inside the script)
20+
21+
```
22+
repro/install-config-2135/
23+
├── repro.sh # thin orchestrator (build/run/publish/before/after)
24+
├── registry/
25+
│ └── Dockerfile # the private registry image (cargo-http-registry)
26+
└── files/
27+
├── acme-internal/ # the internal crate, published to the registry
28+
│ ├── Cargo.toml
29+
│ ├── src/lib.rs # pub fn secret() -> i32 { 42 }
30+
│ └── .cargo/config.toml # registry def, for `cargo publish`
31+
└── monorepo/
32+
├── .cargo/config.toml # PARENT config — does NOT define `acme`
33+
└── childext/ # the pgrx extension
34+
├── Cargo.toml # depends on acme-internal { registry = "acme" }
35+
├── childext.control
36+
├── src/lib.rs # #[pg_extern] fn acme_secret() -> acme_internal::secret()
37+
└── .cargo/config.toml # CHILD config — the ONLY place `acme` is defined
38+
```
39+
40+
`repro.sh` copies `files/` into a scratch dir (`/tmp/acme-demo`) to build, so the
41+
nested crates never interfere with the pgrx workspace.
42+
43+
## Run
44+
45+
```bash
46+
CARGO_PGRX=target/debug/cargo-pgrx \ # the PR build of cargo-pgrx
47+
PG_CONFIG=$HOME/.pgrx/18.4/pgrx-install/bin/pg_config \
48+
PG_PORT=5449 \ # pgrx base_port + major (5431 + 18)
49+
PGRX_SRC=$PWD \ # your pgrx checkout
50+
repro/install-config-2135/repro.sh
51+
```
52+
53+
Expected:
54+
55+
- **BEFORE** (no `--config`):
56+
`cargo metadata ... registry index was not found in any configuration: 'acme'`
57+
- **AFTER** (`--config childext/.cargo/config.toml`): builds + installs.
58+
- **SQL proof**: `SELECT acme_secret();``42`.
59+
60+
Teardown: `docker rm -f acme-registry && rm -rf /tmp/acme-demo`
61+
62+
## Notes / honest caveats
63+
64+
- **`PGRX_BUILD_FLAGS` can't fix this** — it only reaches the build step, never
65+
the `cargo metadata` call that runs first (and fails first). The PR forwards
66+
`--config` to every cargo invocation install makes (metadata, rustc, the
67+
`get_version` metadata, and the schema `cargo run`).
68+
- **Registry index over `file://`**`cargo-http-registry`'s HTTP git-index does
69+
not serve cleanly in every environment (cargo can get HTTP 500), so the index
70+
is read from the registry's git repo on the shared Docker volume, while publish
71+
+ crate downloads still go over HTTP to the container. What's being demonstrated
72+
(config resolution / `--config`) is unaffected.
73+
- **`CARGO_TARGET_DIR` is set** by `repro.sh`: `pgrx-pg-config::get_target_dir()`
74+
runs its own `cargo metadata --no-deps`, which an undefined registry also breaks
75+
and which does not yet receive `--config` (gap #4). Setting `CARGO_TARGET_DIR`
76+
makes it return early, as pgrx/CI usually do. Forwarding `--config` there too is
77+
a possible follow-up.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Registry definition used when PUBLISHING acme-internal.
2+
# The index is the registry's git repo on the shared Docker volume; publish +
3+
# downloads go over HTTP to the container (see registry/Dockerfile).
4+
[registries.acme]
5+
index = "file:///tmp/acme-demo/reg/.git"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "acme-internal"
3+
version = "0.1.0"
4+
edition = "2021"
5+
description = "Internal-only crate, available ONLY from the private `acme` registry"
6+
license = "MIT"
7+
8+
[dependencies]
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//! A pretend company-internal crate. It is published only to the private
2+
//! `acme` registry, so anything depending on it can only build when that
3+
//! registry is configured.
4+
5+
/// The "secret" value the extension will expose through SQL.
6+
pub fn secret() -> i32 {
7+
42
8+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# monorepo-root config, shared across the org's many Rust services.
2+
# NOTE: it does NOT define the `acme` registry — that lives in the extension's own childext/.cargo/config.toml. Building from this root inherits THIS file.
3+
[net]
4+
retry = 2
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# This submodule's OWN config. It declares the private `acme` registry that `childext` depends on. The parent monorepo config (../.cargo/config.toml) does not have this, so building from the monorepo root cannot see it — which is the whole point: you must pass `--config childext/.cargo/config.toml` so cargo (and `cargo pgrx install`) picks up the right config for this repo.
2+
[target.'cfg(target_os="macos")']
3+
rustflags = ["-Clink-arg=-Wl,-undefined,dynamic_lookup"]
4+
5+
[registries.acme]
6+
index = "file:///tmp/acme-demo/reg/.git"
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "childext"
3+
version = "0.0.0"
4+
edition = "2021"
5+
6+
[lib]
7+
crate-type = ["cdylib"]
8+
9+
[features]
10+
default = ["pg13"]
11+
pg13 = ["pgrx/pg13", "pgrx-tests/pg13"]
12+
pg14 = ["pgrx/pg14", "pgrx-tests/pg14"]
13+
pg15 = ["pgrx/pg15", "pgrx-tests/pg15"]
14+
pg16 = ["pgrx/pg16", "pgrx-tests/pg16"]
15+
pg17 = ["pgrx/pg17", "pgrx-tests/pg17"]
16+
pg18 = ["pgrx/pg18", "pgrx-tests/pg18"]
17+
pg19 = ["pgrx/pg19", "pgrx-tests/pg19"]
18+
pg_test = []
19+
20+
[dependencies]
21+
acme-internal = { version = "0.1", registry = "acme" }
22+
pgrx = { path = "__PGRX_SRC__/pgrx" }
23+
24+
[dev-dependencies.pgrx-tests]
25+
path = "__PGRX_SRC__/pgrx-tests"
26+
27+
[profile.dev]
28+
panic = "unwind"
29+
30+
[profile.release]
31+
panic = "unwind"
32+
opt-level = 3
33+
lto = "fat"
34+
codegen-units = 1
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
comment = 'childext: demonstrates a pgrx extension depending on a private-registry crate'
2+
default_version = '@CARGO_VERSION@'
3+
module_pathname = 'childext'
4+
relocatable = false
5+
superuser = true
6+
trusted = false
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
use pgrx::prelude::*;
2+
3+
::pgrx::pg_module_magic!();
4+
5+
/// Exposes a value that comes from the private `acme-internal` crate, proving
6+
/// the internal dependency was resolved, compiled and linked into the extension.
7+
#[pg_extern]
8+
fn acme_secret() -> i32 {
9+
acme_internal::secret()
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM rust:slim
2+
RUN apt-get update \
3+
&& apt-get install -y --no-install-recommends git ca-certificates pkg-config libssl-dev \
4+
&& rm -rf /var/lib/apt/lists/* \
5+
&& cargo install cargo-http-registry \
6+
&& git config --system user.email "registry@acme.invalid" \
7+
&& git config --system user.name "acme registry" \
8+
&& git config --system --add safe.directory '*'
9+
EXPOSE 8444
10+
# /reg is a bind-mounted volume holding the git index + uploaded .crate files
11+
ENTRYPOINT ["cargo-http-registry", "/reg", "--addr", "0.0.0.0:8444"]

0 commit comments

Comments
 (0)