-
Notifications
You must be signed in to change notification settings - Fork 323
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
Changes from all commits
c4cbef3
0967d46
c243131
14100ee
caeaad9
8db7405
25b19ec
b908923
931b09d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -126,7 +126,7 @@ | |
<comment>Dev drive size free</comment> | ||
</data> | ||
<data name="DevDriveInsightsCard.Description" xml:space="preserve"> | ||
<value>All things, dev drives, optimizations, etc.</value> | ||
<value>All things, Dev Drives, optimizations, etc.</value> | ||
<comment>The description for the Dev Drive Insights settings card</comment> | ||
</data> | ||
<data name="DevDriveInsightsCard.Header" xml:space="preserve"> | ||
|
@@ -161,9 +161,9 @@ | |
<value>Enable end task in taskbar by right click</value> | ||
<comment>The description for the end task on task bar settings card</comment> | ||
</data> | ||
<data name="ExampleDevDriveLocation" xml:space="preserve"> | ||
<value>Example: E:\packages\pip</value> | ||
<comment>Example dev drive location</comment> | ||
<data name="ExampleText" xml:space="preserve"> | ||
<value>Example: </value> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is getting reflected. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
<comment>Example string, will be followed by a sample location to move the cache to a dev drive location</comment> | ||
</data> | ||
<data name="EndTaskOnTaskBar.Header" xml:space="preserve"> | ||
<value>End Task</value> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,15 +2,22 @@ | |
// Licensed under the MIT License. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Data.SqlTypes; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using CommunityToolkit.Mvvm.ComponentModel; | ||
using CommunityToolkit.Mvvm.Input; | ||
using DevHome.Common.Extensions; | ||
using DevHome.Common.Services; | ||
using DevHome.Common.TelemetryEvents; | ||
using DevHome.Telemetry; | ||
using Microsoft.UI.Xaml.Controls; | ||
using Serilog; | ||
using Windows.Media.Protection; | ||
using Windows.Storage.Pickers; | ||
using WinUIEx; | ||
using static Microsoft.Extensions.Logging.EventSource.LoggingEventSource; | ||
|
||
namespace DevHome.Customization.ViewModels.DevDriveInsights; | ||
|
||
|
@@ -19,6 +26,9 @@ namespace DevHome.Customization.ViewModels.DevDriveInsights; | |
/// </summary> | ||
public partial class OptimizeDevDriveDialogViewModel : ObservableObject | ||
{ | ||
[ObservableProperty] | ||
private List<string> _existingDevDriveLetters; | ||
|
||
[ObservableProperty] | ||
private string _exampleDevDriveLocation; | ||
|
||
|
@@ -40,11 +50,16 @@ public partial class OptimizeDevDriveDialogViewModel : ObservableObject | |
[ObservableProperty] | ||
private string _directoryPathTextBox; | ||
|
||
public OptimizeDevDriveDialogViewModel(string existingCacheLocation, string environmentVariableToBeSet) | ||
public OptimizeDevDriveDialogViewModel( | ||
string existingCacheLocation, | ||
string environmentVariableToBeSet, | ||
string exampleDevDriveLocation, | ||
List<string> existingDevDriveLetters) | ||
{ | ||
DirectoryPathTextBox = string.Empty; | ||
var stringResource = new StringResource("DevHome.Customization.pri", "DevHome.Customization/Resources"); | ||
ExampleDevDriveLocation = stringResource.GetLocalized("ExampleDevDriveLocation"); | ||
ExistingDevDriveLetters = existingDevDriveLetters; | ||
ExampleDevDriveLocation = stringResource.GetLocalized("ExampleText") + exampleDevDriveLocation; | ||
ChooseDirectoryPromptText = stringResource.GetLocalized("ChooseDirectoryPromptText"); | ||
MakeChangesText = stringResource.GetLocalized("MakeChangesText"); | ||
ExistingCacheLocation = existingCacheLocation; | ||
|
@@ -78,7 +93,20 @@ private async Task BrowseButtonClick(object sender) | |
} | ||
} | ||
|
||
private void MoveDirectory(string sourceDirectory, string targetDirectory) | ||
private string RemovePrivacyInfo(string input) | ||
{ | ||
var output = input; | ||
var userProfilePath = Environment.ExpandEnvironmentVariables("%userprofile%"); | ||
if (input.StartsWith(userProfilePath, StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
var index = input.LastIndexOf(userProfilePath, StringComparison.OrdinalIgnoreCase) + userProfilePath.Length; | ||
output = Path.Join("%userprofile%", input.Substring(index)); | ||
} | ||
|
||
return output; | ||
} | ||
|
||
private bool MoveDirectory(string sourceDirectory, string targetDirectory) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm on the fence about returning 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 |
||
{ | ||
try | ||
{ | ||
|
@@ -110,10 +138,13 @@ private void MoveDirectory(string sourceDirectory, string targetDirectory) | |
|
||
// Delete the source directory | ||
Directory.Delete(sourceDirectory, true); | ||
return true; | ||
} | ||
catch (Exception ex) | ||
{ | ||
Log.Error(ex, $"Error in MoveDirectory. Error: {ex}"); | ||
Log.Error($"Error in MoveDirectory. Error: {ex}"); | ||
TelemetryFactory.Get<ITelemetry>().LogError("DevDriveInsights_PackageCacheMoveDirectory_Error", LogLevel.Critical, new ExceptionEvent(ex.HResult, RemovePrivacyInfo(sourceDirectory))); | ||
return false; | ||
} | ||
} | ||
|
||
|
@@ -129,6 +160,19 @@ private void SetEnvironmentVariable(string variableName, string value) | |
} | ||
} | ||
|
||
private bool ChosenDirectoryInDevDrive(string directoryPath) | ||
{ | ||
foreach (var devDriveLetter in ExistingDevDriveLetters) | ||
{ | ||
if (directoryPath.StartsWith(devDriveLetter + ":", StringComparison.OrdinalIgnoreCase)) | ||
{ | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
} | ||
|
||
[RelayCommand] | ||
private void DirectoryInputConfirmed() | ||
{ | ||
|
@@ -137,9 +181,21 @@ private void DirectoryInputConfirmed() | |
if (!string.IsNullOrEmpty(directoryPath)) | ||
{ | ||
// Handle the selected folder | ||
// 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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
if (ChosenDirectoryInDevDrive(directoryPath)) | ||
{ | ||
if (MoveDirectory(ExistingCacheLocation, directoryPath)) | ||
{ | ||
SetEnvironmentVariable(EnvironmentVariableToBeSet, directoryPath); | ||
var existingCacheLocationVetted = RemovePrivacyInfo(ExistingCacheLocation); | ||
Log.Debug($"Moved cache from {existingCacheLocationVetted} to {directoryPath}"); | ||
TelemetryFactory.Get<ITelemetry>().Log("DevDriveInsights_PackageCacheMovedSuccessfully_Event", LogLevel.Critical, new ExceptionEvent(0, existingCacheLocationVetted)); | ||
} | ||
} | ||
else | ||
{ | ||
Log.Error($"Chosen directory {directoryPath} not on a dev drive."); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,12 +12,17 @@ | |
using DevHome.Customization.Helpers; | ||
using DevHome.Customization.ViewModels.DevDriveInsights; | ||
using DevHome.Customization.Views; | ||
using Microsoft.Internal.Windows.DevHome.Helpers; | ||
using Serilog; | ||
|
||
namespace DevHome.Customization.ViewModels; | ||
|
||
public partial class DevDriveInsightsViewModel : ObservableObject | ||
{ | ||
private readonly ShellSettings _shellSettings; | ||
|
||
public ObservableCollection<Breadcrumb> Breadcrumbs { get; } | ||
|
||
public ObservableCollection<DevDriveCardViewModel> DevDriveCardCollection { get; private set; } = new(); | ||
|
||
public ObservableCollection<DevDriveOptimizerCardViewModel> DevDriveOptimizerCardCollection { get; private set; } = new(); | ||
|
@@ -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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @krschau I know StyleCop changed recently. I remember StyleCop wanting all There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
||
private static readonly string _localAppDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); | ||
|
||
private static readonly string _userProfilePath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); | ||
|
||
private const string PackagesStr = "packages"; | ||
|
||
private const string CacheStr = "cache"; | ||
|
||
private const string ArchivesStr = "archives"; | ||
|
||
public DevDriveInsightsViewModel(IDevDriveManager devDriveManager, OptimizeDevDriveDialogViewModelFactory optimizeDevDriveDialogViewModelFactory) | ||
{ | ||
_shellSettings = new ShellSettings(); | ||
|
||
var stringResource = new StringResource("DevHome.Customization.pri", "DevHome.Customization/Resources"); | ||
Breadcrumbs = | ||
[ | ||
new(stringResource.GetLocalized("MainPage_Header"), typeof(MainPageViewModel).FullName!), | ||
new(stringResource.GetLocalized("DevDriveInsights_Header"), typeof(DevDriveInsightsViewModel).FullName!) | ||
]; | ||
|
||
_optimizeDevDriveDialogViewModelFactory = optimizeDevDriveDialogViewModelFactory; | ||
DevDriveManagerObj = devDriveManager; | ||
} | ||
|
@@ -237,17 +259,60 @@ public void UpdateListViewModelList() | |
EnvironmentVariable = "PIP_CACHE_DIR", | ||
CacheDirectory = new List<string> | ||
{ | ||
Path.Join(_localAppDataPath, "pip", "cache"), | ||
Path.Join(_localAppDataPath, "packages", "PythonSoftwareFoundation.Python"), | ||
Path.Join(_localAppDataPath, "pip", CacheStr), | ||
Path.Join(_localAppDataPath, PackagesStr, "PythonSoftwareFoundation.Python"), | ||
}, | ||
ExampleDirectory = Path.Join("D:", "packages", "pip", "cache"), | ||
ExampleSubDirectory = Path.Join(PackagesStr, "pip", CacheStr), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "NuGet cache (dotnet)", | ||
EnvironmentVariable = "NUGET_PACKAGES", | ||
CacheDirectory = new List<string> { Path.Join(_userProfilePath, ".nuget", "packages") }, | ||
ExampleDirectory = Path.Join("D:", "packages", "NuGet", "Cache"), | ||
CacheDirectory = new List<string> { Path.Join(_userProfilePath, ".nuget", PackagesStr) }, | ||
dhoehna marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ExampleSubDirectory = Path.Join(PackagesStr, "NuGet", CacheStr), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "Npm cache (NodeJS)", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this need localization? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think so because these are product names. |
||
EnvironmentVariable = "NPM_CONFIG_CACHE", | ||
CacheDirectory = new List<string> | ||
{ | ||
Path.Join(_appDataPath, "npm-cache"), | ||
Path.Join(_localAppDataPath, "npm-cache"), | ||
}, | ||
ExampleSubDirectory = Path.Join(PackagesStr, "npm"), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "Vcpkg cache", | ||
EnvironmentVariable = "VCPKG_DEFAULT_BINARY_CACHE", | ||
CacheDirectory = new List<string> | ||
{ | ||
Path.Join(_appDataPath, "vcpkg", ArchivesStr), | ||
Path.Join(_localAppDataPath, "vcpkg", ArchivesStr), | ||
}, | ||
ExampleSubDirectory = Path.Join(PackagesStr, "vcpkg"), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "Cargo cache (Rust)", | ||
EnvironmentVariable = "CARGO_HOME", | ||
CacheDirectory = new List<string> { Path.Join(_userProfilePath, ".cargo") }, | ||
ExampleSubDirectory = Path.Join(PackagesStr, "cargo"), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "Maven cache (Java)", | ||
EnvironmentVariable = "MAVEN_OPTS", | ||
CacheDirectory = new List<string> { Path.Join(_userProfilePath, ".m2") }, | ||
ExampleSubDirectory = Path.Join(PackagesStr, "m2"), | ||
}, | ||
new DevDriveCacheData | ||
{ | ||
CacheName = "Gradle cache (Java)", | ||
EnvironmentVariable = "GRADLE_USER_HOME", | ||
CacheDirectory = new List<string> { Path.Join(_userProfilePath, ".gradle") }, | ||
ExampleSubDirectory = Path.Join(PackagesStr, "gradle"), | ||
} | ||
]; | ||
|
||
|
@@ -261,13 +326,13 @@ public void UpdateListViewModelList() | |
} | ||
else | ||
{ | ||
var subDirectories = Directory.GetDirectories(_localAppDataPath + "\\Packages", "*", SearchOption.TopDirectoryOnly); | ||
var subDirectories = Directory.GetDirectories(Path.Join(_localAppDataPath, PackagesStr), "*", SearchOption.TopDirectoryOnly); | ||
var matchingSubdirectory = subDirectories.FirstOrDefault(subdir => subdir.StartsWith(cacheDirectory, StringComparison.OrdinalIgnoreCase)); | ||
if (Directory.Exists(matchingSubdirectory)) | ||
{ | ||
if (matchingSubdirectory.Contains("PythonSoftwareFoundation")) | ||
{ | ||
return Path.Join(matchingSubdirectory, "LocalCache", "Local", "pip", "cache"); | ||
return Path.Join(matchingSubdirectory, "LocalCache", "Local", "pip", CacheStr); | ||
} | ||
|
||
return matchingSubdirectory; | ||
|
@@ -307,12 +372,16 @@ public void UpdateOptimizerListViewModelList() | |
continue; | ||
} | ||
|
||
List<string> existingDevDriveLetters = ExistingDevDrives.Select(x => x.DriveLetter.ToString()).ToList(); | ||
|
||
var exampleDirectory = Path.Join(existingDevDriveLetters[0] + ":", cache.ExampleSubDirectory); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You sure that existingDevDriveLetters[0] will never be empty? #ByDesign There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
var card = new DevDriveOptimizerCardViewModel( | ||
_optimizeDevDriveDialogViewModelFactory, | ||
cache.CacheName!, | ||
existingCacheLocation, | ||
cache.ExampleDirectory!, // example location on dev drive to move cache to | ||
cache.EnvironmentVariable!); // environmentVariableToBeSet | ||
exampleDirectory!, // example location on dev drive to move cache to | ||
cache.EnvironmentVariable!, // environmentVariableToBeSet | ||
existingDevDriveLetters); | ||
DevDriveOptimizerCardCollection.Add(card); | ||
} | ||
|
||
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.There was a problem hiding this comment.
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,
Clear as mud :)
There was a problem hiding this comment.
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
toserviceProvider
or use some whitespace to make this layout more clear.