13 ArgumentNullException.ThrowIfNull(args);
16 string? inputDirectory =
null;
17 bool endOfOptions =
false;
19 for (
int index = 0; index < args.Length; index++)
21 string argument = args[index];
25 if (!TrySetInputDirectory(argument, ref inputDirectory, out
string? error))
27 return Failure(error!);
39 if (argument is
"-h" or
"--help")
44 if (argument ==
"--version")
49 if (!argument.StartsWith(
"-", StringComparison.Ordinal) ||
52 if (!TrySetInputDirectory(argument, ref inputDirectory, out
string? error))
54 return Failure(error!);
60 SplitOption(argument, out
string optionName, out
string? inlineValue);
66 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? output, out
string? outputError))
68 return Failure(outputError!);
71 options.OutputDirectory = output;
76 if (!TryReadPositiveInt(args, ref index, inlineValue, optionName, out
int parallelism, out
string? parallelismError))
78 return Failure(parallelismError!);
81 options.MaxDegreeOfParallelism = parallelism;
85 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? levelValue, out
string? levelError))
87 return Failure(levelError!);
90 if (!TryParseLevel(levelValue!, out SolutionCheckLevel level))
93 "Invalid --level value. Expected structural, feasibility, or full.");
96 options.CheckOptions.Level = level;
99 case "--search-pattern":
100 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? searchPattern, out
string? patternError))
102 return Failure(patternError!);
105 options.SearchPattern = searchPattern!;
109 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? resultId, out
string? resultIdError))
111 return Failure(resultIdError!);
114 options.KnownResultId = resultId;
117 case "--result-name-contains":
118 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? resultName, out
string? resultNameError))
120 return Failure(resultNameError!);
123 options.KnownResultNameContains = resultName;
126 case "--feasibility-tolerance":
127 case "--feasibility-tol":
128 if (!TryReadTolerance(args, ref index, inlineValue, optionName, out
double feasibilityTolerance, out
string? feasibilityError))
130 return Failure(feasibilityError!);
133 options.CheckOptions.FeasibilityTolerance = feasibilityTolerance;
136 case "--zero-tolerance":
138 if (!TryReadTolerance(args, ref index, inlineValue, optionName, out
double zeroTolerance, out
string? zeroError))
140 return Failure(zeroError!);
143 options.CheckOptions.ZeroTolerance = zeroTolerance;
146 case "--integrality-tolerance":
147 case "--integrality-tol":
148 if (!TryReadTolerance(args, ref index, inlineValue, optionName, out
double integralityTolerance, out
string? integralityError))
150 return Failure(integralityError!);
153 options.CheckOptions.IntegralityTolerance = integralityTolerance;
156 case "--objective-absolute-tolerance":
157 case "--objective-abs-tol":
158 if (!TryReadTolerance(args, ref index, inlineValue, optionName, out
double objectiveAbsoluteTolerance, out
string? objectiveAbsoluteError))
160 return Failure(objectiveAbsoluteError!);
163 options.CheckOptions.ObjectiveAbsoluteTolerance = objectiveAbsoluteTolerance;
166 case "--objective-relative-tolerance":
167 case "--objective-rel-tol":
168 if (!TryReadTolerance(args, ref index, inlineValue, optionName, out
double objectiveRelativeTolerance, out
string? objectiveRelativeError))
170 return Failure(objectiveRelativeError!);
173 options.CheckOptions.ObjectiveRelativeTolerance = objectiveRelativeTolerance;
177 if (!TryReadNonNegativeInt(args, ref index, inlineValue, optionName, out
int maximumIssues, out
string? maximumIssuesError))
179 return Failure(maximumIssuesError!);
182 options.ReportOptions.MaximumDetailedIssues = maximumIssues;
185 case "--evaluator-name":
186 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? evaluatorName, out
string? evaluatorNameError))
188 return Failure(evaluatorNameError!);
191 options.VerificationOptions.EvaluatorName = evaluatorName!;
194 case "--evaluator-version":
195 if (!TryReadValue(args, ref index, inlineValue, optionName, out
string? evaluatorVersion, out
string? evaluatorVersionError))
197 return Failure(evaluatorVersionError!);
200 options.VerificationOptions.EvaluatorVersion = evaluatorVersion!;
203 case "--no-recursive":
204 if (!RejectInlineValue(inlineValue, optionName, out
string? noRecursiveError))
206 return Failure(noRecursiveError!);
209 options.SearchSubdirectories =
false;
213 if (!RejectInlineValue(inlineValue, optionName, out
string? strictXmlError))
215 return Failure(strictXmlError!);
218 options.IgnoreNonLotSizingInstanceXml =
false;
222 if (!RejectInlineValue(inlineValue, optionName, out
string? noReportsError))
224 return Failure(noReportsError!);
227 options.WriteReports =
false;
230 case "--no-progress":
232 if (!RejectInlineValue(inlineValue, optionName, out
string? noProgressError))
234 return Failure(noProgressError!);
237 options.ShowProgress =
false;
240 case "--continue-after-structural-errors":
241 if (!RejectInlineValue(inlineValue, optionName, out
string? continueError))
243 return Failure(continueError!);
246 options.CheckOptions.ContinueAfterStructuralErrors =
true;
249 case "--include-disabled-constraints":
250 if (!RejectInlineValue(inlineValue, optionName, out
string? disabledError))
252 return Failure(disabledError!);
255 options.CheckOptions.IgnoreDisabledConstraints =
false;
258 case "--no-apply-evaluation":
259 if (!RejectInlineValue(inlineValue, optionName, out
string? applyError))
261 return Failure(applyError!);
264 options.VerificationOptions.ApplyToSolutionEvaluation =
false;
267 case "--no-update-known-result":
268 if (!RejectInlineValue(inlineValue, optionName, out
string? updateError))
270 return Failure(updateError!);
273 options.VerificationOptions.UpdateKnownResultFeasibility =
false;
276 case "--no-promote-known-result":
277 if (!RejectInlineValue(inlineValue, optionName, out
string? promoteError))
279 return Failure(promoteError!);
282 options.VerificationOptions.PromoteFullyVerifiedKnownResult =
false;
286 if (!RejectInlineValue(inlineValue, optionName, out
string? infoError))
288 return Failure(infoError!);
291 options.ReportOptions.IncludeInformationIssues =
false;
294 case "--no-warnings":
295 if (!RejectInlineValue(inlineValue, optionName, out
string? warningsError))
297 return Failure(warningsError!);
300 options.ReportOptions.IncludeWarningIssues =
false;
304 return Failure($
"Unknown option '{optionName}'. Use --help for usage.");
308 if (
string.IsNullOrWhiteSpace(inputDirectory))
310 return Failure(
"An input directory is required. Use --help for usage.");
313 options.InputDirectory = inputDirectory;
317 options.BuildCampaignOptions();
319 catch (Exception exception) when (
320 exception is ArgumentException or InvalidOperationException)
322 return Failure(exception.Message);