From a04ae4ad391c77186c69185219e7977cc609260a Mon Sep 17 00:00:00 2001 From: vados Date: Wed, 27 Mar 2024 13:15:22 +0900 Subject: [PATCH] refactor: use pg minor version as an argument --- cargo-pgrx/src/command/init.rs | 93 +++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 19 deletions(-) diff --git a/cargo-pgrx/src/command/init.rs b/cargo-pgrx/src/command/init.rs index 6ceba77c00..7bf8ba1525 100644 --- a/cargo-pgrx/src/command/init.rs +++ b/cargo-pgrx/src/command/init.rs @@ -63,10 +63,11 @@ impl FromStr for PostgresInitVersionInput { match s { // If the string is the path to a valid file, then we can use it s if std::path::Path::new(s).exists() => Ok(Self::PgConfigPath(PathBuf::from(s))), + // If the path is 'download' then we can prompt a managed download "download" => Ok(Self::PgrxManagedDownload), - s => Ok(Self::VersionedDownload(s.into())), - // TODO: check if it's a valid version string? [d]+.[d]* ? - // s => bail!("unrecognized input [{s}], please specify a valid PG_CONFIG path, 'download' or the path to a HTTP tarball") + s => bail!( + "unrecognized input [{s}], please specify a valid PG_CONFIG path, or 'download'" + ), } } } @@ -82,10 +83,16 @@ impl PostgresInitVersionInput { /// into a [`PgConfig`] which can be used as part of a [`Pgrx`] fn resolve( &self, - pg_major_version: &str, + pg_version: &str, pgrx_home: impl AsRef, pg_init: &Init, ) -> eyre::Result { + // Determine major and minor version + let Some((major_version, minor_version)) = pg_version.split_once('.') else { + bail!("unexpected format of version string, should be ."); + }; + + // Build a PgConfig based on the versions that were provided let pg_config = match self { // If a config path was specified, then we can look it up Self::PgConfigPath(pg_config_path) => { @@ -96,17 +103,14 @@ impl PostgresInitVersionInput { let Ok(default_pgrx) = get_default_pgrx().as_ref() else { bail!("failed to generate default pgrx config"); }; - default_pgrx.get(pg_major_version).wrap_err_with(|| { - format!("{pg_major_version} is not a known Postgres major version") + default_pgrx.get(major_version).wrap_err_with(|| { + format!("{major_version} is not a known Postgres major version") })? } // If the remote tarball was specified, we expect it to contain the full pg version *somewhere* Self::VersionedDownload(version) => { - let Some((major, minor)) = version.split_once('.') else { - bail!("unexpected format of version string, should be ."); - }; - let major = u16::from_str_radix(major, 10)?; - let minor = u16::from_str_radix(minor, 10)?; + let major = u16::from_str_radix(major_version, 10)?; + let minor = u16::from_str_radix(minor_version, 10)?; let pg_full_version = PgVersion::new( major, PgMinorVersion::Release(minor), @@ -120,9 +124,9 @@ impl PostgresInitVersionInput { // to ensure we didn't somehow give a pg_config with the wrong version if let Self::VersionedDownload(_) | Self::PgConfigPath(_) = self { let label = pg_config.label().ok(); - if label.is_some() && label.as_deref() != Some(pg_major_version) { + if label.is_some() && label.as_deref() != Some(major_version) { bail!( - "wrong `pg_config` given to `--{pg_major_version}` `{:?}` is for PostgreSQL {}", + "wrong `pg_config` given to `--{major_version}` `{:?}` is for PostgreSQL {}", pg_config.path(), pg_config.major_version()?, ); @@ -140,26 +144,55 @@ pub(crate) struct Init { /// If installed locally, the path to PG12's `pgconfig` tool, or `download` to have pgrx download/compile/install it #[clap(env = "PG12_PG_CONFIG", long)] pg12: Option, + + /// Specify a minor version for PG12 + #[clap(env = "PG12_MINOR_VERSION", long)] + pg12_minor_version: Option, + /// If installed locally, the path to PG13's `pgconfig` tool, or `download` to have pgrx download/compile/install it #[clap(env = "PG13_PG_CONFIG", long)] pg13: Option, + + /// Specify a minor version for PG13 + #[clap(env = "PG13_MINOR_VERSION", long)] + pg13_minor_version: Option, + /// If installed locally, the path to PG14's `pgconfig` tool, or `download` to have pgrx download/compile/install it #[clap(env = "PG14_PG_CONFIG", long)] pg14: Option, + + /// Specify a minor version for PG14 + #[clap(env = "PG14_MINOR_VERSION", long)] + pg14_minor_version: Option, + /// If installed locally, the path to PG15's `pgconfig` tool, or `download` to have pgrx download/compile/install it #[clap(env = "PG15_PG_CONFIG", long)] pg15: Option, + + /// Specify a minor version for PG15 + #[clap(env = "PG15_MINOR_VERSION", long)] + pg15_minor_version: Option, + /// If installed locally, the path to PG16's `pgconfig` tool, or `download` to have pgrx download/compile/install it #[clap(env = "PG16_PG_CONFIG", long)] pg16: Option, + + /// Specify a minor version for PG16 + #[clap(env = "PG16_MINOR_VERSION", long)] + pg16_minor_version: Option, + #[clap(from_global, action = ArgAction::Count)] verbose: u8, + #[clap(long, help = "Base port number")] base_port: Option, + #[clap(long, help = "Base testing port number")] base_testing_port: Option, + #[clap(long, help = "Additional flags to pass to the configure script")] configure_flag: Vec, + /// Compile PostgreSQL with the necessary flags to detect a good amount of /// memory errors when run under Valgrind. /// @@ -167,8 +200,10 @@ pub(crate) struct Init { /// installed, but the resulting build is usable without valgrind. #[clap(long)] valgrind: bool, + #[clap(long, short, help = "Allow N make jobs at once")] jobs: Option, + #[clap(skip)] jobserver: OnceLock, } @@ -189,22 +224,42 @@ impl CommandExecute for Init { ) .unwrap(); - // parse versions provided into a lookup of requested versions (if present) + // Parse versions provided into a lookup of requested versions (if present) let mut versions = HashMap::new(); if let Some(ref version) = self.pg12 { - versions.insert("pg12", PostgresInitVersionInput::from_str(version)?); + let minor_suffix = self.pg12_minor_version.map(|v| format!(".{v}")).unwrap_or_default(); + versions.insert( + "pg12", + PostgresInitVersionInput::from_str(&format!("{version}{minor_suffix}"))?, + ); } if let Some(ref version) = self.pg13 { - versions.insert("pg13", PostgresInitVersionInput::from_str(version)?); + let minor_suffix = self.pg13_minor_version.map(|v| format!(".{v}")).unwrap_or_default(); + versions.insert( + "pg13", + PostgresInitVersionInput::from_str(&format!("{version}{minor_suffix}"))?, + ); } if let Some(ref version) = self.pg14 { - versions.insert("pg14", PostgresInitVersionInput::from_str(version)?); + let minor_suffix = self.pg14_minor_version.map(|v| format!(".{v}")).unwrap_or_default(); + versions.insert( + "pg14", + PostgresInitVersionInput::from_str(&format!("{version}{minor_suffix}"))?, + ); } if let Some(ref version) = self.pg15 { - versions.insert("pg15", PostgresInitVersionInput::from_str(version)?); + let minor_suffix = self.pg15_minor_version.map(|v| format!(".{v}")).unwrap_or_default(); + versions.insert( + "pg15", + PostgresInitVersionInput::from_str(&format!("{version}{minor_suffix}"))?, + ); } if let Some(ref version) = self.pg16 { - versions.insert("pg16", PostgresInitVersionInput::from_str(version)?); + let minor_suffix = self.pg16_minor_version.map(|v| format!(".{v}")).unwrap_or_default(); + versions.insert( + "pg16", + PostgresInitVersionInput::from_str(&format!("{version}{minor_suffix}"))?, + ); } // Resolve all versions required and then push them into the config