Skip to content

Commit 42186f7

Browse files
authored
New Command: Update Dotnet Templates (#4)
* Users can now update specific templates * users can now update all templates * Added toasts for when templates are updated
1 parent 8c35281 commit 42186f7

3 files changed

Lines changed: 192 additions & 1 deletion

File tree

src/NuGetPackageSearchCmdPalExtension/NuGetPackageSearchCmdPalExtensionCommandsProvider.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public NuGetPackageSearchCmdPalExtensionCommandsProvider()
1818
_commands = [
1919
new CommandItem(new Pages.SearchNuGetPackagesPage()) { Title = "Search NuGet Packages" },
2020
new CommandItem(new Pages.SearchDotnetTemplatesPage()) {Title = "Search Dotnet Templates"},
21+
new CommandItem(new Pages.UpdateDotnetTemplatesPage()) {Title = "Update Dotnet Templates"},
2122
new CommandItem(new Pages.SearchDotnetToolsPage()){Title = "Search Dotnet Tools"}
2223
];
2324
}

src/NuGetPackageSearchCmdPalExtension/Package.appxmanifest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<Identity
1313
Name="23610AlickolliSoftware.NuGetPackageSearchforComman"
1414
Publisher="CN=5CECD841-CF4E-45AF-B443-573F4A3614A0"
15-
Version="0.0.4.0" />
15+
Version="0.0.5.0" />
1616
<!-- When you're ready to publish your extension, you'll need to change the
1717
Publisher= to match your own identity -->
1818

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
using Microsoft.CommandPalette.Extensions;
2+
using Microsoft.CommandPalette.Extensions.Toolkit;
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading;
9+
using System.Threading.Tasks;
10+
using Windows.ApplicationModel;
11+
12+
namespace NuGetPackageSearchCmdPalExtension.Pages
13+
{
14+
internal sealed partial class UpdateDotnetTemplatesPage : ListPage
15+
{
16+
public UpdateDotnetTemplatesPage()
17+
{
18+
// Retrieve the app version
19+
var version = Package.Current.Id.Version;
20+
var appVersion = $"{version.Major}.{version.Minor}.{version.Build}.{version.Revision}";
21+
22+
Icon = new IconInfo("\uE773");
23+
Title = $"NuGet Package Search Extension - v{appVersion}";
24+
Name = "Update";
25+
}
26+
27+
public override IListItem[] GetItems()
28+
{
29+
var items = new List<IListItem>();
30+
31+
try
32+
{
33+
var process = new Process
34+
{
35+
StartInfo = new ProcessStartInfo
36+
{
37+
FileName = "dotnet",
38+
Arguments = "new update --check-only",
39+
RedirectStandardOutput = true,
40+
RedirectStandardError = true,
41+
UseShellExecute = false,
42+
CreateNoWindow = true
43+
}
44+
};
45+
46+
process.Start();
47+
string output = process.StandardOutput.ReadToEnd();
48+
string error = process.StandardError.ReadToEnd();
49+
process.WaitForExit();
50+
51+
Debug.WriteLine("dotnet new update --check-only output:");
52+
Debug.WriteLine(output);
53+
if (!string.IsNullOrWhiteSpace(error))
54+
{
55+
Debug.WriteLine("dotnet new update --check-only error:");
56+
Debug.WriteLine(error);
57+
}
58+
59+
// Parse the table section
60+
var lines = output.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
61+
int tableStart = -1;
62+
for (int i = 0; i < lines.Length; i++)
63+
{
64+
if (lines[i].Trim().StartsWith("Package", StringComparison.Ordinal) &&
65+
lines[i].Contains("Current") && lines[i].Contains("Latest"))
66+
{
67+
tableStart = i + 2; // Skip header and separator
68+
break;
69+
}
70+
}
71+
72+
if (tableStart != -1)
73+
{
74+
for (int i = tableStart; i < lines.Length; i++)
75+
{
76+
var line = lines[i];
77+
if (string.IsNullOrWhiteSpace(line) ||
78+
line.StartsWith("To update the package use:", StringComparison.Ordinal) ||
79+
line.StartsWith("To update all the packages use:", StringComparison.Ordinal))
80+
break;
81+
82+
// Split by whitespace, but only for the first 3 columns
83+
var parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
84+
if (parts.Length >= 3)
85+
{
86+
var package = parts[0];
87+
var current = parts[1];
88+
var latest = parts[2];
89+
90+
items.Add(new ListItem
91+
{
92+
Title = package,
93+
Subtitle = $"Current: {current} → Latest: {latest}",
94+
Icon = new IconInfo("\uE7B8"),
95+
Command = new AnonymousCommand(UpdateTemplate(package, latest))
96+
{
97+
Name = "Update Template",
98+
Icon = new IconInfo("\uE896")
99+
},
100+
MoreCommands = [
101+
new CommandContextItem(
102+
"Update All Templates",
103+
name:"Update All Templates",
104+
action: UpdateAllTemplates(),
105+
result:CommandResult.GoHome()
106+
)
107+
{
108+
Icon = new IconInfo("\uE896"),
109+
}
110+
]
111+
});
112+
}
113+
}
114+
}
115+
116+
if (items.Count == 0)
117+
{
118+
items.Add(new ListItem
119+
{
120+
Title = "No template updates available.",
121+
Icon = new IconInfo("\uE8FB"),
122+
Command = new NoOpCommand()
123+
});
124+
}
125+
}
126+
catch (Exception ex)
127+
{
128+
Debug.WriteLine("Exception in GetItems: " + ex);
129+
130+
items.Add(new ListItem
131+
{
132+
Title = "Error checking for template updates",
133+
Subtitle = ex.Message,
134+
Icon = new IconInfo("\uEA39"),
135+
Command = new NoOpCommand()
136+
});
137+
}
138+
139+
return [.. items];
140+
}
141+
142+
public static Action UpdateTemplate(string packageName, string version)
143+
{
144+
return () =>
145+
{
146+
var toast = new ToastStatusMessage($"Updating Template: {packageName} to {version}");
147+
toast.Show();
148+
Thread.Sleep(TimeSpan.FromSeconds(5));
149+
var process = new Process
150+
{
151+
StartInfo = new ProcessStartInfo
152+
{
153+
FileName = "dotnet",
154+
Arguments = $"new install {packageName}::{version} --force",
155+
RedirectStandardOutput = true,
156+
RedirectStandardError = true,
157+
UseShellExecute = false,
158+
CreateNoWindow = false
159+
}
160+
};
161+
process.Start();
162+
process.WaitForExit();
163+
};
164+
}
165+
166+
public static Action UpdateAllTemplates()
167+
{
168+
return () =>
169+
{
170+
var toast = new ToastStatusMessage("Updating All Dotnet Templates");
171+
toast.Show();
172+
Thread.Sleep(TimeSpan.FromSeconds(5));
173+
var process = new Process
174+
{
175+
StartInfo = new ProcessStartInfo
176+
{
177+
FileName = "dotnet",
178+
Arguments = "new update",
179+
RedirectStandardOutput = true,
180+
RedirectStandardError = true,
181+
UseShellExecute = false,
182+
CreateNoWindow = false
183+
}
184+
};
185+
process.Start();
186+
process.WaitForExit();
187+
};
188+
}
189+
}
190+
}

0 commit comments

Comments
 (0)