-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add simplistic command-line interface and unit tests
- Loading branch information
Showing
3 changed files
with
132 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
pub mod error; | ||
pub mod operating_system; | ||
pub mod package_type; | ||
|
||
use std::str::FromStr; | ||
use std::sync::LazyLock; | ||
|
||
use operating_system::OperatingSystem; | ||
use purl::GenericPurl; | ||
|
||
use crate::error::{Error, Result}; | ||
use crate::package_type::{Cargo, Generic, PackageType, Pgxn, Postgres}; | ||
|
||
static SUPPORTED_PACKAGE_TYPES: LazyLock<Vec<Box<dyn PackageType>>> = LazyLock::new(|| { | ||
vec![ | ||
Box::new(Pgxn), | ||
Box::new(Generic), | ||
Box::new(Cargo), | ||
Box::new(Postgres), | ||
] | ||
}); | ||
|
||
/// Given a PURL, return the installation command to install the given package. | ||
pub async fn resolve_package(purl: &str, os: OperatingSystem) -> Result<String> { | ||
let purl = GenericPurl::<String>::from_str(purl)?; | ||
|
||
let package_type = SUPPORTED_PACKAGE_TYPES | ||
.iter() | ||
.find(|supported_package_type| supported_package_type.name() == purl.package_type()) | ||
.ok_or_else(|| Error::UnknownPackage(purl.package_type().to_string()))?; | ||
|
||
package_type | ||
.resolve_package_for_operating_system(purl.name(), os) | ||
.await | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use crate::{operating_system::OperatingSystem, resolve_package}; | ||
|
||
#[tokio::test] | ||
async fn resolves_generic_packages() { | ||
assert_eq!( | ||
resolve_package("pkg:generic/ripgrep", OperatingSystem::Debian) | ||
.await | ||
.unwrap(), | ||
"sudo apt-get install -y rust-ripgrep" | ||
); | ||
|
||
assert_eq!( | ||
resolve_package("pkg:generic/ripgrep", OperatingSystem::RedHat) | ||
.await | ||
.unwrap(), | ||
"sudo dnf install -y rust-ripgrep" | ||
); | ||
|
||
assert_eq!( | ||
resolve_package("pkg:generic/ripgrep", OperatingSystem::Mac) | ||
.await | ||
.unwrap(), | ||
"brew install ripgrep" | ||
); | ||
} | ||
|
||
#[tokio::test] | ||
async fn resolves_other_packages() { | ||
assert_eq!( | ||
resolve_package("pkg:cargo/cargo-pgrx", OperatingSystem::Debian) | ||
.await | ||
.unwrap(), | ||
"cargo install cargo-pgrx" | ||
); | ||
|
||
assert_eq!( | ||
resolve_package("pkg:pgxn/pgtap", OperatingSystem::Debian) | ||
.await | ||
.unwrap(), | ||
"pgxn install pgtap" | ||
); | ||
|
||
assert_eq!( | ||
resolve_package("pkg:pgxn/temporal-tables", OperatingSystem::Debian) | ||
.await | ||
.unwrap(), | ||
"pgxn install temporal-tables" | ||
); | ||
|
||
assert_eq!( | ||
resolve_package("pkg:postgres/plpgsql", OperatingSystem::Debian) | ||
.await | ||
.unwrap(), | ||
"pgxn install plpgsql" | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,31 @@ | ||
pub mod error; | ||
pub mod operating_system; | ||
pub mod package_type; | ||
use pgxn_deps::{error::Result, operating_system::OperatingSystem, resolve_package}; | ||
|
||
use std::{str::FromStr, sync::LazyLock}; | ||
use argh::FromArgs; | ||
|
||
use package_type::{Cargo, Generic, PackageType, Pgxn, Postgres}; | ||
use purl::GenericPurl; | ||
#[derive(FromArgs)] | ||
/// Obtain the installation command for a given purl package, according to PGXNv2 specs | ||
struct Command { | ||
/// operating system to install the package on | ||
#[argh(option)] | ||
os: Option<OperatingSystem>, | ||
|
||
use crate::error::{Error, Result}; | ||
|
||
static SUPPORTED_PACKAGE_TYPES: LazyLock<Vec<Box<dyn PackageType>>> = LazyLock::new(|| { | ||
vec![ | ||
Box::new(Pgxn), | ||
Box::new(Generic), | ||
Box::new(Cargo), | ||
Box::new(Postgres), | ||
] | ||
}); | ||
|
||
/// Given a PURL, return the installation command to install the given package. | ||
pub async fn resolve_package(purl: &str) -> Result<String> { | ||
let purl = GenericPurl::<String>::from_str(purl)?; | ||
|
||
let package_type = SUPPORTED_PACKAGE_TYPES | ||
.iter() | ||
.find(|supported_package_type| supported_package_type.name() == purl.package_type()) | ||
.ok_or_else(|| Error::UnknownPackage(purl.package_type().to_string()))?; | ||
|
||
package_type.resolve_package(purl.name()).await | ||
/// a purl string | ||
#[argh(positional)] | ||
purl: String, | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<()> { | ||
resolve_package("pkg:cargo/cargo-pgrx").await?; | ||
resolve_package("pkg:postgres/plpgsql").await?; | ||
resolve_package("pkg:pgxn/pgtap").await?; | ||
resolve_package("pkg:generic/curl").await?; | ||
let command: Command = argh::from_env(); | ||
|
||
let operating_system = match command.os { | ||
Some(os) => os, | ||
None => OperatingSystem::detect()?, | ||
}; | ||
|
||
let installation_command = resolve_package(&command.purl, operating_system).await?; | ||
|
||
println!("{installation_command}"); | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters