Skip to content

Resolve SonarCloud Issues#754

Closed
christianhelle wants to merge 5 commits into
mainfrom
sonar-cloud-issues
Closed

Resolve SonarCloud Issues#754
christianhelle wants to merge 5 commits into
mainfrom
sonar-cloud-issues

Conversation

@christianhelle

@christianhelle christianhelle commented Sep 17, 2025

Copy link
Copy Markdown
Owner

Extract constants for magic numbers and hardcoded strings, refactor complex methods to reduce size and improve clarity, and simplify LINQ queries for better readability. These changes enhance code maintainability and make future modifications easier.

Summary by CodeRabbit

  • New Features
    • Enhanced CLI output: clearer header/support info, improved success summary, and consistent donation banners.
  • Refactor
    • Centralized content-type/status-code handling; no behavior changes.
    • Streamlined header parameter decision logic; behavior unchanged.
    • Reorganized interface grouping internally; generated interfaces remain the same.
  • Style
    • Improved table formatting (aligned columns, consistent widths) and file size display.
    • Consistent spinner timing for progress feedback.
  • Chores
    • Replaced hard-coded URLs and literals with constants.
    • Unified error handling and validation flow for clearer messages.

- Add constants for file size calculation (1024), spinner delay (100ms)
- Extract hardcoded URLs for GitHub issues, sponsors, and Buy Me Coffee
- Replace hardcoded messages with constants for better maintainability
- Replace magic number 55 with TableWidth constant
- Improves code maintainability by centralizing configuration values
- Extract DisplayHeader method to handle version display and ASCII art
- Extract DisplaySupportInfo method to handle support key display
- Extract IsVersionRequest method to check for version arguments
- Extract LoadSettingsFileIfProvided method to handle settings file loading
- Extract ShowPathFilteringWarnings method to display path filtering warnings
- Extract ShowSuccessSummary method to display success metrics
- Extract ShowDonationBanner method to display donation information
- Extract HandleException method to handle all exception scenarios

This reduces the ExecuteAsync method from ~250 lines to ~30 lines and significantly improves maintainability by separating concerns.
- Add constants for file column widths (FileNameColumnWidth, FileSizeColumnWidth, FileLinesColumnWidth)
- Extract HTTP status codes as constants (SuccessStatusCodes, StatusCode2XX, DefaultResponseKey)
- Add content type constants (MultipartFormDataContentType, ApplicationJsonContentType)
- Replace hardcoded column widths in file formatting with named constants
- Replace hardcoded content types with constants for better maintainability

This improves code readability and makes it easier to modify formatting and content types consistently across the codebase.
- Create ShouldGenerateHeaderParameter method to improve readability
- Replace complex boolean expression with three conditions (securityScheme.Type == ApiKey && securityScheme.In == Header && !already exists)
- Improves code maintainability by making the condition logic more explicit and testable

This addresses a complex conditional expression that was hard to read and understand.
- Break down complex SelectMany and GroupBy chain into clearer intermediate variables
- Use meaningful variable names (pathOperations, group.Key) instead of (k, v, kv)
- Split complex expression into two distinct operations
- Improve code maintainability by making the data transformation more explicit

This addresses a complex LINQ expression that was hard to understand and maintain.
Copilot AI review requested due to automatic review settings September 17, 2025 20:41
@coderabbitai

coderabbitai Bot commented Sep 17, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Refactors across core generators and CLI. Centralizes constants for status codes and content-types, reorganizes interface grouping logic, extracts helper for header-parameter decision, and modularizes GenerateCommand with constants, helpers, validation, output formatting, spinner timing, error handling, and analytics. No public API signature changes.

Changes

