Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress Bar for Git solution download #4039

Merged
merged 9 commits into from
Dec 26, 2024

Conversation

GokulBothe99
Copy link
Contributor

@GokulBothe99 GokulBothe99 commented Dec 18, 2024

Thank you for your contribution.
Before submitting this PR, please make sure:

  • PR description and commit message should describe the changes done in this PR
  • Verify the PR is pointing to correct branch i.e. Release or Beta branch if the code fix is for specific release , else point it to master
  • Latest Code from master or specific release branch is merged to your branch
  • No unwanted\commented\junk code is included
  • No new warning upon build solution
  • Code Summary\Comments are added to my code which explains what my code is doing
  • Existing unit test cases are passed
  • New Unit tests are added for your development
  • Sanity Tests are successfully executed for New and Existing Functionality
  • Verify that changes are compatible with all relevant browsers and platforms.
  • After creating pull request there should not be any conflicts
  • Resolve all Codacy comments
  • Builds and checks are passed before PR is sent for review
  • Resolve code review comments
  • Update the Help Library document to match any feature changes

Summary by CodeRabbit

  • New Features

    • Added a new ProgressNotifier class for enhanced progress notifications during operations.
    • Introduced a xConnectButton for connecting and searching repositories on the Source Control Projects page.
    • Enhanced project downloading with progress reporting and cancellation capabilities.
    • Updated project retrieval methods to support progress notifications and cancellation.
    • Improved solution download process with progress logging.
    • Increased dimensions of the Source Control Projects page for better layout.
    • Updated project files to manage dependencies for LibGit2Sharp.
  • Bug Fixes

    • Improved error handling in various methods related to project retrieval and downloading.
  • Chores

    • Cleaned up project structure by removing obsolete files and adding new package references for LibGit2Sharp.
    • Updated project properties and package references in project files.

Copy link
Contributor

coderabbitai bot commented Dec 18, 2024

Walkthrough

This pull request introduces significant changes to the source control functionality across multiple projects. Key modifications include the removal of obsolete files and the addition of a new ProgressNotifier class for progress tracking and cancellation support during project retrieval operations. Updates to package references for LibGit2Sharp are also included, reflecting a cleanup of project dependencies. The changes enhance the user interface and experience during project downloads, allowing for better feedback and control over the download process.

Changes

File Change Summary
Ginger/Ginger/Ginger.csproj, Ginger/GingerCore/GingerCore.csproj, Ginger/GingerCoreNET/GingerCoreNET.csproj Added/Updated LibGit2Sharp package references; removed obsolete files.
Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml, Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs Added progress tracking UI elements and download cancellation support.
Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs, Ginger/GingerCore/SourceControl/SVNSourceControl.cs, Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs, Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs, Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs, Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs Updated GetProject method signatures to support progress notification and cancellation.
Ginger/GingerCoreCommon/UIElement/ProgressNotifier.cs New class for managing progress notifications and events.

Possibly related PRs

Suggested Reviewers

  • Maheshkale447

Poem

🐰 A Rabbit's Ode to Source Control Progress 🌟
With progress bars and cancellation's might,
Our code now dances with newfound delight.
LibGit2Sharp joins our merry refrain,
Tracking downloads without any pain.
Progress marches on, step by step so bright!


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (3)
Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (1)

Line range hint 529-597: Check for partial download edge cases.
The logic updates the UI for success/failure, but consider verifying partial downloads or network interruptions, ensuring consistent final states for the progress bar and text.

- bool getProjectResult = ...
+ // Possibly track partial progress or fail states 
+ bool getProjectResult = ...
Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs (1)

Line range hint 135-149: Implement progress tracking in GetProject method

The method signature has been updated to support progress tracking, but the implementation doesn't utilize these parameters. Consider updating the implementation to report progress during the clone operation.

 public override bool GetProject(string Path, string URI, ref string error, ProgressNotifier progressNotifier = null, CancellationToken cancellationToken = default)
 {
     RepositoryUrl = URI;
+    progressNotifier?.ReportProgress(0, "Initializing Git clone...");
+    try {
+        bool result = RunGITCommand(new object[] { "clone", GetCloneUrlString(), "." }, Path);
+        progressNotifier?.ReportProgress(100, "Clone completed");
+        return result;
+    }
+    catch (Exception ex) when (cancellationToken.IsCancellationRequested) {
+        error = "Operation cancelled by user";
+        return false;
+    }
-    return RunGITCommand(new object[] { "clone", GetCloneUrlString(), "." }, Path);
 }

