Skip to content

Commit 48de81b

Browse files
committed
Refactor to static and simplify
1 parent ad27fb5 commit 48de81b

File tree

4 files changed

+68
-185
lines changed

4 files changed

+68
-185
lines changed

src/Cli/func/Helpers/DotnetHelpers.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public static void EnsureDotnet()
3030
{
3131
try
3232
{
33-
_ = new DotnetMuxer().MuxerPath;
33+
_ = DotnetMuxer.GetMuxerPath();
3434
}
3535
catch (InvalidOperationException ex)
3636
{
Lines changed: 31 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,61 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT License. See LICENSE in the project root for license information.
33

4-
// Copied from: https://github.com/dotnet/sdk/blob/main/src/Cli/Microsoft.DotNet.Cli.Utils/Muxer.cs
4+
// Adapted from: https://github.com/dotnet/sdk/blob/main/src/Cli/Microsoft.DotNet.Cli.Utils/Muxer.cs
55
using System.Runtime.InteropServices;
66

77
namespace Azure.Functions.Cli.Helpers;
88

9-
public class DotnetMuxer
9+
internal static class DotnetMuxer
1010
{
11-
public static readonly string MuxerName = "dotnet";
12-
13-
private readonly string _muxerPath;
14-
15-
public static readonly string ExeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
16-
17-
public DotnetMuxer()
11+
private static readonly string _muxerName = "dotnet";
12+
private static readonly string _exeSuffix = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty;
13+
14+
/// <summary>
15+
/// Locates the dotnet muxer (dotnet executable).
16+
/// </summary>
17+
/// <returns>The full path to the dotnet executable.</returns>
18+
/// <exception cref="InvalidOperationException">Thrown when the dotnet executable cannot be located.</exception>
19+
public static string GetMuxerPath()
1820
{
21+
string muxerPath;
22+
1923
// Most scenarios are running dotnet.dll as the app
2024
// Root directory with muxer should be two above app base: <root>/sdk/<version>
2125
string rootPath = Path.GetDirectoryName(Path.GetDirectoryName(AppContext.BaseDirectory.TrimEnd(Path.DirectorySeparatorChar)));
2226
if (rootPath is not null)
2327
{
24-
string muxerPathMaybe = Path.Combine(rootPath, $"{MuxerName}{FileNameSuffixes.CurrentPlatform.Exe}");
25-
if (File.Exists(muxerPathMaybe))
28+
muxerPath = Path.Combine(rootPath, $"{_muxerName}{_exeSuffix}");
29+
if (File.Exists(muxerPath))
2630
{
27-
_muxerPath = muxerPathMaybe;
31+
return muxerPath;
2832
}
2933
}
3034

31-
if (_muxerPath is null)
32-
{
33-
// Best-effort search for muxer.
34-
string processPath = Environment.ProcessPath;
35+
// Best-effort search for muxer.
36+
muxerPath = Environment.ProcessPath;
3537

36-
// The current process should be dotnet in most normal scenarios except when dotnet.dll is loaded in a custom host like the testhost
37-
if (processPath is not null && !Path.GetFileNameWithoutExtension(processPath).Equals("dotnet", StringComparison.OrdinalIgnoreCase))
38+
// The current process should be dotnet in most normal scenarios except when dotnet.dll is loaded in a custom host like the testhost
39+
if (muxerPath is not null && !Path.GetFileNameWithoutExtension(muxerPath).Equals("dotnet", StringComparison.OrdinalIgnoreCase))
40+
{
41+
// SDK sets DOTNET_HOST_PATH as absolute path to current dotnet executable
42+
muxerPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH");
43+
if (muxerPath is null)
3844
{
39-
// SDK sets DOTNET_HOST_PATH as absolute path to current dotnet executable
40-
processPath = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH");
41-
if (processPath is null)
45+
// fallback to DOTNET_ROOT which typically holds some dotnet executable
46+
string root = Environment.GetEnvironmentVariable("DOTNET_ROOT");
47+
if (root is not null)
4248
{
43-
// fallback to DOTNET_ROOT which typically holds some dotnet executable
44-
var root = Environment.GetEnvironmentVariable("DOTNET_ROOT");
45-
if (root is not null)
46-
{
47-
processPath = Path.Combine(root, $"dotnet{ExeSuffix}");
48-
}
49+
muxerPath = Path.Combine(root, $"dotnet{_exeSuffix}");
4950
}
5051
}
51-
52-
_muxerPath = processPath;
5352
}
54-
}
5553

56-
internal string SharedFxVersion
57-
{
58-
get
54+
if (muxerPath is null)
5955
{
60-
var depsFile = new FileInfo(GetDataFromAppDomain("FX_DEPS_FILE") ?? string.Empty);
61-
return depsFile.Directory?.Name ?? string.Empty;
56+
throw new InvalidOperationException("Unable to locate dotnet multiplexer");
6257
}
63-
}
6458

65-
public string MuxerPath
66-
{
67-
get
68-
{
69-
if (_muxerPath == null)
70-
{
71-
throw new InvalidOperationException("Unable to locate dotnet multiplexer");
72-
}
73-
74-
return _muxerPath;
75-
}
76-
}
77-
78-
public static string GetDataFromAppDomain(string propertyName)
79-
{
80-
return AppContext.GetData(propertyName) as string;
59+
return muxerPath;
8160
}
8261
}

src/Cli/func/Helpers/FileNameSuffixes.cs

Lines changed: 0 additions & 78 deletions
This file was deleted.

test/Cli/Func.UnitTests/HelperTests/DotnetMuxerTests.cs

Lines changed: 36 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,86 +9,68 @@ namespace Azure.Functions.Cli.UnitTests.HelperTests
99
public class DotnetMuxerTests
1010
{
1111
[Fact]
12-
public void DotnetMuxer_FindsMuxerPath_WhenDotnetExists()
12+
public void GetMuxerPath_ReturnsMuxerPath_WhenDotnetExists()
1313
{
14-
// Arrange & Act
15-
var muxer = new DotnetMuxer();
14+
// Act
15+
var path = DotnetMuxer.GetMuxerPath();
1616

1717
// Assert
18-
Assert.NotNull(muxer.MuxerPath);
19-
Assert.False(string.IsNullOrWhiteSpace(muxer.MuxerPath));
18+
Assert.NotNull(path);
19+
Assert.False(string.IsNullOrWhiteSpace(path));
2020
}
2121

2222
[Fact]
23-
public void MuxerPath_ThrowsInvalidOperationException_WhenNotFound()
23+
public void GetMuxerPath_ContainsDotnetExecutable()
2424
{
25-
// This test is tricky because DotnetMuxer's constructor tries to find dotnet
26-
// In a normal test environment, dotnet will be found
27-
// We can only test the property behavior
28-
var muxer = new DotnetMuxer();
29-
30-
// If we got here, dotnet was found (which is expected in test environment)
31-
Assert.NotNull(muxer.MuxerPath);
32-
}
25+
// Act
26+
var path = DotnetMuxer.GetMuxerPath();
3327

34-
[Fact]
35-
public void MuxerName_IsCorrect()
36-
{
3728
// Assert
38-
Assert.Equal("dotnet", DotnetMuxer.MuxerName);
39-
}
40-
41-
[Fact]
42-
public void ExeSuffix_IsCorrectForPlatform()
43-
{
44-
// Act & Assert
45-
if (OperatingSystem.IsWindows())
46-
{
47-
Assert.Equal(".exe", DotnetMuxer.ExeSuffix);
48-
}
49-
else
50-
{
51-
Assert.Equal(string.Empty, DotnetMuxer.ExeSuffix);
52-
}
29+
Assert.Contains("dotnet", path, StringComparison.OrdinalIgnoreCase);
5330
}
5431

5532
[Fact]
56-
public void GetDataFromAppDomain_ReturnsNull_ForNonExistentKey()
33+
public void GetMuxerPath_PointsToExecutableFile()
5734
{
5835
// Act
59-
var result = DotnetMuxer.GetDataFromAppDomain("NON_EXISTENT_KEY_12345");
36+
var path = DotnetMuxer.GetMuxerPath();
6037

6138
// Assert
62-
Assert.Null(result);
39+
// The path should exist as a file
40+
Assert.True(
41+
File.Exists(path) || File.Exists(path + ".exe"),
42+
$"Expected muxer path '{path}' to exist");
6343
}
6444

6545
[Fact]
66-
public void MuxerPath_ContainsDotnetExecutable()
46+
public void GetMuxerPath_PointsToFunctionalDotnetExecutable()
6747
{
68-
// Arrange
69-
var muxer = new DotnetMuxer();
70-
7148
// Act
72-
var path = muxer.MuxerPath;
49+
var path = DotnetMuxer.GetMuxerPath();
7350

74-
// Assert
75-
Assert.Contains("dotnet", path, StringComparison.OrdinalIgnoreCase);
76-
}
51+
// Assert - invoke dotnet --version to verify it's functional
52+
var startInfo = new System.Diagnostics.ProcessStartInfo
53+
{
54+
FileName = path,
55+
Arguments = "--version",
56+
RedirectStandardOutput = true,
57+
RedirectStandardError = true,
58+
UseShellExecute = false,
59+
CreateNoWindow = true
60+
};
7761

78-
[Fact]
79-
public void MuxerPath_PointsToExecutableFile()
80-
{
81-
// Arrange
82-
var muxer = new DotnetMuxer();
62+
using var process = System.Diagnostics.Process.Start(startInfo);
63+
Assert.NotNull(process);
8364

84-
// Act
85-
var path = muxer.MuxerPath;
65+
var output = process.StandardOutput.ReadToEnd();
66+
process.WaitForExit();
8667

8768
// Assert
88-
// The path should exist as a file
89-
Assert.True(
90-
File.Exists(path) || File.Exists(path + ".exe"),
91-
$"Expected muxer path '{path}' to exist");
69+
Assert.Equal(0, process.ExitCode);
70+
Assert.False(string.IsNullOrWhiteSpace(output), "Expected dotnet --version to produce output");
71+
72+
// Verify output looks like a version number (e.g., "8.0.100")
73+
Assert.Matches(@"^\d+\.\d+\.\d+", output.Trim());
9274
}
9375
}
9476
}

0 commit comments

Comments
 (0)