@@ -59,15 +59,19 @@ public class FoDSastScanSetupCommand extends AbstractFoDScanSetupCommand<FoDScan
5959 @ Option (names = {"--language-level" })
6060 private String languageLevel ;
6161 @ Option (names = {"--oss" })
62- private final Boolean performOpenSourceAnalysis = false ;
62+ private Boolean performOpenSourceAnalysis ;
63+ @ Option (names = {"--no-oss" })
64+ private Boolean noPerformOpenSourceAnalysis ;
6365 @ Option (names = {"--audit-preference" }, required = true )
6466 private FoDEnums .AuditPreferenceTypes auditPreferenceType ;
6567 @ Option (names = {"--include-third-party-libs" })
6668 private final Boolean includeThirdPartyLibraries = false ;
6769 @ Option (names = {"--use-source-control" })
6870 private final Boolean useSourceControl = false ;
6971 @ Option (names ={"--use-aviator" })
70- private Boolean useAviator = false ;
72+ private Boolean useAviator ;
73+ @ Option (names ={"--no-aviator" })
74+ private Boolean noUseAviator ;
7175
7276 // TODO We don't actually use a progress writer, but for now we can't
7377 // remove the --progress option to maintain backward compatibility.
@@ -116,26 +120,70 @@ protected JsonNode setup(UnirestInstance unirest, FoDReleaseDescriptor releaseDe
116120 validateEntitlement (currentSetup , entitlementIdToUse , relId , atd );
117121 LOG .info ("Configuring release to use entitlement " + entitlementIdToUse );
118122
119- var technologyStackId = getTechnologyStackId (unirest );
120- var languageLevelId = getLanguageLevelId (unirest , technologyStackId );
123+ // Determine technology stack / language level IDs:
124+ // Always lookup the configured technology stack (including the default "Auto Detect"),
125+ // so the associated numeric id (e.g. 32) is used when the user did not explicitly pass the option.
126+ Integer technologyStackId = getTechnologyStackId (unirest );
121127
122- FoDScanConfigSastSetupRequest setupSastScanRequest = FoDScanConfigSastSetupRequest .builder ()
128+ Integer languageLevelId ;
129+ if (languageLevel != null && languageLevel .length () > 0 ) {
130+ languageLevelId = getLanguageLevelId (unirest , technologyStackId );
131+ } else if (currentSetup != null && currentSetup .getLanguageLevelId () != null ) {
132+ languageLevelId = currentSetup .getLanguageLevelId ();
133+ } else {
134+ languageLevelId = null ;
135+ }
136+
137+ if (performOpenSourceAnalysis != null && noPerformOpenSourceAnalysis != null ) {
138+ throw new FcliSimpleException ("Cannot specify both --oss and --no-oss" );
139+ }
140+ if (useAviator != null && noUseAviator != null ) {
141+ throw new FcliSimpleException ("Cannot specify both --use-aviator and --no-aviator" );
142+ }
143+
144+ var builder = FoDScanConfigSastSetupRequest .builder ()
123145 .entitlementId (entitlementIdToUse )
124146 .assessmentTypeId (assessmentTypeId )
125147 .entitlementFrequencyType (entitlementFrequencyTypeMixin .getEntitlementFrequencyType ().name ())
126148 .technologyStackId (technologyStackId )
127149 .languageLevelId (languageLevelId )
128- .performOpenSourceAnalysis (performOpenSourceAnalysis )
129150 .auditPreferenceType (auditPreferenceType .name ())
130151 .includeThirdPartyLibraries (includeThirdPartyLibraries )
131- .useSourceControl (useSourceControl )
132- .includeFortifyAviator (useAviator ).build ();
152+ .useSourceControl (useSourceControl );
153+
154+ // Final OSS value priority: explicit --oss > explicit --no-oss > existing setup value
155+ Boolean ossValue = null ;
156+ if (performOpenSourceAnalysis != null ) {
157+ ossValue = performOpenSourceAnalysis ;
158+ } else if (noPerformOpenSourceAnalysis != null ) {
159+ ossValue = Boolean .FALSE ;
160+ } else if (currentSetup != null && currentSetup .getPerformOpenSourceAnalysis () != null ) {
161+ ossValue = currentSetup .getPerformOpenSourceAnalysis ();
162+ }
163+ if (ossValue != null ) {
164+ builder .performOpenSourceAnalysis (ossValue );
165+ }
166+
167+ // Final Aviator value priority: explicit --use-aviator > explicit --no-aviator > existing setup value
168+ Boolean aviatorValue = null ;
169+ if (useAviator != null ) {
170+ aviatorValue = useAviator ;
171+ } else if (noUseAviator != null ) {
172+ aviatorValue = Boolean .FALSE ;
173+ } else if (currentSetup != null && currentSetup .getIncludeFortifyAviator () != null ) {
174+ aviatorValue = currentSetup .getIncludeFortifyAviator ();
175+ }
176+ if (aviatorValue != null ) {
177+ builder .includeFortifyAviator (aviatorValue );
178+ }
179+
180+ FoDScanConfigSastSetupRequest setupSastScanRequest = builder .build ();
133181
134182 return FoDScanConfigSastHelper .setupScan (unirest , releaseDescriptor , setupSastScanRequest ).asJsonNode ();
135183 }
136184
137185 private Integer getLanguageLevelId (UnirestInstance unirest , Integer technologyStackId ) {
138- Integer languageLevelId = 0 ;
186+ Integer languageLevelId = null ;
139187 FoDLookupDescriptor lookupDescriptor = null ;
140188 if (languageLevel != null && languageLevel .length () > 0 ) {
141189 try {
@@ -156,8 +204,8 @@ private Integer getTechnologyStackId(UnirestInstance unirest) {
156204 } catch (JsonProcessingException ex ) {
157205 throw new FcliTechnicalException (ex .getMessage ());
158206 }
159- // TODO return 0 or null, or throw exception?
160- return lookupDescriptor ==null ? 0 : Integer .valueOf (lookupDescriptor .getValue ());
207+ // Return null when not found so the field can be omitted from the request JSON
208+ return lookupDescriptor ==null ? null : Integer .valueOf (lookupDescriptor .getValue ());
161209 }
162210
163211 private void validateEntitlement (FoDScanConfigSastDescriptor currentSetup , Integer entitlementIdToUse , String relId , FoDReleaseAssessmentTypeDescriptor atd ) {
0 commit comments