@@ -25,15 +25,16 @@ pub struct Action {
2525 #[ input( description = "GitHub Token" ) ]
2626 token : String ,
2727
28- /// GitHub Repository where the extractor is located
28+ /// GitHub Repositories where the extractors are located
2929 #[ input(
30- description = "GitHub Repository where the extractor is located" ,
31- required = true
30+ description = "GitHub Repositories where the extractors are located" ,
31+ required = true ,
32+ split = ","
3233 ) ]
33- extractor : String ,
34+ extractor : Vec < String > ,
3435
35- /// Language(d) to use
36- #[ input( description = "Language(s) to use" , split = "," , required = true ) ]
36+ /// Language(d) to use, e.g. `iac`, `javascript`, `python`, etc.
37+ #[ input( description = "Language(s) to use" , split = "," ) ]
3738 language : Vec < String > ,
3839
3940 /// Attestation
@@ -49,19 +50,22 @@ pub struct Action {
4950}
5051
5152impl Action {
52- /// Gets the repository to use for the extractor . If the repository is not provided,
53+ /// Gets the repositories to use for the extractors . If no repositories are provided,
5354 /// it will use the repository that the action is running in.
54- pub fn extractor_repository ( & self ) -> Result < Repository > {
55- let repo = if self . extractor . is_empty ( ) {
56- log:: debug!( "No extractor repository provided, using the current repository" ) ;
57- self . get_repository ( ) ?
58- } else {
59- log:: debug!( "Using the provided extractor repository" ) ;
60- self . extractor . clone ( )
61- } ;
62- log:: info!( "Extractor Repository :: {}" , repo) ;
63-
64- Ok ( Repository :: parse ( & repo) ?)
55+ pub fn extractor_repositories ( & self ) -> Result < Vec < Repository > > {
56+ let mut repositories = Vec :: new ( ) ;
57+ for extractor in & self . extractor {
58+ let repo = if extractor. is_empty ( ) {
59+ log:: debug!( "No extractor repository provided, using the current repository" ) ;
60+ self . get_repository ( ) ?
61+ } else {
62+ log:: debug!( "Using the provided extractor repository" ) ;
63+ extractor. clone ( )
64+ } ;
65+ log:: info!( "Extractor Repository :: {}" , repo) ;
66+ repositories. push ( Repository :: parse ( & repo) ?) ;
67+ }
68+ Ok ( repositories)
6569 }
6670
6771 pub fn languages ( & self ) -> Vec < CodeQLLanguage > {
@@ -107,12 +111,63 @@ mod tests {
107111
108112 fn action ( ) -> Action {
109113 Action {
110- extractor : "owner/repo" . to_string ( ) ,
114+ extractor : vec ! [ "owner/repo1" . to_string( ) , "owner/repo2" . to_string( ) ] ,
115+ language : vec ! [ "iac" . to_string( ) ] ,
116+ ..Default :: default ( )
117+ }
118+ }
119+
120+ fn action_with_extractors ( extractors : Vec < String > ) -> Action {
121+ Action {
122+ extractor : extractors,
111123 language : vec ! [ "iac" . to_string( ) ] ,
112124 ..Default :: default ( )
113125 }
114126 }
115127
128+ #[ test]
129+ fn test_extractor_repositories ( ) {
130+ let action = action ( ) ;
131+ let repositories = action. extractor_repositories ( ) . unwrap ( ) ;
132+ assert_eq ! ( repositories. len( ) , 2 ) ;
133+ assert_eq ! ( repositories[ 0 ] . to_string( ) , "owner/repo1" ) ;
134+ assert_eq ! ( repositories[ 1 ] . to_string( ) , "owner/repo2" ) ;
135+ }
136+
137+ #[ test]
138+ fn test_extractor_repositories_multiple ( ) {
139+ let action = action_with_extractors ( vec ! [
140+ "owner/repo1" . to_string( ) ,
141+ "owner/repo2" . to_string( ) ,
142+ ] ) ;
143+ let repositories = action. extractor_repositories ( ) . unwrap ( ) ;
144+ assert_eq ! ( repositories. len( ) , 2 ) ;
145+ assert_eq ! ( repositories[ 0 ] . to_string( ) , "owner/repo1" ) ;
146+ assert_eq ! ( repositories[ 1 ] . to_string( ) , "owner/repo2" ) ;
147+ }
148+
149+ #[ test]
150+ fn test_extractor_repositories_single ( ) {
151+ let action = action_with_extractors ( vec ! [ "owner/repo1" . to_string( ) ] ) ;
152+ let repositories = action. extractor_repositories ( ) . unwrap ( ) ;
153+ assert_eq ! ( repositories. len( ) , 1 ) ;
154+ assert_eq ! ( repositories[ 0 ] . to_string( ) , "owner/repo1" ) ;
155+ }
156+
157+ #[ test]
158+ fn test_extractor_repositories_empty ( ) {
159+ let action = action_with_extractors ( vec ! [ ] ) ;
160+ let result = action. extractor_repositories ( ) ;
161+ assert ! ( result. is_err( ) , "Expected error for empty extractor list" ) ;
162+ }
163+
164+ #[ test]
165+ fn test_extractor_repositories_invalid_format ( ) {
166+ let action = action_with_extractors ( vec ! [ "invalid_repo_format" . to_string( ) ] ) ;
167+ let result = action. extractor_repositories ( ) ;
168+ assert ! ( result. is_err( ) , "Expected error for invalid repository format" ) ;
169+ }
170+
116171 #[ test]
117172 fn test_validate_languages ( ) {
118173 let action = action ( ) ;
0 commit comments