|
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 |
|
@@ -133,11 +155,25 @@ public void run() { |
133 | 155 | } |
134 | 156 | } |
135 | 157 |
|
| 158 | + // Load settings from scanoss.json if provided, otherwise use defaults |
| 159 | + ScanossSettings settings = new ScanossSettings(); |
136 | 160 | if(settingsPath != null && !settingsPath.isEmpty()) { |
137 | 161 | settings = ScanossSettings.createFromPath(Paths.get(settingsPath)); |
138 | 162 | if (settings == null) throw new RuntimeException("Error: Failed to read settings file"); |
139 | 163 | printMsg(err, String.format("Settings file read %s", settings)); |
140 | 164 | } |
| 165 | + // Build file_snippet config from CLI arguments (lowest priority) |
| 166 | + FileSnippet fileSnippetCLI = FileSnippet.builder() |
| 167 | + .minSnippetHits(minSnippetHits) |
| 168 | + .minSnippetLines(minSnippetLines) |
| 169 | + .rankingThreshold(rankingThreshold) |
| 170 | + .skipHeaders(skipHeaders) |
| 171 | + .skipHeadersLimit(skipHeadersLimit) |
| 172 | + .rankingEnabled(parseTriStateBoolean(ranking)) |
| 173 | + .honourFileExts(parseTriStateBoolean(honourFileExts)) |
| 174 | + .build(); |
| 175 | + // Resolve: file_snippet from scanoss.json (highest priority) overrides CLI values |
| 176 | + settings.getSettings().setFileSnippet(FileSnippet.resolve(fileSnippetCLI, settings.getSettings().getFileSnippet())); |
141 | 177 |
|
142 | 178 |
|
143 | 179 | if (com.scanoss.cli.CommandLine.debug) { |
@@ -166,7 +202,6 @@ public void run() { |
166 | 202 | .snippetLimit(snippetLimit).customCert(caCertPem).proxy(proxy).hpsm(enableHpsm) |
167 | 203 | .settings(settings).obfuscate(obfuscate) |
168 | 204 | .build(); |
169 | | - |
170 | 205 | File f = new File(fileFolder); |
171 | 206 | if (!f.exists()) { |
172 | 207 | throw new RuntimeException(String.format("Error: File or folder does not exist: %s\n", fileFolder)); |
@@ -198,6 +233,19 @@ private String loadFileToString(@NonNull String filename) { |
198 | 233 | } |
199 | 234 | } |
200 | 235 |
|
| 236 | + /** |
| 237 | + * Parse a tri-state boolean string value. |
| 238 | + * |
| 239 | + * @param value the string value ("true", "false", "unset", or null) |
| 240 | + * @return Boolean.TRUE, Boolean.FALSE, or null for unset |
| 241 | + */ |
| 242 | + private static Boolean parseTriStateBoolean(String value) { |
| 243 | + if (value == null || value.equalsIgnoreCase("unset")) { |
| 244 | + return null; |
| 245 | + } |
| 246 | + return Boolean.parseBoolean(value); |
| 247 | + } |
| 248 | + |
201 | 249 | /** |
202 | 250 | * Scan the specified file and output the results |
203 | 251 | * |
@@ -245,7 +293,7 @@ private void scanFolder(String folder) { |
245 | 293 | if (CommandLine.debug) { |
246 | 294 | e.printStackTrace(err); |
247 | 295 | } |
248 | | - throw new RuntimeException(String.format("Something went wrong while scanning %s.", folder)); |
| 296 | + throw new RuntimeException(String.format("Something went wrong while scanning %s.", folder), e); |
249 | 297 | } |
250 | 298 | } |
251 | 299 | } |
0 commit comments