@@ -101,7 +101,7 @@ Possible valid values are:
101101
102102Use \" stackablectl operator list\" to list available versions for all operators
103103Use \" stackablectl operator describe <OPERATOR>\" to get available versions for one operator" ) ]
104- operators : Vec < operator :: OperatorSpec > ,
104+ operators : Vec < coffee :: OperatorOrCoffee > ,
105105
106106 /// Namespace in the cluster used to deploy the operators
107107 #[ arg( long, default_value = DEFAULT_OPERATOR_NAMESPACE , visible_aliases( [ "operator-ns" ] ) ) ]
@@ -332,6 +332,24 @@ async fn install_cmd(
332332 info ! ( "Installing operator(s)" ) ;
333333 Span :: current ( ) . pb_set_message ( "Installing operator(s)" ) ;
334334
335+ let operators: Vec < & operator:: OperatorSpec > = args
336+ . operators
337+ . iter ( )
338+ . filter_map ( |operator| match operator {
339+ coffee:: OperatorOrCoffee :: Coffee => {
340+ indicatif_println ! ( "{}" , coffee:: COFFEE_ASCII_ART ) ;
341+ None
342+ }
343+ coffee:: OperatorOrCoffee :: Operator ( spec) => Some ( spec) ,
344+ } )
345+ . collect ( ) ;
346+
347+ // In case no operators need to be installed (e.g. coffee was already installed), there is no
348+ // need to connect to Kubernetes and potentially produce error messages.
349+ if operators. is_empty ( ) {
350+ return Ok ( String :: new ( ) ) ;
351+ }
352+
335353 args. local_cluster
336354 . install_if_needed ( )
337355 . await
@@ -350,7 +368,7 @@ async fn install_cmd(
350368 . await
351369 . context ( LoadOperatorValuesSnafu ) ?;
352370
353- for operator in & args . operators {
371+ for operator in & operators {
354372 let operator_helm_values = values_for_operator ( & operator_values, & operator. name ) ;
355373
356374 operator
@@ -374,8 +392,8 @@ async fn install_cmd(
374392 )
375393 . with_output ( format ! (
376394 "Installed {num_of_operators} {suffix}" ,
377- num_of_operators = args . operators. len( ) ,
378- suffix = if args . operators. len( ) == 1 {
395+ num_of_operators = operators. len( ) ,
396+ suffix = if operators. len( ) == 1 {
379397 "operator"
380398 } else {
381399 "operators"
@@ -622,3 +640,36 @@ where
622640 None => Ok ( vec ! [ ] ) ,
623641 }
624642}
643+
644+ mod coffee {
645+ use std:: str:: FromStr ;
646+
647+ pub const COFFEE_ASCII_ART : & str = r#"
648+ ) )
649+ ( (
650+ .------.
651+ | |]
652+ \ /
653+ `----'
654+
655+ Psst... "coffee" is not an operator, but we get it.
656+ Stackable runs on coffee too. Have a great day! ☕
657+ "# ;
658+
659+ #[ derive( Clone , Debug ) ]
660+ pub enum OperatorOrCoffee {
661+ Operator ( super :: operator:: OperatorSpec ) ,
662+ Coffee ,
663+ }
664+
665+ impl FromStr for OperatorOrCoffee {
666+ type Err = super :: operator:: SpecParseError ;
667+
668+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
669+ match s {
670+ "coffee" | "coffe" => Ok ( OperatorOrCoffee :: Coffee ) ,
671+ _ => s. parse ( ) . map ( OperatorOrCoffee :: Operator ) ,
672+ }
673+ }
674+ }
675+ }
0 commit comments