-
Notifications
You must be signed in to change notification settings - Fork 263
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2266 from itowlson/trigger-metadata-protocol
Multi-trigger: ask triggers which flags they can accept
- Loading branch information
Showing
4 changed files
with
251 additions
and
70 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
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
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,86 @@ | ||
use clap::{Args, CommandFactory}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::ffi::OsString; | ||
|
||
use crate::{cli::TriggerExecutorCommand, TriggerExecutor}; | ||
|
||
/// Contains information about the trigger flags (and potentially | ||
/// in future configuration) that a consumer (such as `spin up`) | ||
/// can query using `--launch-metadata-only`. | ||
#[derive(Clone, Debug, Deserialize, Serialize)] | ||
pub struct LaunchMetadata { | ||
all_flags: Vec<LaunchFlag>, | ||
} | ||
|
||
// This assumes no triggers that want to participate in multi-trigger | ||
// use positional arguments. This is a restriction we'll have to make | ||
// anyway: suppose triggers A and B both take one positional arg, and | ||
// the user writes `spin up 123 456` - which value would go to which trigger? | ||
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] | ||
struct LaunchFlag { | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
#[serde(default)] | ||
short: Option<String>, | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
#[serde(default)] | ||
long: Option<String>, | ||
} | ||
|
||
impl LaunchMetadata { | ||
pub fn infer<Executor: TriggerExecutor>() -> Self | ||
where | ||
Executor::RunConfig: Args, | ||
{ | ||
let all_flags: Vec<_> = TriggerExecutorCommand::<Executor>::command() | ||
.get_arguments() | ||
.map(LaunchFlag::infer) | ||
.collect(); | ||
|
||
LaunchMetadata { all_flags } | ||
} | ||
|
||
pub fn matches<'a>(&self, groups: &[Vec<&'a OsString>]) -> Vec<&'a OsString> { | ||
let mut matches = vec![]; | ||
|
||
for group in groups { | ||
if group.is_empty() { | ||
continue; | ||
} | ||
if self.is_match(group[0]) { | ||
matches.extend(group); | ||
} | ||
} | ||
|
||
matches | ||
} | ||
|
||
fn is_match(&self, arg: &OsString) -> bool { | ||
self.all_flags.iter().any(|f| f.is_match(arg)) | ||
} | ||
|
||
pub fn is_group_match(&self, group: &[&OsString]) -> bool { | ||
if group.is_empty() { | ||
false | ||
} else { | ||
self.all_flags.iter().any(|f| f.is_match(group[0])) | ||
} | ||
} | ||
} | ||
|
||
impl LaunchFlag { | ||
fn infer(arg: &clap::Arg) -> Self { | ||
Self { | ||
long: arg.get_long().map(|s| format!("--{s}")), | ||
short: arg.get_short().map(|ch| format!("-{ch}")), | ||
} | ||
} | ||
|
||
fn is_match(&self, candidate: &OsString) -> bool { | ||
let Some(s) = candidate.to_str() else { | ||
return false; | ||
}; | ||
let candidate = Some(s.to_owned()); | ||
|
||
candidate == self.long || candidate == self.short | ||
} | ||
} |
Oops, something went wrong.