Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -360,4 +360,6 @@ MigrationBackup/
.ionide/

# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd

!DMApp.AutomationTests/TestFiles/Solutions/HugeSolution/Debug_2/Debug
38 changes: 38 additions & 0 deletions Assemblers.Automation/Assemblers.Automation.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Skyline.DataMiner.CICD.Assemblers.Automation</AssemblyName>
<RootNamespace>Skyline.DataMiner.CICD.Assemblers.Automation</RootNamespace>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>SkylineCommunications</Authors>
<Company>Skyline Communications</Company>
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<PackageIcon>icon.png</PackageIcon>
<PackageProjectUrl>https://skyline.be/</PackageProjectUrl>
<PackageTags>Skyline;DataMiner;CICD</PackageTags>
<Description>Library providing methods for converting Visual Studio DIS Automation Solutions to individual DataMiner AutomationScript artifacts (e.g. XML, DLLs,...).</Description>
<PackageReadmeFile>README.md</PackageReadmeFile>
<RepositoryUrl>https://github.com/SkylineCommunications/Skyline.DataMiner.CICD.Packages</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<Version>0.0.2-local</Version>
</PropertyGroup>

<ItemGroup>
<None Include="..\README.md" Pack="true" PackagePath="" />
<None Include="..\_NuGetItems\icon.png" Pack="true" PackagePath="" />
<None Include="..\_NuGetItems\LICENSE.txt" Pack="true" PackagePath="" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Assemblers.Common\Assemblers.Common.csproj" />
<ProjectReference Include="..\Parsers.Automation\Parsers.Automation.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="$(MSBuildProjectName)Tests" />
</ItemGroup>

</Project>
725 changes: 725 additions & 0 deletions Assemblers.Automation/AutomationScriptBuilder.cs

Large diffs are not rendered by default.

90 changes: 90 additions & 0 deletions Assemblers.Automation/AutomationScriptSolutionBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
namespace Skyline.DataMiner.CICD.Assemblers.Automation
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using Skyline.DataMiner.CICD.Assemblers.Common;
using Skyline.DataMiner.CICD.Loggers;
using Skyline.DataMiner.CICD.Parsers.Automation.VisualStudio;
using Skyline.DataMiner.CICD.Parsers.Automation.Xml;
using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio;
using Skyline.DataMiner.CICD.Parsers.Common.VisualStudio.Projects;