Security: Avoid exposing credentials in URLs

The current implementation includes credentials in the Git URL, which could be logged or exposed. Consider using credential helper or environment variables.

 string GetCloneUrlString()
 {
     if (string.IsNullOrEmpty(SourceControlUser))
     {
         return URI;
     }
-    Uri url = new Uri(URI);
-    string scheme = url.Scheme;
-    return url.Scheme + @"://" + SourceControlUser + ":" + SourceControlPass + "@" + url.Host + url.AbsolutePath;
+    // Use credential helper instead
+    return URI;
 }
Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (1)

Line range hint 174-187: Improve error handling in GetLatest method

The method has a potential issue where it returns true even when the operation fails but there are no conflicts. Consider revising the logic to handle all failure cases.

Apply this diff to fix the error handling:

 public static bool GetLatest(string path, SourceControlBase SourceControl)
 {
     string error = string.Empty;
     List<string> conflictsPaths = [];
     if (!SourceControl.GetLatest(path, ref error, ref conflictsPaths))
     {
-        if (conflictsPaths.Count > 0)
-        {
-            Reporter.ToUser(eUserMsgKey.SourceControlUpdateFailed, error);
-            return false;
-        }
+        Reporter.ToUser(eUserMsgKey.SourceControlUpdateFailed, error);
+        return false;
     }
     return true;
 }
🧹 Nitpick comments (8)
Ginger/GingerCore/GeneralLib/GenericWindow.xaml.cs (2)

274-285: LGTM: Progress bar initialization follows existing patterns

The implementation maintains consistency with existing UI element handling. Consider extracting the magic number 10 into a constant for better maintainability.

+  private const int MIN_LEFT_MARGIN = 10;
   ...
   if (margin.Left < MIN_LEFT_MARGIN)
   {
-    margin.Left = 10;
+    margin.Left = MIN_LEFT_MARGIN;
   }

287-298: Consider refactoring duplicate initialization logic

The progress bar and text initialization blocks contain identical logic. Consider extracting the common initialization code into a helper method.

+  private void InitializeBottomPanelElement(FrameworkElement element)
+  {
+    if (element != null)
+    {
+      Thickness margin = element.Margin;
+      if (margin.Left < MIN_LEFT_MARGIN)
+      {
+        margin.Left = MIN_LEFT_MARGIN;
+      }
+      element.Margin = margin;
+      DockPanel.SetDock(element, Dock.Top);
+      BottomPanel.Children.Add(element);
+    }
+  }

   // Usage:
-  if (progressBar != null)
-  {
-    Thickness margin = progressBar.Margin;
-    if (margin.Left < 10)
-    {
-      margin.Left = 10;
-    }
-    progressBar.Margin = margin;
-    DockPanel.SetDock(progressBar, Dock.Top);
-    BottomPanel.Children.Add(progressBar);
-  }
+  InitializeBottomPanelElement(progressBar);
+  InitializeBottomPanelElement(progressBarText);
Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (3)

45-48: Initialize UI elements using dependency injection or XAML (optional).
While inline instantiation is concise, large-scale solutions often standardize UI instantiation in XAML for clarity and separation of concerns.


323-339: UI layout adjustments: margin & alignment.
The newly added progress bar and text block are well placed. Consider verifying that the dynamic resizing doesn't disrupt other UI elements in various window sizes.


598-605: Reset or dispose of the cancellation token source.
Currently, StopDownload() only cancels the token. Consider disposing or recreating the token source after cancellation to avoid reusing a canceled token source.

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (1)

446-507: Robust approach to Git fetch options and progress events.
The code effectively leverages fetch and transfer progress callbacks. Consider verifying large repository performance and memory usage. Also, ensure that OnCheckoutProgress logs partial file paths carefully to avoid PII or sensitive info.

Ginger/GingerCoreCommon/UIElement/ProgressNotifier.cs (1)

1-29: Clean event-driven progress utility.
This class is straightforward and well-documented. Consider using a thread-safe approach (e.g., lock or synchronization context) if multiple threads raise progress events.

Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml (1)

124-127: Consider adding progress indicators

Since we're implementing progress tracking, consider adding a progress bar and status text in this section of the UI.

 <Button x:Name="DownloadButton" Click="DownloadButton_Click"  Grid.Row="6" Grid.Column="1"  Content="Download Solution"  HorizontalAlignment="Right" Style="{StaticResource @InputButtonStyle}" Visibility="Collapsed"/>

