Skip to content

Commit 6d4bcd6

Browse files
committed
Add --cargo passthrough for cargo-pgrx install/package/run/test #2135
Monorepo/submodule layouts fail because cargo resolves .cargo/config.toml from the CWD upward, so building from the parent repo picks up the wrong config and cargo metadata (the first cargo call) dies — e.g. a private registry declared only in the submodule's config. Add a repeatable --cargo <FLAG> that is forwarded verbatim to every cargo invocation cargo-pgrx makes (cargo metadata, cargo rustc, get_version, cargo test), so global flags like --config/--offline/--locked reach all of them: cargo pgrx install --cargo=--config=child/.cargo/config.toml
1 parent 7827d0d commit 6d4bcd6

16 files changed

Lines changed: 183 additions & 19 deletions

cargo-pgrx/src/cargo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ impl Cargo {
152152
cmd.arg(features.features.join(" "));
153153
}
154154

155-
// And now the miscellaneous build flags!
155+
// And now the miscellaneous build flags!, `PGRX_BUILD_FLAGS` stays build-only.
156156
let flags = env::var("PGRX_BUILD_FLAGS").unwrap_or_default();
157157
for arg in flags.split_ascii_whitespace() {
158158
cmd.arg(arg);

cargo-pgrx/src/command/bench.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ impl CommandExecute for Bench {
9999
&self.features,
100100
self.package.as_deref(),
101101
self.manifest_path.as_deref(),
102+
&[],
102103
)?;
103104
let mut resolved_features = self.features.clone();
104105
let (pg_config, _) = pg_config_and_version(
@@ -117,7 +118,7 @@ impl CommandExecute for Bench {
117118
}
118119

119120
let postgresql_conf = collect_postgresql_conf_settings(&self.postgresql_conf)?;
120-
let extversion = crate::command::install::get_version(&package_manifest_path)?;
121+
let extversion = crate::command::install::get_version(&package_manifest_path, &[])?;
121122
let mut features = resolved_features;
122123
ensure_feature(&mut features, "pg_bench");
123124
let profile = CargoProfile::from_flags(
@@ -138,6 +139,7 @@ impl CommandExecute for Bench {
138139
false,
139140
self.target.as_deref(),
140141
&postgresql_conf,
142+
&[],
141143
)?;
142144

143145
if self.resetdb {

cargo-pgrx/src/command/connect.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ impl CommandExecute for Connect {
5252
&Features::default(),
5353
self.package.as_deref(),
5454
self.manifest_path.as_deref(),
55+
&[],
5556
)?;
5657
let (pg_config, _pg_version) = match pg_config_and_version(
5758
&pgrx,

cargo-pgrx/src/command/get.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ impl CommandExecute for Get {
3434
#[tracing::instrument(level = "error", skip(self))]
3535
fn execute(self) -> eyre::Result<()> {
3636
let metadata =
37-
crate::metadata::metadata(&Default::default(), self.manifest_path.as_deref())
37+
crate::metadata::metadata(&Default::default(), self.manifest_path.as_deref(), &[])
3838
.wrap_err("couldn't get cargo metadata")?;
3939
crate::metadata::validate(self.manifest_path.as_deref(), &metadata)?;
4040
let package_manifest_path =

cargo-pgrx/src/command/install.rs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ pub(crate) struct Install {
5757
pub(crate) features: clap_cargo::Features,
5858
#[clap(long)]
5959
pub(crate) target: Option<String>,
60+
/// Extra flag forwarded verbatim to every `cargo` invocation (repeatable).
61+
/// e.g. `--cargo=--config=child/.cargo/config.toml --cargo=--offline`
62+
#[clap(long = "cargo", value_name = "FLAG")]
63+
pub(crate) cargo: Vec<String>,
6064
#[clap(from_global, action = ArgAction::Count)]
6165
pub(crate) verbose: u8,
6266
}
@@ -72,8 +76,10 @@ impl CommandExecute for Install {
7276
return sudo_install.execute();
7377
}
7478

75-
let metadata = crate::metadata::metadata(&self.features, self.manifest_path.as_deref())
76-
.wrap_err("couldn't get cargo metadata")?;
79+
let cargo_flags = std::mem::take(&mut self.cargo);
80+
let metadata =
81+
crate::metadata::metadata(&self.features, self.manifest_path.as_deref(), &cargo_flags)
82+
.wrap_err("couldn't get cargo metadata")?;
7783
crate::metadata::validate(self.manifest_path.as_deref(), &metadata)?;
7884
let package_manifest_path =
7985
crate::manifest::manifest_path(&metadata, self.package.as_deref())
@@ -110,6 +116,7 @@ impl CommandExecute for Install {
110116
None,
111117
&self.features,
112118
self.target.as_deref(),
119+
&cargo_flags,
113120
)?;
114121
Ok(())
115122
}
@@ -147,6 +154,7 @@ pub(crate) fn install_extension(
147154
base_directory: Option<PathBuf>,
148155
features: &clap_cargo::Features,
149156
target: Option<&str>,
157+
cargo_flags: &[String],
150158
) -> eyre::Result<Vec<PathBuf>> {
151159
let mut output_tracking = Vec::new();
152160

@@ -158,7 +166,7 @@ pub(crate) fn install_extension(
158166
let build_manifest_path =
159167
manifest_path_for_build(user_manifest_path, user_package, package_manifest_path);
160168
let build_command_output =
161-
build_extension(build_manifest_path, user_package, profile, features, target)?;
169+
build_extension(build_manifest_path, user_package, profile, features, target, cargo_flags)?;
162170
let build_command_bytes = build_command_output.stdout;
163171
let build_command_reader = BufReader::new(build_command_bytes.as_slice());
164172
let build_command_stream = CargoMessage::parse_stream(build_command_reader);
@@ -192,12 +200,13 @@ pub(crate) fn install_extension(
192200
true,
193201
package_manifest_path,
194202
&mut output_tracking,
203+
cargo_flags,
195204
)?;
196205
}
197206

198207
{
199208
let so_name = if versioned_so {
200-
let extver = get_version(package_manifest_path)?;
209+
let extver = get_version(package_manifest_path, cargo_flags)?;
201210
// note: versioned so-name format must agree with pgrx-utils
202211
format!("{extname}-{extver}")
203212
} else {
@@ -234,6 +243,7 @@ pub(crate) fn install_extension(
234243
false,
235244
package_manifest_path,
236245
&mut output_tracking,
246+
cargo_flags,
237247
)?;
238248
}
239249

@@ -248,6 +258,7 @@ pub(crate) fn install_extension(
248258
&extdir,
249259
true,
250260
&mut output_tracking,
261+
cargo_flags,
251262
)?;
252263

253264
println!("{} installing {}", " Finished".bold().green(), extname);
@@ -261,6 +272,7 @@ fn copy_file(
261272
do_filter: bool,
262273
package_manifest_path: &Path,
263274
output_tracking: &mut Vec<PathBuf>,
275+
cargo_flags: &[String],
264276
) -> eyre::Result<()> {
265277
let Some(dest_dir) = dest.parent() else {
266278
// what fresh hell could ever cause such an error?
@@ -282,7 +294,7 @@ fn copy_file(
282294
// we want to filter the contents of the file we're to copy
283295
let input = fs::read_to_string(src)
284296
.wrap_err_with(|| format!("failed to read `{}`", src.display()))?;
285-
let input = filter_contents(package_manifest_path, input)?;
297+
let input = filter_contents(package_manifest_path, input, cargo_flags)?;
286298

287299
fs::write(&dest, input).wrap_err_with(|| {
288300
format!("failed writing `{}` to `{}`", src.display(), dest.display())
@@ -303,6 +315,7 @@ pub(crate) fn build_extension(
303315
profile: &CargoProfile,
304316
features: &clap_cargo::Features,
305317
target: Option<&str>,
318+
cargo_flags: &[String],
306319
) -> eyre::Result<std::process::Output> {
307320
let flags = std::env::var("PGRX_BUILD_FLAGS").unwrap_or_default();
308321

@@ -341,6 +354,10 @@ pub(crate) fn build_extension(
341354
command.arg(arg);
342355
}
343356

357+
for arg in cargo_flags {
358+
command.arg(arg);
359+
}
360+
344361
if let Some(target) = target {
345362
command.arg("--target");
346363
command.arg(target);
@@ -388,10 +405,11 @@ fn copy_sql_files(
388405
extdir: &Path,
389406
skip_build: bool,
390407
output_tracking: &mut Vec<PathBuf>,
408+
cargo_flags: &[String],
391409
) -> eyre::Result<()> {
392410
let (_, extname) = find_control_file(package_manifest_path)?;
393411
{
394-
let version = get_version(package_manifest_path)?;
412+
let version = get_version(package_manifest_path, cargo_flags)?;
395413
let filename = format!("{extname}--{version}.sql");
396414
let dest = extdir.join(filename);
397415

@@ -432,6 +450,7 @@ fn copy_sql_files(
432450
true,
433451
package_manifest_path,
434452
output_tracking,
453+
cargo_flags,
435454
)?;
436455
}
437456
}
@@ -482,7 +501,7 @@ pub(crate) fn find_library_file(
482501

483502
static CARGO_VERSION: OnceLock<MemoizeKeyValue> = OnceLock::new();
484503

485-
pub(crate) fn get_version(manifest_path: &Path) -> eyre::Result<String> {
504+
pub(crate) fn get_version(manifest_path: &Path, cargo_flags: &[String]) -> eyre::Result<String> {
486505
let path_string = manifest_path.to_owned();
487506

488507
if let Some(version) =
@@ -494,8 +513,9 @@ pub(crate) fn get_version(manifest_path: &Path) -> eyre::Result<String> {
494513
let version = match get_property(manifest_path, "default_version")? {
495514
Some(v) => {
496515
if v == "@CARGO_VERSION@" {
497-
let metadata = crate::metadata::metadata(&Default::default(), Some(manifest_path))
498-
.wrap_err("couldn't get cargo metadata")?;
516+
let metadata =
517+
crate::metadata::metadata(&Default::default(), Some(manifest_path), cargo_flags)
518+
.wrap_err("couldn't get cargo metadata")?;
499519
crate::metadata::validate(Some(manifest_path), &metadata)?;
500520
let manifest_path = crate::manifest::manifest_path(&metadata, None)
501521
.wrap_err("Couldn't get manifest path")?;
@@ -587,15 +607,19 @@ pub(crate) fn format_display_path(path: &Path) -> eyre::Result<String> {
587607
Ok(out)
588608
}
589609

590-
fn filter_contents(manifest_path: &Path, mut input: String) -> eyre::Result<String> {
610+
fn filter_contents(
611+
manifest_path: &Path,
612+
mut input: String,
613+
cargo_flags: &[String],
614+
) -> eyre::Result<String> {
591615
if input.contains("@GIT_HASH@") {
592616
// avoid doing this if we don't actually have the token
593617
// the project might not be a git repo so running `git`
594618
// would fail
595619
input = input.replace("@GIT_HASH@", &get_git_hash(manifest_path)?);
596620
}
597621

598-
input = input.replace("@CARGO_VERSION@", &get_version(manifest_path)?);
622+
input = input.replace("@CARGO_VERSION@", &get_version(manifest_path, cargo_flags)?);
599623

600624
Ok(input)
601625
}

cargo-pgrx/src/command/package.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,21 @@ pub(crate) struct Package {
4646
pub(crate) features: clap_cargo::Features,
4747
#[clap(long)]
4848
pub(crate) target: Option<String>,
49+
/// Extra flag forwarded verbatim to every `cargo` invocation (repeatable).
50+
/// e.g. `--cargo=--config=child/.cargo/config.toml --cargo=--offline`
51+
#[clap(long = "cargo", value_name = "FLAG")]
52+
pub(crate) cargo: Vec<String>,
4953
#[clap(from_global, action = ArgAction::Count)]
5054
pub(crate) verbose: u8,
5155
}
5256

5357
impl Package {
5458
pub(crate) fn perform(mut self) -> eyre::Result<(PathBuf, Vec<PathBuf>)> {
5559
warn_if_pg_bench_enabled(&self.features, "package");
56-
let metadata = crate::metadata::metadata(&self.features, self.manifest_path.as_deref())
57-
.wrap_err("couldn't get cargo metadata")?;
60+
let cargo_flags = std::mem::take(&mut self.cargo);
61+
let metadata =
62+
crate::metadata::metadata(&self.features, self.manifest_path.as_deref(), &cargo_flags)
63+
.wrap_err("couldn't get cargo metadata")?;
5864
crate::metadata::validate(self.manifest_path.as_deref(), &metadata)?;
5965
let package_manifest_path =
6066
crate::manifest::manifest_path(&metadata, self.package.as_deref())
@@ -96,6 +102,7 @@ impl Package {
96102
self.test,
97103
&self.features,
98104
self.target.as_deref(),
105+
&cargo_flags,
99106
)?;
100107

101108
Ok((out_dir, output_files))
@@ -125,6 +132,7 @@ pub(crate) fn package_extension(
125132
is_test: bool,
126133
features: &clap_cargo::Features,
127134
target: Option<&str>,
135+
cargo_flags: &[String],
128136
) -> eyre::Result<Vec<PathBuf>> {
129137
let out_dir_exists = out_dir.try_exists().wrap_err_with(|| {
130138
format!("failed to access {} while packaging extension", out_dir.display())
@@ -144,6 +152,7 @@ pub(crate) fn package_extension(
144152
Some(out_dir),
145153
features,
146154
target,
155+
cargo_flags,
147156
)
148157
}
149158

cargo-pgrx/src/command/regress.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,7 @@ impl CommandExecute for Regress {
360360
&self.features,
361361
self.package.as_deref(),
362362
self.manifest_path.as_deref(),
363+
&[],
363364
)?;
364365
let extname = get_property(&manifest_path, "extname")?
365366
.expect("extension name property `extname` should always be known");

cargo-pgrx/src/command/run.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ pub(crate) struct Run {
5656
install_only: bool,
5757
#[clap(long)]
5858
valgrind: bool,
59+
/// Extra flag forwarded verbatim to every `cargo` invocation (repeatable).
60+
/// e.g. `--cargo=--config=child/.cargo/config.toml --cargo=--offline`
61+
#[clap(long = "cargo", value_name = "FLAG")]
62+
cargo: Vec<String>,
5963
}
6064

6165
impl From<&Regress> for Run {
@@ -73,6 +77,7 @@ impl From<&Regress> for Run {
7377
pgcli: false,
7478
install_only: false,
7579
valgrind: regress.valgrind,
80+
cargo: Vec::new(),
7681
}
7782
}
7883
}
@@ -98,6 +103,7 @@ impl Run {
98103
&self.features,
99104
self.package.as_deref(),
100105
self.manifest_path.as_deref(),
106+
&self.cargo,
101107
)?;
102108
let (pg_config, _pg_version) = pg_config_and_version(
103109
&pgrx,
@@ -130,6 +136,7 @@ impl Run {
130136
self.valgrind,
131137
self.target.as_deref(),
132138
postgresql_conf,
139+
&self.cargo,
133140
)?;
134141

135142
Ok((pg_config, dbname))
@@ -165,6 +172,7 @@ pub(crate) fn run(
165172
use_valgrind: bool,
166173
target: Option<&str>,
167174
postgresql_conf: &HashMap<String, String>,
175+
cargo_flags: &[String],
168176
) -> eyre::Result<()> {
169177
// stop postgres
170178
stop_postgres(pg_config)?;
@@ -180,6 +188,7 @@ pub(crate) fn run(
180188
None,
181189
features,
182190
target,
191+
cargo_flags,
183192
)?;
184193

185194
if install_only {

cargo-pgrx/src/command/schema.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ impl CommandExecute for Schema {
9797
&self.features,
9898
self.package.as_deref(),
9999
self.manifest_path.as_deref(),
100+
&[],
100101
)?;
101102
// This does meaningful mutation, unfortunately
102103
let (_pg_config, _pg_version) = pg_config_and_version(

cargo-pgrx/src/command/start.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ impl CommandExecute for Start {
5454
&clap_cargo::Features::default(),
5555
me.package.as_deref(),
5656
me.manifest_path.as_deref(),
57+
&[],
5758
)?;
5859

5960
let (pg_config, _) =
@@ -65,6 +66,7 @@ impl CommandExecute for Start {
6566
&clap_cargo::Features::default(),
6667
self.package.as_deref(),
6768
self.manifest_path.as_deref(),
69+
&[],
6870
)?;
6971

7072
let postgresql_conf = collect_postgresql_conf_settings(&self.postgresql_conf)?;

0 commit comments

Comments
 (0)