< Summary

Information
Class: DotNetApiDiff.ExitCodes.ExitCodeManager
Assembly: DotNetApiDiff
File(s): /home/runner/work/dotnet-api-diff/dotnet-api-diff/src/DotNetApiDiff/ExitCodes/ExitCodeManager.cs
Line coverage
96%
Covered lines: 95
Uncovered lines: 3
Coverable lines: 98
Total lines: 236
Line coverage: 96.9%
Branch coverage
80%
Covered branches: 63
Total branches: 78
Branch coverage: 80.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
.ctor(...)100%11100%
GetExitCode(...)80%1010100%
GetExitCode(...)70%1010100%
GetExitCode(...)57.14%151482.35%
GetExitCodeForException(...)95.83%2424100%
GetExitCode(...)70%1010100%
GetExitCodeDescription(...)100%1010100%

File(s)

/home/runner/work/dotnet-api-diff/dotnet-api-diff/src/DotNetApiDiff/ExitCodes/ExitCodeManager.cs

#LineLine coverage
 1// Copyright DotNet API Diff Project Contributors - SPDX Identifier: MIT
 2using System.Reflection;
 3using System.Security;
 4using DotNetApiDiff.Interfaces;
 5using DotNetApiDiff.Models;
 6using Microsoft.Extensions.Logging;
 7
 8namespace DotNetApiDiff.ExitCodes
 9{
 10    /// <summary>
 11    /// Manages application exit codes based on comparison results.
 12    /// </summary>
 13    public class ExitCodeManager : IExitCodeManager
 14    {
 15        private readonly ILogger<ExitCodeManager>? _logger;
 16
 17        /// <summary>
 18        /// Exit code for successful comparison with no breaking changes.
 19        /// </summary>
 20        public const int Success = 0;
 21
 22        /// <summary>
 23        /// Exit code for successful comparison with breaking changes detected.
 24        /// </summary>
 25        public const int BreakingChangesDetected = 1;
 26
 27        /// <summary>
 28        /// Exit code for errors during comparison.
 29        /// </summary>
 30        public const int ComparisonError = 2;
 31
 32        /// <summary>
 33        /// Exit code for assembly loading failures.
 34        /// </summary>
 35        public const int AssemblyLoadError = 3;
 36
 37        /// <summary>
 38        /// Exit code for configuration errors.
 39        /// </summary>
 40        public const int ConfigurationError = 4;
 41
 42        /// <summary>
 43        /// Exit code for invalid command line arguments.
 44        /// </summary>
 45        public const int InvalidArguments = 5;
 46
 47        /// <summary>
 48        /// Exit code for file not found errors.
 49        /// </summary>
 50        public const int FileNotFound = 6;
 51
 52        /// <summary>
 53        /// Exit code for unexpected/unhandled errors.
 54        /// </summary>
 55        public const int UnexpectedError = 99;
 56
 57        /// <summary>
 58        /// Initializes a new instance of the <see cref="ExitCodeManager"/> class.
 59        /// </summary>
 3960        public ExitCodeManager()
 3961        {
 3962        }
 63
 64        /// <summary>
 65        /// Initializes a new instance of the <see cref="ExitCodeManager"/> class with a logger.
 66        /// </summary>
 67        /// <param name="logger">The logger to use for logging exit code information.</param>
 5468        public ExitCodeManager(ILogger<ExitCodeManager> logger)
 5469        {
 5470            _logger = logger;
 5471        }
 72
 73        /// <summary>
 74        /// Determines the appropriate exit code based on comparison results.
 75        /// </summary>
 76        /// <param name="hasBreakingChanges">Whether breaking changes were detected.</param>
 77        /// <param name="hasErrors">Whether errors occurred during comparison.</param>
 78        /// <returns>The appropriate exit code.</returns>
 79        public int GetExitCode(bool hasBreakingChanges, bool hasErrors)
 580        {
 581            if (hasErrors)
 282            {
 283                _logger?.LogWarning("Errors occurred during comparison, returning ComparisonError exit code");
 284                return ComparisonError;
 85            }
 86
 387            if (hasBreakingChanges)
 288            {
 289                _logger?.LogWarning("Breaking changes detected, returning BreakingChangesDetected exit code");
 290                return BreakingChangesDetected;
 91            }
 92
 193            _logger?.LogInformation("No breaking changes or errors detected, returning Success exit code");
 194            return Success;
 595        }
 96
 97        /// <summary>
 98        /// Determines the appropriate exit code based on a comparison result.
 99        /// </summary>
 100        /// <param name="comparisonResult">The comparison result to evaluate.</param>
 101        /// <returns>The appropriate exit code.</returns>
 102        public int GetExitCode(ComparisonResult comparisonResult)
 4103        {
 4104            if (comparisonResult == null)
 1105            {
 1106                _logger?.LogWarning("Comparison result is null, returning ComparisonError exit code");
 1107                return ComparisonError;
 108            }
 109
 110            // Check for breaking changes
 3111            if (comparisonResult.HasBreakingChanges)
 1112            {
 1113                _logger?.LogWarning("Breaking changes detected in comparison result, returning BreakingChangesDetected e
 1114                return BreakingChangesDetected;
 115            }
 116
 2117            _logger?.LogInformation("No breaking changes detected in comparison result, returning Success exit code");
 2118            return Success;
 4119        }
 120
 121        /// <summary>
 122        /// Determines the appropriate exit code based on an API comparison.
 123        /// </summary>
 124        /// <param name="apiComparison">The API comparison to evaluate.</param>
 125        /// <returns>The appropriate exit code.</returns>
 126        public int GetExitCode(ApiComparison apiComparison)
 6127        {
 6128            if (apiComparison == null)
 0129            {
 0130                _logger?.LogWarning("API comparison is null, returning ComparisonError exit code");
 0131                return ComparisonError;
 132            }
 133
 134            // Validate the comparison result
 6135            if (!apiComparison.IsValid())
 1136            {
 1137                _logger?.LogWarning("API comparison is invalid, returning ComparisonError exit code");
 1138                return ComparisonError;
 139            }
 140
 141            // Check for breaking changes
 5142            if (apiComparison.HasBreakingChanges)
 3143            {
 3144                int breakingChangesCount = apiComparison.BreakingChangesCount;
 3145                _logger?.LogWarning("{Count} breaking changes detected in API comparison, returning BreakingChangesDetec
 3146                return BreakingChangesDetected;
 147            }
 148
 2149            _logger?.LogInformation("No breaking changes detected in API comparison, returning Success exit code");
 2150            return Success;
 6151        }
 152
 153        /// <summary>
 154        /// Determines the appropriate exit code for an exception scenario.
 155        /// </summary>
 156        /// <param name="exception">The exception that occurred.</param>
 157        /// <returns>The appropriate exit code.</returns>
 158        public int GetExitCodeForException(Exception exception)
 16159        {
 16160            if (exception == null)
 1161            {
 1162                _logger?.LogWarning("Exception is null, returning UnexpectedError exit code");
 1163                return UnexpectedError;
 164            }
 165
 15166            int exitCode = exception switch
 15167            {
 2168                FileNotFoundException => FileNotFound,
 1169                DirectoryNotFoundException => FileNotFound,
 1170                ReflectionTypeLoadException => AssemblyLoadError,
 1171                BadImageFormatException => AssemblyLoadError,
 1172                SecurityException => AssemblyLoadError,
 1173                ArgumentNullException => InvalidArguments,
 2174                ArgumentException => InvalidArguments,
 1175                InvalidOperationException => ConfigurationError,
 1176                NotSupportedException => ConfigurationError,
 4177                _ => UnexpectedError
 15178            };
 179
 15180            _logger?.LogWarning(
 15181                "Exception of type {ExceptionType} occurred, returning {ExitCode} exit code",
 15182                exception.GetType().Name,
 15183                GetExitCodeDescription(exitCode));
 184
 15185            return exitCode;
 16186        }
 187
 188        /// <summary>
 189        /// Determines the appropriate exit code based on a combination of API comparison and exception.
 190        /// </summary>
 191        /// <param name="apiComparison">The API comparison to evaluate, or null if not available.</param>
 192        /// <param name="exception">The exception that occurred, or null if no exception.</param>
 193        /// <returns>The appropriate exit code.</returns>
 194        public int GetExitCode(ApiComparison? apiComparison, Exception? exception)
 4195        {
 196            // If there's an exception, it takes precedence
 4197            if (exception != null)
 2198            {
 2199                _logger?.LogWarning("Exception present, determining exit code based on exception");
 2200                return GetExitCodeForException(exception);
 201            }
 202
 203            // If there's no API comparison, return comparison error
 2204            if (apiComparison == null)
 1205            {
 1206                _logger?.LogWarning("API comparison is null, returning ComparisonError exit code");
 1207                return ComparisonError;
 208            }
 209
 210            // Otherwise, determine based on the API comparison
 1211            _logger?.LogInformation("Determining exit code based on API comparison");
 1212            return GetExitCode(apiComparison);
 4213        }
 214
 215        /// <summary>
 216        /// Gets a human-readable description of the exit code.
 217        /// </summary>
 218        /// <param name="exitCode">The exit code to describe.</param>
 219        /// <returns>A description of what the exit code means.</returns>
 220        public string GetExitCodeDescription(int exitCode)
 15221        {
 15222            return exitCode switch
 15223            {
 1224                Success => "Comparison completed successfully with no breaking changes detected.",
 1225                BreakingChangesDetected => "Comparison completed successfully but breaking changes were detected.",
 1226                ComparisonError => "An error occurred during the comparison process.",
 1227                AssemblyLoadError => "Failed to load one or more assemblies for comparison.",
 1228                ConfigurationError => "Configuration error or invalid settings detected.",
 1229                InvalidArguments => "Invalid command line arguments provided.",
 1230                FileNotFound => "One or more required files could not be found.",
 7231                UnexpectedError => "An unexpected error occurred during execution.",
 1232                _ => $"Unknown exit code: {exitCode}"
 15233            };
 15234        }
 235    }
 236}