+<StackPanel Grid.Row="6" Grid.Column="0" Orientation="Vertical" Margin="0,0,10,0">
+    <TextBlock x:Name="progressText" Text="" Style="{StaticResource @TextBlockStyle}"/>
+    <ProgressBar x:Name="progressBar" Height="20" Maximum="100" Visibility="Collapsed"/>
+</StackPanel>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1843b14 and c045fde.

⛔ Files ignored due to path filters (3)
  • Ginger/Ginger/DLLs/LibGit2Sharp.dll is excluded by !**/*.dll, !**/*.dll
  • Ginger/GingerCore/DLLs/LibGit2Sharp.dll is excluded by !**/*.dll, !**/*.dll
  • Ginger/GingerCoreNET/DLLS/LibGit2Sharp.dll is excluded by !**/*.dll, !**/*.dll
📒 Files selected for processing (14)
  • Ginger/Ginger/Ginger.csproj (1 hunks)
  • Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml (6 hunks)
  • Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (8 hunks)
  • Ginger/GingerCore/GeneralLib/General.cs (2 hunks)
  • Ginger/GingerCore/GeneralLib/GenericWindow.xaml.cs (2 hunks)
  • Ginger/GingerCore/GingerCore.csproj (1 hunks)
  • Ginger/GingerCore/SourceControl/SVNSourceControl.cs (3 hunks)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (3 hunks)
  • Ginger/GingerCoreCommon/UIElement/ProgressNotifier.cs (1 hunks)
  • Ginger/GingerCoreNET/GingerCoreNET.csproj (1 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (2 hunks)
🔇 Additional comments (21)
Ginger/GingerCore/GeneralLib/GenericWindow.xaml.cs (1)

57-57: LGTM: Constructor signature updated appropriately

The addition of optional FrameworkElement parameters maintains backward compatibility while enabling progress tracking functionality.

Ginger/GingerCore/GeneralLib/General.cs (2)

57-57: LGTM: Method signature updated consistently

The LoadGenericWindow signature update aligns with the GenericWindow constructor changes while maintaining backward compatibility.


73-73: LGTM: Window instantiation updated appropriately

The GenericWindow instantiation correctly includes the new progress tracking parameters while preserving existing functionality.

Ginger/GingerCore/GingerCore.csproj (1)

501-503: LGTM! LibGit2Sharp package reference added.

The addition of LibGit2Sharp and its native binaries packages with specific versions is appropriate for implementing Git functionality.

Ginger/GingerCoreNET/GingerCoreNET.csproj (1)

283-285: LGTM! LibGit2Sharp package reference added.

The migration from direct DLL reference to NuGet package management is a good practice for better dependency management.

Ginger/Ginger/Ginger.csproj (1)

717-717: Verify LibGit2Sharp version consistency across projects.

All projects should use the same version of LibGit2Sharp to avoid compatibility issues.

✅ Verification successful

LibGit2Sharp version is consistent across projects

The version check reveals that all projects using PackageReference are consistently using LibGit2Sharp version 0.31.0:

  • Ginger/Ginger/Ginger.csproj: Version="0.31.0"
  • Ginger/GingerCore/GingerCore.csproj: Version="0.31.0"
  • Ginger/GingerCoreNET/GingerCoreNET.csproj: Version="0.31.0"

Additionally, projects using LibGit2Sharp.NativeBinaries are also consistent with Version="2.0.323".

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check LibGit2Sharp package versions across all .csproj files
echo "Checking LibGit2Sharp package versions:"
rg -A 1 '<PackageReference Include="LibGit2Sharp"' --type csproj

Length of output: 186


Script:

#!/bin/bash
# Search for all .csproj files and then grep for LibGit2Sharp references
fd '\.csproj$' | xargs grep -A 1 'LibGit2Sharp'

Length of output: 1701

Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (5)

21-28: Use directives look good.
Bringing in the threading and UIElement namespaces is consistent with the new progress/cancellation features.


70-71: Proper event subscription for progress notifications.
This robustly ties the UI updates to the progress notifier. Ensure you unsubscribe from these events if the page is disposed to avoid potential memory leaks.


613-619: Avoid empty messages.
You skip updating progressText if the message is empty. Confirm that ignoring empty messages is intentional, especially if they might represent status placeholders.


626-632: Progress bar updates appear correct.
The method properly updates Maximum and Value. Ensure that total steps are never zero to avoid potential divide-by-zero or invalid range scenarios in other call sites.


266-280: ⚠️ Potential issue

Ensure thread-safety when toggling busy states.
Because you're updating shared flags (e.g. SourceControlIntegration.BusyInProcessWhileDownloading) and cancellation logic, confirm no race conditions exist if multiple downloads are triggered in parallel.

Ginger/GingerCore/SourceControl/SVNSourceControl.cs (1)

Line range hint 21-32: Imports for progress and threading.
These additions set up progress-based operations, yet the code doesn't seem to use them within the class except for optional parameters.

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2)

