Skip to content

Commit

Permalink
Merge pull request #406 from boinkor-net/tests
Browse files Browse the repository at this point in the history
Add tests for the destination URL
  • Loading branch information
antifuchs authored Dec 6, 2024
2 parents 61292b4 + 3dbc74b commit a7b7338
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 43 deletions.
34 changes: 34 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,6 @@ version = "1.40.0"
[metadata.template_ci.clippy]
allow_failure = false
version = "stable"

[dev-dependencies]
test-case = "3.3.1"
57 changes: 57 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use std::{
sync::Arc,
};
use tokio::process::Command;
use url::Url;

/// The tracing target that's used to log messages emitted by
/// subprocesses.
Expand Down Expand Up @@ -225,3 +226,59 @@ impl Flavor {
}
}
}

#[derive(Debug, Clone)]
pub struct Destination {
pub os_flavor: Flavor,
pub hostname: String,
pub config_name: Option<String>,
}

impl FromStr for Destination {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(url) = Url::parse(s) {
// we have a URL, let's see if it matches something we can deal with:
match (url.scheme(), url.host_str(), url.path(), url.username()) {
("nixos", Some(host), path, username) => {
let hostname = if username.is_empty() {
host.to_string()
} else {
format!("{username}@{host}")
};
Ok(Destination {
os_flavor: Flavor::Nixos,
hostname,
config_name: path
.strip_prefix('/')
.filter(|path| !path.is_empty())
.map(String::from),
})
}
_ => anyhow::bail!("Unable to parse {s}"),
}
} else {
Ok(Destination {
os_flavor: Flavor::Nixos,
hostname: s.to_string(),
config_name: None,
})
}
}
}

#[cfg(test)]
mod test {
use super::Destination;
use test_case::test_case;

#[test_case("nixos://foo", true ; "when both operands are negative")]
#[test_case("fleepybeepo://foo", false ; "invalid flavor")]
#[test_case("nixos:///foo", false ; "invalid hostname")]
#[test_case("nixos://foobar@foo", true ; "with a username")]
#[test_case("nixos://foobar@foo/configname", true ; "with a config name")]
fn destination_parsing(input: &str, parses: bool) {
assert_eq!(input.parse::<Destination>().is_ok(), parses);
}
}
44 changes: 1 addition & 43 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,11 @@ use tracing::instrument;

use anyhow::Context;
use clap::Parser;
use deploy_flake::{Flake, Flavor};
use deploy_flake::{Destination, Flake};
use openssh::{KnownHosts, Session};
use std::{path::PathBuf, str::FromStr};
use tracing_subscriber::prelude::*;
use tracing_subscriber::EnvFilter;
use url::Url;

#[derive(Debug, Clone)]
struct Destination {
os_flavor: Flavor,
hostname: String,
config_name: Option<String>,
}

impl FromStr for Destination {
type Err = anyhow::Error;

fn from_str(s: &str) -> Result<Self, Self::Err> {
if let Ok(url) = Url::parse(s) {
// we have a URL, let's see if it matches something we can deal with:
match (url.scheme(), url.host_str(), url.path(), url.username()) {
("nixos", Some(host), path, username) => {
let hostname = if username.is_empty() {
host.to_string()
} else {
format!("{username}@{host}")
};
Ok(Destination {
os_flavor: Flavor::Nixos,
hostname,
config_name: path
.strip_prefix('/')
.filter(|path| !path.is_empty())
.map(String::from),
})
}
_ => anyhow::bail!("Unable to parse {s}"),
}
} else {
Ok(Destination {
os_flavor: Flavor::Nixos,
hostname: s.to_string(),
config_name: None,
})
}
}
}

#[derive(clap::ValueEnum, Clone, Copy, Debug, Eq, PartialEq)]
enum Behavior {
Expand Down

0 comments on commit a7b7338

Please sign in to comment.