Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="CodingWithCalvin.VsixSdk/0.3.0">
<Project Sdk="CodingWithCalvin.VsixSdk/0.3.0">

<PropertyGroup>
<TargetFramework>net48</TargetFramework>
Expand All @@ -9,11 +9,8 @@
<UseWPF>true</UseWPF>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<DeployExtension>True</DeployExtension>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CodingWithCalvin.Otel4Vsix" Version="0.2.2" />
<PackageReference Include="Microsoft.VisualStudio.SDK" Version="17.14.40265" />
</ItemGroup>

Expand All @@ -29,4 +26,4 @@
</Content>
</ItemGroup>

</Project>
</Project>
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
using System.Collections.Generic;
using System.ComponentModel.Design;
using System.IO;
using System.Windows.Interop;
using System.Windows.Threading;
using CodingWithCalvin.ProjectRenamifier.Dialogs;
using CodingWithCalvin.ProjectRenamifier.Services;
using CodingWithCalvin.Otel4Vsix;
using EnvDTE;
using EnvDTE80;

Expand Down Expand Up @@ -44,6 +46,8 @@ private void Execute(object sender, EventArgs e)
{
ThreadHelper.ThrowIfNotOnUIThread();

using var activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.Execute");

if (!(ServiceProvider.GetService(typeof(DTE)) is DTE2 dte))
{
return;
Expand All @@ -63,9 +67,10 @@ private void RenameProject(Project project, DTE2 dte)
{
ThreadHelper.ThrowIfNotOnUIThread();

var currentName = Path.GetFileNameWithoutExtension(project.FullName);
using var activity = VsixTelemetry.StartCommandActivity("ProjectRenamifier.RenameProject");

var dialog = new RenameProjectDialog(currentName);
var currentName = Path.GetFileNameWithoutExtension(project.FullName);
var dialog = new RenameProjectDialog(currentName);

// Set the owner to the VS main window for proper modal behavior
var helper = new WindowInteropHelper(dialog)
Expand All @@ -75,13 +80,16 @@ private void RenameProject(Project project, DTE2 dte)

if (dialog.ShowDialog() != true)
{
VsixTelemetry.LogInformation("Rename cancelled by user");
return;
}

var newName = dialog.NewProjectName;
var projectFilePath = project.FullName;
var originalProjectFilePath = projectFilePath;

VsixTelemetry.LogInformation("Renaming project");

// Show progress dialog
var progressDialog = new RenameProgressDialog(currentName);
var progressHelper = new WindowInteropHelper(progressDialog)
Expand All @@ -93,7 +101,7 @@ private void RenameProject(Project project, DTE2 dte)
var stepIndex = 0;
var projectRemovedFromSolution = false;
var projectReaddedToSolution = false;
System.Collections.Generic.List<string> referencingProjects = null;
List<string> referencingProjects = null;
Project parentSolutionFolder = null;

try
Expand Down Expand Up @@ -172,13 +180,27 @@ private void RenameProject(Project project, DTE2 dte)
DoEvents();
System.Threading.Thread.Sleep(500);
progressDialog.Close();

activity?.SetTag("rename.success", true);
activity?.SetTag("rename.steps_completed", stepIndex);
VsixTelemetry.LogInformation("Successfully renamed project");
}
catch (Exception ex)
{
// Mark the current step as failed
progressDialog.FailStep(stepIndex, ex.Message);
DoEvents();

activity?.RecordError(ex);
activity?.SetTag("rename.success", false);
activity?.SetTag("rename.failed_step", stepIndex);

VsixTelemetry.TrackException(ex, new Dictionary<string, object>
{
{ "operation.name", "RenameProject" },
{ "step.index", stepIndex }
});

// Attempt rollback if project was removed but not re-added
if (projectRemovedFromSolution && !projectReaddedToSolution)
{
Expand All @@ -187,13 +209,16 @@ private void RenameProject(Project project, DTE2 dte)
// Try to re-add the project at its current location
var currentProjectPath = File.Exists(projectFilePath) ? projectFilePath : originalProjectFilePath;
if (File.Exists(currentProjectPath))
{
SolutionFolderService.AddProjectToSolution(dte.Solution, currentProjectPath, parentSolutionFolder);
{ SolutionFolderService.AddProjectToSolution(dte.Solution, currentProjectPath, parentSolutionFolder);
VsixTelemetry.LogInformation("Rollback: Re-added project");
}
}
catch
catch (Exception rollbackEx)
{
// Rollback failed, nothing more we can do
VsixTelemetry.TrackException(rollbackEx, new Dictionary<string, object>
{
{ "operation.name", "RenameProject.Rollback" }
});
}
}

Expand Down
7 changes: 7 additions & 0 deletions src/CodingWithCalvin.ProjectRenamifier/HoneycombConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace CodingWithCalvin.ProjectRenamifier
{
internal static class HoneycombConfig
{
public const string ApiKey = "PLACEHOLDER";
}
}
29 changes: 29 additions & 0 deletions src/CodingWithCalvin.ProjectRenamifier/ProjectRenamifierPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
global using Task = System.Threading.Tasks.Task;
using System.Runtime.InteropServices;
using System.Threading;
using CodingWithCalvin.Otel4Vsix;

namespace CodingWithCalvin.ProjectRenamifier
{
Expand All @@ -14,10 +15,38 @@ public sealed class ProjectRenamifierPackage : AsyncPackage
{
protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress<ServiceProgressData> progress)
{
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

var builder = VsixTelemetry.Configure()
.WithServiceName(VsixInfo.DisplayName)
.WithServiceVersion(VsixInfo.Version)
.WithVisualStudioAttributes(this)
.WithEnvironmentAttributes();

#if !DEBUG
builder
.WithOtlpHttp("https://api.honeycomb.io")
.WithHeader("x-honeycomb-team", HoneycombConfig.ApiKey);
#endif

builder.Initialize();

await Task.Run(() =>
{
RenamifyProjectCommand.Initialize(this);
});

VsixTelemetry.LogInformation("Project Renamifier initialized successfully");
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
VsixTelemetry.Shutdown();
}

base.Dispose(disposing);
}
}
}