22-30: Threading and UI references.
Using these namespaces is consistent with the new approach. Validate minimal coupling with UI elements in this core class for maintainability.


512-515: ⚠️ Potential issue

Cancel logic in exception flow.
You handle cancellation gracefully, returning false if cancellation is requested. Confirm that partial Git clones (or leftover files) are cleaned up if cancellation occurs mid-transfer.

Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs (1)

20-20: LGTM!

The new using directives are correctly added to support progress tracking and cancellation functionality.

Also applies to: 26-26

Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs (1)

20-20: LGTM!

The new using directives are correctly added to support progress tracking and cancellation functionality.

Also applies to: 26-26

Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml (3)

12-12: LGTM!

The window height increase accommodates the new UI elements while maintaining proper spacing.

Also applies to: 14-14


24-24: LGTM!

The grid row height adjustment improves the overall layout balance.


115-117: LGTM!

The spacing between elements improves readability and visual hierarchy.

Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (1)

22-22: LGTM: Method signature enhancement with progress tracking and cancellation support

The addition of ProgressNotifier and CancellationToken parameters enhances the method's capability to support progress tracking and cancellation of long-running operations.

Also applies to: 130-130

Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (1)

Line range hint 153-167: LGTM: Robust error handling implementation

The implementation includes proper error handling with:

  • Null checks for error messages
  • Exception handling with logging
  • Proper propagation of progress and cancellation parameters

Ginger/Ginger/Ginger.csproj Outdated Show resolved Hide resolved
Ginger/GingerCore/SourceControl/SVNSourceControl.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (3)
Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (3)

45-48: Consider accessibility improvements for the progress bar.

The progress bar's light yellow background might not provide sufficient contrast for users with visual impairments. Consider using system colors or high-contrast colors that meet WCAG guidelines.

-progressBar.Background = System.Windows.Media.Brushes.LightYellow;
+progressBar.Background = System.Windows.Media.SystemColors.ControlLightBrush;

Also applies to: 70-71


323-338: Make progress bar height DPI-aware.

The fixed height of 16 pixels might not scale properly on high-DPI displays. Consider using WPF's device-independent units or system metrics.

-progressBar.Height = 16;
+progressBar.Height = SystemParameters.MenuBarHeight * 0.75; // Scales with system DPI

266-276: Add timeout handling for long-running downloads.

The download operation could potentially hang indefinitely. Consider implementing a timeout mechanism to prevent infinite waits.

+private const int DOWNLOAD_TIMEOUT_MINUTES = 30;

 private async Task DownloadSolution()
 {
     try
     {
+        using var timeoutCts = new CancellationTokenSource(TimeSpan.FromMinutes(DOWNLOAD_TIMEOUT_MINUTES));
+        using var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(timeoutCts.Token, _cancellationTokenSource.Token);
         // ... existing code ...
-        bool getProjectResult = await Task.Run(() => SourceControlIntegration.GetProject(mSourceControl, solutionInfo.LocalFolder, ProjectURI, progressNotifier, _cancellationTokenSource.Token));
+        bool getProjectResult = await Task.Run(() => SourceControlIntegration.GetProject(mSourceControl, solutionInfo.LocalFolder, ProjectURI, progressNotifier, linkedCts.Token));
     }
+    catch (OperationCanceledException) when (timeoutCts?.Token.IsCancellationRequested == true)
+    {
+        Reporter.ToUser(eUserMsgKey.StaticErrorMessage, $"Download timed out after {DOWNLOAD_TIMEOUT_MINUTES} minutes");
+    }
     // ... rest of the code ...
 }

Also applies to: 529-598

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c045fde and 9a57b82.

📒 Files selected for processing (3)
  • Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (8 hunks)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (2)
Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (2)

696-696: Simplify the return statement.

The redundant assignment to getProjectResult can be simplified.

-    return getProjectResult = SourceControlIntegration.GetProject(mSourceControl, sol.LocalFolder, ProjectURI, progressNotifier);
+    return SourceControlIntegration.GetProject(mSourceControl, sol.LocalFolder, ProjectURI, progressNotifier);

Line range hint 523-697: Consider refactoring the DownloadSolution method.

