Skip to content

Commit

Permalink
Git extension integration in Repository Management. (#3896)
Browse files Browse the repository at this point in the history
* Refining Repository Management's UI. (#3557)

* Adding the Repository tool

* WIP

* View is set up.  Test ata as well.

* Aligning columns.  Adding column spacing.

* Reverting this change

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/Strings/en-us/Resources.resw

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Adressing comments

* Revert "Reverting this change"

This reverts commit 711dd78.

* Moving to experimental

* Disabling by default

* Removing from experimental.  Addressing comments.

* Reverting to main

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/DevHome.RepositoryManagement.csproj

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/Extensions/ServiceExtensions.cs

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Removing duplicate xaml code

* Adding to the mermaid diagram

* Got lost in the shuffle

* Removing a refrence

---------

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Adding EF core, database project, and some usage. (#3674)

* WIP

* EF works.  Can save data.

* Can read and write. :)

* Repos are added when cloned.

* Putting save/load into a different class

* Adding default values

* Cleaning up names and using statements

* More comments

* Removing refrence to the public nuget

* Restoring the nuget config

* Adding a test.  Better defining dates

* Adding some tests

* More comments.

* Better path comparison.

* Removing unused equals code

* Adding more comments.  Making new migrations

* Moving this to experimental

* WIP

* Some telemetry and logging

* THings build again.

* Returning this back

* I believe I am understanding this.

* Can update

* Almost done with open in FE

* Try/Catching everything.  Open in FE should be done.

* Open in CMD works. :)

* Re-adding changes lost due to merge

* Getting saving straightened out.

* WIP

* Move Repository done.

* Removing 1:1.  Finishing RemoveFromList

* Adding _items

* Adding configuration file information to the repository table

* Opening the configuration file location in FE

* Deleting a repository.

* Add to winget configuration file.

* Cleaning up the code

* Icon for a configuration file.  UI updates when hiding a repo

* All the buttons do something.

* Removing 'local'

* Making sure the test works

* New test works

* Another TODO

* Fixing more things before PR.

* Removing another un-used using.

* MOre un used usings.

* Another Todo

* Anotehr TODO

* Localized strings

* WIP

* Adding enhanced information if it can be found.

* Commit, Filtering, and Sorting.

* Fixing up the merge

* Removing Move/Delete because of a bug in FileExplorerGitIntegration.

* Adding a TODO

* A small commit

* Removing some unused usings

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/Strings/en-us/Resources.resw

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/Strings/en-us/Resources.resw

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Update tools/RepositoryManagement/DevHome.RepositoryManagement/Strings/en-us/Resources.resw

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>

* Adressing comments

* Adressing comments

* Addressing code quality comments

* Update database/DevHome.Database/DatabaseModels/RepositoryManagement/Repository.cs

Co-authored-by: Ryan Shepherd <ryansh@microsoft.com>

* Fixing some issues.

* Added a TODO

* Adding drop down to select a source control provider

* Hide source control selection

* FIxing indentation

---------

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>
Co-authored-by: Ryan Shepherd <ryansh@microsoft.com>
  • Loading branch information
