Skip to content

Commit

Permalink
refactor; moved purge logic from restore to set version
Browse files Browse the repository at this point in the history
  • Loading branch information
iadonkey committed Aug 19, 2024
1 parent 8374bfc commit fb90165
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 31 deletions.
3 changes: 0 additions & 3 deletions TwinpackCli/Commands/RestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ public class RestoreCommand : Command
public bool SkipDownload { get; set; }
[Option("force-download", Required = false, Default = null, HelpText = "Forces the download of package(s) even if they are already available on the system.")]
public bool ForceDownload { get; set; }
[Option("purge-packages", Required = false, Default = null, HelpText = "Removes all references that are not configured packages.")]
public bool PurgePackages { get; set; }
[Option("headed", Required = false, Default = false, HelpText = "Enables the use of the Beckhoff Automation Interface, which is required for installing and/or uninstalling packages on the target. In 'headless' mode, install operations have to be performed by Beckhoff's 'RepTool.exe'. Defaults to false")]
public bool Headed { get; set; }
public override int Execute()
Expand All @@ -38,7 +36,6 @@ public override int Execute()
_twinpack.RestorePackagesAsync(
new TwinpackService.RestorePackageOptions
{
PurgePackages = PurgePackages,
SkipDownload = SkipDownload,
IncludeProvidedPackages = IncludeProvidedPackages,
ForceDownload = ForceDownload,
Expand Down
3 changes: 3 additions & 0 deletions TwinpackCli/Commands/SetVersionCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,16 @@ public class SetVersionCommand : Command

[Option("headed", Required = false, Default = false, HelpText = "Enables the use of the Beckhoff Automation Interface, which is required for installing and/or uninstalling packages on the target. In 'headless' mode, install operations have to be performed by Beckhoff's 'RepTool.exe'. Defaults to false")]
public bool Headed { get; set; }
[Option("purge-packages", Required = false, Default = null, HelpText = "Removes all references that are not configured packages.")]
public bool PurgePackages { get; set; }
public override int Execute()
{
Initialize(Headed);

_twinpack.SetPackageVersionAsync(Version,
new SetPackageVersionOptions
{
PurgePackages = PurgePackages,
ProjectName = ProjectName,
PlcName = PlcName,
SyncFrameworkPackages = SyncFrameworkPackages,
Expand Down
72 changes: 49 additions & 23 deletions TwinpackCore/Core/TwinpackService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ public AddPackageOptions(AddPackageOptions rhs)
}
public class RestorePackageOptions : AddPackageOptions
{
public bool PurgePackages = false;
public bool IncludeProvidedPackages = false;
public List<string> ExcludedPackages;
}
Expand All @@ -67,6 +66,7 @@ public class UpdatePackageOptions : AddPackageOptions

public class SetPackageVersionOptions
{
public bool PurgePackages = false;
public string? ProjectName;
public string? PlcName;
public bool SyncFrameworkPackages;
Expand Down Expand Up @@ -337,17 +337,6 @@ public async System.Threading.Tasks.Task RemovePackagesAsync(List<PackageItem> p

public async System.Threading.Tasks.Task<List<PackageItem>> RestorePackagesAsync(RestorePackageOptions options = default, CancellationToken cancellationToken = default)
{
if (options?.PurgePackages == true && _automationInterface != null)
{
foreach(var project in _config.Projects)
{
foreach (var plc in project.Plcs)
{
await _automationInterface.RemoveAllPackagesAsync(project.Name, plc.Name);
}
}
}

var usedPackages = await RetrieveUsedPackagesAsync(token: cancellationToken);
var packages = usedPackages.Select(x => new PackageItem(x) { Package = x.Used, PackageVersion = x.Used }).ToList();

Expand Down Expand Up @@ -577,7 +566,7 @@ public async Task<List<PackageItem>> DownloadPackagesAsync(List<PackageItem> pac
foreach(var affectedPackage in affectedPackages)
{
// check if we find the package on the system
bool referenceFound = (_automationInterface is AutomationInterfaceHeadless) || (!options.ForceDownload && _automationInterface != null && await _automationInterface.IsPackageInstalledAsync(affectedPackage));
bool referenceFound = !options.ForceDownload && _automationInterface != null && await _automationInterface.IsPackageInstalledAsync(affectedPackage);

if (!referenceFound || options.ForceDownload)
{
Expand All @@ -596,6 +585,18 @@ public bool IsPackageInstalled(PackageItem package)

public async System.Threading.Tasks.Task SetPackageVersionAsync(string version, SetPackageVersionOptions options = default, CancellationToken cancellationToken = default)
{
if (options?.PurgePackages == true && _automationInterface != null)
{
_logger.Info("Purging packages");
foreach (var project in _config.Projects)
{
foreach (var plc in project.Plcs)
{
await _automationInterface.RemoveAllPackagesAsync(project.Name, plc.Name);
}
}
}

// set the version of all plcs in the project(s)
var plcs = _config.Projects
.Where(x => options.ProjectName == null || x.Name == options.ProjectName)
Expand Down Expand Up @@ -624,6 +625,8 @@ public async System.Threading.Tasks.Task SetPackageVersionAsync(string version,
affectedPackages = affectedPackages.Concat(plcs.SelectMany(
x => x.Packages.Select(y => new PackageItem
{
ProjectName = x.ProjectName,
PlcName = x.Name,
Config = new ConfigPlcPackage { Name = y.Name }
})))
.GroupBy(x => x.Config.Name)
Expand All @@ -637,17 +640,22 @@ public async System.Threading.Tasks.Task SetPackageVersionAsync(string version,
.Where(x => x.PackageVersion.Framework != null && plcs.Any(y => y.Name == x.PackageVersion.Name))
.Select(x => x.PackageVersion.Framework).Distinct().ToList();

affectedPackages = affectedPackages.Where(x => frameworks.Contains(x.PackageVersion.Framework)).ToList();
var frameworkPackages = affectedPackages.Where(x => frameworks.Contains(x.PackageVersion.Framework)).ToList();

if (frameworkPackages.Any())
_logger.Info("Synchronizing framework packages");

foreach(var project in _config.Projects)
var existingPackages = affectedPackages.Where(x => !frameworks.Contains(x.PackageVersion.Framework)).ToList();
var notExistingPackages = new List<PackageItem>();
foreach (var project in _config.Projects)
{
foreach(var plc in project.Plcs)
{
var plcPackages = plc.Packages.Where(x => affectedPackages.Any(y => y.PackageVersion.Name == x.Name)).ToList();
var packageToOverwrite = new List<PackageItem>();
var plcPackages = plc.Packages.Where(x => frameworkPackages.Any(y => y.PackageVersion.Name == x.Name)).ToList();

foreach (var plcPackage in plcPackages)
{
var affectedPackage = affectedPackages.First(y => y.PackageVersion.Name == plcPackage.Name);
var affectedPackage = frameworkPackages.First(y => y.PackageVersion.Name == plcPackage.Name);

// check if the requested version is actually on a package server already
var requestedPackage = await _packageServers.ResolvePackageAsync(plcPackage.Name,
Expand All @@ -661,27 +669,45 @@ public async System.Threading.Tasks.Task SetPackageVersionAsync(string version,

if (requestedPackage?.Version == version)
{
// since the package actually exists, we can add it to the plcproj file
plcPackage.Version = version;
plcPackage.Branch = requestedPackage?.Branch;
plcPackage.Target = requestedPackage?.Target;
plcPackage.Configuration = requestedPackage?.Configuration;

packageToOverwrite.Add(new PackageItem(affectedPackage) { ProjectName = project.Name, PlcName = plc.Name, Package = null, PackageVersion = null, Config = plcPackage });
// since the package actually exists, we can add it to the plcproj file
existingPackages.Add(new PackageItem(affectedPackage) { ProjectName = project.Name, PlcName = plc.Name, Package = null, PackageVersion = null, Config = plcPackage });
}
else
{
plcPackage.Version = version;
plcPackage.Branch = options?.PreferredFrameworkBranch;
plcPackage.Target = options?.PreferredFrameworkTarget;
plcPackage.Configuration = options?.PreferredFrameworkConfiguration;

// only a headless interface allows to add not existing packages
if (_automationInterface is AutomationInterfaceHeadless)
{
notExistingPackages.Add(new PackageItem(affectedPackage)
{
ProjectName = project.Name,
PlcName = plc.Name,
PackageVersion = new PackageVersionGetResponse(affectedPackage.PackageVersion)
{
Version = version,
Branch = plcPackage.Branch,
Configuration = plcPackage.Configuration,
Target = plcPackage.Target
},
Config = plcPackage
});
}
}
}

foreach (var package in packageToOverwrite)
await AddPackageAsync(package);
}
}

await AddPackagesAsync(existingPackages);
await AddPackagesAsync(notExistingPackages, new AddPackageOptions { SkipDownload = true, IncludeDependencies = false });
}

_automationInterface?.SaveAll();
Expand Down
6 changes: 3 additions & 3 deletions TwinpackCore/Protocol/Api.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ public PackageGetResponse(PackageGetResponse package)
License = package.License;
LicenseTmcBinary = package.LicenseTmcBinary;
LicenseBinary = package.LicenseBinary;
Branches = new List<string>(package.Branches);
Targets = new List<string>(package.Targets);
Configurations = new List<string>(package.Configurations);
Branches = package.Branches?.Any() == true ? new List<string>(package.Branches) : new List<string>();
Targets = package.Branches?.Any() == true ? new List<string>(package.Targets) : new List<string>();
Configurations = package.Branches?.Any() == true ? new List<string>(package.Configurations) : new List<string>();
}

[JsonPropertyName("package-id")]
Expand Down
15 changes: 13 additions & 2 deletions TwinpackTests/SystemTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace TwinpackTests
{
using Microsoft.VisualStudio.PlatformUI;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -343,8 +344,18 @@ public async Task SetPackageVersion_VersionNotExistingOnPackageServers_Async(str
var plcprojPackages = plcprojPlc.Packages;
var plcprojPackage = plcprojPackages.FirstOrDefault(x => x.Name == "PlcLibrary1");
Assert.AreEqual(newVersion1, plcprojPlc?.Version);
Assert.AreEqual("1.2.3.4", plcprojPackages.FirstOrDefault(x => x.Name == "PlcLibrary1")?.Version);
Assert.AreEqual(null, plcprojPackages.FirstOrDefault(x => x.Name == "Tc3_Module")?.Version);

if (_automationInterface is AutomationInterfaceHeadless)
{
Assert.AreEqual(newVersion1, plcprojPackages.FirstOrDefault(x => x.Name == "PlcLibrary1")?.Version);
Assert.AreEqual(null, plcprojPackages.FirstOrDefault(x => x.Name == "Tc3_Module")?.Version);
}
else
{
Assert.AreEqual("1.2.3.4", plcprojPackages.FirstOrDefault(x => x.Name == "PlcLibrary1")?.Version);
Assert.AreEqual(null, plcprojPackages.FirstOrDefault(x => x.Name == "Tc3_Module")?.Version);
}


// act - add package, including dependencies
await twinpack.SetPackageVersionAsync(newVersion2, new TwinpackService.SetPackageVersionOptions { SyncFrameworkPackages = true,
Expand Down

0 comments on commit fb90165

Please sign in to comment.