diff --git a/src/JavaVersionSwitcher.Tests/ConfigurationServiceTests.cs b/src/JavaVersionSwitcher.Tests/ConfigurationServiceTests.cs index 02540c83..c726879d 100644 --- a/src/JavaVersionSwitcher.Tests/ConfigurationServiceTests.cs +++ b/src/JavaVersionSwitcher.Tests/ConfigurationServiceTests.cs @@ -6,119 +6,118 @@ using Shouldly; using Xunit; -namespace JavaVersionSwitcher.Tests +namespace JavaVersionSwitcher.Tests; + +public class ConfigurationServiceTests { - public class ConfigurationServiceTests + [Fact] + public async Task SetConfiguration_throws_on_wrong_provider() { - [Fact] - public async Task SetConfiguration_throws_on_wrong_provider() - { - // arrange - using var fixture = new ConfigurationServiceFixture(); - const string providerName = "non-existent-provider"; + // arrange + using var fixture = new ConfigurationServiceFixture(); + const string providerName = "non-existent-provider"; - // act - // ReSharper disable once AccessToDisposedClosure - async Task Act() => await fixture.Service.SetConfiguration(providerName, null, null); + // act + // ReSharper disable once AccessToDisposedClosure + async Task Act() => await fixture.Service.SetConfiguration(providerName, null, null); - // assert - (await Should.ThrowAsync((Func)Act)) - .Message - .ShouldSatisfyAllConditions( - m => m.ShouldStartWith("No ConfigurationProvider"), - m => m.ShouldContain(providerName)); - } + // assert + (await Should.ThrowAsync((Func)Act)) + .Message + .ShouldSatisfyAllConditions( + m => m.ShouldStartWith("No ConfigurationProvider"), + m => m.ShouldContain(providerName)); + } - [Fact] - public async Task SetConfiguration_throws_on_wrong_setting() - { - // arrange - const string providerName = "provider"; - using var fixture = new ConfigurationServiceFixture(); - fixture.WithConfigurationProvider(providerName); - const string setting = "non-existent-setting"; + [Fact] + public async Task SetConfiguration_throws_on_wrong_setting() + { + // arrange + const string providerName = "provider"; + using var fixture = new ConfigurationServiceFixture(); + fixture.WithConfigurationProvider(providerName); + const string setting = "non-existent-setting"; - // act' - // ReSharper disable once AccessToDisposedClosure - async Task Act() => await fixture.Service.SetConfiguration(providerName, setting, null); + // act' + // ReSharper disable once AccessToDisposedClosure + async Task Act() => await fixture.Service.SetConfiguration(providerName, setting, null); - // assert - (await Should.ThrowAsync((Func)Act)) - .Message - .ShouldSatisfyAllConditions( - m => m.ShouldStartWith("No Configuration with the name"), - m => m.ShouldContain(setting)); - } + // assert + (await Should.ThrowAsync((Func)Act)) + .Message + .ShouldSatisfyAllConditions( + m => m.ShouldStartWith("No Configuration with the name"), + m => m.ShouldContain(setting)); + } - [Fact] - public async Task SetConfiguration_writes_value_to_xml() - { - // arrange - const string providerName = "pName"; - const string settingsName = "settingsName"; - const string value = "a value"; - using var fixture = new ConfigurationServiceFixture(); - fixture.WithConfigurationProvider(providerName, settingsName); + [Fact] + public async Task SetConfiguration_writes_value_to_xml() + { + // arrange + const string providerName = "pName"; + const string settingsName = "settingsName"; + const string value = "a value"; + using var fixture = new ConfigurationServiceFixture(); + fixture.WithConfigurationProvider(providerName, settingsName); - // act' - await fixture.Service.SetConfiguration(providerName, settingsName, value); + // act' + await fixture.Service.SetConfiguration(providerName, settingsName, value); - // assert - var xml = fixture.ReadXml(providerName, settingsName); - xml.Value.ShouldBe(value); - } + // assert + var xml = fixture.ReadXml(providerName, settingsName); + xml.Value.ShouldBe(value); + } - [Fact] - public async Task GetConfiguration_returns_empty_for_not_set_setting() - { - // arrange - const string providerName = "pName"; - const string settingsName = "settingsName"; - using var fixture = new ConfigurationServiceFixture(); - fixture.WithConfigurationProvider(providerName, settingsName); + [Fact] + public async Task GetConfiguration_returns_empty_for_not_set_setting() + { + // arrange + const string providerName = "pName"; + const string settingsName = "settingsName"; + using var fixture = new ConfigurationServiceFixture(); + fixture.WithConfigurationProvider(providerName, settingsName); - // act' - var actual = await fixture.Service.GetConfiguration(providerName, settingsName); + // act' + var actual = await fixture.Service.GetConfiguration(providerName, settingsName); - // assert - actual.ShouldBe(string.Empty); - } + // assert + actual.ShouldBe(string.Empty); + } - [Fact] - public async Task GetConfiguration_returns_the_value_from_xml() - { - // arrange - const string providerName = "pName"; - const string settingsName = "settingsName"; - const string expected = "some value"; - using var fixture = new ConfigurationServiceFixture(); - fixture.WithConfigurationProvider(providerName, settingsName); - fixture.EnsureSetting(providerName, settingsName, expected); + [Fact] + public async Task GetConfiguration_returns_the_value_from_xml() + { + // arrange + const string providerName = "pName"; + const string settingsName = "settingsName"; + const string expected = "some value"; + using var fixture = new ConfigurationServiceFixture(); + fixture.WithConfigurationProvider(providerName, settingsName); + fixture.EnsureSetting(providerName, settingsName, expected); - // act' - var actual = await fixture.Service.GetConfiguration(providerName, settingsName); + // act' + var actual = await fixture.Service.GetConfiguration(providerName, settingsName); - // assert - actual.ShouldBe(expected); - } + // assert + actual.ShouldBe(expected); + } - [Fact] - public async Task SetConfiguration_removes_empty_settings() - { - // arrange - const string providerName = "pName"; - const string settingsName = "settingsName"; - using var fixture = new ConfigurationServiceFixture(); - fixture.WithConfigurationProvider(providerName, settingsName); - fixture.EnsureSetting(providerName, settingsName, "some value"); + [Fact] + public async Task SetConfiguration_removes_empty_settings() + { + // arrange + const string providerName = "pName"; + const string settingsName = "settingsName"; + using var fixture = new ConfigurationServiceFixture(); + fixture.WithConfigurationProvider(providerName, settingsName); + fixture.EnsureSetting(providerName, settingsName, "some value"); - // act' - await fixture.Service.SetConfiguration(providerName, settingsName, null); + // act' + await fixture.Service.SetConfiguration(providerName, settingsName, null); - // assert - var xml = fixture.ReadXml(); - xml.Parent.ShouldBeNull("this should be the root node."); - xml.Elements().Count().ShouldBe(0); - } + // assert + var xml = fixture.ReadXml(); + xml.Parent.ShouldBeNull("this should be the root node."); + xml.Elements().Count().ShouldBe(0); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/Fixtures/CommandFixture.cs b/src/JavaVersionSwitcher.Tests/Fixtures/CommandFixture.cs index 35910e8e..5f7d12cd 100644 --- a/src/JavaVersionSwitcher.Tests/Fixtures/CommandFixture.cs +++ b/src/JavaVersionSwitcher.Tests/Fixtures/CommandFixture.cs @@ -8,56 +8,55 @@ using Spectre.Console.Cli; using Spectre.Console.Testing; -namespace JavaVersionSwitcher.Tests.Fixtures +namespace JavaVersionSwitcher.Tests.Fixtures; + +public class CommandFixture { - public class CommandFixture + public CommandFixture() { - public CommandFixture() - { - Logger = new Logger(Console); - } + Logger = new Logger(Console); + } - public TestConsole Console { get; } = new TestConsole(); + public TestConsole Console { get; } = new TestConsole(); - public Logger Logger { get; } + public Logger Logger { get; } - public TestConfigurationService ConfigurationService { get; } = new TestConfigurationService(); + public TestConfigurationService ConfigurationService { get; } = new TestConfigurationService(); - public Mock JavaHomeAdapter { get; } = new Mock(); + public Mock JavaHomeAdapter { get; } = new Mock(); - public Mock PathAdapter { get; } = new Mock(); + public Mock PathAdapter { get; } = new Mock(); - public Mock JavaInstallationsAdapter { get; } = new Mock(); + public Mock JavaInstallationsAdapter { get; } = new Mock(); - private ITypeRegistrar BuildRegistrar() - { - var container = new Container(); - container.RegisterInstance(Logger); - container.RegisterInstance(ConfigurationService); - container.RegisterInstance(JavaHomeAdapter.Object); - container.RegisterInstance(PathAdapter.Object); - container.RegisterInstance(JavaInstallationsAdapter.Object); + private ITypeRegistrar BuildRegistrar() + { + var container = new Container(); + container.RegisterInstance(Logger); + container.RegisterInstance(ConfigurationService); + container.RegisterInstance(JavaHomeAdapter.Object); + container.RegisterInstance(PathAdapter.Object); + container.RegisterInstance(JavaInstallationsAdapter.Object); - container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); - container.Collection.Register( - new[] - { - typeof(JavaInstallationsAdapterConfigurationProvider), - }, - Lifestyle.Singleton); + container.Collection.Register( + new[] + { + typeof(JavaInstallationsAdapterConfigurationProvider), + }, + Lifestyle.Singleton); - return new SimpleInjectorRegistrar(container); - } + return new SimpleInjectorRegistrar(container); + } - public int Run(params string[] args) - { - AnsiConsole.Console = Console; - var registrar = BuildRegistrar(); - var app = new CommandApp(registrar); - app.Configure(Program.ConfigureApp); + public int Run(params string[] args) + { + AnsiConsole.Console = Console; + var registrar = BuildRegistrar(); + var app = new CommandApp(registrar); + app.Configure(Program.ConfigureApp); - return app.Run(args); - } + return app.Run(args); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/Fixtures/ConfigurationServiceFixture.cs b/src/JavaVersionSwitcher.Tests/Fixtures/ConfigurationServiceFixture.cs index f552802a..a3b2032c 100644 --- a/src/JavaVersionSwitcher.Tests/Fixtures/ConfigurationServiceFixture.cs +++ b/src/JavaVersionSwitcher.Tests/Fixtures/ConfigurationServiceFixture.cs @@ -9,88 +9,87 @@ using Moq; using Shouldly; -namespace JavaVersionSwitcher.Tests.Fixtures +namespace JavaVersionSwitcher.Tests.Fixtures; + +public class ConfigurationServiceFixture : IDisposable { - public class ConfigurationServiceFixture : IDisposable - { - private readonly List _configurationProviders = new List(); - private readonly Mock _storageAdapter; - private readonly string _tmpFile; + private readonly List _configurationProviders = new List(); + private readonly Mock _storageAdapter; + private readonly string _tmpFile; - public ConfigurationServiceFixture() - { - _tmpFile = Path.GetTempFileName()+".xml"; - _storageAdapter = new Mock(); - _storageAdapter.Setup(x => x.ConfigurationFilePath).Returns(_tmpFile); - } + public ConfigurationServiceFixture() + { + _tmpFile = Path.GetTempFileName()+".xml"; + _storageAdapter = new Mock(); + _storageAdapter.Setup(x => x.ConfigurationFilePath).Returns(_tmpFile); + } - public ConfigurationService Service => new ConfigurationService(_configurationProviders, _storageAdapter.Object); + public ConfigurationService Service => new ConfigurationService(_configurationProviders, _storageAdapter.Object); - public void WithConfigurationProvider(string providerName, params string[] settings) - { - var configurationProvider = new Mock(); - configurationProvider.Setup(x => x.ProviderName).Returns(providerName); - configurationProvider.Setup(x => x.Settings).Returns(settings); + public void WithConfigurationProvider(string providerName, params string[] settings) + { + var configurationProvider = new Mock(); + configurationProvider.Setup(x => x.ProviderName).Returns(providerName); + configurationProvider.Setup(x => x.Settings).Returns(settings); - _configurationProviders.Add(configurationProvider.Object); - } + _configurationProviders.Add(configurationProvider.Object); + } - public void EnsureSetting([NotNull]string providerName, [NotNull]string setting, string value) - { - var doc = new XDocument(); - doc.Add(ReadXml()); - var root = doc.Root; + public void EnsureSetting([NotNull]string providerName, [NotNull]string setting, string value) + { + var doc = new XDocument(); + doc.Add(ReadXml()); + var root = doc.Root; - var providerElm = root!.Elements(providerName).SingleOrDefault(); - if (providerElm == null) - { - providerElm = new XElement(providerName); - root.Add(providerElm); - } + var providerElm = root!.Elements(providerName).SingleOrDefault(); + if (providerElm == null) + { + providerElm = new XElement(providerName); + root.Add(providerElm); + } - var settingElm = providerElm.Elements(setting).SingleOrDefault(); - if (settingElm == null) - { - settingElm = new XElement(setting); - providerElm.Add(settingElm); - } - - settingElm.Value = value; - doc.Save(_tmpFile); + var settingElm = providerElm.Elements(setting).SingleOrDefault(); + if (settingElm == null) + { + settingElm = new XElement(setting); + providerElm.Add(settingElm); } - public XElement ReadXml(string providerName = null, string setting = null) + settingElm.Value = value; + doc.Save(_tmpFile); + } + + public XElement ReadXml(string providerName = null, string setting = null) + { + if (!File.Exists(_tmpFile)) { - if (!File.Exists(_tmpFile)) - { - return new XElement("temp-settings"); - } - - var xml = XDocument.Load(_tmpFile); - if (providerName == null) - { - return xml.Root; - } + return new XElement("temp-settings"); + } - var providerElm = xml.Root!.Elements(providerName).SingleOrDefault(); - providerElm.ShouldNotBeNull("a provider element should have been created."); - var settingElm = providerElm.Elements(setting).SingleOrDefault(); - if (setting == null) - { - return providerElm; - } + var xml = XDocument.Load(_tmpFile); + if (providerName == null) + { + return xml.Root; + } - settingElm.ShouldNotBeNull("a settings element should have been created."); - return settingElm; + var providerElm = xml.Root!.Elements(providerName).SingleOrDefault(); + providerElm.ShouldNotBeNull("a provider element should have been created."); + var settingElm = providerElm.Elements(setting).SingleOrDefault(); + if (setting == null) + { + return providerElm; } + + settingElm.ShouldNotBeNull("a settings element should have been created."); + return settingElm; + } - public void Dispose() + public void Dispose() + { + GC.SuppressFinalize(this); + if (_tmpFile != null && File.Exists(_tmpFile)) { - GC.SuppressFinalize(this); - if (_tmpFile != null && File.Exists(_tmpFile)) - { - File.Delete(_tmpFile); - } + File.Delete(_tmpFile); } } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/GetConfigCommandTests.cs b/src/JavaVersionSwitcher.Tests/GetConfigCommandTests.cs index 77ac9002..82f6cf7b 100644 --- a/src/JavaVersionSwitcher.Tests/GetConfigCommandTests.cs +++ b/src/JavaVersionSwitcher.Tests/GetConfigCommandTests.cs @@ -1,20 +1,19 @@ using Xunit; -namespace JavaVersionSwitcher.Tests +namespace JavaVersionSwitcher.Tests; + +public class GetConfigCommandTests { - public class GetConfigCommandTests + [Fact] + public void Can_Set_CacheTimeout_Configuration() { - [Fact] - public void Can_Set_CacheTimeout_Configuration() - { - /* - var fixture = new CommandFixture(); + /* + var fixture = new CommandFixture(); + + var result = fixture.Run("config", "set", "cache", "timeout", "12"); - var result = fixture.Run("config", "set", "cache", "timeout", "12"); - - result.ShouldBe(0); - fixture.ConfigurationService.Configuration["cache"]["timeout"].ShouldBe("12"); - */ - } + result.ShouldBe(0); + fixture.ConfigurationService.Configuration["cache"]["timeout"].ShouldBe("12"); + */ } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/JavaHomeTests.cs b/src/JavaVersionSwitcher.Tests/JavaHomeTests.cs index 7681fc24..f37b3092 100644 --- a/src/JavaVersionSwitcher.Tests/JavaHomeTests.cs +++ b/src/JavaVersionSwitcher.Tests/JavaHomeTests.cs @@ -6,45 +6,44 @@ using Shouldly; using Xunit; -namespace JavaVersionSwitcher.Tests +namespace JavaVersionSwitcher.Tests; + +public class JavaHomeTests { - public class JavaHomeTests - { - private readonly JavaHomeAdapter _adapter = new JavaHomeAdapter(new Mock().Object); + private readonly JavaHomeAdapter _adapter = new JavaHomeAdapter(new Mock().Object); - [Fact] - public async Task Can_Set_per_process() - { - var expected = Guid.NewGuid().ToString("d"); - await _adapter.SetValue(expected, EnvironmentScope.Process); + [Fact] + public async Task Can_Set_per_process() + { + var expected = Guid.NewGuid().ToString("d"); + await _adapter.SetValue(expected, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.Process); + var actual = await _adapter.GetValue(EnvironmentScope.Process); - actual.ShouldBe(expected); - } + actual.ShouldBe(expected); + } - [Fact] - public async Task Set_per_process_does_not_modify_user() - { - var existing = await _adapter.GetValue(EnvironmentScope.User); - var modified = existing + Guid.NewGuid().ToString("d"); - await _adapter.SetValue(modified, EnvironmentScope.Process); + [Fact] + public async Task Set_per_process_does_not_modify_user() + { + var existing = await _adapter.GetValue(EnvironmentScope.User); + var modified = existing + Guid.NewGuid().ToString("d"); + await _adapter.SetValue(modified, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.User); + var actual = await _adapter.GetValue(EnvironmentScope.User); - actual.ShouldNotBe(modified); - } + actual.ShouldNotBe(modified); + } - [Fact] - public async Task Set_per_process_does_not_modify_machine() - { - var existing = await _adapter.GetValue(EnvironmentScope.Machine); - var modified = existing + Guid.NewGuid().ToString("d"); - await _adapter.SetValue(modified, EnvironmentScope.Process); + [Fact] + public async Task Set_per_process_does_not_modify_machine() + { + var existing = await _adapter.GetValue(EnvironmentScope.Machine); + var modified = existing + Guid.NewGuid().ToString("d"); + await _adapter.SetValue(modified, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.Machine); + var actual = await _adapter.GetValue(EnvironmentScope.Machine); - actual.ShouldNotBe(modified); - } + actual.ShouldNotBe(modified); } -} +} \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/JavaVersionSwitcher.Tests.csproj b/src/JavaVersionSwitcher.Tests/JavaVersionSwitcher.Tests.csproj index 49269b1d..b25d7339 100644 --- a/src/JavaVersionSwitcher.Tests/JavaVersionSwitcher.Tests.csproj +++ b/src/JavaVersionSwitcher.Tests/JavaVersionSwitcher.Tests.csproj @@ -7,8 +7,10 @@ + + diff --git a/src/JavaVersionSwitcher.Tests/LoggerTests.cs b/src/JavaVersionSwitcher.Tests/LoggerTests.cs index ad5e6d5b..d01b5d41 100644 --- a/src/JavaVersionSwitcher.Tests/LoggerTests.cs +++ b/src/JavaVersionSwitcher.Tests/LoggerTests.cs @@ -3,43 +3,42 @@ using Spectre.Console.Testing; using Xunit; -namespace JavaVersionSwitcher.Tests +namespace JavaVersionSwitcher.Tests; + +public class LoggerTests { - public class LoggerTests - { - private readonly TestConsole _console; - private readonly ILogger _logger; + private readonly TestConsole _console; + private readonly ILogger _logger; - public LoggerTests() - { - _console = new TestConsole(); - _logger = new Logger(_console); - } + public LoggerTests() + { + _console = new TestConsole(); + _logger = new Logger(_console); + } - [Fact] - public void Writes_warning_with_prefix() - { - _logger.LogWarning("test"); + [Fact] + public void Writes_warning_with_prefix() + { + _logger.LogWarning("test"); - _console.Output.ShouldStartWith("WARNING:"); - } + _console.Output.ShouldStartWith("WARNING:"); + } - [Fact] - public void Writes_verbose_when_verbose_is_set() - { - _logger.PrintVerbose = true; - _logger.LogVerbose("test"); + [Fact] + public void Writes_verbose_when_verbose_is_set() + { + _logger.PrintVerbose = true; + _logger.LogVerbose("test"); - _console.Output.ShouldBe("test\n"); - } + _console.Output.ShouldBe("test\n"); + } - [Fact] - public void Writes_nothing_when_verbose_is_not_set() - { - _logger.PrintVerbose = false; - _logger.LogVerbose("test"); + [Fact] + public void Writes_nothing_when_verbose_is_not_set() + { + _logger.PrintVerbose = false; + _logger.LogVerbose("test"); - _console.Output.ShouldBe(string.Empty); - } + _console.Output.ShouldBe(string.Empty); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/PathTests.cs b/src/JavaVersionSwitcher.Tests/PathTests.cs index af0862da..0128a155 100644 --- a/src/JavaVersionSwitcher.Tests/PathTests.cs +++ b/src/JavaVersionSwitcher.Tests/PathTests.cs @@ -5,45 +5,44 @@ using Shouldly; using Xunit; -namespace JavaVersionSwitcher.Tests +namespace JavaVersionSwitcher.Tests; + +public class PathTests { - public class PathTests - { - private readonly PathAdapter _adapter = new PathAdapter(); + private readonly PathAdapter _adapter = new PathAdapter(); - [Fact] - public async Task Can_Set_per_process() - { - var expected = new []{ Guid.NewGuid().ToString("d") }; - await _adapter.SetValue(expected, EnvironmentScope.Process); + [Fact] + public async Task Can_Set_per_process() + { + var expected = new []{ Guid.NewGuid().ToString("d") }; + await _adapter.SetValue(expected, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.Process); + var actual = await _adapter.GetValue(EnvironmentScope.Process); - actual.ShouldBe(expected); - } + actual.ShouldBe(expected); + } - [Fact] - public async Task Set_per_process_does_not_modify_user() - { - var modified = (await _adapter.GetValue(EnvironmentScope.User)).ToList(); - modified.Add(Guid.NewGuid().ToString("d")); - await _adapter.SetValue(modified, EnvironmentScope.Process); + [Fact] + public async Task Set_per_process_does_not_modify_user() + { + var modified = (await _adapter.GetValue(EnvironmentScope.User)).ToList(); + modified.Add(Guid.NewGuid().ToString("d")); + await _adapter.SetValue(modified, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.User); + var actual = await _adapter.GetValue(EnvironmentScope.User); - actual.Count().ShouldBe(modified.Count - 1); - } + actual.Count().ShouldBe(modified.Count - 1); + } - [Fact] - public async Task Set_per_process_does_not_modify_machine() - { - var modified = (await _adapter.GetValue(EnvironmentScope.Machine)).ToList(); - modified.Add(Guid.NewGuid().ToString("d")); - await _adapter.SetValue(modified, EnvironmentScope.Process); + [Fact] + public async Task Set_per_process_does_not_modify_machine() + { + var modified = (await _adapter.GetValue(EnvironmentScope.Machine)).ToList(); + modified.Add(Guid.NewGuid().ToString("d")); + await _adapter.SetValue(modified, EnvironmentScope.Process); - var actual = await _adapter.GetValue(EnvironmentScope.Machine); + var actual = await _adapter.GetValue(EnvironmentScope.Machine); - actual.Count().ShouldBe(modified.Count - 1); - } + actual.Count().ShouldBe(modified.Count - 1); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher.Tests/TestImplementations/TestConfigurationService.cs b/src/JavaVersionSwitcher.Tests/TestImplementations/TestConfigurationService.cs index 69992646..bf9bd5b7 100644 --- a/src/JavaVersionSwitcher.Tests/TestImplementations/TestConfigurationService.cs +++ b/src/JavaVersionSwitcher.Tests/TestImplementations/TestConfigurationService.cs @@ -3,37 +3,36 @@ using System.Threading.Tasks; using JavaVersionSwitcher.Services; -namespace JavaVersionSwitcher.Tests.TestImplementations +namespace JavaVersionSwitcher.Tests.TestImplementations; + +public class TestConfigurationService : IConfigurationService { - public class TestConfigurationService : IConfigurationService - { - public Dictionary> Configuration => - new Dictionary>(); + public Dictionary> Configuration => + new Dictionary>(); - public Task GetConfiguration(string provider, string settingName) - { + public Task GetConfiguration(string provider, string settingName) + { - if (Configuration.TryGetValue(provider, out var settings)) + if (Configuration.TryGetValue(provider, out var settings)) + { + if (settings.TryGetValue(settingName, out var value)) { - if (settings.TryGetValue(settingName, out var value)) - { - return Task.FromResult(value); - } + return Task.FromResult(value); } - - return Task.FromResult(string.Empty); } - public Task SetConfiguration(string provider, string settingName, string value) - { - if (!Configuration.TryGetValue(provider, out var settings)) - { - settings = new Dictionary(); - Configuration.Add(provider, settings); - } + return Task.FromResult(string.Empty); + } - settings[settingName] = value; - return Task.FromResult(null); + public Task SetConfiguration(string provider, string settingName, string value) + { + if (!Configuration.TryGetValue(provider, out var settings)) + { + settings = new Dictionary(); + Configuration.Add(provider, settings); } + + settings[settingName] = value; + return Task.FromResult(null); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/AbstractEnvironmentAdapter.cs b/src/JavaVersionSwitcher/Adapters/AbstractEnvironmentAdapter.cs index 2ba2fc20..29c63019 100644 --- a/src/JavaVersionSwitcher/Adapters/AbstractEnvironmentAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/AbstractEnvironmentAdapter.cs @@ -1,49 +1,48 @@ using System; using System.Threading.Tasks; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Provides generic access to an environment variable. +/// +internal class SimpleEnvironmentAdapter { - /// - /// Provides generic access to an environment variable. - /// - internal class SimpleEnvironmentAdapter - { - private readonly string _variableName; + private readonly string _variableName; - internal SimpleEnvironmentAdapter(string variableName) - { - _variableName = variableName; - } + internal SimpleEnvironmentAdapter(string variableName) + { + _variableName = variableName; + } - public Task GetValue(EnvironmentScope scope) + public Task GetValue(EnvironmentScope scope) + { + return Task.Factory.StartNew(() => { - return Task.Factory.StartNew(() => - { - var target = Convert(scope); - return Environment.GetEnvironmentVariable(_variableName, target) ?? ""; - }); - } + var target = Convert(scope); + return Environment.GetEnvironmentVariable(_variableName, target) ?? ""; + }); + } - public Task SetValue(string value, EnvironmentScope scope) + public Task SetValue(string value, EnvironmentScope scope) + { + return Task.Factory.StartNew(() => { - return Task.Factory.StartNew(() => - { - var target = Convert(scope); - Environment.SetEnvironmentVariable(_variableName, value, target); - }); - } + var target = Convert(scope); + Environment.SetEnvironmentVariable(_variableName, value, target); + }); + } - private static EnvironmentVariableTarget Convert(EnvironmentScope scope) + private static EnvironmentVariableTarget Convert(EnvironmentScope scope) + { + var target = scope switch { - var target = scope switch - { - EnvironmentScope.Machine => EnvironmentVariableTarget.Machine, - EnvironmentScope.User => EnvironmentVariableTarget.User, - EnvironmentScope.Process => EnvironmentVariableTarget.Process, - _ => EnvironmentVariableTarget.Process - }; + EnvironmentScope.Machine => EnvironmentVariableTarget.Machine, + EnvironmentScope.User => EnvironmentVariableTarget.User, + EnvironmentScope.Process => EnvironmentVariableTarget.Process, + _ => EnvironmentVariableTarget.Process + }; - return target; - } + return target; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/EnvironmentScope.cs b/src/JavaVersionSwitcher/Adapters/EnvironmentScope.cs index ae732ac3..1570673c 100644 --- a/src/JavaVersionSwitcher/Adapters/EnvironmentScope.cs +++ b/src/JavaVersionSwitcher/Adapters/EnvironmentScope.cs @@ -1,30 +1,29 @@ -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Defines the scope of environment access. +/// +public enum EnvironmentScope { /// - /// Defines the scope of environment access. + /// Current process scope. + /// + /// Reading this value means accessing the "effective" + /// value. I.e. Process > User > Machine + /// /// - public enum EnvironmentScope - { - /// - /// Current process scope. - /// - /// Reading this value means accessing the "effective" - /// value. I.e. Process > User > Machine - /// - /// - Process, + Process, - /// - /// User scope. - /// - User, + /// + /// User scope. + /// + User, - /// - /// Machine scope. - /// - /// (Writing this scope might require super-user permissions.) - /// - /// - Machine - } + /// + /// Machine scope. + /// + /// (Writing this scope might require super-user permissions.) + /// + /// + Machine } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IJavaHomeAdapter.cs b/src/JavaVersionSwitcher/Adapters/IJavaHomeAdapter.cs index b0b8f8c0..454a8087 100644 --- a/src/JavaVersionSwitcher/Adapters/IJavaHomeAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/IJavaHomeAdapter.cs @@ -2,25 +2,24 @@ using System.Threading.Tasks; using JetBrains.Annotations; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Provides access to the JAVA_HOME variable. +/// +public interface IJavaHomeAdapter { /// - /// Provides access to the JAVA_HOME variable. + /// Gets the value of JAVA_HOME. /// - public interface IJavaHomeAdapter - { - /// - /// Gets the value of JAVA_HOME. - /// - /// The scope. - /// The value of JAVA_HOME. - [NotNull] Task GetValue(EnvironmentScope scope); + /// The scope. + /// The value of JAVA_HOME. + [NotNull] Task GetValue(EnvironmentScope scope); - /// - /// Sets the value of JAVA_HOME. - /// - /// The value to set. - /// The scope. - Task SetValue([NotNull] string value, EnvironmentScope scope); - } + /// + /// Sets the value of JAVA_HOME. + /// + /// The value to set. + /// The scope. + Task SetValue([NotNull] string value, EnvironmentScope scope); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IJavaInstallationsAdapter.cs b/src/JavaVersionSwitcher/Adapters/IJavaInstallationsAdapter.cs index 8e65e507..bdb1c35b 100644 --- a/src/JavaVersionSwitcher/Adapters/IJavaInstallationsAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/IJavaInstallationsAdapter.cs @@ -2,18 +2,17 @@ using System.Threading.Tasks; using JavaVersionSwitcher.Models; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Provides access to java installations . +/// +public interface IJavaInstallationsAdapter { /// - /// Provides access to java installations . + /// List all installed java versions. /// - public interface IJavaInstallationsAdapter - { - /// - /// List all installed java versions. - /// - /// - /// The list java installations. - Task> GetJavaInstallations(bool forceReScan = false); - } + /// + /// The list java installations. + Task> GetJavaInstallations(bool forceReScan = false); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IPathAdapter.cs b/src/JavaVersionSwitcher/Adapters/IPathAdapter.cs index 5bd8f697..a686a450 100644 --- a/src/JavaVersionSwitcher/Adapters/IPathAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/IPathAdapter.cs @@ -2,26 +2,25 @@ using System.Threading.Tasks; using JetBrains.Annotations; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Provides access to the PATH variable +/// and some functions for modifying it. +/// +public interface IPathAdapter { /// - /// Provides access to the PATH variable - /// and some functions for modifying it. + /// Gets the value of PATH. /// - public interface IPathAdapter - { - /// - /// Gets the value of PATH. - /// - /// The scope. - /// The value of JAVA_HOME. - [NotNull] Task> GetValue(EnvironmentScope scope); + /// The scope. + /// The value of JAVA_HOME. + [NotNull] Task> GetValue(EnvironmentScope scope); - /// - /// Sets the value of PATH. - /// - /// The value to set. - /// The scope. - Task SetValue([NotNull] IEnumerable value, EnvironmentScope scope); - } + /// + /// Sets the value of PATH. + /// + /// The value to set. + /// The scope. + Task SetValue([NotNull] IEnumerable value, EnvironmentScope scope); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IRegistryAdapter.cs b/src/JavaVersionSwitcher/Adapters/IRegistryAdapter.cs new file mode 100644 index 00000000..fb0fbb08 --- /dev/null +++ b/src/JavaVersionSwitcher/Adapters/IRegistryAdapter.cs @@ -0,0 +1,8 @@ +using System.Collections.Generic; + +namespace JavaVersionSwitcher.Adapters; + +public interface IRegistryAdapter +{ + IAsyncEnumerable GetInstallationPaths(); +} \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IShellAdapter.cs b/src/JavaVersionSwitcher/Adapters/IShellAdapter.cs index 7ba95676..671e5ac6 100644 --- a/src/JavaVersionSwitcher/Adapters/IShellAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/IShellAdapter.cs @@ -1,7 +1,6 @@ -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +public interface IShellAdapter { - public interface IShellAdapter - { - ShellType GetShellType(); - } + ShellType GetShellType(); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/IStorageAdapter.cs b/src/JavaVersionSwitcher/Adapters/IStorageAdapter.cs index 20d98103..dd1e70f9 100644 --- a/src/JavaVersionSwitcher/Adapters/IStorageAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/IStorageAdapter.cs @@ -1,19 +1,18 @@ -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +/// Information about where (in the FileSystem) +/// "our" files are located. +/// +public interface IStorageAdapter { /// - /// Information about where (in the FileSystem) - /// "our" files are located. + /// Gets the path to the main config file /// - public interface IStorageAdapter - { - /// - /// Gets the path to the main config file - /// - string ConfigurationFilePath { get; } + string ConfigurationFilePath { get; } - /// - /// Gets the path to the cache file - /// - string JavaInstallationCacheFilePath { get; } - } + /// + /// Gets the path to the cache file + /// + string JavaInstallationCacheFilePath { get; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/JavaHomeAdapter.cs b/src/JavaVersionSwitcher/Adapters/JavaHomeAdapter.cs index 130ae67f..44a96d00 100644 --- a/src/JavaVersionSwitcher/Adapters/JavaHomeAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/JavaHomeAdapter.cs @@ -1,33 +1,32 @@ using System.Threading.Tasks; using JavaVersionSwitcher.Logging; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +public class JavaHomeAdapter : IJavaHomeAdapter { - /// - public class JavaHomeAdapter : IJavaHomeAdapter - { - private readonly ILogger _logger; - private readonly SimpleEnvironmentAdapter _adapter; + private readonly ILogger _logger; + private readonly SimpleEnvironmentAdapter _adapter; - public JavaHomeAdapter(ILogger logger) - { - _logger = logger; - _adapter = new SimpleEnvironmentAdapter("JAVA_HOME"); - } + public JavaHomeAdapter(ILogger logger) + { + _logger = logger; + _adapter = new SimpleEnvironmentAdapter("JAVA_HOME"); + } - /// - public async Task GetValue(EnvironmentScope scope) - { - var val =await _adapter.GetValue(scope); - _logger.LogVerbose($"Read JAVA_HOME: {val}"); - return val; - } + /// + public async Task GetValue(EnvironmentScope scope) + { + var val =await _adapter.GetValue(scope); + _logger.LogVerbose($"Read JAVA_HOME: {val}"); + return val; + } - /// - public async Task SetValue(string value, EnvironmentScope scope) - { - _logger.LogVerbose($"Setting JAVA_HOME to: {value}"); - await _adapter.SetValue(value, scope); - } + /// + public async Task SetValue(string value, EnvironmentScope scope) + { + _logger.LogVerbose($"Setting JAVA_HOME to: {value}"); + await _adapter.SetValue(value, scope); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/JavaInstallationsAdapter.cs b/src/JavaVersionSwitcher/Adapters/JavaInstallationsAdapter.cs index ad0af92f..feb73a76 100644 --- a/src/JavaVersionSwitcher/Adapters/JavaInstallationsAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/JavaInstallationsAdapter.cs @@ -11,192 +11,191 @@ using JavaVersionSwitcher.Services; using Spectre.Console; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +public class JavaInstallationsAdapter : IJavaInstallationsAdapter { - /// - public class JavaInstallationsAdapter : IJavaInstallationsAdapter + private readonly ILogger _logger; + private readonly IConfigurationService _configurationService; + private readonly JavaInstallationsAdapterConfigurationProvider _configurationProvider; + private readonly IStorageAdapter _storageAdapter; + private readonly IAnsiConsole _console; + + public JavaInstallationsAdapter( + ILogger logger, + IConfigurationService configurationService, + JavaInstallationsAdapterConfigurationProvider configurationProvider, + IStorageAdapter storageAdapter, + IAnsiConsole console) { - private readonly ILogger _logger; - private readonly IConfigurationService _configurationService; - private readonly JavaInstallationsAdapterConfigurationProvider _configurationProvider; - private readonly IStorageAdapter _storageAdapter; - private readonly IAnsiConsole _console; - - public JavaInstallationsAdapter( - ILogger logger, - IConfigurationService configurationService, - JavaInstallationsAdapterConfigurationProvider configurationProvider, - IStorageAdapter storageAdapter, - IAnsiConsole console) - { - _logger = logger; - _configurationService = configurationService; - _configurationProvider = configurationProvider; - _storageAdapter = storageAdapter; - _console = console; - } + _logger = logger; + _configurationService = configurationService; + _configurationProvider = configurationProvider; + _storageAdapter = storageAdapter; + _console = console; + } - /// - public async Task> GetJavaInstallations(bool forceReScan = false) + /// + public async Task> GetJavaInstallations(bool forceReScan = false) + { + if (!forceReScan && await HasRecentCacheData()) { - if (!forceReScan && await HasRecentCacheData()) - { - try - { - return await LoadCacheData(); - } - catch (Exception ex) - { - _logger.LogVerbose($"{ex.GetType().Name} while reading cached data."); - } - } - - var data = (await ForceScan()).ToList(); - try { - await SaveCacheData(data); - } + return await LoadCacheData(); + } catch (Exception ex) { - _logger.LogVerbose($"{ex.GetType().Name} while writing data cache."); + _logger.LogVerbose($"{ex.GetType().Name} while reading cached data."); } + } - return data; + var data = (await ForceScan()).ToList(); + + try + { + await SaveCacheData(data); + } + catch (Exception ex) + { + _logger.LogVerbose($"{ex.GetType().Name} while writing data cache."); } + return data; + } + - private async Task SaveCacheData(IEnumerable data) - { - var file = _storageAdapter.JavaInstallationCacheFilePath; - Directory.CreateDirectory(Path.GetDirectoryName(file)!); - var serializer = new XmlSerializer(typeof(JavaInstallation[])); - await using var stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None); - await using var writer = new StreamWriter(stream, Encoding.UTF8); + private async Task SaveCacheData(IEnumerable data) + { + var file = _storageAdapter.JavaInstallationCacheFilePath; + Directory.CreateDirectory(Path.GetDirectoryName(file)!); + var serializer = new XmlSerializer(typeof(JavaInstallation[])); + await using var stream = new FileStream(file, FileMode.Create, FileAccess.Write, FileShare.None); + await using var writer = new StreamWriter(stream, Encoding.UTF8); - serializer.Serialize(writer, data.ToArray()); - } + serializer.Serialize(writer, data.ToArray()); + } - private async Task> LoadCacheData() - { - var file = _storageAdapter.JavaInstallationCacheFilePath; - var serializer = new XmlSerializer(typeof(JavaInstallation[])); - await using var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); - using var reader = new StreamReader(stream, Encoding.UTF8); + private async Task> LoadCacheData() + { + var file = _storageAdapter.JavaInstallationCacheFilePath; + var serializer = new XmlSerializer(typeof(JavaInstallation[])); + await using var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read); + using var reader = new StreamReader(stream, Encoding.UTF8); - return (JavaInstallation[])serializer.Deserialize(reader); - } + return (JavaInstallation[])serializer.Deserialize(reader); + } - private async Task HasRecentCacheData() + private async Task HasRecentCacheData() + { + var fileName = _storageAdapter.JavaInstallationCacheFilePath; + var file = new FileInfo(fileName); + if (!file.Exists) { - var fileName = _storageAdapter.JavaInstallationCacheFilePath; - var file = new FileInfo(fileName); - if (!file.Exists) - { - return false; - } - - var timeout = await _configurationProvider.GetCacheTimeout(_configurationService); - return file.LastWriteTime.AddDays(timeout) >= DateTime.Now; + return false; } - private async Task> ForceScan() - { - var result = new List(); - await _console.Status() - .StartAsync("Initializing...", async ctx => - { - ctx.Status("Scanning for java installations"); - ctx.Spinner(Spinner.Known.Star); - ctx.SpinnerStyle(Style.Parse("green")); - - var start = - (await _configurationProvider.GetStartPaths(_configurationService)) - .Select(Environment.ExpandEnvironmentVariables) - .Distinct() - .Where(x => !string.IsNullOrEmpty(x)) - .ToList(); - _logger.LogVerbose( - $@"Scanning for installations in:{Environment.NewLine} - {string.Join($"{Environment.NewLine} - ", start)}"); + var timeout = await _configurationProvider.GetCacheTimeout(_configurationService); + return file.LastWriteTime.AddDays(timeout) >= DateTime.Now; + } + + private async Task> ForceScan() + { + var result = new List(); + await _console.Status() + .StartAsync("Initializing...", async ctx => + { + ctx.Status("Scanning for java installations"); + ctx.Spinner(Spinner.Known.Star); + ctx.SpinnerStyle(Style.Parse("green")); + + var start = + (await _configurationProvider.GetStartPaths(_configurationService)) + .Select(Environment.ExpandEnvironmentVariables) + .Distinct() + .Where(x => !string.IsNullOrEmpty(x)) + .ToList(); + _logger.LogVerbose( + $@"Scanning for installations in:{Environment.NewLine} - {string.Join($"{Environment.NewLine} - ", start)}"); - var javaExeFiles = await FindFileRecursive(start); - foreach (var javaExeFile in javaExeFiles) + var javaExeFiles = await FindFileRecursive(start); + foreach (var javaExeFile in javaExeFiles) + { + var (version, fullVersion) = await GetVersion(javaExeFile).ConfigureAwait(false); + var installation = new JavaInstallation { - var (version, fullVersion) = await GetVersion(javaExeFile).ConfigureAwait(false); - var installation = new JavaInstallation - { - Location = Directory.GetParent(javaExeFile)?.Parent?.FullName, - Version = version, - FullVersion = fullVersion - }; - result.Add(installation); - } - }).ConfigureAwait(false); + Location = Directory.GetParent(javaExeFile)?.Parent?.FullName, + Version = version, + FullVersion = fullVersion + }; + result.Add(installation); + } + }).ConfigureAwait(false); - return result; - } + return result; + } - private Task> FindFileRecursive(IEnumerable startPaths) + private Task> FindFileRecursive(IEnumerable startPaths) + { + return Task.Factory.StartNew>(() => { - return Task.Factory.StartNew>(() => - { - var queue = new Queue(); - startPaths.ToList().ForEach(queue.Enqueue); + var queue = new Queue(); + startPaths.ToList().ForEach(queue.Enqueue); - var results = new List(); - while (queue.TryDequeue(out var item)) + var results = new List(); + while (queue.TryDequeue(out var item)) + { + try { - try + results.AddRange(Directory.GetFiles(item, "java.exe", SearchOption.TopDirectoryOnly)); + var subfolders = Directory.GetDirectories(item); + foreach (var subfolder in subfolders) { - results.AddRange(Directory.GetFiles(item, "java.exe", SearchOption.TopDirectoryOnly)); - var subfolders = Directory.GetDirectories(item); - foreach (var subfolder in subfolders) - { - queue.Enqueue(subfolder); - } - } - catch (Exception ex) - { - _logger.LogVerbose($"{ex.GetType().Name} while accessing {item}"); + queue.Enqueue(subfolder); } } + catch (Exception ex) + { + _logger.LogVerbose($"{ex.GetType().Name} while accessing {item}"); + } + } - return results; - }); - } + return results; + }); + } - private async Task> GetVersion(string javaExePath) + private async Task> GetVersion(string javaExePath) + { + var proc = new Process { - var proc = new Process + StartInfo = new ProcessStartInfo { - StartInfo = new ProcessStartInfo - { - FileName = javaExePath, - Arguments = "-version", - UseShellExecute = false, - RedirectStandardError = true, - CreateNoWindow = true - } - }; + FileName = javaExePath, + Arguments = "-version", + UseShellExecute = false, + RedirectStandardError = true, + CreateNoWindow = true + } + }; - proc.Start(); + proc.Start(); - string version = null; - var fullVersion = new StringBuilder(); - while (!proc.StandardError.EndOfStream) + string version = null; + var fullVersion = new StringBuilder(); + while (!proc.StandardError.EndOfStream) + { + var line = await proc.StandardError.ReadLineAsync().ConfigureAwait(false); + fullVersion.AppendLine(line); + if (string.IsNullOrEmpty(version)) { - var line = await proc.StandardError.ReadLineAsync().ConfigureAwait(false); - fullVersion.AppendLine(line); - if (string.IsNullOrEmpty(version)) - { - version = line; - } + version = line; } - - proc.WaitForExit(); - return new Tuple(version, fullVersion.ToString()); } + + await proc.WaitForExitAsync(); + return new Tuple(version, fullVersion.ToString()); } -} +} \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/PathAdapter.cs b/src/JavaVersionSwitcher/Adapters/PathAdapter.cs index 25cd0585..974d1e73 100644 --- a/src/JavaVersionSwitcher/Adapters/PathAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/PathAdapter.cs @@ -3,30 +3,29 @@ using System.IO; using System.Threading.Tasks; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +public class PathAdapter : IPathAdapter { - /// - public class PathAdapter : IPathAdapter - { - private readonly SimpleEnvironmentAdapter _adapter; + private readonly SimpleEnvironmentAdapter _adapter; - public PathAdapter() - { - _adapter = new SimpleEnvironmentAdapter("PATH"); - } + public PathAdapter() + { + _adapter = new SimpleEnvironmentAdapter("PATH"); + } - /// - public async Task> GetValue(EnvironmentScope scope) - { - var fullPath = await _adapter.GetValue(scope); - return fullPath.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries); - } + /// + public async Task> GetValue(EnvironmentScope scope) + { + var fullPath = await _adapter.GetValue(scope); + return fullPath.Split(Path.PathSeparator, StringSplitOptions.RemoveEmptyEntries); + } - /// - public async Task SetValue(IEnumerable value, EnvironmentScope scope) - { - var fullPath = string.Join(Path.PathSeparator, value); - await _adapter.SetValue(fullPath, scope); - } + /// + public async Task SetValue(IEnumerable value, EnvironmentScope scope) + { + var fullPath = string.Join(Path.PathSeparator, value); + await _adapter.SetValue(fullPath, scope); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/RegistryAdapter.cs b/src/JavaVersionSwitcher/Adapters/RegistryAdapter.cs new file mode 100644 index 00000000..d20f74ed --- /dev/null +++ b/src/JavaVersionSwitcher/Adapters/RegistryAdapter.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using JavaVersionSwitcher.Logging; +using JetBrains.Annotations; +using Microsoft.Win32; + +namespace JavaVersionSwitcher.Adapters; + +public class RegistryAdapter : IRegistryAdapter +{ + private readonly ILogger _logger; + + public RegistryAdapter(ILogger logger) + { + _logger = logger; + } + + [ItemCanBeNull] + private static Task GetHklmAsync() + { + return AsyncRegistryKey.Hklm; + } + + internal class AsyncRegistryKey + { +#pragma warning disable CA1416 + private readonly RegistryKey _key; + + private AsyncRegistryKey(RegistryKey key) + { + _key = key; + } + + [ItemCanBeNull] + internal static Task Hklm + { + get + { + return RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? Task.Factory.StartNew(() => new AsyncRegistryKey(Registry.LocalMachine)) + : Task.Factory.StartNew(() => null); + } + } + + [ItemCanBeNull] + internal Task OpenSubKey(string name) + { + return Task.Factory.StartNew(() => + { + var subKey = _key.OpenSubKey(name); + return subKey == null + ? null + : new AsyncRegistryKey(subKey); + }); + } + + internal Task GetSubKeyNames() + { + return Task.FromResult(_key.GetSubKeyNames()); + } + + [ItemCanBeNull] + internal Task GetValue(string name) + { + return Task.FromResult(_key.GetValue(name)); + } + + public override string ToString() + { + return _key.ToString(); + } +#pragma warning restore CA1416 + } + + public async IAsyncEnumerable GetInstallationPaths() + { + var localMachine = await GetHklmAsync(); + if (localMachine == null) + { + _logger.LogVerbose($"Not Checking the registry, since we're running on {RuntimeInformation.RuntimeIdentifier}"); + yield break; + } + + var javaSoft = await localMachine.OpenSubKey("SOFTWARE\\JavaSoft"); + if (javaSoft == null) + { + _logger.LogWarning(@"RegKey 'HKLM\Software\JavaSoft' does not exist."); + yield break; + } + + var roots = new[] + { + "Java Development Kit", + "Java Development Kit", + "JDK", + "JRE", + }; + + foreach (var root in roots) + { + var rootKey = await javaSoft.OpenSubKey(root); + if (rootKey == null) + { + continue; + } + + var keyNames = await rootKey.GetSubKeyNames(); + foreach (var name in keyNames) + { + _logger.LogVerbose($"Checking SubKey: {rootKey}\\{name}"); + var key = await rootKey.OpenSubKey(name); + if (key == null) + { + _logger.LogWarning($"SubKey '{rootKey}\\{name}' was reported to exist, but it does not."); + continue; + } + + if (await key.GetValue("JavaHome") is not string javaHome) + { + continue; + } + + yield return javaHome; + } + } + } +} \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/ShellAdapter.cs b/src/JavaVersionSwitcher/Adapters/ShellAdapter.cs index ec23b56a..4c983bd4 100644 --- a/src/JavaVersionSwitcher/Adapters/ShellAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/ShellAdapter.cs @@ -3,94 +3,93 @@ using System.Runtime.InteropServices; using JavaVersionSwitcher.Logging; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +// some of this was inspired by https://stackoverflow.com/a/2336322/180156 +public class ShellAdapter : IShellAdapter { - // some of this was inspired by https://stackoverflow.com/a/2336322/180156 - public class ShellAdapter : IShellAdapter - { - private readonly ILogger _logger; + private readonly ILogger _logger; - public ShellAdapter(ILogger logger) - { - _logger = logger; - } + public ShellAdapter(ILogger logger) + { + _logger = logger; + } - public ShellType GetShellType() + public ShellType GetShellType() + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return ShellType.Unknown; - } + return ShellType.Unknown; + } - try + 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)) { - 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; - } + proc = GetParentProcess(proc); } - catch(Exception e) + + _logger.LogVerbose("Parent process name is: " + proc.ProcessName); + var name = proc.ProcessName.ToLowerInvariant(); + switch (name) { - _logger.LogVerbose($"{e.GetType().Name} while finding parent process: {e.Message}"); - return ShellType.Unknown; + case "pwsh": + case "powershell": + return ShellType.PowerShell; + case "cmd": + return ShellType.CommandPrompt; + default: + return ShellType.Unknown; } } - - private static Process GetParentProcess(Process process) + catch(Exception e) { - return FindPidFromIndexedProcessName(FindIndexedProcessName(process.Id)); + _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)); + } #pragma warning disable CA1416 - private static string FindIndexedProcessName(int pid) + private static string FindIndexedProcessName(int pid) + { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new NotImplementedException( - "Accessing parent process is currently only available on windows."); - } + throw new NotImplementedException( + "Accessing parent process is currently only available on windows."); + } - var processName = Process.GetProcessById(pid).ProcessName; - var processesByName = Process.GetProcessesByName(processName); - string processIndexedName = null; + 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; - } + 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) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - throw new NotImplementedException( - "Accessing parent process is currently only available on windows."); - } + return processIndexedName; + } - var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName); - return Process.GetProcessById((int) parentId.NextValue()); + private static Process FindPidFromIndexedProcessName(string indexedProcessName) { + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + throw new NotImplementedException( + "Accessing parent process is currently only available on windows."); } -#pragma warning restore CA1416 + + var parentId = new PerformanceCounter("Process", "Creating Process ID", indexedProcessName); + return Process.GetProcessById((int) parentId.NextValue()); } +#pragma warning restore CA1416 } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/ShellType.cs b/src/JavaVersionSwitcher/Adapters/ShellType.cs index d2bd9858..57e6c862 100644 --- a/src/JavaVersionSwitcher/Adapters/ShellType.cs +++ b/src/JavaVersionSwitcher/Adapters/ShellType.cs @@ -1,20 +1,19 @@ -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +public enum ShellType { - public enum ShellType - { - /// - /// Unknown - /// - Unknown, + /// + /// Unknown + /// + Unknown, - /// - /// PowerShell - /// - PowerShell, + /// + /// PowerShell + /// + PowerShell, - /// - /// CMD - /// - CommandPrompt, - } + /// + /// CMD + /// + CommandPrompt, } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Adapters/StorageAdapter.cs b/src/JavaVersionSwitcher/Adapters/StorageAdapter.cs index c35e6a5d..2af4aa0b 100644 --- a/src/JavaVersionSwitcher/Adapters/StorageAdapter.cs +++ b/src/JavaVersionSwitcher/Adapters/StorageAdapter.cs @@ -1,29 +1,28 @@ using System; using System.IO; -namespace JavaVersionSwitcher.Adapters +namespace JavaVersionSwitcher.Adapters; + +/// +public class StorageAdapter : IStorageAdapter { - /// - public class StorageAdapter : IStorageAdapter - { - private string _baseFolder; + private string _baseFolder; - /// - public string ConfigurationFilePath => GetPath("settings.xml"); + /// + public string ConfigurationFilePath => GetPath("settings.xml"); - /// - public string JavaInstallationCacheFilePath => GetPath("installations.xml"); + /// + public string JavaInstallationCacheFilePath => GetPath("installations.xml"); - private string GetPath(string fileName) + private string GetPath(string fileName) + { + if (_baseFolder == null) { - if (_baseFolder == null) - { - var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); - var app = typeof(StorageAdapter).Assembly.GetName().Name ?? "JavaVersionSwitcher"; - _baseFolder = Path.Combine(appData, app); - } + var appData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); + var app = typeof(StorageAdapter).Assembly.GetName().Name ?? "JavaVersionSwitcher"; + _baseFolder = Path.Combine(appData, app); + } - return Path.Combine(_baseFolder, fileName); - } - } + return Path.Combine(_baseFolder, fileName); + } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/CheckSettingsCommand.cs b/src/JavaVersionSwitcher/Commands/CheckSettingsCommand.cs index 015305e3..2e3d43f0 100644 --- a/src/JavaVersionSwitcher/Commands/CheckSettingsCommand.cs +++ b/src/JavaVersionSwitcher/Commands/CheckSettingsCommand.cs @@ -8,96 +8,112 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands +namespace JavaVersionSwitcher.Commands; + +[UsedImplicitly] +internal sealed class CheckSettingsCommand : AsyncCommand { + private readonly IJavaHomeAdapter _javaHomeAdapter; + private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; + private readonly IPathAdapter _pathAdapter; + private readonly IRegistryAdapter _registryAdapter; + private readonly ILogger _logger; + private readonly IAnsiConsole _console; + + public CheckSettingsCommand( + IJavaHomeAdapter javaHomeAdapter, + IJavaInstallationsAdapter javaInstallationsAdapter, + IPathAdapter pathAdapter, + IRegistryAdapter registryAdapter, + ILogger logger, + IAnsiConsole console + ) + { + _javaHomeAdapter = javaHomeAdapter; + _javaInstallationsAdapter = javaInstallationsAdapter; + _pathAdapter = pathAdapter; + _registryAdapter = registryAdapter; + _logger = logger; + _console = console; + } + [UsedImplicitly] - internal sealed class CheckSettingsCommand : AsyncCommand + public sealed class Settings : CommonCommandSettings { - private readonly IJavaHomeAdapter _javaHomeAdapter; - private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; - private readonly IPathAdapter _pathAdapter; - private readonly ILogger _logger; - private readonly IAnsiConsole _console; + /* + TODO: Implement + [CommandOption("--fix")] + [Description("if set, any found problem is attempted to be fixed.")] + [DefaultValue(false)] + public bool Fix { get; init; } + */ + } - public CheckSettingsCommand( - IJavaHomeAdapter javaHomeAdapter, - IJavaInstallationsAdapter javaInstallationsAdapter, - IPathAdapter pathAdapter, - ILogger logger, - IAnsiConsole console - ) + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; + var javaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process); + if (string.IsNullOrEmpty(javaHome)) { - _javaHomeAdapter = javaHomeAdapter; - _javaInstallationsAdapter = javaInstallationsAdapter; - _pathAdapter = pathAdapter; - _logger = logger; - _console = console; + _console.MarkupLine("[red]JAVA_HOME is not set[/] JAVA_HOME needs to be set, for PATH check to work."); + return 1; } - - [UsedImplicitly] - public sealed class Settings : CommonCommandSettings + + _console.MarkupLine("[green]JAVA_HOME[/]: " + javaHome); + + var javaInstallations = await _javaInstallationsAdapter + .GetJavaInstallations() + .ConfigureAwait(false); + var paths = (await _pathAdapter.GetValue(EnvironmentScope.Process)).ToList(); + + var errors = false; + var javaHomeBin = Path.Combine(javaHome, "bin"); + var javaHomeInPath = paths.FirstOrDefault(x => + x.StartsWith(javaHomeBin, StringComparison.OrdinalIgnoreCase) && + (x.Length == javaHomeBin.Length || x.Length == javaHomeBin.Length + 1)); + if (javaHomeInPath != null) { - /* - TODO: Implement - [CommandOption("--fix")] - [Description("if set, any found problem is attempted to be fixed.")] - [DefaultValue(false)] - public bool Fix { get; init; } - */ + _console.MarkupLine("[green]JAVA_HOME\\bin is in PATH[/]: " + javaHomeInPath); } - - public override async Task ExecuteAsync(CommandContext context, Settings settings) + else { - _logger.PrintVerbose = settings.Verbose; - var javaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process); - if (string.IsNullOrEmpty(javaHome)) - { - _console.MarkupLine("[red]JAVA_HOME is not set[/] JAVA_HOME needs to be set, for PATH check to work."); - return 1; - } - _console.MarkupLine("[green]JAVA_HOME[/]: "+javaHome); + errors = true; + _console.MarkupLine(@"[red]JAVA_HOME\bin is not in PATH[/] JAVA_HOME\bin needs to be in PATH."); + } - var javaInstallations = await _javaInstallationsAdapter - .GetJavaInstallations() - .ConfigureAwait(false); - var paths = (await _pathAdapter.GetValue(EnvironmentScope.Process)).ToList(); + foreach (var java in javaInstallations) + { + var javaInstallationsInPath = paths + .Where(x => x.StartsWith(java.Location, StringComparison.OrdinalIgnoreCase)) + .Where(x => !x.Equals(javaHomeInPath)); - var errors = false; - var javaHomeBin = Path.Combine(javaHome, "bin"); - var javaHomeInPath = paths.FirstOrDefault(x => - x.StartsWith(javaHomeBin, StringComparison.OrdinalIgnoreCase) && - (x.Length == javaHomeBin.Length || x.Length == javaHomeBin.Length + 1)); - if (javaHomeInPath != null) - { - _console.MarkupLine("[green]JAVA_HOME\\bin is in PATH[/]: "+javaHomeInPath); - } - else + foreach (var path in javaInstallationsInPath) { errors = true; - _console.MarkupLine("[red]JAVA_HOME\\bin is not in PATH[/] JAVA_HOME\\bin needs to be in PATH."); + _console.MarkupLine($"[red]Additional java in PATH[/]: {path}"); } + } - foreach (var java in javaInstallations) + await foreach (var path in _registryAdapter.GetInstallationPaths()) + { + var binPath = Path.Combine(path, "bin", "java.exe"); + if (File.Exists(binPath)) { - var javaInstallationsInPath = paths - .Where(x => x.StartsWith(java.Location, StringComparison.OrdinalIgnoreCase)) - .Where(x => !x.Equals(javaHomeInPath)); - - foreach (var path in javaInstallationsInPath) - { - errors = true; - _console.MarkupLine($"[red]Additional java in PATH[/]: {path}"); - } + continue; } - if (errors) - { - _console.MarkupLine("[yellow]There were errors.[/]"); - _console.MarkupLine("[yellow]Fixing errors is not implemented. You need to fix them manually![/]"); - return 1; - } + var warn = + $"Path for java installation '{path}' set in Windows Registry. But does not contain a java executable!"; + _console.MarkupLine($"[red]{warn}[/]"); + } - return 0; + if (errors) + { + _console.MarkupLine("[yellow]There were errors.[/]"); + _console.MarkupLine("[yellow]Fixing errors is not implemented. You need to fix them manually![/]"); + return 1; } + + return 0; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/CommonCommandSettings.cs b/src/JavaVersionSwitcher/Commands/CommonCommandSettings.cs index 8a1a7a6c..b57a3cbd 100644 --- a/src/JavaVersionSwitcher/Commands/CommonCommandSettings.cs +++ b/src/JavaVersionSwitcher/Commands/CommonCommandSettings.cs @@ -1,13 +1,12 @@ using System.ComponentModel; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands +namespace JavaVersionSwitcher.Commands; + +public abstract class CommonCommandSettings : CommandSettings { - public abstract class CommonCommandSettings : CommandSettings - { - [CommandOption("--verbose")] - [Description("Show verbose messages.")] - [DefaultValue(false)] - public bool Verbose { get; set; } - } + [CommandOption("--verbose")] + [Description("Show verbose messages.")] + [DefaultValue(false)] + public bool Verbose { get; set; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/ScanJavaInstallationsCommand.cs b/src/JavaVersionSwitcher/Commands/ScanJavaInstallationsCommand.cs index 32b86a33..f8f1cd19 100644 --- a/src/JavaVersionSwitcher/Commands/ScanJavaInstallationsCommand.cs +++ b/src/JavaVersionSwitcher/Commands/ScanJavaInstallationsCommand.cs @@ -7,52 +7,51 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands +namespace JavaVersionSwitcher.Commands; + +[UsedImplicitly] +internal sealed class ScanJavaInstallationsCommand : AsyncCommand { + private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; + private readonly ILogger _logger; + private readonly IAnsiConsole _console; + + public ScanJavaInstallationsCommand( + IJavaInstallationsAdapter javaInstallationsAdapter, + ILogger logger, + IAnsiConsole console) + { + _javaInstallationsAdapter = javaInstallationsAdapter; + _logger = logger; + _console = console; + } + [UsedImplicitly] - internal sealed class ScanJavaInstallationsCommand : AsyncCommand + public sealed class Settings : CommonCommandSettings { - private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; - private readonly ILogger _logger; - private readonly IAnsiConsole _console; + [CommandOption("--force")] + [DefaultValue(false)] + [Description("Force re-scan and do not use cached data.")] + public bool Force { get; [UsedImplicitly] set; } + } - public ScanJavaInstallationsCommand( - IJavaInstallationsAdapter javaInstallationsAdapter, - ILogger logger, - IAnsiConsole console) - { - _javaInstallationsAdapter = javaInstallationsAdapter; - _logger = logger; - _console = console; - } - - [UsedImplicitly] - public sealed class Settings : CommonCommandSettings + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; + var installations = await _javaInstallationsAdapter + .GetJavaInstallations(settings.Force) + .ConfigureAwait(false); + var table = new Table(); + table.AddColumn("Java path"); + table.AddColumn("version"); + foreach (var javaInstallation in installations.OrderBy(x => x.Location)) { - [CommandOption("--force")] - [DefaultValue(false)] - [Description("Force re-scan and do not use cached data.")] - public bool Force { get; [UsedImplicitly] set; } + //var txt = javaInstallation.Version; + //if(ver) + table.AddRow(javaInstallation.Location, javaInstallation.Version ?? "unknown"); } - public override async Task ExecuteAsync(CommandContext context, Settings settings) - { - _logger.PrintVerbose = settings.Verbose; - var installations = await _javaInstallationsAdapter - .GetJavaInstallations(settings.Force) - .ConfigureAwait(false); - var table = new Table(); - table.AddColumn("Java path"); - table.AddColumn("version"); - foreach (var javaInstallation in installations.OrderBy(x => x.Location)) - { - //var txt = javaInstallation.Version; - //if(ver) - table.AddRow(javaInstallation.Location, javaInstallation.Version ?? "unknown"); - } - - _console.Write(table); - return 0; - } + _console.Write(table); + return 0; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/SwitchVersionCommand.cs b/src/JavaVersionSwitcher/Commands/SwitchVersionCommand.cs index 405674ea..1a639d6a 100644 --- a/src/JavaVersionSwitcher/Commands/SwitchVersionCommand.cs +++ b/src/JavaVersionSwitcher/Commands/SwitchVersionCommand.cs @@ -10,106 +10,105 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands +namespace JavaVersionSwitcher.Commands; + +[UsedImplicitly] +internal sealed class SwitchVersionCommand : AsyncCommand { - [UsedImplicitly] - internal sealed class SwitchVersionCommand : AsyncCommand - { - private readonly IJavaHomeAdapter _javaHomeAdapter; - private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; - private readonly IPathAdapter _pathAdapter; - private readonly ILogger _logger; - private readonly IShellAdapter _shellAdapter; - private readonly IAnsiConsole _console; + private readonly IJavaHomeAdapter _javaHomeAdapter; + private readonly IJavaInstallationsAdapter _javaInstallationsAdapter; + private readonly IPathAdapter _pathAdapter; + private readonly ILogger _logger; + private readonly IShellAdapter _shellAdapter; + private readonly IAnsiConsole _console; - public SwitchVersionCommand( - IJavaHomeAdapter javaHomeAdapter, - IJavaInstallationsAdapter javaInstallationsAdapter, - IPathAdapter pathAdapter, - ILogger logger, - IShellAdapter shellAdapter, - IAnsiConsole console - ) - { - _javaHomeAdapter = javaHomeAdapter; - _javaInstallationsAdapter = javaInstallationsAdapter; - _pathAdapter = pathAdapter; - _logger = logger; - _shellAdapter = shellAdapter; - _console = console; - } + public SwitchVersionCommand( + IJavaHomeAdapter javaHomeAdapter, + IJavaInstallationsAdapter javaInstallationsAdapter, + IPathAdapter pathAdapter, + ILogger logger, + IShellAdapter shellAdapter, + IAnsiConsole console + ) + { + _javaHomeAdapter = javaHomeAdapter; + _javaInstallationsAdapter = javaInstallationsAdapter; + _pathAdapter = pathAdapter; + _logger = logger; + _shellAdapter = shellAdapter; + _console = console; + } - [UsedImplicitly] - public sealed class Settings : CommonCommandSettings - { - [CommandOption("--machine")] - [DefaultValue(false)] - [Description("set variables in machine scope instead of user. needs admin privileges.")] - public bool MachineScope { get; [UsedImplicitly] set; } - } + [UsedImplicitly] + public sealed class Settings : CommonCommandSettings + { + [CommandOption("--machine")] + [DefaultValue(false)] + [Description("set variables in machine scope instead of user. needs admin privileges.")] + public bool MachineScope { get; [UsedImplicitly] set; } + } - public override async Task ExecuteAsync(CommandContext context, Settings settings) - { - _logger.PrintVerbose = settings.Verbose; - var installations = await _javaInstallationsAdapter - .GetJavaInstallations() - .ConfigureAwait(false); + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; + var installations = await _javaInstallationsAdapter + .GetJavaInstallations() + .ConfigureAwait(false); - var newJavaHome = _console.Prompt( - new SelectionPrompt() - .Title("Which java should be set?") - .PageSize(25) - .MoreChoicesText("[grey](Move up and down to reveal more installations)[/]") - .AddChoices(installations.Select(x => x.Location).ToArray())); + var newJavaHome = _console.Prompt( + new SelectionPrompt() + .Title("Which java should be set?") + .PageSize(25) + .MoreChoicesText("[grey](Move up and down to reveal more installations)[/]") + .AddChoices(installations.Select(x => x.Location).ToArray())); - string javaBin = null; - await _console.Status() - .StartAsync("Applying...", async ctx => - { - ctx.Spinner(Spinner.Known.Star); - ctx.SpinnerStyle(Style.Parse("green")); + string javaBin = null; + await _console.Status() + .StartAsync("Applying...", async ctx => + { + ctx.Spinner(Spinner.Known.Star); + ctx.SpinnerStyle(Style.Parse("green")); - var scope = settings.MachineScope - ? EnvironmentScope.Machine - : EnvironmentScope.User; + var scope = settings.MachineScope + ? EnvironmentScope.Machine + : EnvironmentScope.User; - var oldJavaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process); - var paths = (await _pathAdapter.GetValue(scope)).ToList(); - if (!string.IsNullOrEmpty(oldJavaHome)) - { - paths = paths.Where(x => !x.StartsWith(oldJavaHome,StringComparison.OrdinalIgnoreCase)).ToList(); - } + var oldJavaHome = await _javaHomeAdapter.GetValue(EnvironmentScope.Process); + var paths = (await _pathAdapter.GetValue(scope)).ToList(); + if (!string.IsNullOrEmpty(oldJavaHome)) + { + paths = paths.Where(x => !x.StartsWith(oldJavaHome,StringComparison.OrdinalIgnoreCase)).ToList(); + } - javaBin = Path.Combine(newJavaHome, "bin"); - paths.Add(javaBin); + javaBin = Path.Combine(newJavaHome, "bin"); + paths.Add(javaBin); - await _javaHomeAdapter.SetValue(newJavaHome, scope); - await _pathAdapter.SetValue(paths, scope); - }).ConfigureAwait(false); + await _javaHomeAdapter.SetValue(newJavaHome, scope); + await _pathAdapter.SetValue(paths, scope); + }).ConfigureAwait(false); - var shellType = _shellAdapter.GetShellType(); - var refreshCommands = new List(); - switch (shellType) - { - case ShellType.PowerShell: - refreshCommands.Add($"$env:JAVA_HOME=\"{newJavaHome}\""); - refreshCommands.Add($"$env:PATH=\"{javaBin}{Path.PathSeparator}$($env:PATH)\""); - break; - case ShellType.CommandPrompt: - refreshCommands.Add($"set \"JAVA_HOME={newJavaHome}\""); - refreshCommands.Add($"set \"PATH={javaBin}{Path.PathSeparator}%PATH%\""); - break; - } + var shellType = _shellAdapter.GetShellType(); + var refreshCommands = new List(); + switch (shellType) + { + case ShellType.PowerShell: + refreshCommands.Add($"$env:JAVA_HOME=\"{newJavaHome}\""); + refreshCommands.Add($"$env:PATH=\"{javaBin}{Path.PathSeparator}$($env:PATH)\""); + break; + case ShellType.CommandPrompt: + refreshCommands.Add($"set \"JAVA_HOME={newJavaHome}\""); + refreshCommands.Add($"set \"PATH={javaBin}{Path.PathSeparator}%PATH%\""); + break; + } - _console.MarkupLine(refreshCommands.Count > 0 - ? "[yellow]The environment has been modified. Apply modifications:[/]" - : "[yellow]The environment has been modified. You need to refresh it.[/]"); + _console.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; + foreach (var line in refreshCommands) + { + _console.WriteLine(line); } + return 0; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/config/CommonConfigCommandSettings.cs b/src/JavaVersionSwitcher/Commands/config/CommonConfigCommandSettings.cs index c2bfc271..3011b1de 100644 --- a/src/JavaVersionSwitcher/Commands/config/CommonConfigCommandSettings.cs +++ b/src/JavaVersionSwitcher/Commands/config/CommonConfigCommandSettings.cs @@ -3,31 +3,30 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands.config +namespace JavaVersionSwitcher.Commands.config; + +public abstract class CommonConfigCommandSettings : CommonCommandSettings { - public abstract class CommonConfigCommandSettings : CommonCommandSettings - { - [CommandArgument(0, "[Provider]")] - [Description("Name of the provider.")] - public string Provider { get; [UsedImplicitly] set; } + [CommandArgument(0, "[Provider]")] + [Description("Name of the provider.")] + public string Provider { get; [UsedImplicitly] set; } - [CommandArgument(1, "[Name]")] - [Description("Name of the option for that provider.")] - public string Name { get; [UsedImplicitly] set; } + [CommandArgument(1, "[Name]")] + [Description("Name of the option for that provider.")] + public string Name { get; [UsedImplicitly] set; } - public override ValidationResult Validate() + public override ValidationResult Validate() + { + if (string.IsNullOrEmpty(Provider)) { - if (string.IsNullOrEmpty(Provider)) - { - return ValidationResult.Error("Provider must be set."); - } - - if (string.IsNullOrEmpty(Name)) - { - return ValidationResult.Error("Name must be set."); - } + return ValidationResult.Error("Provider must be set."); + } - return ValidationResult.Success(); + if (string.IsNullOrEmpty(Name)) + { + return ValidationResult.Error("Name must be set."); } + + return ValidationResult.Success(); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/config/GetConfigCommand.cs b/src/JavaVersionSwitcher/Commands/config/GetConfigCommand.cs index 66ef8a9c..781a9aac 100644 --- a/src/JavaVersionSwitcher/Commands/config/GetConfigCommand.cs +++ b/src/JavaVersionSwitcher/Commands/config/GetConfigCommand.cs @@ -5,38 +5,37 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands.config +namespace JavaVersionSwitcher.Commands.config; + +[UsedImplicitly] +public class GetConfigCommand : AsyncCommand { - [UsedImplicitly] - public class GetConfigCommand : AsyncCommand - { - private readonly ILogger _logger; - private readonly IConfigurationService _service; - private readonly IAnsiConsole _console; + private readonly ILogger _logger; + private readonly IConfigurationService _service; + private readonly IAnsiConsole _console; - public GetConfigCommand( - ILogger logger, - IConfigurationService service, - IAnsiConsole console) - { - _logger = logger; - _service = service; - _console = console; - } + public GetConfigCommand( + ILogger logger, + IConfigurationService service, + IAnsiConsole console) + { + _logger = logger; + _service = service; + _console = console; + } - [UsedImplicitly] - public sealed class Settings : CommonConfigCommandSettings - { - } + [UsedImplicitly] + public sealed class Settings : CommonConfigCommandSettings + { + } - public override async Task ExecuteAsync(CommandContext context, Settings settings) - { - _logger.PrintVerbose = settings.Verbose; + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; - var val = await _service.GetConfiguration(settings.Provider, settings.Name); - _console.MarkupLine(val); + var val = await _service.GetConfiguration(settings.Provider, settings.Name); + _console.MarkupLine(val); - return 0; - } + return 0; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/config/SetConfigCommand.cs b/src/JavaVersionSwitcher/Commands/config/SetConfigCommand.cs index fe3c9b58..c9f6c03c 100644 --- a/src/JavaVersionSwitcher/Commands/config/SetConfigCommand.cs +++ b/src/JavaVersionSwitcher/Commands/config/SetConfigCommand.cs @@ -5,39 +5,37 @@ using JetBrains.Annotations; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands.config +namespace JavaVersionSwitcher.Commands.config; + +[UsedImplicitly] +public class SetConfigCommand : AsyncCommand { - [UsedImplicitly] - public class SetConfigCommand : AsyncCommand - { - private readonly ILogger _logger; - private readonly IConfigurationService _service; + private readonly ILogger _logger; + private readonly IConfigurationService _service; - public SetConfigCommand( - ILogger logger, - IConfigurationService service) - { - _logger = logger; - _service = service; - } + public SetConfigCommand( + ILogger logger, + IConfigurationService service) + { + _logger = logger; + _service = service; + } + [UsedImplicitly] + public sealed class Settings : CommonConfigCommandSettings + { + [CommandArgument(2, "[Value]")] + [Description("The value to set.")] [UsedImplicitly] - public sealed class Settings : CommonConfigCommandSettings - { - [CommandArgument(2, "[Value]")] - [Description("The value to set.")] - [UsedImplicitly] - public string Value { get; set; } - } + public string Value { get; set; } + } - public override async Task ExecuteAsync(CommandContext context, Settings settings) - { - _logger.PrintVerbose = settings.Verbose; + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; - await _service.SetConfiguration(settings.Provider, settings.Name, settings.Value); + await _service.SetConfiguration(settings.Provider, settings.Name, settings.Value); - return 0; - } + return 0; } - } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Commands/config/ShowConfigCommand.cs b/src/JavaVersionSwitcher/Commands/config/ShowConfigCommand.cs index 28baf6db..8a6f9fcf 100644 --- a/src/JavaVersionSwitcher/Commands/config/ShowConfigCommand.cs +++ b/src/JavaVersionSwitcher/Commands/config/ShowConfigCommand.cs @@ -9,114 +9,113 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher.Commands.config +namespace JavaVersionSwitcher.Commands.config; + +[UsedImplicitly] +public class ShowConfigCommand : AsyncCommand { - [UsedImplicitly] - public class ShowConfigCommand : AsyncCommand - { - private readonly ILogger _logger; - private readonly IConfigurationService _service; - private readonly IEnumerable _providers; - private readonly IAnsiConsole _console; + private readonly ILogger _logger; + private readonly IConfigurationService _service; + private readonly IEnumerable _providers; + private readonly IAnsiConsole _console; - public ShowConfigCommand( - ILogger logger, - IConfigurationService service, - IEnumerable providers, - IAnsiConsole console) - { - _logger = logger; - _service = service; - _providers = providers; - _console = console; - } + public ShowConfigCommand( + ILogger logger, + IConfigurationService service, + IEnumerable providers, + IAnsiConsole console) + { + _logger = logger; + _service = service; + _providers = providers; + _console = console; + } - [UsedImplicitly] - public sealed class Settings : CommonCommandSettings - { - [CommandOption("--providers")] - [Description("Show provider names only.")] - [DefaultValue(false)] - public bool Providers { get; [UsedImplicitly] set; } + [UsedImplicitly] + public sealed class Settings : CommonCommandSettings + { + [CommandOption("--providers")] + [Description("Show provider names only.")] + [DefaultValue(false)] + public bool Providers { get; [UsedImplicitly] set; } - [CommandOption("--provider")] - [Description("Show settings for one provider only.")] - public string Provider { get; [UsedImplicitly] set; } + [CommandOption("--provider")] + [Description("Show settings for one provider only.")] + public string Provider { get; [UsedImplicitly] set; } - public override ValidationResult Validate() + public override ValidationResult Validate() + { + if (Providers && !string.IsNullOrEmpty(Provider)) { - if (Providers && !string.IsNullOrEmpty(Provider)) - { - return ValidationResult.Error("--providers and --provider are mutually exclusive."); - } - - return ValidationResult.Success(); + return ValidationResult.Error("--providers and --provider are mutually exclusive."); } + + return ValidationResult.Success(); } + } - public override async Task ExecuteAsync(CommandContext context, Settings settings) + public override async Task ExecuteAsync(CommandContext context, Settings settings) + { + _logger.PrintVerbose = settings.Verbose; + if (settings.Providers) { - _logger.PrintVerbose = settings.Verbose; - if (settings.Providers) - { - return await ListProviders(); - } - - if (!string.IsNullOrEmpty(settings.Provider)) - { - return await ListSettingsForProviders(settings.Provider); - } - - return await ListAllSettings(); + return await ListProviders(); } - private async Task ListSettingsForProviders(string settingsProvider) + if (!string.IsNullOrEmpty(settings.Provider)) { - var provider = _providers.FirstOrDefault(p => - p.ProviderName.Equals(settingsProvider, StringComparison.OrdinalIgnoreCase)); - if (provider == null) - { - _console.MarkupLine($"[red]No provider named {settingsProvider}[/]"); - return await Task.FromResult(1); - } - - _logger.LogVerbose($"Listing setting for {provider.ProviderName}:"); - foreach (var setting in provider.Settings.OrderBy(x => x)) - { - _console.WriteLine(setting); - } - - return await Task.FromResult(0); + return await ListSettingsForProviders(settings.Provider); } - private async Task ListAllSettings() - { - var table = new Table(); - table.AddColumn("Provider"); - table.AddColumn("Setting"); - table.AddColumn("Configured value"); + return await ListAllSettings(); + } - foreach (var provider in _providers.OrderBy(p => p.ProviderName)) - { - foreach (var setting in provider.Settings.OrderBy(x => x)) - { - var val = await _service.GetConfiguration(provider.ProviderName, setting); - table.AddRow(provider.ProviderName, setting, val); - } - } + private async Task ListSettingsForProviders(string settingsProvider) + { + var provider = _providers.FirstOrDefault(p => + p.ProviderName.Equals(settingsProvider, StringComparison.OrdinalIgnoreCase)); + if (provider == null) + { + _console.MarkupLine($"[red]No provider named {settingsProvider}[/]"); + return await Task.FromResult(1); + } - _console.Write(table); - return 0; + _logger.LogVerbose($"Listing setting for {provider.ProviderName}:"); + foreach (var setting in provider.Settings.OrderBy(x => x)) + { + _console.WriteLine(setting); } + + return await Task.FromResult(0); + } + + private async Task ListAllSettings() + { + var table = new Table(); + table.AddColumn("Provider"); + table.AddColumn("Setting"); + table.AddColumn("Configured value"); - private async Task ListProviders() + foreach (var provider in _providers.OrderBy(p => p.ProviderName)) { - foreach (var name in _providers.Select(p => p.ProviderName).OrderBy(x => x)) + foreach (var setting in provider.Settings.OrderBy(x => x)) { - _console.WriteLine(name); + var val = await _service.GetConfiguration(provider.ProviderName, setting); + table.AddRow(provider.ProviderName, setting, val); } + } - return await Task.FromResult(0); + _console.Write(table); + return 0; + } + + private async Task ListProviders() + { + foreach (var name in _providers.Select(p => p.ProviderName).OrderBy(x => x)) + { + _console.WriteLine(name); } + + return await Task.FromResult(0); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/JavaVersionSwitcher.csproj b/src/JavaVersionSwitcher/JavaVersionSwitcher.csproj index 6b46e902..c89b5efc 100644 --- a/src/JavaVersionSwitcher/JavaVersionSwitcher.csproj +++ b/src/JavaVersionSwitcher/JavaVersionSwitcher.csproj @@ -37,6 +37,7 @@ + @@ -45,6 +46,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/src/JavaVersionSwitcher/Logging/ILogger.cs b/src/JavaVersionSwitcher/Logging/ILogger.cs index c1c8ef14..bddc8ae2 100644 --- a/src/JavaVersionSwitcher/Logging/ILogger.cs +++ b/src/JavaVersionSwitcher/Logging/ILogger.cs @@ -1,27 +1,26 @@ -namespace JavaVersionSwitcher.Logging +namespace JavaVersionSwitcher.Logging; + +/// +/// The internal logger +/// +public interface ILogger { /// - /// The internal logger + /// Verbose messages will be printed, + /// only if this is set to true /// - public interface ILogger - { - /// - /// Verbose messages will be printed, - /// only if this is set to true - /// - bool PrintVerbose { get; set; } + bool PrintVerbose { get; set; } - /// - /// Log a verbose message. - /// See also . - /// - /// The text to print. - void LogVerbose(string text); + /// + /// Log a verbose message. + /// See also . + /// + /// The text to print. + void LogVerbose(string text); - /// - /// Logs a warning. - /// - /// The text to log. - void LogWarning(string text); - } + /// + /// Logs a warning. + /// + /// The text to log. + void LogWarning(string text); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Logging/Logger.cs b/src/JavaVersionSwitcher/Logging/Logger.cs index 6935c6c7..1e18abec 100644 --- a/src/JavaVersionSwitcher/Logging/Logger.cs +++ b/src/JavaVersionSwitcher/Logging/Logger.cs @@ -1,31 +1,30 @@ using Spectre.Console; -namespace JavaVersionSwitcher.Logging +namespace JavaVersionSwitcher.Logging; + +public class Logger : ILogger { - public class Logger : ILogger - { - private readonly IAnsiConsole _console; + private readonly IAnsiConsole _console; - public Logger(IAnsiConsole console) - { - _console = console; - } + public Logger(IAnsiConsole console) + { + _console = console; + } - public bool PrintVerbose { get; set; } + public bool PrintVerbose { get; set; } - public void LogVerbose(string text) + public void LogVerbose(string text) + { + if (!PrintVerbose) { - if (!PrintVerbose) - { - return; - } - - _console.MarkupLine($"[gray]{text}[/]"); + return; } + + _console.MarkupLine($"[gray]{text}[/]"); + } - public void LogWarning(string text) - { - _console.MarkupLine($"[yellow]WARNING: {text}[/]"); - } + public void LogWarning(string text) + { + _console.MarkupLine($"[yellow]WARNING: {text}[/]"); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Models/JavaInstallation.cs b/src/JavaVersionSwitcher/Models/JavaInstallation.cs index 80d90cc2..08079564 100644 --- a/src/JavaVersionSwitcher/Models/JavaInstallation.cs +++ b/src/JavaVersionSwitcher/Models/JavaInstallation.cs @@ -2,17 +2,16 @@ using System.Diagnostics; using System.Xml.Serialization; -namespace JavaVersionSwitcher.Models +namespace JavaVersionSwitcher.Models; + +[Serializable] +[DebuggerDisplay("{" + nameof(Version) + "}")] +public class JavaInstallation { - [Serializable] - [DebuggerDisplay("{" + nameof(Version) + "}")] - public class JavaInstallation - { - public string Location { get; set; } + public string Location { get; set; } - [XmlAttribute] - public string Version { get; set; } + [XmlAttribute] + public string Version { get; set; } - public string FullVersion { get; set; } - } + public string FullVersion { get; set; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Program.cs b/src/JavaVersionSwitcher/Program.cs index bb9a5b6f..4a652830 100644 --- a/src/JavaVersionSwitcher/Program.cs +++ b/src/JavaVersionSwitcher/Program.cs @@ -8,82 +8,82 @@ using Spectre.Console; using Spectre.Console.Cli; -namespace JavaVersionSwitcher +namespace JavaVersionSwitcher; + +[UsedImplicitly] +public class Program { - [UsedImplicitly] - public class Program + private static int Main(string[] args) { - private static int Main(string[] args) - { - var registrar = BuildRegistrar(); - var app = new CommandApp(registrar); - app.Configure(ConfigureApp); - return app.Run(args); - } + var registrar = BuildRegistrar(); + var app = new CommandApp(registrar); + app.Configure(ConfigureApp); + return app.Run(args); + } - public static void ConfigureApp(IConfigurator config) - { - config.SetApplicationName("dotnet jvs"); - config.AddExample(new[] { "scan", "--force" }); - config.AddExample(new[] { "switch" }); + public static void ConfigureApp(IConfigurator config) + { + config.SetApplicationName("dotnet jvs"); + config.AddExample(new[] { "scan", "--force" }); + config.AddExample(new[] { "switch" }); - config.SetExceptionHandler(ex => - { + config.SetExceptionHandler(ex => + { #if DEBUG - AnsiConsole.WriteException(ex, ExceptionFormats.ShowLinks); + AnsiConsole.WriteException(ex, ExceptionFormats.ShowLinks); #else AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything); #endif - return -1; - }); + return -1; + }); - config.AddCommand("scan") - .WithAlias("scan-for-java") - .WithDescription("Scan for existing java installations."); - config.AddCommand("check") - .WithDescription("Checks if environment is set up correctly."); - config.AddCommand("switch") - .WithDescription("Switch to a different Java version."); - config.AddBranch("config", cfg => - { - cfg.SetDescription("get or set configurations options."); + config.AddCommand("scan") + .WithAlias("scan-for-java") + .WithDescription("Scan for existing java installations."); + config.AddCommand("check") + .WithDescription("Checks if environment is set up correctly."); + config.AddCommand("switch") + .WithDescription("Switch to a different Java version."); + config.AddBranch("config", cfg => + { + cfg.SetDescription("get or set configurations options."); - cfg.AddCommand("get") - .WithDescription("get configuration options."); - cfg.AddCommand("set") - .WithDescription("set configuration options."); - cfg.AddCommand("show") - .WithDescription("show possible configuration options."); - }); + cfg.AddCommand("get") + .WithDescription("get configuration options."); + cfg.AddCommand("set") + .WithDescription("set configuration options."); + cfg.AddCommand("show") + .WithDescription("show possible configuration options."); + }); #if DEBUG - config.ValidateExamples(); + config.ValidateExamples(); #endif - } + } - private static ITypeRegistrar BuildRegistrar() - { - var container = new Container(); - container.Options.ResolveUnregisteredConcreteTypes = true; - container.Register(Lifestyle.Singleton); + private static ITypeRegistrar BuildRegistrar() + { + var container = new Container(); + container.Options.ResolveUnregisteredConcreteTypes = true; + container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); - container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); + container.Register(Lifestyle.Singleton); - container.Collection.Register( - new[] - { - typeof(JavaInstallationsAdapterConfigurationProvider), - }, - Lifestyle.Singleton); + container.Collection.Register( + new[] + { + typeof(JavaInstallationsAdapterConfigurationProvider), + }, + Lifestyle.Singleton); - return new SimpleInjectorRegistrar(container); - } + return new SimpleInjectorRegistrar(container); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Services/ConfigurationService.cs b/src/JavaVersionSwitcher/Services/ConfigurationService.cs index c0129213..38f1cfa6 100644 --- a/src/JavaVersionSwitcher/Services/ConfigurationService.cs +++ b/src/JavaVersionSwitcher/Services/ConfigurationService.cs @@ -8,127 +8,126 @@ using System.Xml.Linq; using JavaVersionSwitcher.Adapters; -namespace JavaVersionSwitcher.Services +namespace JavaVersionSwitcher.Services; + +/// +public class ConfigurationService : IConfigurationService { - /// - public class ConfigurationService : IConfigurationService + private readonly IStorageAdapter _storageAdapter; + private readonly IReadOnlyCollection _providers; + private readonly XNamespace _ns = XNamespace.None; + + public ConfigurationService( + IEnumerable providers, + IStorageAdapter storageAdapter) + { + _storageAdapter = storageAdapter; + _providers = providers?.ToList(); + } + + /// + public async Task GetConfiguration(string providerName, string settingName) { - private readonly IStorageAdapter _storageAdapter; - private readonly IReadOnlyCollection _providers; - private readonly XNamespace _ns = XNamespace.None; + var provider = GetProvider(providerName); + EnsureSettingNameIsValid(provider, settingName); + + return await ReadSetting(provider.ProviderName, settingName); + } + + /// + public async Task SetConfiguration(string providerName, string settingName, string value) + { + var provider = GetProvider(providerName); + EnsureSettingNameIsValid(provider, settingName); + + await WriteSetting(provider.ProviderName, settingName, value); + } - public ConfigurationService( - IEnumerable providers, - IStorageAdapter storageAdapter) + private async Task WriteSetting(string providerName, string settingName, string value) + { + var doc = await GetXmlConfig(); + var root = doc.Root; + var providerElement = root!.Elements(_ns + providerName).FirstOrDefault(); + if (providerElement == null) { - _storageAdapter = storageAdapter; - _providers = providers?.ToList(); + providerElement = new XElement(_ns + providerName); + root.Add(providerElement); } - - /// - public async Task GetConfiguration(string providerName, string settingName) + + var settingElement = providerElement.Elements(_ns + settingName).FirstOrDefault(); + if (settingElement == null) { - var provider = GetProvider(providerName); - EnsureSettingNameIsValid(provider, settingName); - - return await ReadSetting(provider.ProviderName, settingName); + settingElement = new XElement(_ns + settingName); + providerElement.Add(settingElement); } - /// - public async Task SetConfiguration(string providerName, string settingName, string value) + if (string.IsNullOrEmpty(value)) { - var provider = GetProvider(providerName); - EnsureSettingNameIsValid(provider, settingName); - - await WriteSetting(provider.ProviderName, settingName, value); + settingElement.Remove(); } - - private async Task WriteSetting(string providerName, string settingName, string value) + else { - var doc = await GetXmlConfig(); - var root = doc.Root; - var providerElement = root!.Elements(_ns + providerName).FirstOrDefault(); - if (providerElement == null) - { - providerElement = new XElement(_ns + providerName); - root.Add(providerElement); - } - - var settingElement = providerElement.Elements(_ns + settingName).FirstOrDefault(); - if (settingElement == null) - { - settingElement = new XElement(_ns + settingName); - providerElement.Add(settingElement); - } - - if (string.IsNullOrEmpty(value)) - { - settingElement.Remove(); - } - else - { - settingElement.Value = value; - } - - if (!providerElement.Elements().Any()) - { - providerElement.Remove(); - } - - await SaveXmlConfig(doc); + settingElement.Value = value; } - private async Task SaveXmlConfig(XDocument doc) + if (!providerElement.Elements().Any()) { - var fileName = _storageAdapter.ConfigurationFilePath; - await using var stream = new StreamWriter(fileName, false, Encoding.UTF8); - await doc.SaveAsync(stream, SaveOptions.None, CancellationToken.None); + providerElement.Remove(); } + + await SaveXmlConfig(doc); + } + + private async Task SaveXmlConfig(XDocument doc) + { + var fileName = _storageAdapter.ConfigurationFilePath; + await using var stream = new StreamWriter(fileName, false, Encoding.UTF8); + await doc.SaveAsync(stream, SaveOptions.None, CancellationToken.None); + } - private async Task ReadSetting(string providerName, string settingName) + private async Task ReadSetting(string providerName, string settingName) + { + var doc = await GetXmlConfig(); + var providerElement = doc.Root!.Elements(_ns + providerName).FirstOrDefault(); + if (providerElement == null) { - var doc = await GetXmlConfig(); - var providerElement = doc.Root!.Elements(_ns + providerName).FirstOrDefault(); - if (providerElement == null) - { - return string.Empty; - } - - var settingElement = providerElement.Elements(_ns + settingName).FirstOrDefault(); - return settingElement?.Value ?? string.Empty; + return string.Empty; } + + var settingElement = providerElement.Elements(_ns + settingName).FirstOrDefault(); + return settingElement?.Value ?? string.Empty; + } - private async Task GetXmlConfig() + private async Task GetXmlConfig() + { + var fileName = _storageAdapter.ConfigurationFilePath; + var file = new FileInfo(fileName); + if (!file.Exists) { - var fileName = _storageAdapter.ConfigurationFilePath; - var file = new FileInfo(fileName); - if (!file.Exists) - { - var doc = new XDocument(); - doc.Add(new XElement(_ns + "JavaVersionSwitcher")); - return doc; - } - - await using var stream = file.OpenRead(); - var loaded = XDocument.Load(stream); - return loaded; + var doc = new XDocument(); + doc.Add(new XElement(_ns + "JavaVersionSwitcher")); + return doc; } - private void EnsureSettingNameIsValid(IConfigurationProvider provider, string name) + await using var stream = file.OpenRead(); + var loaded = XDocument.Load(stream); + return loaded; + } + + private void EnsureSettingNameIsValid(IConfigurationProvider provider, string name) + { + var exists = provider.Settings.Any(x => x.Equals(name, StringComparison.OrdinalIgnoreCase)); + if (!exists) { - var exists = provider.Settings.Any(x => x.Equals(name, StringComparison.OrdinalIgnoreCase)); - if (!exists) - { - throw new KeyNotFoundException( - $"No Configuration with the name of {name} exists in provider {provider.ProviderName}."); - } + throw new KeyNotFoundException( + $"No Configuration with the name of {name} exists in provider {provider.ProviderName}."); } + } - private IConfigurationProvider GetProvider(string name) - { - return _providers.FirstOrDefault(x => - x.ProviderName.Equals(name, StringComparison.OrdinalIgnoreCase)) ?? - throw new KeyNotFoundException($"No ConfigurationProvider with the name of {name} exists."); - } + private IConfigurationProvider GetProvider(string name) + { + return _providers.FirstOrDefault(x => + x.ProviderName.Equals(name, StringComparison.OrdinalIgnoreCase)) ?? + throw new KeyNotFoundException($"No ConfigurationProvider with the name of {name} exists."); } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Services/IConfigurationProvider.cs b/src/JavaVersionSwitcher/Services/IConfigurationProvider.cs index d312764b..db4af3a5 100644 --- a/src/JavaVersionSwitcher/Services/IConfigurationProvider.cs +++ b/src/JavaVersionSwitcher/Services/IConfigurationProvider.cs @@ -1,20 +1,19 @@ using System.Collections.Generic; -namespace JavaVersionSwitcher.Services +namespace JavaVersionSwitcher.Services; + +/// +/// Provides some configurations +/// +public interface IConfigurationProvider { /// - /// Provides some configurations + /// Gets the Name of this provider. /// - public interface IConfigurationProvider - { - /// - /// Gets the Name of this provider. - /// - string ProviderName { get; } + string ProviderName { get; } - /// - /// Gets all settings this provider provides. - /// - IEnumerable Settings { get; } - } + /// + /// Gets all settings this provider provides. + /// + IEnumerable Settings { get; } } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Services/IConfigurationService.cs b/src/JavaVersionSwitcher/Services/IConfigurationService.cs index 640e30d4..42bddedb 100644 --- a/src/JavaVersionSwitcher/Services/IConfigurationService.cs +++ b/src/JavaVersionSwitcher/Services/IConfigurationService.cs @@ -1,26 +1,25 @@ using System.Threading.Tasks; -namespace JavaVersionSwitcher.Services +namespace JavaVersionSwitcher.Services; + +/// +/// Access configuration settings. +/// +public interface IConfigurationService { /// - /// Access configuration settings. + /// Get a configuration setting. /// - public interface IConfigurationService - { - /// - /// Get a configuration setting. - /// - /// The name of the provider, see . - /// The name of the setting of that provider. See - /// The value. - public Task GetConfiguration(string provider, string settingName); + /// The name of the provider, see . + /// The name of the setting of that provider. See + /// The value. + public Task GetConfiguration(string provider, string settingName); - /// - /// Set a configuration setting. - /// - /// The name of the provider, see . - /// The name of the setting of that provider. See - /// The value to set. - public Task SetConfiguration(string provider, string settingName, string value); - } + /// + /// Set a configuration setting. + /// + /// The name of the provider, see . + /// The name of the setting of that provider. See + /// The value to set. + public Task SetConfiguration(string provider, string settingName, string value); } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/Services/JavaInstallationsAdapterConfigurationProvider.cs b/src/JavaVersionSwitcher/Services/JavaInstallationsAdapterConfigurationProvider.cs index efc7570c..f43fbda3 100644 --- a/src/JavaVersionSwitcher/Services/JavaInstallationsAdapterConfigurationProvider.cs +++ b/src/JavaVersionSwitcher/Services/JavaInstallationsAdapterConfigurationProvider.cs @@ -4,79 +4,78 @@ using System.Threading.Tasks; using JavaVersionSwitcher.Logging; -namespace JavaVersionSwitcher.Services +namespace JavaVersionSwitcher.Services; + +/// +public class JavaInstallationsAdapterConfigurationProvider : IConfigurationProvider { - /// - public class JavaInstallationsAdapterConfigurationProvider : IConfigurationProvider - { - private readonly ILogger _logger; - private const string Timeout = "timeout"; - private const string StartPaths = "startPaths"; + private readonly ILogger _logger; + private const string Timeout = "timeout"; + private const string StartPaths = "startPaths"; - public JavaInstallationsAdapterConfigurationProvider( - ILogger logger) - { - _logger = logger; - } + public JavaInstallationsAdapterConfigurationProvider( + ILogger logger) + { + _logger = logger; + } - /// - public string ProviderName => "scan"; + /// + public string ProviderName => "scan"; - /// - public IEnumerable Settings => new []{ StartPaths, Timeout }; + /// + public IEnumerable Settings => new []{ StartPaths, Timeout }; - public async Task GetCacheTimeout(IConfigurationService service) + public async Task GetCacheTimeout(IConfigurationService service) + { + const int @default = 7; + var providerName = ProviderName; + var displayName = $"{providerName}:{Timeout}"; + var config = await service.GetConfiguration( + providerName, + Timeout); + if (string.IsNullOrEmpty(config)) { - const int @default = 7; - var providerName = ProviderName; - var displayName = $"{providerName}:{Timeout}"; - var config = await service.GetConfiguration( - providerName, - Timeout); - if (string.IsNullOrEmpty(config)) - { - return @default; - } - - if (int.TryParse(config, out var parsed)) - { - _logger.LogVerbose($"Using configured value for {displayName} of {parsed} days."); - return parsed; - } - - _logger.LogWarning( - $"Configured value for {displayName} of {config} could not be parsed."); return @default; } + + if (int.TryParse(config, out var parsed)) + { + _logger.LogVerbose($"Using configured value for {displayName} of {parsed} days."); + return parsed; + } + + _logger.LogWarning( + $"Configured value for {displayName} of {config} could not be parsed."); + return @default; + } - public async Task> GetStartPaths(IConfigurationService service) + public async Task> GetStartPaths(IConfigurationService service) + { + var providerName = ProviderName; + var displayName = $"{providerName}:{StartPaths}"; + var @default = new[] { - var providerName = ProviderName; - var displayName = $"{providerName}:{StartPaths}"; - var @default = new[] - { - "%ProgramW6432%", - "%ProgramFiles(x86)%" - }; + "%ProgramW6432%", + "%ProgramFiles(x86)%" + }; - var config = await service.GetConfiguration(providerName, StartPaths); - if (string.IsNullOrEmpty(config)) - { - return @default; - } - - var parts = config.Split(";", StringSplitOptions.RemoveEmptyEntries); - if (parts.Length == 0) - { - _logger.LogWarning( - $"Configured value for {displayName} of '{config}' results in an empty list."); - return @default; - } + var config = await service.GetConfiguration(providerName, StartPaths); + if (string.IsNullOrEmpty(config)) + { + return @default; + } - _logger.LogVerbose($"Using configured values for {displayName} "); - parts.ToList().ForEach(x => _logger.LogVerbose($" - {x}")); - return parts; + var parts = config.Split(";", StringSplitOptions.RemoveEmptyEntries); + if (parts.Length == 0) + { + _logger.LogWarning( + $"Configured value for {displayName} of '{config}' results in an empty list."); + return @default; } + _logger.LogVerbose($"Using configured values for {displayName} "); + parts.ToList().ForEach(x => _logger.LogVerbose($" - {x}")); + return parts; } + } \ No newline at end of file diff --git a/src/JavaVersionSwitcher/SimpleInjectorRegistrar.cs b/src/JavaVersionSwitcher/SimpleInjectorRegistrar.cs deleted file mode 100644 index 3bfc369b..00000000 --- a/src/JavaVersionSwitcher/SimpleInjectorRegistrar.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Linq; -using SimpleInjector; -using Spectre.Console.Cli; - -namespace JavaVersionSwitcher -{ - /// - /// Shallow wrapper around SimpleInjector - /// - public class SimpleInjectorRegistrar : ITypeRegistrar - { - private readonly Container _container; - private readonly Type[] _knownMultiRegistrations; - - public SimpleInjectorRegistrar(Container container) - { - _container = container; - _knownMultiRegistrations = new[] - { - typeof(ICommand), - typeof(ICommand<>) - }; - } - - public void Register(Type service, Type implementation) - { - if (_knownMultiRegistrations.Contains(service)) - { - _container.Collection.Append(service, implementation, Lifestyle.Singleton); - return; - } - - _container.Register(service, implementation, Lifestyle.Singleton); - } - - public void RegisterInstance(Type service, object implementation) - { - _container.RegisterInstance(service, implementation); - } - - public void RegisterLazy(Type service, Func factory) - { - _container.Register(service, factory, Lifestyle.Singleton); - } - - public ITypeResolver Build() - { - _container.Verify(); - return new SimpleInjectorTypeResolver(_container); - } - - private class SimpleInjectorTypeResolver : ITypeResolver - { - private readonly Container _container; - - public SimpleInjectorTypeResolver(Container container) - { - _container = container; - } - - public object Resolve(Type type) - { - if (type == null) - { - throw new ArgumentNullException(nameof(type)); - } - - return _container.GetInstance(type); - } - } - } -} \ No newline at end of file