1
1
use super :: {
2
2
schema, ComponentKey , DataType , OutputId , SinkOuter , SourceOuter , SourceOutput , TransformOuter ,
3
- TransformOutput ,
3
+ TransformOutput , WildcardMatching ,
4
4
} ;
5
5
use indexmap:: { set:: IndexSet , IndexMap } ;
6
6
use std:: collections:: { HashMap , HashSet , VecDeque } ;
@@ -65,17 +65,20 @@ impl Graph {
65
65
transforms : & IndexMap < ComponentKey , TransformOuter < String > > ,
66
66
sinks : & IndexMap < ComponentKey , SinkOuter < String > > ,
67
67
schema : schema:: Options ,
68
+ wildcard_matching : WildcardMatching ,
68
69
) -> Result < Self , Vec < String > > {
69
- Self :: new_inner ( sources, transforms, sinks, false , schema)
70
+ Self :: new_inner ( sources, transforms, sinks, false , schema, wildcard_matching )
70
71
}
71
72
72
73
pub fn new_unchecked (
73
74
sources : & IndexMap < ComponentKey , SourceOuter > ,
74
75
transforms : & IndexMap < ComponentKey , TransformOuter < String > > ,
75
76
sinks : & IndexMap < ComponentKey , SinkOuter < String > > ,
76
77
schema : schema:: Options ,
78
+ wildcard_matching : WildcardMatching ,
77
79
) -> Self {
78
- Self :: new_inner ( sources, transforms, sinks, true , schema) . expect ( "errors ignored" )
80
+ Self :: new_inner ( sources, transforms, sinks, true , schema, wildcard_matching)
81
+ . expect ( "errors ignored" )
79
82
}
80
83
81
84
fn new_inner (
@@ -84,6 +87,7 @@ impl Graph {
84
87
sinks : & IndexMap < ComponentKey , SinkOuter < String > > ,
85
88
ignore_errors : bool ,
86
89
schema : schema:: Options ,
90
+ wildcard_matching : WildcardMatching ,
87
91
) -> Result < Self , Vec < String > > {
88
92
let mut graph = Graph :: default ( ) ;
89
93
let mut errors = Vec :: new ( ) ;
@@ -127,15 +131,15 @@ impl Graph {
127
131
128
132
for ( id, config) in transforms. iter ( ) {
129
133
for input in config. inputs . iter ( ) {
130
- if let Err ( e) = graph. add_input ( input, id, & available_inputs) {
134
+ if let Err ( e) = graph. add_input ( input, id, & available_inputs, wildcard_matching ) {
131
135
errors. push ( e) ;
132
136
}
133
137
}
134
138
}
135
139
136
140
for ( id, config) in sinks {
137
141
for input in config. inputs . iter ( ) {
138
- if let Err ( e) = graph. add_input ( input, id, & available_inputs) {
142
+ if let Err ( e) = graph. add_input ( input, id, & available_inputs, wildcard_matching ) {
139
143
errors. push ( e) ;
140
144
}
141
145
}
@@ -153,6 +157,7 @@ impl Graph {
153
157
from : & str ,
154
158
to : & ComponentKey ,
155
159
available_inputs : & HashMap < String , OutputId > ,
160
+ wildcard_matching : WildcardMatching ,
156
161
) -> Result < ( ) , String > {
157
162
if let Some ( output_id) = available_inputs. get ( from) {
158
163
self . edges . push ( Edge {
@@ -166,6 +171,18 @@ impl Graph {
166
171
Some ( Node :: Sink { .. } ) => "sink" ,
167
172
_ => panic ! ( "only transforms and sinks have inputs" ) ,
168
173
} ;
174
+ // allow empty result if relaxed wildcard matching is enabled
175
+ match wildcard_matching {
176
+ WildcardMatching :: Relaxed => {
177
+ // using value != glob::Pattern::escape(value) to check if value is a glob
178
+ // TODO: replace with proper check when https://github.com/rust-lang/glob/issues/72 is resolved
179
+ if from != glob:: Pattern :: escape ( from) {
180
+ info ! ( "Input \" {from}\" for {output_type} \" {to}\" didn’t match any components, but this was ignored because `relaxed_wildcard_matching` is enabled." ) ;
181
+ return Ok ( ( ) ) ;
182
+ }
183
+ }
184
+ WildcardMatching :: Strict => { }
185
+ }
169
186
info ! (
170
187
"Available components:\n {}" ,
171
188
self . nodes
@@ -472,9 +489,14 @@ mod test {
472
489
}
473
490
}
474
491
475
- fn test_add_input ( & mut self , node : & str , input : & str ) -> Result < ( ) , String > {
492
+ fn test_add_input (
493
+ & mut self ,
494
+ node : & str ,
495
+ input : & str ,
496
+ wildcard_matching : WildcardMatching ,
497
+ ) -> Result < ( ) , String > {
476
498
let available_inputs = self . input_map ( ) . unwrap ( ) ;
477
- self . add_input ( input, & node. into ( ) , & available_inputs)
499
+ self . add_input ( input, & node. into ( ) , & available_inputs, wildcard_matching )
478
500
}
479
501
}
480
502
@@ -655,14 +677,22 @@ mod test {
655
677
// make sure we're good with dotted paths
656
678
assert_eq ! (
657
679
Ok ( ( ) ) ,
658
- graph. test_add_input( "errored_log_sink" , "log_to_log.errors" )
680
+ graph. test_add_input(
681
+ "errored_log_sink" ,
682
+ "log_to_log.errors" ,
683
+ WildcardMatching :: Strict
684
+ )
659
685
) ;
660
686
661
687
// make sure that we're not cool with an unknown dotted path
662
688
let expected = "Input \" log_to_log.not_errors\" for sink \" bad_log_sink\" doesn't match any components." . to_string ( ) ;
663
689
assert_eq ! (
664
690
Err ( expected) ,
665
- graph. test_add_input( "bad_log_sink" , "log_to_log.not_errors" )
691
+ graph. test_add_input(
692
+ "bad_log_sink" ,
693
+ "log_to_log.not_errors" ,
694
+ WildcardMatching :: Strict
695
+ )
666
696
) ;
667
697
}
668
698
@@ -745,6 +775,40 @@ mod test {
745
775
) ;
746
776
}
747
777
778
+ #[ test]
779
+ fn wildcard_matching ( ) {
780
+ let mut graph = Graph :: default ( ) ;
781
+ graph. add_source ( "log_source" , DataType :: Log ) ;
782
+
783
+ // don't add inputs to these yet since they're not validated via these helpers
784
+ graph. add_sink ( "sink" , DataType :: Log , vec ! [ ] ) ;
785
+
786
+ // make sure we're not good with non existing inputs with relaxed wildcard matching disabled
787
+ let wildcard_matching = WildcardMatching :: Strict ;
788
+ let expected =
789
+ "Input \" bad_source-*\" for sink \" sink\" doesn't match any components." . to_string ( ) ;
790
+ assert_eq ! (
791
+ Err ( expected) ,
792
+ graph. test_add_input( "sink" , "bad_source-*" , wildcard_matching)
793
+ ) ;
794
+
795
+ // make sure we're good with non existing inputs with relaxed wildcard matching enabled
796
+ let wildcard_matching = WildcardMatching :: Relaxed ;
797
+ assert_eq ! (
798
+ Ok ( ( ) ) ,
799
+ graph. test_add_input( "sink" , "bad_source-*" , wildcard_matching)
800
+ ) ;
801
+
802
+ // make sure we're not good with non existing inputs that are not wildcards even when relaxed wildcard matching is enabled
803
+ let wildcard_matching = WildcardMatching :: Relaxed ;
804
+ let expected =
805
+ "Input \" bad_source-1\" for sink \" sink\" doesn't match any components." . to_string ( ) ;
806
+ assert_eq ! (
807
+ Err ( expected) ,
808
+ graph. test_add_input( "sink" , "bad_source-1" , wildcard_matching)
809
+ ) ;
810
+ }
811
+
748
812
#[ test]
749
813
fn paths_to_sink_simple ( ) {
750
814
let mut graph = Graph :: default ( ) ;
0 commit comments