From d7eebe743792f7d251f85463bdd709f4f5a4fa49 Mon Sep 17 00:00:00 2001 From: Donkey Date: Sat, 14 Sep 2024 22:21:41 +0200 Subject: [PATCH] feat: error handling in Config.CreateFromSolution and AutomationInterfaceHeadless to deal with 'solution does not exist' --- TwinpackCore/Configuration/ConfigFactory.cs | 3 +++ .../Core/AutomationInterfaceHeadless.cs | 11 +++++++++++ TwinpackCore/Core/TwinpackService.cs | 3 +-- TwinpackTests/ConfigFactoryTest.cs | 19 +++++++++++++++++++ TwinpackTests/SystemTest.cs | 1 - TwinpackTests/TwinpackServiceTest.cs | 18 +++++++++++++----- 6 files changed, 47 insertions(+), 8 deletions(-) diff --git a/TwinpackCore/Configuration/ConfigFactory.cs b/TwinpackCore/Configuration/ConfigFactory.cs index aaa29f2..c0b68e0 100644 --- a/TwinpackCore/Configuration/ConfigFactory.cs +++ b/TwinpackCore/Configuration/ConfigFactory.cs @@ -185,6 +185,9 @@ public static async Task CreateFromSolutionFileAsync(string path=".", bo } } + if (solution?.Projects?.FirstOrDefault()?.Plcs?.FirstOrDefault() == null) + return null; + foreach (var project in solution.Projects) { var projectConfig = new ConfigProject(); diff --git a/TwinpackCore/Core/AutomationInterfaceHeadless.cs b/TwinpackCore/Core/AutomationInterfaceHeadless.cs index a596faf..b4f7680 100644 --- a/TwinpackCore/Core/AutomationInterfaceHeadless.cs +++ b/TwinpackCore/Core/AutomationInterfaceHeadless.cs @@ -93,6 +93,8 @@ static void AddOptions(XElement root, AddPlcLibraryOptions options) await RemovePackageAsync(package, forceRemoval: true); var plcConfig = _config.Projects.FirstOrDefault(x => x.Name == package.ProjectName).Plcs.FirstOrDefault(x => x.Name == package.PlcName); + if (plcConfig.FilePath == null || !File.Exists(plcConfig.FilePath)) + throw new FileNotFoundException($"Plc '{plcConfig.Name}' can not be found {(plcConfig.FilePath == null ? "" : "in " + plcConfig.FilePath)}"); var xdoc = XDocument.Load(plcConfig.FilePath); var project = xdoc.Elements(TcNs + "Project").FirstOrDefault(); @@ -163,6 +165,9 @@ public override async System.Threading.Tasks.Task RemovePackageAsync(PackageItem if (plcConfig == null) throw new InvalidOperationException($"Project '{package.ProjectName}' (Plc {package.PlcName}) is not configured in {_config.FilePath}"); + if (plcConfig.FilePath == null || !File.Exists(plcConfig.FilePath)) + throw new FileNotFoundException($"Plc '{plcConfig.Name}' can not be found {(plcConfig.FilePath == null ? "" : "in " + plcConfig.FilePath)}"); + var xdoc = XDocument.Load(plcConfig.FilePath); var project = xdoc.Elements(TcNs + "Project").FirstOrDefault(); if (project == null) @@ -214,6 +219,9 @@ public override async System.Threading.Tasks.Task RemoveAllPackagesAsync(string { var plcConfig = _config.Projects.FirstOrDefault(x => x.Name == projectName).Plcs.FirstOrDefault(x => x.Name == plcName); + if (plcConfig.FilePath == null || !File.Exists(plcConfig.FilePath)) + throw new FileNotFoundException($"Plc '{plcConfig.Name}' can not be found {(plcConfig.FilePath == null ? "" : "in " + plcConfig.FilePath)}"); + var xdoc = XDocument.Load(plcConfig.FilePath); var project = xdoc.Elements(TcNs + "Project").FirstOrDefault(); if (project == null) @@ -248,6 +256,9 @@ public override async Task UninstallPackageAsync(PackageItem package) public override async System.Threading.Tasks.Task SetPackageVersionAsync(ConfigPlcProject plc, CancellationToken cancellationToken = default) { + if (plc.FilePath == null || !File.Exists(plc.FilePath)) + throw new FileNotFoundException($"Plc '{plc.Name}' can not be found {(plc.FilePath == null ? "" : "in " + plc.FilePath)}"); + var xdoc = XDocument.Load(plc.FilePath); var project = xdoc.Elements(TcNs + "Project").FirstOrDefault(); if (project == null) diff --git a/TwinpackCore/Core/TwinpackService.cs b/TwinpackCore/Core/TwinpackService.cs index f811a97..23a3082 100644 --- a/TwinpackCore/Core/TwinpackService.cs +++ b/TwinpackCore/Core/TwinpackService.cs @@ -433,9 +433,8 @@ public async System.Threading.Tasks.Task> AddPackagesAsync(Lis cancellationToken.ThrowIfCancellationRequested(); } - // add affected packages as references - foreach (var package in options?.IncludeDependencies == true ? affectedPackages : packages) + foreach (var package in (options?.IncludeDependencies == true ? affectedPackages : packages).Where(x => x.PackageVersion?.Name != null)) { _logger.Info($"Adding {package.PackageVersion.Name} {package.PackageVersion.Version} (distributor: {package.PackageVersion.DistributorName})"); diff --git a/TwinpackTests/ConfigFactoryTest.cs b/TwinpackTests/ConfigFactoryTest.cs index ada10e4..a20922a 100644 --- a/TwinpackTests/ConfigFactoryTest.cs +++ b/TwinpackTests/ConfigFactoryTest.cs @@ -43,6 +43,25 @@ public async Task CreateFromSolutionFileWithoutFilterAsync() Assert.AreEqual(@"Tc3_Module=*", references[2]); } + [DataRow(true)] + [DataRow(false)] + [DataTestMethod] + public async Task CreateFromSolution_DirectoryNotFound_Async(bool continueWithoutSolution) + { + await Assert.ThrowsExceptionAsync(async () => await ConfigFactory.CreateFromSolutionFileAsync(@"assets\NoSuchDirectory", continueWithoutSolution)); + } + + [DataRow(true)] + [DataRow(false)] + [DataTestMethod] + public async Task CreateFromSolution_NoFiles_Async(bool continueWithoutSolution) + { + if (!Directory.Exists(@"assets\NoSolutionInside")) + Directory.CreateDirectory(@"assets\NoSolutionInside"); + + Assert.IsNull(await ConfigFactory.CreateFromSolutionFileAsync(@"assets\NoSolutionInside", continueWithoutSolution)); + } + [TestMethod] public async Task CreateFromSolutionFileWithFilterAsync() { diff --git a/TwinpackTests/SystemTest.cs b/TwinpackTests/SystemTest.cs index 195aff7..b647250 100644 --- a/TwinpackTests/SystemTest.cs +++ b/TwinpackTests/SystemTest.cs @@ -49,7 +49,6 @@ public static void SetUp(TestContext context) } } - public class SystemTest { protected static Config _config; diff --git a/TwinpackTests/TwinpackServiceTest.cs b/TwinpackTests/TwinpackServiceTest.cs index 9b750d8..7fe066d 100644 --- a/TwinpackTests/TwinpackServiceTest.cs +++ b/TwinpackTests/TwinpackServiceTest.cs @@ -878,7 +878,7 @@ public async Task DownloadPackageVersionAsync_DownloadProvidedPackages() Assert.IsTrue(downloadedPackageVersions.Any(x => x.PackageVersion.Name == "ExternalLib3")); } - private TwinpackService BuildMultiProjectConfig() + private TwinpackService BuildMultiProjectConfig(out Config config) { var packageServer = new PackageServerMock { @@ -935,6 +935,14 @@ private TwinpackService BuildMultiProjectConfig() } }, new PackageVersionGetResponse() + { + Name = "ZCore", Version = "1.5.0.3", Branch = "main", Configuration = "Release", Target = "TC3.1", + Dependencies = new List + { + new PackageVersionGetResponse() { Name = "ExternalLib1", Version = "2.2.3.4" }, + } + }, + new PackageVersionGetResponse() { Name = "ExternalLib1", Version = "1.2.3.4", Branch = "main", Configuration = "Release", Target = "TC3.1", }, @@ -946,7 +954,7 @@ private TwinpackService BuildMultiProjectConfig() Connected = true }; - var config = new Config + config = new Config { Projects = new List { @@ -994,7 +1002,7 @@ private TwinpackService BuildMultiProjectConfig() [TestMethod] public async Task RestoreAsync_NoIncludedProvidedPackages_NoIncludedDependencies() { - var twinpack = BuildMultiProjectConfig(); + var twinpack = BuildMultiProjectConfig(out _); var packages = await twinpack.RestorePackagesAsync( new TwinpackService.RestorePackageOptions @@ -1016,7 +1024,7 @@ public async Task RestoreAsync_NoIncludedProvidedPackages_NoIncludedDependencies [TestMethod] public async Task RestoreAsync_IncludedProvidedPackages_NoIncludedDependencies() { - var twinpack = BuildMultiProjectConfig(); + var twinpack = BuildMultiProjectConfig(out _); var packages = await twinpack.RestorePackagesAsync( new TwinpackService.RestorePackageOptions @@ -1052,7 +1060,7 @@ public async Task RestoreAsync_IncludedProvidedPackages_NoIncludedDependencies() [TestMethod] public async Task RestoreAsync_IncludedProvidedPackages_IncludedDependencies() { - var twinpack = BuildMultiProjectConfig(); + var twinpack = BuildMultiProjectConfig(out _); var packages = await twinpack.RestorePackagesAsync( new TwinpackService.RestorePackageOptions