The method is quite long (175+ lines) and handles multiple responsibilities:

  1. Source control type determination and initialization
  2. Solution existence checking
  3. Project URI construction
  4. Solution update/download logic

Consider breaking it down into smaller, focused methods for better maintainability.

Suggested structure:

private static SourceControlBase InitializeSourceControl()
private static string ConstructProjectUri(SolutionInfo solution)
private static bool UpdateExistingSolution(SourceControlBase sourceControl, string solutionFolder, bool undoChanges, ProgressNotifier progress)
private static bool DownloadNewSolution(SourceControlBase sourceControl, string solutionFolder, string projectUri, ProgressNotifier progress)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a57b82 and cb929fa.

📒 Files selected for processing (2)
  • Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (4 hunks)
🔇 Additional comments (3)
Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (2)

23-23: LGTM: Required namespace for progress notification support.

The addition of the UIElement namespace is necessary for the ProgressNotifier functionality.


153-163: LGTM: Well-implemented progress tracking and error handling.

The changes effectively:

  1. Support progress tracking through ProgressNotifier
  2. Enable operation cancellation via CancellationToken
  3. Improve error handling by checking for empty error strings
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (1)

80-80: LGTM: Progress tracking initialization is well implemented.

The progress tracking setup is correctly implemented with proper event subscription and integration with the download operation.

Also applies to: 566-570

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (1)

Line range hint 454-472: Consider removing the old implementation

The old implementation of GetProject appears to be redundant now that we have the new implementation with progress tracking. The code is mostly duplicated.

Remove the old implementation since it's superseded by the new one with progress tracking.

♻️ Duplicate comments (1)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (1)

540-544: 🛠️ Refactor suggestion

Consider cleanup on cancellation

When a download is cancelled, partially downloaded files should be cleaned up.

🧹 Nitpick comments (3)
Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (1)

131-131: Consider adding XML documentation for the abstract method

The new abstract method lacks XML documentation explaining the purpose of the new parameters and their usage.

Add XML documentation:

+        /// <summary>
+        /// Gets a project from source control with progress tracking and cancellation support.
+        /// </summary>
+        /// <param name="Path">The local path where the project will be downloaded</param>
+        /// <param name="URI">The remote URI of the project</param>
+        /// <param name="error">Output parameter to capture any error messages</param>
+        /// <param name="progressNotifier">Optional progress notifier for reporting progress</param>
+        /// <param name="cancellationToken">Optional cancellation token to cancel the operation</param>
+        /// <returns>True if the operation is successful, otherwise false</returns>
         public abstract bool GetProject(string Path, string URI, ref string error, Amdocs.Ginger.Common.UIElement.ProgressNotifier progressNotifier = null, CancellationToken cancellationToken = default);
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2)

498-506: Consider adding progress message validation

The progress message is directly passed to the notifier without validation or sanitization.

 fetchOptions.OnProgress = progress =>
 {
-    progressNotifier.NotifyProgressDetailText($"{progress}");
+    var sanitizedProgress = !string.IsNullOrEmpty(progress) ? progress : "Processing...";
+    progressNotifier.NotifyProgressDetailText(sanitizedProgress);
     if (cancellationToken.IsCancellationRequested)
     {
         return false;
     }
     return true;
 };

529-533: Add null check for path parameter in checkout progress

The checkout progress callback should validate the path parameter before using it.

 co.OnCheckoutProgress = (path, completedSteps, totalSteps) =>
 {
-    progressNotifier.NotifyProgressDetailText($"{completedSteps}/{totalSteps}");
+    var message = !string.IsNullOrEmpty(path) 
+        ? $"Checking out: {path} ({completedSteps}/{totalSteps})"
+        : $"Checking out files: {completedSteps}/{totalSteps}";
+    progressNotifier.NotifyProgressDetailText(message);
     progressNotifier.NotifyProgressUpdated(completedSteps, totalSteps);
 };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb929fa and 8fed2ed.

📒 Files selected for processing (7)
  • Ginger/Ginger/Ginger.csproj (1 hunks)
  • Ginger/GingerCore/SourceControl/SVNSourceControl.cs (3 hunks)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs
  • Ginger/GingerCore/SourceControl/SVNSourceControl.cs
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs
  • Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs
🔇 Additional comments (5)
Ginger/Ginger/Ginger.csproj (2)

717-717: Check for redundant LibGit2Sharp references.

A previous review identified a redundant LibGit2Sharp.dll reference in the ProjectDll folder. Please ensure this has been addressed to avoid version conflicts.

