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
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
os: [ windows-2019 ]

env:
#COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
GITHUB_PAT: ${{ secrets.GH_TOKEN }}
GPR_PASSWORD: ${{ secrets.GPR_PASSWORD }}
GPR_USER: ${{ secrets.GPR_USER }}
Expand Down
7 changes: 7 additions & 0 deletions src/JavaVersionSwitcher/Adapters/IShellAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace JavaVersionSwitcher.Adapters
{
public interface IShellAdapter
{
ShellType GetShellType();
}
}
73 changes: 73 additions & 0 deletions src/JavaVersionSwitcher/Adapters/ShellAdapter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using System.Diagnostics;
using JavaVersionSwitcher.Logging;

namespace JavaVersionSwitcher.Adapters
{
// some of this was inspired by https://stackoverflow.com/a/2336322/180156
public class ShellAdapter : IShellAdapter
{
private readonly ILogger _logger;

public ShellAdapter(ILogger logger)
{
_logger = logger;
}

public ShellType GetShellType()
{
try
{
var proc = GetParentProcess(Process.GetCurrentProcess());
// when calling "dotnet jvs" the parent is "dotnet" - not sure if that's the case for dotnet-jvs.exe
if ("dotnet".Equals(proc.ProcessName, StringComparison.OrdinalIgnoreCase))
{
proc = GetParentProcess(proc);
}

_logger.LogVerbose("Parent process name is: " + proc.ProcessName);
var name = proc.ProcessName.ToLowerInvariant();
switch (name)
{
case "pwsh":
case "powershell":
return ShellType.PowerShell;
case "cmd":
return ShellType.CommandPrompt;
default:
return ShellType.Unknown;
}
}
catch(Exception e)
{
_logger.LogVerbose($"{e.GetType().Name} while finding parent process: {e.Message}");
return ShellType.Unknown;
}
}

private static Process GetParentProcess(Process process) {
return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id));
}

private static string FindIndexedProcessName(int pid) {
var processName = Process.GetProcessById(pid).ProcessName;
var processesByName = Process.GetProcessesByName(processName);
string processIndexedName = null;

for (var index = 0; index < processesByName.Length; index++) {
processIndexedName = index == 0 ? processName : processName + "#" + index;
var processId = new PerformanceCounter("Process", "ID Process", processIndexedName);
if ((int) processId.NextValue() == pid) {
return processIndexedName;
}
}

return processIndexedName;
}

private static Process FindPidFromIndexedProcessName(string indexedProcessName) {
var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName);
return Process.GetProcessById((int) parentId.NextValue());
}
}
}
20 changes: 20 additions & 0 deletions src/JavaVersionSwitcher/Adapters/ShellType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace JavaVersionSwitcher.Adapters
{
public enum ShellType
{
/// <summary>
/// Unknown
/// </summary>
Unknown,

/// <summary>
/// PowerShell
/// </summary>
PowerShell,

/// <summary>
/// CMD
/// </summary>
CommandPrompt,
}
}
36 changes: 32 additions & 4 deletions src/JavaVersionSwitcher/Commands/SwitchVersionCommand.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
Expand All @@ -18,18 +19,21 @@ internal sealed class SwitchVersionCommand : AsyncCommand<SwitchVersionCommand.S
private readonly IJavaInstallationsAdapter _javaInstallationsAdapter;
private readonly IPathAdapter _pathAdapter;
private readonly ILogger _logger;
private readonly IShellAdapter _shellAdapter;

public SwitchVersionCommand(
IJavaHomeAdapter javaHomeAdapter,
IJavaInstallationsAdapter javaInstallationsAdapter,
IPathAdapter pathAdapter,
ILogger logger
ILogger logger,
IShellAdapter shellAdapter
)
{
_javaHomeAdapter = javaHomeAdapter;
_javaInstallationsAdapter = javaInstallationsAdapter;
_pathAdapter = pathAdapter;
_logger = logger;
_shellAdapter = shellAdapter;
}

[UsedImplicitly]
Expand All @@ -56,6 +60,8 @@ public override async Task<int> ExecuteAsync(CommandContext context, Settings se
.AddChoices(installations.Select(x => x.Location).ToArray())
);

string javaHome = null;
string javaBin = null;
await AnsiConsole.Status()
.StartAsync("Applying...", async ctx =>
{
Expand All @@ -66,20 +72,42 @@ await AnsiConsole.Status()
? EnvironmentScope.Machine
: EnvironmentScope.User;

var javaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process);
javaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process);
var paths = (await _pathAdapter.GetValue(scope)).ToList();
if (!string.IsNullOrEmpty(javaHome))
{
paths = paths.Where(x => !x.StartsWith(javaHome,StringComparison.OrdinalIgnoreCase)).ToList();
}

paths.Add(Path.Combine(selected, "bin"));
javaBin = Path.Combine(selected, "bin");
paths.Add(javaBin);

await _javaHomeAdapter.SetValue(selected, scope);
await _pathAdapter.SetValue(paths, scope);
}).ConfigureAwait(false);

AnsiConsole.MarkupLine("[yellow]The environment has been modified. You need to refresh it.[/]");
var shellType = _shellAdapter.GetShellType();
var refreshCommands = new List<string>();
switch (shellType)
{
case ShellType.PowerShell:
refreshCommands.Add($"$env:JAVA_HOME=\"{javaHome}\"");
refreshCommands.Add($"$env:PATH=\"{javaBin}{Path.PathSeparator}$($env:PATH)\"");
break;
case ShellType.CommandPrompt:
refreshCommands.Add($"set \"JAVA_HOME={javaHome}\"");
refreshCommands.Add($"set \"PATH={javaBin}{Path.PathSeparator}%PATH%\"");
break;
}

AnsiConsole.MarkupLine(refreshCommands.Count > 0
? "[yellow]The environment has been modified. Apply modifications:[/]"
: "[yellow]The environment has been modified. You need to refresh it.[/]");

foreach (var line in refreshCommands)
{
Console.WriteLine(line);
}
return 0;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/JavaVersionSwitcher/JavaVersionSwitcher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<PackageReference Include="JetBrains.Annotations" Version="2021.1.0" />
<PackageReference Include="SimpleInjector" Version="5.3.1" />
<PackageReference Include="Spectre.Console" Version="0.40.0" />
<PackageReference Include="System.Diagnostics.PerformanceCounter" Version="5.0.0" />
</ItemGroup>

</Project>
1 change: 1 addition & 0 deletions src/JavaVersionSwitcher/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ private static ITypeRegistrar BuildRegistrar()
container.Register<IPathAdapter, PathAdapter>(Lifestyle.Singleton);
container.Register<IJavaInstallationsAdapter, JavaInstallationsAdapter>(Lifestyle.Singleton);
container.Register<JavaInstallationsAdapterConfigurationProvider>(Lifestyle.Singleton);
container.Register<IShellAdapter, ShellAdapter>(Lifestyle.Singleton);

container.Collection.Register<IConfigurationProvider>(
new[]
Expand Down