Skip to content

Commit

Permalink
fixup! Trigger tedge multicall with symlinks as well as sub-commands
Browse files Browse the repository at this point in the history
  • Loading branch information
didier-wenzek committed Jan 6, 2025
1 parent 9b65b83 commit b735319
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 30 deletions.
70 changes: 58 additions & 12 deletions crates/core/tedge/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use clap::CommandFactory;
use clap::FromArgMatches;
use clap::Parser;
use std::alloc;
use std::ffi::OsString;
use std::future::Future;
use std::io::IsTerminal;
use std::path::PathBuf;
Expand All @@ -35,7 +36,7 @@ fn main() -> anyhow::Result<()> {
tedge_apt_plugin::run_and_exit(try_opt);
}

let opt = parse_multicall_if_known(&executable_name);
let opt = parse_multicall(&executable_name, std::env::args_os());
match opt {
TEdgeOptMulticall::Component(Component::TedgeMapper(opt)) => {
let tedge_config = tedge_config::TEdgeConfig::load(&opt.common.config_dir)?;
Expand Down Expand Up @@ -124,7 +125,11 @@ fn executable_name() -> Option<String> {
)
}

fn parse_multicall_if_known(executable_name: &Option<String>) -> TEdgeOptMulticall {
fn parse_multicall<Arg, Args>(executable_name: &Option<String>, args: Args) -> TEdgeOptMulticall
where
Args: IntoIterator<Item = Arg>,
Arg: Into<OsString> + Clone,
{
let cmd = TEdgeOptMulticall::command();

let is_known_subcommand = executable_name
Expand All @@ -133,7 +138,7 @@ fn parse_multicall_if_known(executable_name: &Option<String>) -> TEdgeOptMultica
let cmd = cmd.multicall(is_known_subcommand);

let cmd2 = cmd.clone();
match TEdgeOptMulticall::from_arg_matches(&cmd.get_matches()) {
match TEdgeOptMulticall::from_arg_matches(&cmd.get_matches_from(args)) {
Ok(TEdgeOptMulticall::Tedge { cmd, common }) => redirect_if_multicall(cmd, common),
Ok(t) => t,
Err(e) => {
Expand All @@ -148,15 +153,56 @@ fn parse_multicall_if_known(executable_name: &Option<String>) -> TEdgeOptMultica
// This method has to be kept in sync with TEdgeOpt::build_command
fn redirect_if_multicall(cmd: TEdgeOpt, common: CommonArgs) -> TEdgeOptMulticall {
match cmd {
TEdgeOpt::Mapper(opt) => {
TEdgeOptMulticall::Component(Component::TedgeMapper(opt.with_common_args(common)))
}
TEdgeOpt::Agent(opt) => {
TEdgeOptMulticall::Component(Component::TedgeAgent(opt.with_common_args(common)))
}
TEdgeOpt::Write(opt) => {
TEdgeOptMulticall::Component(Component::TedgeWrite(opt.with_common_args(common)))
}
TEdgeOpt::Mapper(opt) => TEdgeOptMulticall::Component(Component::TedgeMapper(opt)),
TEdgeOpt::Agent(opt) => TEdgeOptMulticall::Component(Component::TedgeAgent(opt)),
TEdgeOpt::Write(opt) => TEdgeOptMulticall::Component(Component::TedgeWrite(opt)),
cmd => TEdgeOptMulticall::Tedge { cmd, common },
}
}

#[cfg(test)]
mod tests {
use crate::parse_multicall;
use crate::Component;
use crate::TEdgeOptMulticall;
use test_case::test_case;

#[test]
fn launching_a_mapper() {
let exec = Some("tedge-mapper".to_string());
let cmd = parse_multicall(&exec, ["tedge-mapper", "c8y"]);
assert!(matches!(
cmd,
TEdgeOptMulticall::Component(Component::TedgeMapper(_))
))
}

#[test]
fn using_tedge_to_launch_a_mapper() {
let exec = Some("tedge".to_string());
let cmd = parse_multicall(&exec, ["tedge", "mapper", "c8y"]);
assert!(matches!(
cmd,
TEdgeOptMulticall::Component(Component::TedgeMapper(_))
))
}

#[test_case("tedge-mapper c8y --config-dir /some/dir")]
#[test_case("tedge-mapper --config-dir /some/dir c8y")]
#[test_case("tedge mapper c8y --config-dir /some/dir --debug")]
#[test_case("tedge mapper --config-dir /some/dir c8y --debug")]
#[test_case("tedge --config-dir /some/dir mapper c8y")]
// clap fails to raise an error here and takes the inner value for all global args
#[test_case("tedge --config-dir /oops mapper c8y --config-dir /some/dir")]
fn setting_config_dir(cmd_line: &'static str) {
let args: Vec<&str> = cmd_line.split(' ').collect();
let exec = Some(args.get(0).unwrap().to_string());
let cmd = parse_multicall(&exec, args);
match cmd {
TEdgeOptMulticall::Component(Component::TedgeMapper(mapper)) => {
assert_eq!(mapper.common.config_dir, "/some/dir")
}
_ => panic!(),
}
}
}
6 changes: 0 additions & 6 deletions crates/core/tedge_agent/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ pub struct AgentOpt {
pub mqtt_topic_root: Option<Arc<str>>,
}

impl AgentOpt {
pub fn with_common_args(self, common: CommonArgs) -> Self {
Self { common, ..self }
}
}

pub async fn run(agent_opt: AgentOpt) -> Result<(), anyhow::Error> {
let tedge_config_location =
tedge_config::TEdgeConfigLocation::from_custom_root(agent_opt.common.config_dir.clone());
Expand Down
6 changes: 0 additions & 6 deletions crates/core/tedge_mapper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,6 @@ impl fmt::Display for MapperName {
}
}

impl MapperOpt {
pub fn with_common_args(self, common: CommonArgs) -> Self {
Self { common, ..self }
}
}

pub async fn run(mapper_opt: MapperOpt) -> anyhow::Result<()> {
let mapper_name = mapper_opt.name.to_string();
let component = lookup_component(mapper_opt.name);
Expand Down
6 changes: 0 additions & 6 deletions crates/core/tedge_write/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,6 @@ pub struct Args {
common: CommonArgs,
}

impl Args {
pub fn with_common_args(self, common: CommonArgs) -> Self {
Self { common, ..self }
}
}

pub fn run(args: Args) -> anyhow::Result<()> {
log_init(
"tedge-write",
Expand Down

0 comments on commit b735319

Please sign in to comment.