#!/bin/bash
# Description: Check for redundant LibGit2Sharp references in the project

# Search for LibGit2Sharp references in the project file
rg -A 5 "LibGit2Sharp" Ginger/Ginger/Ginger.csproj

# Look for LibGit2Sharp.dll files
fd -e dll "LibGit2Sharp"

717-717: Verify the LibGit2Sharp package version.

The addition of LibGit2Sharp is appropriate for implementing Git operations with progress tracking. However, let's verify the version 0.31.0 for security and compatibility.

✅ Verification successful

LibGit2Sharp package reference is correctly implemented

The verification shows:

  • Only one LibGit2Sharp package reference exists in the project file, with no redundant .dll references
  • The package is actively used in the codebase (GingerCoreNET/SourceControl/GITSourceControl.cs)
  • Version 0.31.0 is the latest stable version available on NuGet
  • No security vulnerabilities were found for this package
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for latest versions and security advisories for LibGit2Sharp

# Check NuGet for latest versions
curl -s https://api.nuget.org/v3/registration5-gz-semver2/libgit2sharp/index.json | jq -r '.items[0].items[].catalogEntry | select(.version != null) | .version' | sort -V | tail -n 5

# Check for security advisories
gh api graphql -f query='
{
  securityVulnerabilities(first: 5, ecosystem: NUGET, package: "LibGit2Sharp") {
    nodes {
      advisory {
        summary
        severity
        publishedAt
      }
      vulnerableVersionRange
      firstPatchedVersion {
        identifier
      }
    }
  }
}'

Length of output: 590


Script:

#!/bin/bash
# Let's try a different approach to check for LibGit2Sharp references and versions
# First, check for any duplicate references to LibGit2Sharp
rg -i "libgit2sharp" Ginger/Ginger/Ginger.csproj

# Then check for any .dll references that might be redundant
rg -i "\.dll" Ginger/Ginger/Ginger.csproj

# Also check for any direct usage of LibGit2Sharp in the codebase
ast-grep --pattern 'using LibGit2Sharp;'

Length of output: 7618

Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (1)

22-23: LGTM: Required using directives added for async support

The addition of System.Threading and System.Threading.Tasks namespaces is necessary for the new cancellation and async functionality.

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2)

22-22: LGTM: Required using directives added

The addition of UIElement and Threading namespaces is necessary for the new progress tracking functionality.

Also applies to: 30-30


475-484: LGTM: Well-documented method signature

The XML documentation for the new implementation is clear and comprehensive.

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs Outdated Show resolved Hide resolved
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (1)

569-570: Consider enhancing error handling in the download process.

The current implementation only logs an error message when the download fails. Consider providing more detailed error information and potentially throwing an exception for better error handling upstream.

                if (!SourceControlIntegration.DownloadSolution(Solution, UndoSolutionLocalChanges, progressNotifier))
                {
-                    Reporter.ToLog(eLogLevel.ERROR, "Failed to Download/update Solution from source control");
+                    string errorMessage = "Failed to Download/update Solution from source control";
+                    Reporter.ToLog(eLogLevel.ERROR, errorMessage);
+                    throw new SourceControlException(errorMessage);
                }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f364b4b and 5ad7190.

📒 Files selected for processing (3)
  • Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs (8 hunks)
  • Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (3 hunks)
👮 Files not reviewed due to content moderation or server errors (2)
  • Ginger/Ginger/SourceControl/SourceControlProjectsPage.xaml.cs
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs
🔇 Additional comments (1)
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (1)

23-23: LGTM: Progress notification setup is clean and follows best practices.

The import and field initialization for progress notification are well-structured and use modern C# features appropriately.

Also applies to: 80-80

Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs Outdated Show resolved Hide resolved
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (2)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2)

484-551: ⚠️ Potential issue

Add cleanup for partially downloaded files on cancellation.

When a download is cancelled, the partially downloaded files remain on disk. Consider implementing cleanup to prevent leftover files.

 public override bool GetProjectWithProgress(string path, string uri, ref string error, ProgressNotifier progressNotifier = null, CancellationToken cancellationToken = default)
 {
+    bool downloadStarted = false;
     try
     {
         // ... existing code ...
         RepositoryRootFolder = LibGit2Sharp.Repository.Clone(uri, path, co);
+        downloadStarted = true;
         return true;
     }
     catch (Exception ex)
     {
         if (!cancellationToken.IsCancellationRequested)
         {
             error = ex.Message + Environment.NewLine + ex.InnerException;
         }
+        else if (downloadStarted)
+        {
+            try
+            {
+                if (Directory.Exists(path))
+                {
+                    Directory.Delete(path, recursive: true);
+                }
+            }
+            catch (Exception cleanupEx)
+            {
+                Reporter.ToLog(eLogLevel.WARN, $"Failed to cleanup cancelled download: {cleanupEx.Message}");
+            }
+        }
         return false;
     }
 }