Cohort / File(s) Summary
Header parameter extraction refactor
src/Refitter.Core/ParameterExtractor.cs
Extracts header-security decision into private ShouldGenerateHeaderParameter helper; GetParameters now calls the helper. Behavior unchanged.
Interface generator constants and content-type handling
src/Refitter.Core/RefitInterfaceGenerator.cs
Introduces private constants for status codes, response keys, and content-types. Refactors GetTypeName and generation branches to use these constants. No control-flow change.
Grouping by tag/interface reorganization
src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs
Replaces custom Key/Combined grouping with IGrouping-based flow. Iteration and lookups now use group.Key. Naming clarifications; behavior preserved.
CLI generation flow modularization and UI constants
src/Refitter/GenerateCommand.cs
Adds numerous private constants; extracts helpers for header/support display, validation, settings loading, success summary, donation banners, and exception handling. Standardizes spinner delay, table widths, file-size formatting, URLs, and output paths. Public signatures unchanged.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant CLI as GenerateCommand
  participant Conf as Settings Loader
  participant Val as OpenAPI Validator
  participant Gen as Generator
  participant W as Writer
  participant A as Analytics

  rect rgba(230,240,255,0.5)
    User->>CLI: run refitter generate [options]
    CLI->>CLI: DisplayHeader(settings)
    CLI->>Conf: LoadSettingsFileIfProvided(...)
    CLI->>CLI: IsVersionRequest?
  end

  alt Validation enabled
    CLI->>Val: ValidateOpenApiSpec(path)
    Val-->>CLI: validation result
  else Skip validation
    CLI-->>CLI: proceed
  end

  CLI->>Gen: Build generator from settings
  alt Multiple output files
    CLI->>W: WriteMultipleFiles(...)
    CLI-->>CLI: Spinner (delay)
  else Single output file
    CLI->>W: WriteSingleFile(...)
    CLI-->>CLI: Spinner (delay)
  end

  CLI->>CLI: ShowSuccessSummary(...)
  CLI->>A: LogFeatureUsage
  CLI-->>User: Success message

  opt Error
    CLI->>CLI: HandleException(ex, settings)
    CLI-->>User: Error details and support info
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement, .NET

Poem

I thump my paw—new constants spring,
Tags regrouped, neat files we bring.
Headers whisper, helpers sing,
Spinners twirl on silky string.
JSON, multipart—types in line,
Generate, validate—looking fine.
Carrot commits! Ship the shine. 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "Resolve SonarCloud Issues" accurately reflects the PR's stated goal and the changes in the diff (extracting constants, simplifying LINQ, and refactoring methods to address SonarCloud warnings), is concise and directly related to the main intent, and is clear enough for a teammate scanning history to understand the primary purpose.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch sonar-cloud-issues

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR addresses SonarCloud code quality issues by improving maintainability through constant extraction, method refactoring, and LINQ simplification. The changes focus on reducing method complexity, eliminating magic numbers, and making the codebase more maintainable.

  • Extract magic numbers and hardcoded strings into named constants for better readability
  • Refactor large methods into smaller, focused helper methods to reduce complexity
  • Simplify LINQ queries for improved readability and performance

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
src/Refitter/GenerateCommand.cs Major refactoring extracting constants, breaking down large methods into focused helper methods
src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs Simplified LINQ query structure by extracting intermediate variables
src/Refitter.Core/RefitInterfaceGenerator.cs Extracted HTTP status codes and content type constants
src/Refitter.Core/ParameterExtractor.cs Extracted complex conditional logic into a named helper method

}
}

if (settings.SkipValidation == false)

Copilot AI Sep 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use !settings.SkipValidation instead of == false for better readability and consistency with C# conventions.

Suggested change
if (settings.SkipValidation == false)
if (!settings.SkipValidation)