/// <summary>
/// Builds the scripts of an Automation script solution.
/// </summary>
public class AutomationScriptSolutionBuilder
{
private readonly AutomationScriptSolution _automationScriptSolution;
private readonly ILogCollector logCollector;

/// <summary>
/// Initializes a new instance of the <see cref="AutomationScriptSolutionBuilder"/> class.
/// </summary>
/// <param name="automationScriptSolution">The Automation script solution.</param>
/// <exception cref="ArgumentNullException"><paramref name="automationScriptSolution"/> is <see langword="null"/>.</exception>
public AutomationScriptSolutionBuilder(AutomationScriptSolution automationScriptSolution)
{
_automationScriptSolution = automationScriptSolution ?? throw new ArgumentNullException(nameof(automationScriptSolution));
}

/// <summary>
/// Initializes a new instance of the <see cref="AutomationScriptSolutionBuilder"/> class.
/// </summary>
/// <param name="automationScriptSolution">The Automation script solution.</param>
/// <param name="logCollector">The log collector.</param>
/// <exception cref="ArgumentNullException"><paramref name="automationScriptSolution"/> is <see langword="null"/>.</exception>
/// <exception cref="ArgumentNullException"><paramref name="logCollector"/> is <see langword="null"/>.</exception>
public AutomationScriptSolutionBuilder(AutomationScriptSolution automationScriptSolution, ILogCollector logCollector)
: this(automationScriptSolution)
{
this.logCollector = logCollector ?? throw new ArgumentNullException(nameof(logCollector));
}

/// <summary>
/// Builds the scripts of an Automation script solution.
/// </summary>
/// <returns>A list of the scripts with its build results.</returns>
public async Task<List<KeyValuePair<Script, BuildResultItems>>> BuildAsync()
{
var allScripts = new ConcurrentBag<Script>(_automationScriptSolution.Scripts.Select(s => s.Script));

ConcurrentBag<KeyValuePair<Script, BuildResultItems>> results = new ConcurrentBag<KeyValuePair<Script, BuildResultItems>>();
var tasks = _automationScriptSolution.Scripts.Select(async item =>
{
(Script script, SolutionFolder folder) = item;

var projects = new Dictionary<string, Project>();

var actionsFolder = folder.GetSubFolder("Actions");
if (actionsFolder != null)
{
foreach (var p in actionsFolder.GetDescendantProjects())
{
projects[p.Name] = _automationScriptSolution.LoadProject(p);
}
}

AutomationScriptBuilder builder;
if (logCollector == null)
{
builder = new AutomationScriptBuilder(script, projects, allScripts, _automationScriptSolution.SolutionDirectory);
}
else
{
builder = new AutomationScriptBuilder(script, projects, allScripts, logCollector, _automationScriptSolution.SolutionDirectory);
}

var buildResult = await builder.BuildAsync().ConfigureAwait(false);
results.Add(new KeyValuePair<Script, BuildResultItems>(script, buildResult));
});

await Task.WhenAll(tasks);

return results.ToList();
}
}
}
74 changes: 74 additions & 0 deletions Assemblers.Automation/ScriptHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
namespace Skyline.DataMiner.CICD.Assemblers.Automation
{
using System;
using System.Linq;

/// <summary>
/// Helper class for use with assembling a Visual Studio solution into a DataMiner file (e.g. protocol XML file or Automation script).
/// </summary>
public static class ScriptHelper
{
/// <summary>
/// The DLLs that are referenced by default by DataMiner.
/// </summary>
public static readonly string[] ScriptDefaultImportDLLs =
{
"mscorlib.dll",
"Skyline.DataMiner.Storage.Types.dll",
"SLAnalyticsTypes.dll",
"SLLoggerUtil.dll",
"SLManagedAutomation.dll",
"SLNetTypes.dll",
"System.dll",
"System.Core.dll",
"System.Xml.dll",
};

/// <summary>
/// The DLLs that need to be referenced with the Files path.
/// </summary>
public static readonly string[] DllsWithFilesPath =
{
"SLSRMLibrary.dll",
};

/// <summary>
/// The DLLs that need to be referenced with the ProtocolScripts path.
/// </summary>
public static readonly string[] DllsWithProtocolScriptsPath =
{
"DataMinerSolutions.dll",
"ProcessAutomation.dll"
};

/// <summary>
/// Gets a value indicating whether the specified DLL is by default referenced by DataMiner.
/// </summary>
/// <param name="dll">The DLL.</param>
/// <returns><c>true</c> if the DLL is by default referenced by DataMiner; otherwise, <c>false</c>.</returns>
public static bool IsDefaultImportDll(string dll)
{
return ScriptDefaultImportDLLs.Contains(dll, StringComparer.OrdinalIgnoreCase);
}

/// <summary>
/// Gets a value indicating whether the specified DLL needs to be referenced via the Files folder instead of the default ProtocolScripts.
/// </summary>
/// <param name="dll">Name of the DLL.</param>
/// <returns><c>true</c> if the DLL needs to be referenced via the Files folder; otherwise <c>false</c>.</returns>
public static bool NeedsFilesPath(string dll)
{
return DllsWithFilesPath.Contains(dll, StringComparer.OrdinalIgnoreCase);
}

/// <summary>
/// Gets a value indicating whether the specified DLL needs to be referenced via the ProtocolScripts folder instead of the default ProtocolScripts\DllImport.
/// </summary>
/// <param name="dll">Name of the DLL.</param>
/// <returns><c>true</c> if the DLL needs to be referenced via the ProtocolScripts folder; otherwise <c>false</c>.</returns>
public static bool NeedsProtocolScriptsPath(string dll)
{
return DllsWithProtocolScriptsPath.Contains(dll, StringComparer.OrdinalIgnoreCase);
}
}
}
34 changes: 34 additions & 0 deletions Assemblers.AutomationTests/Assemblers.AutomationTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net48;net8.0</TargetFrameworks>
<IsPackable>false</IsPackable>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="7.2.0" />
<PackageReference Include="MSTest" Version="4.0.2" />
<PackageReference Include="coverlet.collector" Version="6.0.4">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
<PackageReference Include="XMLUnit.Core" Version="2.11.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Assemblers.Automation\Assemblers.Automation.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Remove="TestFiles\**" />
</ItemGroup>

<ItemGroup>
<Content Include="TestFiles\**">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

</Project>
Loading