499-525: ⚠️ Potential issue

Add null checks for progress parameters.

The code assumes that progress.TotalObjects is not zero, which could lead to a division by zero exception.

 fetchOptions.OnTransferProgress = progress =>
 {
+    if (progress.TotalObjects == 0)
+    {
+        progressNotifier.NotifyProgressDetailText("Initializing...");
+        return true;
+    }
     double percentage = (double)progress.ReceivedObjects / progress.TotalObjects * 100;
     progressNotifier.NotifyProgressDetailText($"{percentage:F2}%              {progress.ReceivedObjects}/{progress.TotalObjects} files downloaded.");
     progressNotifier.NotifyProgressUpdated(progress.ReceivedObjects, progress.TotalObjects);

     // Check for cancellation
     if (cancellationToken.IsCancellationRequested)
     {
         return false;
     }
     return true;
 };
🧹 Nitpick comments (2)
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (2)

80-80: Add XML documentation for the progressNotifier field.

Consider adding XML documentation to describe the purpose and usage of this field.

+        /// <summary>
+        /// Notifier for tracking and reporting progress during source control operations.
+        /// </summary>
         ProgressNotifier progressNotifier = new();

578-585: Enhance XML documentation for the event handler.

The current documentation could be more descriptive about the event's purpose and usage context.

         /// <summary>
-        /// Logs the progress text to the reporter.
+        /// Event handler that logs source control operation progress updates to the reporter.
+        /// This handler is used during solution download/update operations to provide feedback on the progress.
         /// </summary>
         /// <param name="sender">The ProgressNotifier that raised the event.</param>
         /// <param name="e">The progress message describing the current download status.</param>
         private void ProgressNotifier_ProgressText(object sender, string e)
         {
             Reporter.ToLog(eLogLevel.INFO, e);
         }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ad7190 and bc16498.

📒 Files selected for processing (7)
  • Ginger/GingerCore/SourceControl/SVNSourceControl.cs (3 hunks)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs (3 hunks)
  • Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs (2 hunks)
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • Ginger/GingerCoreCommon/SourceControlLib/SourceControlBase.cs
  • Ginger/GingerCoreNET/SourceControl/GitSourceControlShellWrapper.cs
  • Ginger/GingerCoreNET/SourceControl/SVNSourceControlShellWrapper.cs
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs
🔇 Additional comments (5)
Ginger/GingerCore/SourceControl/SVNSourceControl.cs (1)

32-32: LGTM!

The addition of the System.Threading namespace is appropriate for supporting cancellation tokens in the new GetProjectWithProgress method.

Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (3)

22-22: LGTM! Required using directives added.

The new using directives support the progress bar and cancellation functionality.

Also applies to: 30-30


Line range hint 454-472: Add error handling for directory creation.

The directory creation should include error handling as it could fail due to permissions or disk space issues.

 if (!System.IO.Directory.Exists(path))
 {
-    System.IO.Directory.CreateDirectory(path);
+    try 
+    {
+        System.IO.Directory.CreateDirectory(path);
+    }
+    catch (Exception ex)
+    {
+        error = $"Failed to create directory: {ex.Message}";
+        return false;
+    }
 }

475-483: LGTM! Well-documented method.

The XML documentation is comprehensive and clearly describes the method's purpose, parameters, and return value.

Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (1)

23-23: LGTM!

The added namespace is required for the ProgressNotifier functionality and is correctly placed.

Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (1)

475-551: 🛠️ Refactor suggestion

Add cleanup handling for canceled downloads.
When the user cancels mid-clone, partially downloaded files remain. Consider cleaning up the partially downloaded folder within the catch block or when returning false from OnTransferProgress. This avoids leaving incomplete data on disk.

catch (Exception ex)
{
    if (!cancellationToken.IsCancellationRequested)
    {
        error = ex.Message + Environment.NewLine + ex.InnerException;
    }
+   else
+   {
+       // Cleanup partially cloned folder
+       try
+       {
+           if (Directory.Exists(path))
+           {
+               Directory.Delete(path, recursive: true);
+           }
+       }
+       catch (Exception cleanupEx)
+       {
+           Reporter.ToLog(eLogLevel.WARN, $"Failed to clean up after cancellation: {cleanupEx.Message}");
+       }
+   }
    return false;
}
🧹 Nitpick comments (4)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (1)

