Skip to content

Commit 5b3c793

Browse files
johanndevRehanSaeed
authored andcommitted
feat: Add dotnet uninstall command
- Adds the `DotnetNew.UninstallAsync()` method to clean up dotnet template installations between test runs. - Add missing exception annotations - Move the call to `ProcessExtensions.StartAsync` into a private method Fixes: #357
1 parent 2b17399 commit 5b3c793

File tree

1 file changed

+74
-24
lines changed

1 file changed

+74
-24
lines changed

Source/Boxed.DotnetNewTest/DotnetNew.cs

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public static Task InstallAsync<T>(string fileName) =>
2929
/// <param name="assembly">The assembly used to find the directory path of the project to install.</param>
3030
/// <param name="fileName">Name of the file.</param>
3131
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
32+
/// <exception cref="ArgumentNullException">The provided assembly was null.</exception>
3233
/// <exception cref="FileNotFoundException">A file with the specified file name was not found.</exception>
3334
public static Task InstallAsync(Assembly assembly, string fileName)
3435
{
@@ -58,24 +59,15 @@ public static Task InstallAsync(Assembly assembly, string fileName)
5859
/// <param name="timeout">The timeout. Defaults to one minute.</param>
5960
/// <param name="showShellWindow">if set to <c>true</c> show the shell window instead of logging to output.</param>
6061
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
62+
/// <exception cref="ArgumentException">The provided source was null or empty.</exception>
6163
public static async Task InstallAsync(string source, TimeSpan? timeout = null, bool showShellWindow = false)
6264
{
63-
if (source is null)
65+
if (string.IsNullOrWhiteSpace(source))
6466
{
65-
throw new ArgumentNullException(nameof(source));
67+
throw new ArgumentException("Empty or null.", nameof(source));
6668
}
6769

68-
using (var cancellationTokenSource = new CancellationTokenSource(timeout ?? ConfigurationService.DefaultTimeout))
69-
{
70-
await ProcessExtensions
71-
.StartAsync(
72-
DirectoryExtensions.GetCurrentDirectory(),
73-
"dotnet",
74-
$"new --install \"{source}\"",
75-
showShellWindow,
76-
cancellationTokenSource.Token)
77-
.ConfigureAwait(false);
78-
}
70+
await RunDotnetCommandAsync($"new --install \"{source}\"", timeout, showShellWindow).ConfigureAwait(false);
7971
}
8072

8173
/// <summary>
@@ -86,17 +78,63 @@ await ProcessExtensions
8678
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
8779
public static async Task ReinitialiseAsync(TimeSpan? timeout = null, bool showShellWindow = false)
8880
{
89-
using (var cancellationTokenSource = new CancellationTokenSource(timeout ?? ConfigurationService.DefaultTimeout))
81+
await RunDotnetCommandAsync($"new --debug:reinit", timeout, showShellWindow).ConfigureAwait(false);
82+
}
83+
84+
/// <summary>
85+
/// Uninstalls a template from the specified source.
86+
/// </summary>
87+
/// <typeparam name="T">A type from the assembly used to find the directory path of the project to install.</typeparam>
88+
/// <param name="fileName">Name of the file.</param>
89+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
90+
public static Task UninstallAsync<T>(string fileName) =>
91+
UninstallAsync(typeof(T).GetTypeInfo().Assembly, fileName);
92+
93+
/// <summary>
94+
/// Uninstalls a template from the specified source.
95+
/// </summary>
96+
/// <param name="assembly">The assembly used to find the directory path of the project to install.</param>
97+
/// <param name="fileName">Name of the file.</param>
98+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
99+
/// <exception cref="ArgumentNullException">The provided assembly was null.</exception>
100+
/// <exception cref="FileNotFoundException">A file with the specified file name was not found.</exception>
101+
public static Task UninstallAsync(Assembly assembly, string fileName)
102+
{
103+
if (assembly is null)
90104
{
91-
await ProcessExtensions
92-
.StartAsync(
93-
DirectoryExtensions.GetCurrentDirectory(),
94-
"dotnet",
95-
$"new --debug:reinit",
96-
showShellWindow,
97-
cancellationTokenSource.Token)
98-
.ConfigureAwait(false);
105+
throw new ArgumentNullException(nameof(assembly));
106+
}
107+
108+
if (fileName is null)
109+
{
110+
throw new ArgumentNullException(nameof(fileName));
111+
}
112+
113+
var projectFilePath = Path.GetDirectoryName(GetFilePath(assembly, fileName));
114+
if (projectFilePath is null)
115+
{
116+
throw new FileNotFoundException($"{fileName} not found.");
117+
}
118+
119+
return UninstallAsync(projectFilePath);
120+
}
121+
122+
/// <summary>
123+
/// Uninstalls a template from the specified source.
124+
/// </summary>
125+
/// <param name="source">The source.</param>
126+
/// <param name="timeout">The timeout. Defaults to one minute.</param>
127+
/// <param name="showShellWindow">if set to <c>true</c> show the shell window instead of logging to output.</param>
128+
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
129+
/// <exception cref="ArgumentException">The provided source was null or empty.</exception>
130+
public static async Task UninstallAsync(string source, TimeSpan? timeout = null, bool showShellWindow = false)
131+
{
132+
if (string.IsNullOrWhiteSpace(source))
133+
{
134+
throw new ArgumentException("Empty or null.", nameof(source));
99135
}
136+
137+
await RunDotnetCommandAsync($"new --uninstall \"{source}\"", timeout, showShellWindow).ConfigureAwait(false);
100138
}
101139

102140
private static string? GetFilePath(Assembly assembly, string projectName)
@@ -108,8 +146,7 @@ await ProcessExtensions
108146
projectFilePath = directory
109147
.Parent
110148
.GetFiles(projectName, SearchOption.AllDirectories)
111-
.Where(x => !IsInObjDirectory(x.Directory))
112-
.FirstOrDefault()
149+
.FirstOrDefault(x => !IsInObjDirectory(x.Directory))
113150
?.FullName;
114151
if (projectFilePath is not null)
115152
{
@@ -133,5 +170,18 @@ private static bool IsInObjDirectory(DirectoryInfo? directoryInfo)
133170

134171
return IsInObjDirectory(directoryInfo.Parent);
135172
}
173+
174+
private static async Task<(ProcessResult ProcessResult, string Message)> RunDotnetCommandAsync(string arguments, TimeSpan? timeout, bool showShellWindow)
175+
{
176+
using var cancellationTokenSource = new CancellationTokenSource(timeout ?? ConfigurationService.DefaultTimeout);
177+
return await ProcessExtensions
178+
.StartAsync(
179+
DirectoryExtensions.GetCurrentDirectory(),
180+
"dotnet",
181+
arguments,
182+
showShellWindow,
183+
cancellationTokenSource.Token)
184+
.ConfigureAwait(false);
185+
}
136186
}
137187
}

0 commit comments

Comments
 (0)