|
25 | 25 | import com.scanoss.Scanner; |
26 | 26 | import com.scanoss.exceptions.ScannerException; |
27 | 27 | import com.scanoss.exceptions.WinnowingException; |
| 28 | +import com.scanoss.settings.FileSnippet; |
28 | 29 | import com.scanoss.settings.ScanossSettings; |
29 | 30 | import com.scanoss.utils.JsonUtils; |
30 | 31 | import com.scanoss.utils.ProxyUtils; |
@@ -105,6 +106,27 @@ class ScanCommandLine implements Runnable { |
105 | 106 | @picocli.CommandLine.Option(names = {"-H", "--hpsm"}, description = "Use High Precision Snippet Matching algorithm") |
106 | 107 | private boolean enableHpsm = false; |
107 | 108 |
|
| 109 | + @picocli.CommandLine.Option(names = {"--min-snippet-hits"}, description = "Minimum snippet hits required (0 = unset, uses server config)") |
| 110 | + private int minSnippetHits = 0; |
| 111 | + |
| 112 | + @picocli.CommandLine.Option(names = {"--min-snippet-lines"}, description = "Minimum snippet lines required (0 = unset, uses server config)") |
| 113 | + private int minSnippetLines = 0; |
| 114 | + |
| 115 | + @picocli.CommandLine.Option(names = {"--honour-file-exts"}, description = "Honour file extensions (true|false|unset)", arity = "1") |
| 116 | + private String honourFileExts = null; |
| 117 | + |
| 118 | + @picocli.CommandLine.Option(names = {"--ranking"}, description = "Enable/disable ranking (true|false|unset)", arity = "1") |
| 119 | + private String ranking = null; |
| 120 | + |
| 121 | + @picocli.CommandLine.Option(names = {"--ranking-threshold"}, description = "Ranking threshold value (-1 = unset, uses server config)") |
| 122 | + private int rankingThreshold = -1; |
| 123 | + |
| 124 | + @picocli.CommandLine.Option(names = {"--skip-headers"}, description = "Skip license headers, comments and imports at the beginning of files (applies locally)") |
| 125 | + private boolean skipHeaders = false; |
| 126 | + |
| 127 | + @picocli.CommandLine.Option(names = {"--skip-headers-limit"}, description = "Skip limit for license headers (0 = unset, applies locally)") |
| 128 | + private int skipHeadersLimit = 0; |
| 129 | + |
108 | 130 | @picocli.CommandLine.Parameters(arity = "1", description = "file/folder to scan") |
109 | 131 | private String fileFolder; |
110 | 132 |
|
@@ -160,13 +182,13 @@ public void run() { |
160 | 182 | printMsg(err, String.format("Using flags %s", scanFlags)); |
161 | 183 | } |
162 | 184 | } |
| 185 | + FileSnippet cliFileSnippet = buildCliScanConfig(); |
163 | 186 | scanner = Scanner.builder().skipSnippets(skipSnippets).allFolders(allFolders).allExtensions(allExtensions) |
164 | 187 | .hiddenFilesFolders(allHidden).numThreads(numThreads).url(apiUrl).apiKey(apiKey) |
165 | 188 | .retryLimit(retryLimit).timeout(Duration.ofSeconds(timeoutLimit)).scanFlags(scanFlags) |
166 | 189 | .snippetLimit(snippetLimit).customCert(caCertPem).proxy(proxy).hpsm(enableHpsm) |
167 | | - .settings(settings).obfuscate(obfuscate) |
| 190 | + .settings(settings).obfuscate(obfuscate).cliFileSnippet(cliFileSnippet) |
168 | 191 | .build(); |
169 | | - |
170 | 192 | File f = new File(fileFolder); |
171 | 193 | if (!f.exists()) { |
172 | 194 | throw new RuntimeException(String.format("Error: File or folder does not exist: %s\n", fileFolder)); |
@@ -198,6 +220,38 @@ private String loadFileToString(@NonNull String filename) { |
198 | 220 | } |
199 | 221 | } |
200 | 222 |
|
| 223 | + /** |
| 224 | + * Build a ScanConfig from CLI arguments. |
| 225 | + * |
| 226 | + * @return ScanConfig populated with CLI-provided values |
| 227 | + */ |
| 228 | + private FileSnippet buildCliScanConfig() { |
| 229 | + FileSnippet.FileSnippetBuilder builder = FileSnippet.builder() |
| 230 | + .minSnippetHits(minSnippetHits) |
| 231 | + .minSnippetLines(minSnippetLines) |
| 232 | + .rankingThreshold(rankingThreshold) |
| 233 | + .skipHeaders(skipHeaders) |
| 234 | + .skipHeadersLimit(skipHeadersLimit); |
| 235 | + |
| 236 | + builder.honourFileExts(parseTriStateBoolean(honourFileExts)); |
| 237 | + builder.rankingEnabled(parseTriStateBoolean(ranking)); |
| 238 | + |
| 239 | + return builder.build(); |
| 240 | + } |
| 241 | + |
| 242 | + /** |
| 243 | + * Parse a tri-state boolean string value. |
| 244 | + * |
| 245 | + * @param value the string value ("true", "false", "unset", or null) |
| 246 | + * @return Boolean.TRUE, Boolean.FALSE, or null for unset |
| 247 | + */ |
| 248 | + private static Boolean parseTriStateBoolean(String value) { |
| 249 | + if (value == null || value.equalsIgnoreCase("unset")) { |
| 250 | + return null; |
| 251 | + } |
| 252 | + return Boolean.parseBoolean(value); |
| 253 | + } |
| 254 | + |
201 | 255 | /** |
202 | 256 | * Scan the specified file and output the results |
203 | 257 | * |
@@ -245,7 +299,7 @@ private void scanFolder(String folder) { |
245 | 299 | if (CommandLine.debug) { |
246 | 300 | e.printStackTrace(err); |
247 | 301 | } |
248 | | - throw new RuntimeException(String.format("Something went wrong while scanning %s.", folder)); |
| 302 | + throw new RuntimeException(String.format("Something went wrong while scanning %s.", folder), e); |
249 | 303 | } |
250 | 304 | } |
251 | 305 | } |
0 commit comments