Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter all to both config && Cargo .tomls #1487

Merged
merged 5 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 16 additions & 5 deletions cargo-pgrx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,13 +232,22 @@ $ cargo pgrx stop all
Stopping Postgres v15
```

`cargo pgrx` has three commands for managing each Postgres installation: `start`, `stop`, and `status`. Additionally, `cargo pgrx run` (see below) will automatically start its target Postgres instance if not already running.

When starting a Postgres instance, `pgrx` starts it on port `28800 + PG_MAJOR_VERSION`, so Postgres 11 runs on `28811`, 12 on `28812`, etc. Additionally, the first time any of these are started, it'll automatically initialize a `PGDATA` directory in `~/.pgrx/data-[11 | 12 | 13 | 14 | 15]`. Doing so allows `pgrx` to manage either Postgres versions it installed or ones already on your computer, and to make sure that in the latter case, `pgrx` managed versions don't interfere with what might already be running. The locale of the instance is `C.UTF-8` (or equivalently, a locale of `C` with a `ctype` of `UTF8` on macOS), or `C` if the `C.UTF-8` locale is unavailable.
`cargo pgrx` has three commands for managing Postgres installations: `start`, `stop`, and `status`.
Additionally, `cargo pgrx run` (see below) will automatically start its target Postgres instance if
not already running. Note that when directed to use `"all"` Postgres instances, this is interpreted
in terms of an extension's `pg{MAJOR}` features in its Cargo.toml, except for `cargo pgrx status`.

When starting a Postgres instance, `pgrx` starts it on port `28800 + PG_MAJOR_VERSION`, so
Postgres 15 runs on `28815`, 16 on `28816`, etc. Additionally, the first time any of these are
started, it will initialize `PGDATA` directories in `${PGRX_HOME}/data-{12,13,14,15,16}`.
Doing so allows `pgrx` to manage either Postgres versions it installed or ones already on your
computer, and ensure that the `pgrx` managed versions don't interfere with what might already
be running. The locale of the instance is `C.UTF-8` (or equivalently, a locale of `C` with a
`ctype` of `UTF8` on macOS), or `C` if the `C.UTF-8` locale is unavailable.

`pgrx` doesn't tear down these instances. While they're stored in a hidden directory in your home directory, `pgrx` considers these important and permanent database installations.

Once started, you can connect to them using `psql` (if you have it on your $PATH) like so: `psql -p 28812`. However, you probably just want the `cargo pgrx run` command.
Once started, you can connect to them using `psql` (if you have it on your $PATH) like so: `psql -p 28816`. However, you probably just want the `cargo pgrx run` command.

## Compiling and Running Your Extension

Expand Down Expand Up @@ -446,7 +455,9 @@ test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; fini
Stopping Postgres
```

`cargo pgrx test [pg12 | pg13 | pg14 | pg15 | pg16]` runs your `#[test]` and `#[pg_test]` annotated functions using cargo's test system.
`cargo pgrx test ${VERSION}` runs your `#[test]` and `#[pg_test]` annotated functions using cargo's
test system. Note that if you request `cargo pgrx test all`, this will only run tests for versions
configured for control via cargo-pgrx AND set in your extension's Cargo.toml for the pgrx library.

During the testing process, `pgrx` starts a temporary instance of Postgres with its `PGDATA` directory in `./target/pgrx-test-data-PGVER/`. This Postgres instance is stopped as soon as the test framework has finished. The locale of the temporary instance is `C.UTF-8` (or equivalently, a locale of `C` with a `ctype` of `UTF8` on macOS), or `C` if the `C.UTF-8` locale is unavailable.

