@@ -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
483502static 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}
0 commit comments