Copilot uses AI. Check for mistakes.
if (settings.SimpleOutput)
{
Console.WriteLine("Suggestion");
Console.WriteLine("Try using the --skip-validation argument.");

Copilot AI Sep 17, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hardcoded string should use the existing constant SkipValidationSuggestion that was defined at the top of the class for consistency.

Suggested change
Console.WriteLine("Try using the --skip-validation argument.");
Console.WriteLine(SkipValidationSuggestion);

Copilot uses AI. Check for mistakes.
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Sep 17, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.52%. Comparing base (9537523) to head (dfa9c1d).
⚠️ Report is 18 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #754      +/-   ##
==========================================
+ Coverage   95.47%   98.52%   +3.05%     
==========================================
  Files          60       60              
  Lines        2982     2918      -64     
==========================================
+ Hits         2847     2875      +28     
+ Misses        102        4      -98     
- Partials       33       39       +6     
Flag Coverage Δ
unittests 98.52% <ø> (+3.05%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/Refitter/GenerateCommand.cs (3)

49-72: Good modularization of display logic.

The extraction of display logic into separate methods (DisplayHeader, DisplaySupportInfo, ShowSuccessSummary, ShowDonationBanner) improves code organization. However, consider further consolidation.

Consider creating a UIHelper or DisplayManager class to encapsulate all display-related methods, which would further improve separation of concerns:

+internal static class UIHelper
+{
+    public static void DisplayHeader(Settings settings) { ... }
+    public static void DisplaySupportInfo(Settings settings) { ... }
+    // ... other display methods
+}

698-711: Consider adding error handling for settings file loading.

The settings file loading could fail due to file access issues or invalid JSON. Consider wrapping this in appropriate error handling.

 private static async Task<RefitGeneratorSettings> LoadSettingsFileIfProvided(Settings settings, RefitGeneratorSettings refitGeneratorSettings)
 {
     if (!string.IsNullOrWhiteSpace(settings.SettingsFilePath))
     {
-        var json = await File.ReadAllTextAsync(settings.SettingsFilePath);
-        refitGeneratorSettings = Serializer.Deserialize<RefitGeneratorSettings>(json);
+        try
+        {
+            var json = await File.ReadAllTextAsync(settings.SettingsFilePath);
+            refitGeneratorSettings = Serializer.Deserialize<RefitGeneratorSettings>(json);
+        }
+        catch (FileNotFoundException)
+        {
+            throw new InvalidOperationException($"Settings file not found: {settings.SettingsFilePath}");
+        }
+        catch (JsonException ex)
+        {
+            throw new InvalidOperationException($"Invalid JSON in settings file: {ex.Message}");
+        }
         refitGeneratorSettings.OpenApiPath = settings.OpenApiPath!;

841-844: Minor: Inconsistent constant usage for validation suggestion.

While SkipValidationSuggestion constant is defined, the simple output mode on line 836 uses a hardcoded string instead of the constant.

             if (settings.SimpleOutput)
             {
                 Console.WriteLine("Suggestion");
-                Console.WriteLine("Try using the --skip-validation argument.");
+                Console.WriteLine(SkipValidationSuggestion.Replace("💡 ", ""));
                 Console.WriteLine();
             }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cddd996 and dfa9c1d.

📒 Files selected for processing (4)
  • src/Refitter.Core/ParameterExtractor.cs (2 hunks)
  • src/Refitter.Core/RefitInterfaceGenerator.cs (4 hunks)
  • src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs (2 hunks)
  • src/Refitter/GenerateCommand.cs (13 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.cs: Follow existing C# coding conventions defined in .editorconfig
Use PascalCase for public members
Use camelCase for parameters and local variables
Include XML documentation for public APIs
Use meaningful variable and method names

Files:

  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/ParameterExtractor.cs
  • src/Refitter.Core/RefitInterfaceGenerator.cs
  • src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs
src/Refitter/GenerateCommand.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Map new CLI option in CreateRefitGeneratorSettings() within src/Refitter/GenerateCommand.cs

Files:

  • src/Refitter/GenerateCommand.cs
src/Refitter.Core/RefitInterfaceGenerator.cs

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Implement generation logic for new options in src/Refitter.Core/RefitInterfaceGenerator.cs (or related generator classes)

Files:

  • src/Refitter.Core/RefitInterfaceGenerator.cs
🧠 Learnings (3)
📚 Learning: 2025-09-17T20:15:55.699Z
Learnt from: CR
PR: christianhelle/refitter#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-17T20:15:55.699Z
Learning: Applies to src/Refitter/GenerateCommand.cs : Map new CLI option in CreateRefitGeneratorSettings() within src/Refitter/GenerateCommand.cs

Applied to files:

  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/RefitInterfaceGenerator.cs
📚 Learning: 2025-09-17T20:15:55.699Z
Learnt from: CR
PR: christianhelle/refitter#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-17T20:15:55.699Z
Learning: Applies to src/Refitter.Core/Settings/RefitGeneratorSettings.cs : Add corresponding property to src/Refitter.Core/Settings/RefitGeneratorSettings.cs for new CLI options

Applied to files:

  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/RefitInterfaceGenerator.cs
📚 Learning: 2025-09-17T20:15:55.699Z
Learnt from: CR
PR: christianhelle/refitter#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-17T20:15:55.699Z
Learning: Applies to src/Refitter.Core/RefitInterfaceGenerator.cs : Implement generation logic for new options in src/Refitter.Core/RefitInterfaceGenerator.cs (or related generator classes)

Applied to files:

  • src/Refitter/GenerateCommand.cs
  • src/Refitter.Core/RefitInterfaceGenerator.cs
  • src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs
🧬 Code graph analysis (3)
src/Refitter/GenerateCommand.cs (4)
src/Refitter.Core/RefitGenerator.cs (4)
  • Task (22-31)
  • Task (33-43)
  • RefitGenerator (10-309)
  • OpenApiDocument (45-61)
src/Refitter/Analytics.cs (2)
  • Task (105-126)
  • Analytics (11-127)
src/Refitter/Settings.cs (1)
  • Settings (7-256)
src/Refitter.Core/Serializer.cs (1)
  • Serializer (10-38)
src/Refitter.Core/ParameterExtractor.cs (1)
src/Refitter.Tests/XmlDocumentationGeneratorTests.cs (1)
  • CSharpOperationModel (21-26)
src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs (2)
src/Refitter.Core/XmlDocumentationGenerator.cs (2)
  • AppendInterfaceDocumentation (37-45)
  • AppendInterfaceDocumentation (53-65)
src/Refitter.Core/RefitMultipleInterfaceGenerator.cs (1)
  • GenerateInterfaceDeclaration (102-109)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: 👌 Verify build
  • GitHub Check: script
🔇 Additional comments (14)
src/Refitter.Core/ParameterExtractor.cs (2)

54-58: LGTM! Clean extraction of header parameter logic.

The refactoring successfully extracts the condition into a well-named helper method ShouldGenerateHeaderParameter, improving readability while preserving the exact behavior.


307-312: LGTM! Well-structured helper method.

The private helper method follows good practices - descriptive name, clear parameter types, and appropriate placement at the end of the class.

src/Refitter.Core/RefitInterfaceGenerator.cs (3)

128-143: LGTM! Clean refactoring using the new constants.

The GetTypeName method now uses the centralized constants (SuccessStatusCodes, StatusCode2XX, DefaultResponseKey) consistently, eliminating magic strings while preserving the logical flow.


191-194: LGTM! Consistent use of content type constant.

The multipart form-data check now uses the centralized constant.


227-231: LGTM! Content type handling properly uses constants.

Both JSON content type detection and multipart form-data gating now use the centralized constants, maintaining consistency across the codebase.

src/Refitter.Core/RefitMultipleInterfaceByTagGenerator.cs (2)

26-30: LGTM! Cleaner grouping logic with improved clarity.

The refactoring to use LINQ's SelectMany with descriptive parameter names (pathItem, operation) followed by GroupBy creates a more readable two-step approach. The use of IGrouping<string, ...> simplifies the iteration pattern.


35-63: LGTM! Consistent use of group.Key throughout.

All references have been properly updated from kv.Key to group.Key, maintaining the same behavior while working with the cleaner grouping structure.

src/Refitter/GenerateCommand.cs (7)

15-28: LGTM! Well-chosen constants improve maintainability.

The extraction of magic numbers and strings into descriptive constants makes the code more maintainable and self-documenting. The constants are appropriately named and grouped logically.


141-141: LGTM! Consistent use of spinner delay constant.

The hardcoded delay values have been properly replaced with the SpinnerDelayMs constant.

Also applies to: 219-219


232-234: LGTM! Improved table formatting with constants.

The use of column width constants (FileNameColumnWidth, FileSizeColumnWidth, FileLinesColumnWidth, TableWidth) makes the output formatting consistent and easily adjustable.

Also applies to: 272-273, 299-300, 323-324


407-409: LGTM! URL constants improve maintainability.

Centralizing URLs as constants makes them easier to update and reduces duplication between the regular and simple output modes.

Also applies to: 425-428


639-672: LGTM! Well-structured header display with ASCII art.

The header display is cleanly implemented with appropriate branching for simple vs. rich output modes.


775-876: Excellent error handling consolidation.

The HandleException method effectively centralizes all error handling logic, including special cases for OpenAPI version issues, validation suggestions, and telemetry. This reduces code duplication and ensures consistent error handling throughout the application.


192-199: LGTM! File size formatting properly uses constant.

The FormatFileSize method now uses the FileSize1024 constant instead of the magic number.

Comment on lines +11 to +19

// HTTP Status Code Constants
private static readonly string[] SuccessStatusCodes = { "200", "201", "203", "206" };
private const string StatusCode2XX = "2XX";
private const string DefaultResponseKey = "default";

// Content Type Constants
private const string MultipartFormDataContentType = "multipart/form-data";
private const string ApplicationJsonContentType = "application/json";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

LGTM! Well-organized constants improve maintainability.

The extraction of HTTP status codes and content type literals into clearly-named constants reduces magic strings and improves code maintainability. The grouping with comments enhances readability.

Since these constants represent critical values used in HTTP API generation, let me verify they match common OpenAPI specifications and HTTP standards:


🌐 Web query:

What are the standard HTTP 2xx success status codes and their meanings?

💡 Result:

Standard HTTP 2xx success status codes (common official ones) and meanings:

  • 200 OK — request succeeded; payload depends on method. [1][2]
  • 201 Created — request succeeded and a new resource was created. [1][2]
  • 202 Accepted — request accepted for processing, but not completed yet. [1][2]
  • 203 Non‑Authoritative Information — response is from a transforming proxy; not authoritative. [1][2]
  • 204 No Content — request succeeded; no message body in the response. [1][2]
  • 205 Reset Content — request succeeded; client should reset document/view. [1][2]
  • 206 Partial Content — partial GET response (range requests). [1][2]
  • 207 Multi‑Status — WebDAV multi-status response (multiple independent operations). [1]
  • 208 Already Reported — WebDAV: members of a DAV binding already reported. [1]
  • 226 IM Used — server fulfilled a GET with instance-manipulations (Delta encoding). [1]

Sources: IANA HTTP Status Code Registry (official list) and the HTTP RFCs. [1][2]


Action: Add missing 2xx codes or justify their omission.
The SuccessStatusCodes array in src/Refitter.Core/RefitInterfaceGenerator.cs (lines 11–19) currently contains {"200","201","203","206"} but omits standard 2xx codes 202, 204, 205, 207, 208, 226 (per IANA/RFC); add the missing codes or document/handle intentional omissions to avoid misclassifying successful responses.

🤖 Prompt for AI Agents
In src/Refitter.Core/RefitInterfaceGenerator.cs around lines 11 to 19, the
SuccessStatusCodes array currently lists only "200","201","203","206" but omits
other standard 2xx codes (202, 204, 205, 207, 208, 226); update the array to
include the full set of IANA/RFC 2xx codes or, if certain codes are
intentionally excluded, add a clear comment explaining why and ensure any
status-checking logic treats the full 2xx range ("2XX") as successful (or
explicitly maps excluded codes to non-success) so successful responses are not
misclassified.

@christianhelle
christianhelle deleted the sonar-cloud-issues branch September 20, 2025 11:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants