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

More caches added, other improvements #2551

Merged
merged 9 commits into from
Apr 10, 2024

Conversation

SohamDas2021
Copy link
Contributor

@SohamDas2021 SohamDas2021 commented Apr 8, 2024

Summary of the pull request

Adding more package caches listed in https://learn.microsoft.com/en-us/windows/dev-drive/#storing-package-cache-on-dev-drive for Dev Drive optimization.
The PR also consists of the following improvements:

  1. Partial auto refresh. After optimizing a cache, the user can return to Dev Drive insights and see the change reflected.
  2. Visibility on dev drive insights card is made conditional on the presence of dev drives.
  3. Breadcrumb bar back on
  4. Telemetry for Data team

References and relevant issues

Detailed description of the pull request / Additional comments

Validation steps performed

PR checklist

  • Closes #xxx
  • Tests added/passed
  • Documentation updated

@SohamDas2021 SohamDas2021 marked this pull request as ready for review April 8, 2024 21:24
// TODO: If chosen folder not a dev drive location, currently we no-op. Instead we should display the error.
MoveDirectory(ExistingCacheLocation, directoryPath);
SetEnvironmentVariable(EnvironmentVariableToBeSet, directoryPath);
// TODO: If chosen folder not a dev drive location, currently we no-op and log the error. Instead we should display the error.
Copy link
Contributor Author

@SohamDas2021 SohamDas2021 Apr 8, 2024

Choose a reason for hiding this comment

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

// TODO: If chosen folder not a dev drive location, currently we no-op and log the error. Instead we should display the error.

Filed #2563
@bbonaby #Closed

@@ -19,7 +19,7 @@ public static IServiceCollection AddWindowsCustomization(this IServiceCollection
services.AddSingleton<DeveloperFileExplorerViewModel>();
services.AddTransient<DeveloperFileExplorerPage>();

services.AddSingleton<OptimizeDevDriveDialogViewModelFactory>(sp => (cacheLocation, environmentVariable) => ActivatorUtilities.CreateInstance<OptimizeDevDriveDialogViewModel>(sp, cacheLocation, environmentVariable));
services.AddSingleton<OptimizeDevDriveDialogViewModelFactory>(sp => (cacheLocation, environmentVariable, exampleDevDriveLocation, existingDevDriveLetters) => ActivatorUtilities.CreateInstance<OptimizeDevDriveDialogViewModel>(sp, cacheLocation, environmentVariable, exampleDevDriveLocation, existingDevDriveLetters));
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

What is this doing? #Closed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was needed to pass parameters to the Dialog and from the caller UX and remove the DependencyProperties.

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry. Let me a bit more clear. I can't parse what this code is doing. I've never seen => being used twice.

Copy link
Collaborator

Choose a reason for hiding this comment

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

We also define a ViewModel factory this way in the Dashboard, I think I got the syntax from somewhere in SetupFlow. According to a robot,

The first part sp => indicates the input parameter of the lambda expression. In this case, sp represents the IServiceProvider instance that will be passed to the lambda expression.

The second part (cacheLocation, environmentVariable, exampleDevDriveLocation, existingDevDriveLetters) => represents the body of the lambda expression. It defines the logic that will be executed when the lambda expression is invoked.

The body of the lambda expression is ActivatorUtilities.CreateInstance<OptimizeDevDriveDialogViewModel>(sp, cacheLocation, environmentVariable, exampleDevDriveLocation, existingDevDriveLetters). It calls the ActivatorUtilities.CreateInstance method to create an instance of the OptimizeDevDriveDialogViewModel class, passing in the sp (service provider) and the three parameters.

Overall, the lambda expression defines a delegate that can be invoked to create an instance of the OptimizeDevDriveDialogViewModel class with the specified parameters, using the ActivatorUtilities.CreateInstance method.

Clear as mud :)

Copy link
Contributor

Choose a reason for hiding this comment

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

oh
two lambda's. Okay. I understand more.

Maybe add some comments, or expand sp to serviceProvider or use some whitespace to make this layout more clear.

<comment>Example dev drive location</comment>
<data name="ExampleText" xml:space="preserve">
<value>Example: </value>
<comment>Example string</comment>
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

NIT: Add more to the comments to differentiate this from an example. I thought this was a sample copy and pasted from online. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

}
catch (Exception ex)
{
Log.Error($"Error in MoveDirectory. Error: {ex}");
TelemetryFactory.Get<ITelemetry>().LogError("DevDriveInsights_PackageCacheMove_Error", LogLevel.Critical, new ExceptionEvent(ex.HResult, sourceDirectory));
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

This event is Package CacheMove. Another event below is PackageCacheMoved I suggest to Think of event names that differ more than 1 letter. #Resolved

@@ -78,7 +91,7 @@ private async Task BrowseButtonClick(object sender)
}
}

private void MoveDirectory(string sourceDirectory, string targetDirectory)
private int MoveDirectory(string sourceDirectory, string targetDirectory)
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

Please don't use the C++ return HResult pattern. Replace MoveDirectory with Directory.Move

Also, MoveDirectory handled the error. The error code shouldn't be returned. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Directory.Move cannot handle moving between drives.

I am using the error code in the caller. What is the alternative here other than using HResult pattern?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the normal C# way would be to return a bool indicating success. The == 0 below feels very out of place.

private static readonly string _localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);

private static readonly string _userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

private const string ExampleDevDriveDirStr = "D:";
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

This'll bit a bit awkward if the example shows D: but the user is already ising their D: drive. #Resolved

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a valid point. Let me switch to an existing dev drive.

},
new DevDriveCacheData
{
CacheName = "Npm cache (NodeJS)",
Copy link
Contributor

@dhoehna dhoehna Apr 9, 2024

Choose a reason for hiding this comment

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

Also, why are these values hard coded? Shouldn't we not be doing this so DevHome can stay generic? #ByDesign

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Currently for V1, we are only looking to optimize for these caches- https://learn.microsoft.com/en-us/windows/dev-drive/#storing-package-cache-on-dev-drive.

In future we are looking to extend this to allow the user to input the existing cache location and env variable so that it works for any package cache. But that design is not finalized yet.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this need localization?

Copy link
Contributor

Choose a reason for hiding this comment

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

Does this need localization?

I don't think so because these are product names.

<value>Example: E:\packages\pip</value>
<comment>Example dev drive location</comment>
<data name="ExampleText" xml:space="preserve">
<value>Example: </value>
Copy link
Collaborator

@krschau krschau Apr 9, 2024

Choose a reason for hiding this comment

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

Don't include space here, I'm not sure it gets translated. #ByDesign

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is getting reflected.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was referring to the files that aren't checked in, the ones translated to other languages. But it's probably fine.

@@ -78,7 +91,7 @@ private async Task BrowseButtonClick(object sender)
}
}

private void MoveDirectory(string sourceDirectory, string targetDirectory)
private int MoveDirectory(string sourceDirectory, string targetDirectory)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the normal C# way would be to return a bool indicating success. The == 0 below feels very out of place.

},
new DevDriveCacheData
{
CacheName = "Npm cache (NodeJS)",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Does this need localization?

behaviors:NavigationViewHeaderBehavior.HeaderMode="Always"
mc:Ignorable="d">
behaviors:NavigationViewHeaderBehavior.HeaderTemplate="{StaticResource BreadcrumbBarDataTemplate}"
behaviors:NavigationViewHeaderBehavior.HeaderContext="{x:Bind ViewModel}">

<Grid MaxWidth="{ThemeResource MaxPageContentWidth}" Margin="{ThemeResource ContentPageMargin}">
<Grid.RowDefinitions>
Copy link
Collaborator

@krschau krschau Apr 9, 2024

Choose a reason for hiding this comment

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

You don't need the RowDefinitions (or to set the Grid.Row on the ScrollView) since there's only one row.
This page will also have the #566 bug. #Resolved

@krschau
Copy link
Collaborator

krschau commented Apr 9, 2024

Please add some information to the description on this PR. #Resolved

@SohamDas2021
Copy link
Contributor Author

Added. Thx.


In reply to: 2046011290

@@ -78,7 +91,7 @@ private async Task BrowseButtonClick(object sender)
}
}

private void MoveDirectory(string sourceDirectory, string targetDirectory)
private bool MoveDirectory(string sourceDirectory, string targetDirectory)
Copy link
Contributor

@dhoehna dhoehna Apr 10, 2024

Choose a reason for hiding this comment

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

I'm on the fence about returning bool here. Line 172 does not do anything different if the move failed. In this context the caller can assume the move finished successfully if MoveDirectory didn't throw.

On the other, maybe other parts of the code branch depending on the result.

I'll leave it up to you. C# is a "If it does not throw, we're good" #WontFix

@@ -48,12 +53,29 @@ public partial class DevDriveInsightsViewModel : ObservableObject

private IEnumerable<IDevDrive> ExistingDevDrives { get; set; } = Enumerable.Empty<IDevDrive>();

private static readonly string _appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
Copy link
Contributor

Choose a reason for hiding this comment

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

@krschau I know StyleCop changed recently. I remember StyleCop wanting all readonly variables first. Did that change?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm still seeing this error if I don't follow the rule locally in the Dashboard project. All projects should use the same stylecop.json and globalsuppressions.cs. The static keyword seems to be making the error go away? Nothing in the doc for this rule explains what's happening.

https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1214.md

@@ -307,12 +372,20 @@ public void UpdateOptimizerListViewModelList()
continue;
}

List<string> existingDevDriveLetters = new List<string>();
Copy link
Contributor

@dhoehna dhoehna Apr 10, 2024

Choose a reason for hiding this comment

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

NIT: existingDevDriveLetters = ExistingDevDrives.Select(x => x.DriveLetter.ToString()).ToList; #Resolved

existingDevDriveLetters.Add(existingDevDrive.DriveLetter.ToString());
}

var exampleDirectory = Path.Join(existingDevDriveLetters[0] + ":", cache.ExampleSubDirectory);
Copy link
Contributor

@dhoehna dhoehna Apr 10, 2024

Choose a reason for hiding this comment

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

You sure that existingDevDriveLetters[0] will never be empty? #ByDesign

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this code never executes if there are no dev drives. We do not display Dev Drive Insights card at all.

@SohamDas2021 SohamDas2021 merged commit 48d70f2 into main Apr 10, 2024
4 checks passed
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.

3 participants