3 people authored Oct 2, 2024
1 parent 9654c0e commit 3b8cba0
Show file tree
Hide file tree
Showing 29 changed files with 1,225 additions and 156 deletions.
2 changes: 1 addition & 1 deletion common/Models/ExperimentalFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public async Task OnToggledAsync()
[RelayCommand]
public void Open()
{
if (OpenPageKey != null)
if (!string.IsNullOrEmpty(OpenPageKey))
{
Application.Current.GetService<INavigationService>().NavigateTo(OpenPageKey, OpenPageParameter);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Diagnostics.Tracing;
using DevHome.Telemetry;
using Microsoft.Diagnostics.Telemetry.Internal;

namespace DevHome.Common.TelemetryEvents.DevHomeDatabase;

[EventData]
public class DevHomeDatabaseContextEvent : EventBase
{
public override PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance;

public string Step { get; } = string.Empty;

public int HResult { get; }

public string ExceptionMessage { get; } = string.Empty;

public DevHomeDatabaseContextEvent(string step)
{
Step = step;
}

public DevHomeDatabaseContextEvent(string step, Exception ex)
{
Step = step;
HResult = ex.HResult;
ExceptionMessage = ex.Message;
}

public override void ReplaceSensitiveStrings(Func<string, string> replaceSensitiveStrings)
{
// no sensitive strings to replace.
}
}
38 changes: 38 additions & 0 deletions common/TelemetryEvents/DevHomeDatabase/DevHomeDatabaseEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Diagnostics.Tracing;
using DevHome.Telemetry;
using Microsoft.Diagnostics.Telemetry.Internal;

namespace DevHome.Common.TelemetryEvents.DevHomeDatabase;

[EventData]
public class DevHomeDatabaseEvent : EventBase
{
public override PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance;

public string Step { get; } = string.Empty;

public int HResult { get; }

public string ExceptionMessage { get; } = string.Empty;

public DevHomeDatabaseEvent(string step)
{
Step = step;
}

public DevHomeDatabaseEvent(string step, Exception ex)
{
Step = step;
HResult = ex.HResult;
ExceptionMessage = ex.Message;
}

public override void ReplaceSensitiveStrings(Func<string, string> replaceSensitiveStrings)
{
// No sensitive strings to replace.
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System;
using System.Diagnostics.Tracing;
using DevHome.Telemetry;
using Microsoft.Diagnostics.Telemetry.Internal;

namespace DevHome.Common.TelemetryEvents.RepositoryManagement;

[EventData]
public class EnhanceRepositoryErrorEvent : EventBase
{
public override PartA_PrivTags PartA_PrivTags => PartA_PrivTags.ProductAndServicePerformance;

public string Action { get; } = string.Empty;

public int Hresult { get; }

public string ErrorMessage { get; } = string.Empty;

public string RepositoryName { get; } = string.Empty;

public EnhanceRepositoryErrorEvent(string action, int hresult, string errorMessage, string repositoryName)
{
Action = action;
Hresult = hresult;
ErrorMessage = errorMessage;
RepositoryName = repositoryName;
}

public override void ReplaceSensitiveStrings(Func<string, string> replaceSensitiveStrings)
{
// No sensitive strings to replace
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public class Repository
// This causes any fluent API statements to get ignored.
public string? RepositoryUri { get; set; }

public Guid? SourceControlClassId { get; set; }

public bool HasAssignedSourceControlProvider => SourceControlClassId.GetValueOrDefault() != Guid.Empty;

public DateTime? CreatedUTCDate { get; set; }

public DateTime? UpdatedUTCDate { get; set; }
Expand Down
1 change: 1 addition & 0 deletions database/DevHome.Database/DevHomeDatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
repositoryEntity.Property(x => x.CreatedUTCDate).HasDefaultValueSql("datetime()");
repositoryEntity.Property(x => x.UpdatedUTCDate).HasDefaultValueSql("datetime()");
repositoryEntity.Property(x => x.RepositoryUri).HasDefaultValue(string.Empty);
repositoryEntity.Property(x => x.SourceControlClassId).HasDefaultValue(Guid.Empty);
repositoryEntity.ToTable("Repository");
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
IsHidden = table.Column<bool>(type: "INTEGER", nullable: false),
ConfigurationFileLocation = table.Column<string>(type: "TEXT", nullable: true, defaultValue: string.Empty),
RepositoryUri = table.Column<string>(type: "TEXT", nullable: true, defaultValue: string.Empty),
SourceControlClassId = table.Column<Guid>(type: "TEXT", nullable: true, defaultValue: Guid.Empty),
CreatedUTCDate = table.Column<DateTime>(type: "TEXT", nullable: true, defaultValueSql: "datetime()"),
UpdatedUTCDate = table.Column<DateTime>(type: "TEXT", nullable: true, defaultValueSql: "datetime()"),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnType("TEXT")
.HasDefaultValue(string.Empty);
b.Property<Guid?>("SourceControlClassId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT")
.HasDefaultValue(Guid.Empty);
b.Property<DateTime?>("UpdatedUTCDate")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class RepositoryManagementDataAccessService

private readonly DevHomeDatabaseContextFactory _databaseContextFactory;

public RepositoryManagementDataAccessService(DevHomeDatabaseContextFactory databaseContextFactory)
public RepositoryManagementDataAccessService(
DevHomeDatabaseContextFactory databaseContextFactory)
{
_databaseContextFactory = databaseContextFactory;
}
Expand All @@ -30,28 +31,32 @@ public RepositoryManagementDataAccessService(DevHomeDatabaseContextFactory datab
/// Makes a new Repository entity with the provided name and location then saves it
/// to the database.
/// </summary>
/// <param name="repositoryName">The name of the repository to add.</param>
/// <param name="cloneLocation">The local location the repository is cloned to.</param>
/// <returns>The new repository. Can return null if the database threw an exception.</returns>
public Repository? MakeRepository(string repositoryName, string cloneLocation, Uri repositoryUri)
public Repository MakeRepository(string repositoryName, string cloneLocation, string repositoryUri)
{
return MakeRepository(repositoryName, cloneLocation, string.Empty, repositoryUri);
}

public Repository? MakeRepository(string repositoryName, string cloneLocation, string configurationFileLocationAndName, Uri repositoryUri)
public Repository MakeRepository(string repositoryName, string cloneLocation, string configurationFileLocationAndName, string repositoryUri)
{
return MakeRepository(repositoryName, cloneLocation, configurationFileLocationAndName, repositoryUri, null);
}

public Repository MakeRepository(string repositoryName, string cloneLocation, string configurationFileLocationAndName, string repositoryUri, Guid? sourceControlProviderClassId)
{
var existingRepository = GetRepository(repositoryName, cloneLocation);
if (existingRepository != null)
{
_log.Warning($"A Repository with name {repositoryName} and clone location {cloneLocation} exists in the repository already.");
_log.Information($"A Repository with name {repositoryName} and clone location {cloneLocation} exists in the repository already.");
return existingRepository;
}

Repository newRepo = new()
{
RepositoryName = repositoryName,
RepositoryClonePath = cloneLocation,
RepositoryUri = repositoryUri.ToString(),
RepositoryUri = repositoryUri,
SourceControlClassId = sourceControlProviderClassId,
};

if (!string.IsNullOrEmpty(configurationFileLocationAndName))
Expand All @@ -78,7 +83,7 @@ public RepositoryManagementDataAccessService(DevHomeDatabaseContextFactory datab
TelemetryFactory.Get<ITelemetry>().Log(
"DevHome_Database_Event",
LogLevel.Critical,
new DatabaseEvent(nameof(MakeRepository), ex));
new DevHomeDatabaseEvent(nameof(MakeRepository), ex));
return new Repository();
}

Expand Down Expand Up @@ -142,8 +147,6 @@ public bool UpdateCloneLocation(Repository repository, string newLocation)
return false;
}

// TODO: Figure out a method to update the entity in the database and
// the entity in memory.
// Maybe update the tracking information on repository. This way
// EF will catch the change.
repository.RepositoryClonePath = newLocation;
Expand Down Expand Up @@ -173,6 +176,38 @@ public bool UpdateCloneLocation(Repository repository, string newLocation)
return true;
}

public bool SetSourceControlId(Repository repository, Guid sourceControlId)
{
try
{
using var dbContext = _databaseContextFactory.GetNewContext();
var repositoryToUpdate = dbContext.Repositories.Find(repository.RepositoryId);
if (repositoryToUpdate == null)
{
_log.Warning($"{nameof(UpdateCloneLocation)} was called with a RepositoryId of {repository.RepositoryId} and it does not exist in the database.");
return false;
}

// TODO: Figure out a method to update the entity in the database and
// the entity in memory.
repository.SourceControlClassId = sourceControlId;
repositoryToUpdate.SourceControlClassId = sourceControlId;

dbContext.SaveChanges();
}
catch (Exception ex)
{
_log.Error(ex, "Exception when updating the clone location.");
TelemetryFactory.Get<ITelemetry>().Log(
"DevHome_Database_Event",
LogLevel.Critical,
new DatabaseEvent(nameof(UpdateCloneLocation), ex));
return false;
}

return true;
}

public void SetIsHidden(Repository repository, bool isHidden)
{
try
Expand Down Expand Up @@ -214,7 +249,6 @@ public void RemoveRepository(Repository repository)
}

dbContext.Repositories.Remove(repositoryToRemove);

dbContext.SaveChanges();
}
catch (Exception ex)
Expand Down
6 changes: 6 additions & 0 deletions settings/DevHome.Settings/Strings/en-us/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -583,4 +583,10 @@
<data name="RepositoryManagementExperiment_Name" xml:space="preserve">
<value>Repository Management</value>
</data>
<data name="RepositoryManagementSourceControlSelector_Description" xml:space="preserve">
<value>Toggle to allow tester to change the source control provider.</value>
</data>
<data name="RepositoryManagementSourceControlSelector_Name" xml:space="preserve">
<value>Show Souce Control Provider</value>
</data>
</root>
3 changes: 0 additions & 3 deletions src/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,6 @@ public App()
}).
ConfigureServices((context, services) =>
{
// Add databse connection
services.AddDatabase(context);
// Add Serilog logging for ILogger.
services.AddLogging(lb => lb.AddSerilog(dispose: true));
Expand Down
24 changes: 23 additions & 1 deletion src/NavConfig.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,28 @@
"openPage": {
"key": "DevHome.RepositoryManagement.ViewModels.RepositoryManagementMainPageView"
}
},
{
"identity": "RepositoryManagementSourceControlSelector",
"enabledByDefault": true,
"needsFeaturePresenceCheck": false,
"buildTypeOverrides": [
{
"buildType": "dev",
"enabledByDefault": false,
"visible": true
},
{
"buildType": "canary",
"enabledByDefault": false,
"visible": false
},
{
"buildType": "stable",
"enabledByDefault": false,
"visible": false
}
]
}
]
]
}
4 changes: 2 additions & 2 deletions src/Services/PageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ where assembly.GetName().Name == tool.Assembly
{
var enabledByDefault = experimentalFeature.EnabledByDefault;
var needsFeaturePresenceCheck = experimentalFeature.NeedsFeaturePresenceCheck;
var openPageKey = experimentalFeature.OpenPage.Key;
var openPageParameter = experimentalFeature.OpenPage.Parameter;
var openPageKey = experimentalFeature.OpenPage?.Key ?? string.Empty;
var openPageParameter = experimentalFeature.OpenPage?.Parameter ?? string.Empty;
var isVisible = true;
foreach (var buildTypeOverride in experimentalFeature.BuildTypeOverrides ?? Array.Empty<DevHome.Helpers.BuildTypeOverrides>())
{
Expand Down
Loading

0 comments on commit 3b8cba0

Please sign in to comment.