SarifCommand.java

1
package org.egothor.methodatlas.command;
2
3
import java.io.IOException;
4
import java.io.PrintWriter;
5
import java.nio.file.Path;
6
import java.nio.file.Paths;
7
import java.util.List;
8
9
import org.egothor.methodatlas.AiResultCache;
10
import org.egothor.methodatlas.emit.ClassificationOverride;
11
import org.egothor.methodatlas.CliConfig;
12
import org.egothor.methodatlas.ai.AiSuggestionEngine;
13
import org.egothor.methodatlas.api.TestDiscoveryConfig;
14
import org.egothor.methodatlas.emit.SarifEmitter;
15
16
/**
17
 * CLI command handler for the {@code -sarif} output mode.
18
 *
19
 * <p>
20
 * Scans one or more source roots, buffers all discovered test-method records,
21
 * and serializes the result as a single SARIF 2.1.0 JSON document once the
22
 * scan completes. When {@link CliConfig#detectSecrets()} is enabled, credential
23
 * findings are detected (via {@link CredentialDetectionRunner}) and embedded in the
24
 * same SARIF document before it is flushed.
25
 * </p>
26
 *
27
 * @see org.egothor.methodatlas.emit.SarifEmitter
28
 * @see ScanCommand
29
 * @see GitHubAnnotationsCommand
30
 */
31
public final class SarifCommand implements Command {
32
33
    private final CliConfig cliConfig;
34
    private final TestDiscoveryConfig discoveryConfig;
35
    private final AiSuggestionEngine aiEngine;
36
    private final ClassificationOverride override;
37
    private final AiResultCache aiCache;
38
    private final ScanOrchestrator scanOrchestrator;
39
40
    /**
41
     * Creates a new SARIF command.
42
     *
43
     * @param cliConfig         full parsed CLI configuration
44
     * @param discoveryConfig   discovery configuration forwarded to providers
45
     * @param aiEngine          AI engine providing suggestions; {@code null}
46
     *                          when AI is disabled
47
     * @param override          human classification overrides
48
     * @param aiCache           AI result cache
49
     * @param scanOrchestrator  scan-and-emit orchestrator used to process all
50
     *                          configured roots and buffer SARIF results
51
     */
52
    public SarifCommand(CliConfig cliConfig, TestDiscoveryConfig discoveryConfig,
53
            AiSuggestionEngine aiEngine, ClassificationOverride override,
54
            AiResultCache aiCache, ScanOrchestrator scanOrchestrator) {
55
        this.cliConfig = cliConfig;
56
        this.discoveryConfig = discoveryConfig;
57
        this.aiEngine = aiEngine;
58
        this.override = override;
59
        this.aiCache = aiCache;
60
        this.scanOrchestrator = scanOrchestrator;
61
    }
62
63
    /**
64
     * Scans all roots and emits the buffered result as SARIF JSON.
65
     *
66
     * @param out writer that receives the serialized SARIF document
67
     * @return {@code 0} if all files were processed successfully, {@code 1} if
68
     *         any file produced a parse or processing error
69
     * @throws IOException if traversing a file tree fails
70
     */
71
    @Override
72
    public int execute(PrintWriter out) throws IOException {
73 2 1. execute : removed conditional - replaced equality check with true → SURVIVED
2. execute : removed conditional - replaced equality check with false → SURVIVED
        boolean aiEnabled = aiEngine != null;
74 4 1. execute : removed conditional - replaced equality check with false → NO_COVERAGE
2. execute : removed conditional - replaced equality check with false → SURVIVED
3. execute : removed conditional - replaced equality check with true → SURVIVED
4. execute : removed conditional - replaced equality check with true → NO_COVERAGE
        boolean confidenceEnabled = aiEnabled && cliConfig.aiOptions().confidence();
75 2 1. execute : removed conditional - replaced equality check with false → SURVIVED
2. execute : removed conditional - replaced equality check with true → TIMED_OUT
        List<Path> roots = cliConfig.paths().isEmpty() ? List.of(Paths.get(".")) : cliConfig.paths();
76
77
        String filePrefix = ContentHasher.filePrefix(roots);
78 2 1. execute : removed conditional - replaced equality check with false → SURVIVED
2. execute : removed conditional - replaced equality check with true → SURVIVED
        boolean scoresInMessage = !cliConfig.sarifOmitScores();
79
        SarifEmitter sarifEmitter = new SarifEmitter(aiEnabled, confidenceEnabled, filePrefix, scoresInMessage);
80
81
        // Credential detection: prepare() folds triage into the per-class call when
82
        // possible (source sent once) and returns the context the scan threads
83
        // through; finish() records findings into the SARIF document before flush.
84 2 1. execute : removed conditional - replaced equality check with false → SURVIVED
2. execute : removed conditional - replaced equality check with true → SURVIVED
        CredentialDetectionRunner secretRunner = cliConfig.detectSecrets()
85
                ? new CredentialDetectionRunner(cliConfig, discoveryConfig, new PluginLoader(), scanOrchestrator, aiEngine)
86
                : null;
87 2 1. execute : removed conditional - replaced equality check with false → SURVIVED
2. execute : removed conditional - replaced equality check with true → KILLED
        CredentialTriageContext secretCtx = secretRunner != null ? secretRunner.prepare(roots) : null;
88
89
        int result = scanOrchestrator.scan(roots, cliConfig, discoveryConfig, aiEngine,
90
                scanOrchestrator.filterSink(sarifEmitter, cliConfig.securityOnly(),
91
                        cliConfig.minConfidence(), confidenceEnabled), override, aiCache, secretCtx);
92
93 2 1. execute : removed conditional - replaced equality check with false → SURVIVED
2. execute : removed conditional - replaced equality check with true → KILLED
        if (secretRunner != null) {
94 1 1. execute : removed call to org/egothor/methodatlas/command/CredentialDetectionRunner::finish → NO_COVERAGE
            secretRunner.finish(roots, sarifEmitter);
95
        }
96
97 1 1. execute : removed call to org/egothor/methodatlas/emit/SarifEmitter::flush → KILLED
        sarifEmitter.flush(out);
98 1 1. execute : replaced int return with 0 for org/egothor/methodatlas/command/SarifCommand::execute → SURVIVED
        return result;
99
    }
100
}