Line range hint 454-472: Consider consolidating duplicate clone logic.
“GetProject” and “GetProjectWithProgress” both set up nearly identical FetchOptions and clone logic. You could reduce duplication by unifying them into a single core method that both call, differing only in optional progress/cancellation handling.

 public override bool GetProject(string path, string uri, ref string error)
 {
     try
     {
-        var fetchOptions = new FetchOptions
-        {
-            CredentialsProvider = GetSourceCredentialsHandler(),
-        };
-        var co = new CloneOptions(fetchOptions) { BranchName = string.IsNullOrEmpty(SourceControlBranch) ? "master" : SourceControlBranch };
-        RepositoryRootFolder = LibGit2Sharp.Repository.Clone(uri, path, co);
+        return InternalClone(path, uri, ref error);
     }
     catch (Exception ex)
     {
         error = ex.Message + Environment.NewLine + ex.InnerException;
         return false;
     }
     return true;
 }

 // Potentially shared logic
 private bool InternalClone(string path, string uri, ref string error, FetchOptions fetchOptions = null, CloneOptions cloneOptions = null)
 {
     // ...
     return true;
 }
Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (1)

Line range hint 153-175: Add XML documentation for the updated method signature.

The implementation looks good with proper error handling and progress tracking. Consider adding XML documentation to describe the new parameters.

+/// <summary>
+/// Gets a project from source control.
+/// </summary>
+/// <param name="SourceControl">The source control implementation to use.</param>
+/// <param name="Path">The local path where the project will be downloaded.</param>
+/// <param name="URI">The URI of the project in source control.</param>
+/// <param name="progressNotifier">Optional. Notifies about the download progress.</param>
+/// <param name="cancellationToken">Optional. Allows cancellation of the operation.</param>
+/// <returns>True if the project was successfully retrieved, false otherwise.</returns>
 public static bool GetProject(SourceControlBase SourceControl, string Path, string URI, ProgressNotifier progressNotifier = null, System.Threading.CancellationToken cancellationToken = default)
Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (2)

80-80: Consider making the field private.

The field initialization looks good, but consider making it private with readonly modifier since it's only used internally.

-        ProgressNotifier progressNotifier = new();
+        private readonly ProgressNotifier progressNotifier = new();

586-594: Enhance the XML documentation.

While the implementation is correct, the documentation could be more descriptive about the event handler's purpose and usage.

 /// <summary>
-/// Logs the progress text to the reporter.
+/// Handles progress notifications during solution download.
+/// Forwards progress messages to the application's logging system for tracking download status.
 /// </summary>
 /// <param name="sender">The ProgressNotifier that raised the event.</param>
 /// <param name="e">The progress message describing the current download status.</param>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc16498 and 75c6fc9.

📒 Files selected for processing (3)
  • Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (3 hunks)
  • Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (4 hunks)
🔇 Additional comments (6)
Ginger/GingerCoreNET/SourceControl/GITSourceControl.cs (2)

22-22: No issues with added import.
The imported namespace "Amdocs.Ginger.Common.UIElement" is presumably required elsewhere in the file.


30-30: Imports align with new concurrency and task usage.
The addition of System.Threading and System.Threading.Tasks is aligned with the new cancellation token and potential async calls.

Ginger/GingerCoreNET/SourceControl/SourceControlIntegration.cs (2)

23-23: LGTM!

The addition of the UIElement namespace is necessary for the ProgressNotifier functionality.


523-523: LGTM!

The method signature update and progress notification integration are implemented correctly.

Also applies to: 687-687

Ginger/GingerCoreNET/RunLib/CLILib/CLIHelper.cs (2)

23-23: LGTM!

The addition of the UIElement namespace is necessary for the ProgressNotifier functionality.


566-582: LGTM!

The implementation correctly handles:

  • Event subscription lifecycle
  • Error handling with try-catch
  • Proper cleanup with event unsubscription

@Maheshkale447 Maheshkale447 merged commit a7e26aa into master Dec 26, 2024
2 checks passed
@Maheshkale447 Maheshkale447 deleted the BugFix/Update_libGit2Sharp branch December 26, 2024 10:27
@coderabbitai coderabbitai bot mentioned this pull request Dec 26, 2024
15 tasks
@coderabbitai coderabbitai bot mentioned this pull request Feb 5, 2025
15 tasks
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