Expand Down
3 changes: 3 additions & 0 deletions cargo-pgrx/src/command/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ pub(crate) fn init_pgrx(pgrx: &Pgrx, init: &Init) -> eyre::Result<()> {
let mut output_configs = std::thread::scope(|s| -> eyre::Result<Vec<_>> {
let span = tracing::Span::current();
let mut threads = Vec::new();
// This selector does not necessarily match the support expressed in a project's Cargo.toml
// the user will template or handwrite. We may wish to check and emit errors then, but we
// do not require a project at pgrx init time, so permit these oddities for now.
for pg_config in pgrx.iter(PgConfigSelector::All) {
let pg_config = pg_config?;
let span = span.clone();
Expand Down
2 changes: 2 additions & 0 deletions cargo-pgrx/src/command/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,5 @@ fn build_agent_for_url(url: &str) -> eyre::Result<Agent> {
Ok(Agent::new())
}
}

// TODO: Abstract over the repeated `fn perform`?
10 changes: 8 additions & 2 deletions cargo-pgrx/src/command/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::manifest::{get_package_manifest, pg_config_and_version};
use crate::CommandExecute;
use eyre::eyre;
use owo_colors::OwoColorize;
use pgrx_pg_config::{PgConfig, PgConfigSelector, Pgrx};
use pgrx_pg_config::{PgConfig, Pgrx};
use std::path::PathBuf;
use std::process::Stdio;

Expand Down Expand Up @@ -43,15 +43,21 @@ impl CommandExecute for Start {
me.package.as_ref(),
me.manifest_path,
)?;

let (pg_config, _) =
pg_config_and_version(pgrx, &package_manifest, me.pg_version, None, false)?;

start_postgres(&pg_config)
}
let (package_manifest, _) = get_package_manifest(
&clap_cargo::Features::default(),
self.package.as_ref(),
self.manifest_path.clone(),
)?;

let pgrx = Pgrx::from_config()?;
if self.pg_version == Some("all".into()) {
for v in pgrx.iter(PgConfigSelector::All) {
for v in crate::manifest::all_pg_in_both_tomls(&package_manifest, &pgrx) {
let mut versioned_start = self.clone();
versioned_start.pg_version = Some(v?.label()?);
perform(versioned_start, &pgrx)?;
Expand Down
11 changes: 8 additions & 3 deletions cargo-pgrx/src/command/stop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use crate::manifest::{get_package_manifest, pg_config_and_version};
use crate::CommandExecute;
use eyre::eyre;
use owo_colors::OwoColorize;
use pgrx_pg_config::{PgConfig, PgConfigSelector, Pgrx};
use pgrx_pg_config::{PgConfig, Pgrx};
use std::path::PathBuf;
use std::process::Stdio;

Expand Down Expand Up @@ -40,7 +40,7 @@ impl CommandExecute for Stop {
let (package_manifest, _) = get_package_manifest(
&clap_cargo::Features::default(),
me.package.as_ref(),
me.manifest_path,
me.manifest_path.clone(),
)?;
let (pg_config, _) =
pg_config_and_version(pgrx, &package_manifest, me.pg_version, None, false)?;
Expand All @@ -49,8 +49,13 @@ impl CommandExecute for Stop {
}

let pgrx = Pgrx::from_config()?;
let (package_manifest, _) = get_package_manifest(
&clap_cargo::Features::default(),
self.package.as_ref(),
self.manifest_path.clone(),
)?;
if self.pg_version == Some("all".into()) {
for v in pgrx.iter(PgConfigSelector::All) {
for v in crate::manifest::all_pg_in_both_tomls(&package_manifest, &pgrx) {
let mut versioned_start = self.clone();
versioned_start.pg_version = Some(v?.label()?);
perform(versioned_start, &pgrx)?;
Expand Down
9 changes: 7 additions & 2 deletions cargo-pgrx/src/command/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
//LICENSE
//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
use eyre::Context;
use pgrx_pg_config::{get_target_dir, PgConfig, PgConfigSelector, Pgrx};
use pgrx_pg_config::{get_target_dir, PgConfig, Pgrx};
use std::path::{Path, PathBuf};
use std::process::Stdio;

Expand Down Expand Up @@ -80,10 +80,15 @@ impl CommandExecute for Test {
Ok(())
}

let (package_manifest, _) = get_package_manifest(
&self.features,
self.package.as_ref(),
self.manifest_path.as_ref(),
)?;
let pgrx = Pgrx::from_config()?;
if self.pg_version == Some("all".to_string()) {
// run the tests for **all** the Postgres versions we know about
for v in pgrx.iter(PgConfigSelector::All) {
for v in crate::manifest::all_pg_in_both_tomls(&package_manifest, &pgrx) {
let mut versioned_test = self.clone();
versioned_test.pg_version = Some(v?.label()?);
perform(versioned_test, &pgrx)?;
Expand Down
23 changes: 22 additions & 1 deletion cargo-pgrx/src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use cargo_metadata::Metadata;
use cargo_toml::Manifest;
use clap_cargo::Features;
use eyre::{eyre, Context};
use pgrx_pg_config::{PgConfig, Pgrx};
use pgrx_pg_config::{PgConfig, PgConfigSelector, Pgrx};
use std::path::PathBuf;

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -210,3 +210,24 @@ pub(crate) fn get_package_manifest(
package_manifest_path,
))
}

pub(crate) fn all_pg_in_both_tomls<'a>(
manifest: &'a Manifest,
pgrx: &Pgrx,
) -> impl Iterator<Item = eyre::Result<PgConfig>> + 'a {
// Maybe eventually warn when the Cargo.toml has a version our config.toml doesn't,
// as it makes sense to further constrain support from the version set pgrx supports,
// but it doesn't make sense to e.g. not run tests when admin thought it was requested?
pgrx.iter(PgConfigSelector::All).filter(|result| match result {
Ok(pg_config) => {
if let Ok(ver) = pg_config.major_version() {
// Clumsy: we rely on these features enabling `pgrx/pg{ver}` instead of verifying.
manifest.features.contains_key(&format!("pg{ver}"))
} else {
false // Nonsensical to have no major version for a pg_config?
}
}
// Pass errors along
_ => true,
})
}
1 change: 1 addition & 0 deletions pgrx-pg-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ fn main() -> eyre::Result<()> {
emit_rerun_if_changed();

let pg_configs: Vec<(u16, PgConfig)> = if is_for_release {
// This does not cross-check config.toml and Cargo.toml versions, as it is release infra.
Pgrx::from_config()?.iter(PgConfigSelector::All)
.map(|r| r.expect("invalid pg_config"))
.map(|c| (c.major_version().expect("invalid major version"), c))
Expand Down