Mutations

73

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED Covering tests

74

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with false → NO_COVERAGE

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

3.3
Location : execute
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

4.4
Location : execute
Killed by : none
removed conditional - replaced equality check with true → NO_COVERAGE

75

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with true → TIMED_OUT

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

78

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

84

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

87

1.1
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

2.2
Location : execute
Killed by : org.egothor.methodatlas.MethodAtlasAppSarifTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.MethodAtlasAppSarifTest]/[method:sarifMode_outputIsNotCsvHeader(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

93

1.1
Location : execute
Killed by : org.egothor.methodatlas.MethodAtlasAppSarifTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.MethodAtlasAppSarifTest]/[method:sarifMode_outputIsNotCsvHeader(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : execute
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

94

1.1
Location : execute
Killed by : none
removed call to org/egothor/methodatlas/command/CredentialDetectionRunner::finish → NO_COVERAGE

97

1.1
Location : execute
Killed by : org.egothor.methodatlas.MethodAtlasAppSarifTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.MethodAtlasAppSarifTest]/[method:sarifMode_outputIsNotCsvHeader(java.nio.file.Path)]
removed call to org/egothor/methodatlas/emit/SarifEmitter::flush → KILLED

98

1.1
Location : execute
Killed by : none
replaced int return with 0 for org/egothor/methodatlas/command/SarifCommand::execute → SURVIVED
Covering tests

Active mutators

Tests examined


Report generated by PIT 1.22.1