10
10
import com .sap .oss .phosphor .fosstars .model .feature .oss .OssFeatures ;
11
11
import com .sap .oss .phosphor .fosstars .model .subject .oss .GitHubProject ;
12
12
import com .sap .oss .phosphor .fosstars .model .value .ValueHashSet ;
13
- import com .sap .oss .phosphor .fosstars .util .Yaml ;
14
13
import java .io .IOException ;
15
- import java .io .InputStream ;
16
- import java .nio .file .Files ;
17
- import java .nio .file .Path ;
14
+ import java .util .Collections ;
15
+ import java .util .HashMap ;
18
16
import java .util .Map ;
19
- import java .util .Optional ;
17
+ import java .util .function . Predicate ;
20
18
import java .util .regex .Pattern ;
21
- import org .apache .commons .collections4 .IteratorUtils ;
22
19
23
20
/**
24
21
* The data provider gathers info about how a project uses Bandit for static analysis. In
25
22
* particular, it tries to fill out the following features:
26
23
* <ul>
27
- * <li>{@link OssFeatures#RUNS_BANDIT_SCANS}</li>
28
- * <li>{@link OssFeatures#USES_BANDIT_SCAN_CHECKS}</li>
24
+ * <li>{@link OssFeatures#RUNS_BANDIT_SCANS}</li>
25
+ * <li>{@link OssFeatures#USES_BANDIT_SCAN_CHECKS}</li>
29
26
* </ul>
30
27
*/
31
28
public class BanditDataProvider extends AbstractStaticScanToolsDataProvider {
32
29
33
30
/**
34
- * A step in a GitHub action that triggers analysis with Bandit.
31
+ * A Predicate to check the any step in a GitHub action that triggers analysis with Bandit.
35
32
*/
36
- private static final Pattern RUN_STEP_BANDIT_REGEX_PATTERN
37
- = Pattern .compile ("^.*bandit .*$" , Pattern .DOTALL );
33
+ private static final Map <String , Predicate <String >> MATCH_BANDIT_PREDICATE = new HashMap <>();
34
+
35
+ static {
36
+ {
37
+ MATCH_BANDIT_PREDICATE .put ("uses" ,
38
+ step -> Pattern .compile (".*bandit.*$" , Pattern .DOTALL ).matcher (step ).matches ());
39
+ MATCH_BANDIT_PREDICATE .put ("run" ,
40
+ step -> Pattern .compile ("^.*bandit .*$" , Pattern .DOTALL ).matcher (step ).matches ());
41
+ }
42
+ }
38
43
39
44
/**
40
45
* Initializes a data provider.
@@ -51,69 +56,14 @@ protected ValueSet fetchValuesFor(GitHubProject project) throws IOException {
51
56
52
57
LocalRepository repository = GitHubDataFetcher .localRepositoryFor (project );
53
58
54
- Value <Boolean > runsBandit = RUNS_BANDIT_SCANS .value (false );
55
- Value <Boolean > usesBanditScanChecks = USES_BANDIT_SCAN_CHECKS .value (false );
56
-
57
59
// ideally, we're looking for a GitHub action that runs Bandit scan on pull requests
58
60
// but if we just find an action that runs Bandit scans, that's also fine
59
- for (Path configPath : findGitHubActionsIn (repository )) {
60
- try (InputStream content = Files .newInputStream (configPath )) {
61
- Map <String , Object > githubAction = Yaml .readMap (content );
62
- if (triggersScan (githubAction )) {
63
- runsBandit = RUNS_BANDIT_SCANS .value (true );
64
- if (runsOnPullRequests (githubAction )) {
65
- usesBanditScanChecks = USES_BANDIT_SCAN_CHECKS .value (true );
66
- break ;
67
- }
68
- }
69
- }
70
- }
61
+ Visitor visitor = withVisitor ();
62
+ browse (repository , MATCH_BANDIT_PREDICATE , Collections .emptyMap (), visitor );
71
63
72
- return ValueHashSet .from (runsBandit , usesBanditScanChecks );
73
- }
74
-
75
- @ Override
76
- public boolean triggersScan (Map <?, ?> githubAction ) {
77
- return Optional .ofNullable (githubAction .get ("jobs" ))
78
- .filter (Map .class ::isInstance )
79
- .map (Map .class ::cast )
80
- .map (jobs -> jobs .values ())
81
- .filter (Iterable .class ::isInstance )
82
- .map (Iterable .class ::cast )
83
- .map (BanditDataProvider ::scanJobs )
84
- .orElse (false );
85
- }
64
+ Value <Boolean > runsBandit = RUNS_BANDIT_SCANS .value (visitor .runCheck );
65
+ Value <Boolean > usesBanditScanChecks = USES_BANDIT_SCAN_CHECKS .value (visitor .usesCheck );
86
66
87
- /**
88
- * Checks if any step in a collection of jobs triggers a Bandit scan.
89
- *
90
- * @param jobs The collection of jobs from GitHub action.
91
- * @return True if a step triggers a Bandit scan, false otherwise.
92
- */
93
- private static boolean scanJobs (Iterable <?> jobs ) {
94
- return IteratorUtils .toList (jobs .iterator ()).stream ()
95
- .filter (Map .class ::isInstance )
96
- .map (Map .class ::cast )
97
- .map (job -> job .get ("steps" ))
98
- .filter (Iterable .class ::isInstance )
99
- .map (Iterable .class ::cast )
100
- .anyMatch (BanditDataProvider ::hasBanditRunStep );
101
- }
102
-
103
- /**
104
- * Checks if a collection of steps from a GitHub action contains a step that triggers a Bandit
105
- * scan.
106
- *
107
- * @param steps The steps to be checked.
108
- * @return True if the steps contain a step that triggers a Bandit scan, false otherwise.
109
- */
110
- private static boolean hasBanditRunStep (Iterable <?> steps ) {
111
- return IteratorUtils .toList (steps .iterator ()).stream ()
112
- .filter (Map .class ::isInstance )
113
- .map (Map .class ::cast )
114
- .map (step -> step .get ("run" ))
115
- .filter (String .class ::isInstance )
116
- .map (String .class ::cast )
117
- .anyMatch (run -> RUN_STEP_BANDIT_REGEX_PATTERN .matcher (run ).matches ());
67
+ return ValueHashSet .from (runsBandit , usesBanditScanChecks );
118
68
}
119
- }
69
+ }
0 commit comments