Skip to content

Commit 201c7d8

Browse files
Improve bulk file performance and packaging (#11)
1. Generate NuGet package with symbols and move binaries to tasks folder instead of lib so we don't need excludeassets in the packagereference. 2. Improve performance when handling a lot of files and add a basic stress test 3. Fix an exception when merging config files with multiple lists
1 parent 0c828d4 commit 201c7d8

26 files changed

+423
-195
lines changed

.github/workflows/build.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,15 @@ jobs:
4949
run: dotnet build src/AggregateConfigBuildTask.sln --configuration Release -warnaserror -p:Version=${{ steps.get_version.outputs.VERSION }}
5050

5151
- name: Run tests for AggregateConfigBuildTask solution
52-
run: dotnet test src/AggregateConfigBuildTask.sln --configuration Release -warnaserror -p:Version=${{ steps.get_version.outputs.VERSION }}
52+
run: dotnet test src/AggregateConfigBuildTask.sln --configuration Release -warnaserror -p:Version=${{ steps.get_version.outputs.VERSION }} -p:CollectCoverage=true
5353

5454
- name: Upload NuGetPackage artifact
5555
uses: actions/upload-artifact@v4
5656
with:
5757
name: NuGetPackage
58-
path: src/Task/bin/Release/AggregateConfigBuildTask.${{ steps.get_version.outputs.VERSION }}.nupkg
58+
path: |
59+
src/Task/bin/Release/AggregateConfigBuildTask.${{ steps.get_version.outputs.VERSION }}.nupkg
60+
src/Task/bin/Release/AggregateConfigBuildTask.${{ steps.get_version.outputs.VERSION }}.snupkg
5961
6062
integration_tests:
6163
needs: build
@@ -89,7 +91,7 @@ jobs:
8991
run: dotnet build test/IntegrationTests.sln --configuration Release -warnaserror -p:Version=${{ needs.build.outputs.VERSION }}
9092

9193
- name: Run IntegrationTests
92-
run: dotnet test test/IntegrationTests.sln --configuration Release -warnaserror -p:Version=${{ needs.build.outputs.VERSION }}
94+
run: dotnet test test/IntegrationTests.sln --configuration Release -warnaserror -p:Version=${{ needs.build.outputs.VERSION }} -p:CollectCoverage=true
9395

9496
- name: Upload integration results artifact
9597
uses: actions/upload-artifact@v4

README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@ dotnet add package AggregateConfigBuildTask
2525
Alternatively, add the following line to your `.csproj` file:
2626

2727
```xml
28-
<PackageReference Include="AggregateConfigBuildTask" Version="{latest}">
29-
<PrivateAssets>all</PrivateAssets>
30-
<ExcludeAssets>native;contentFiles;analyzers;runtime</ExcludeAssets>
31-
</PackageReference>
28+
<PackageReference Include="AggregateConfigBuildTask" Version="{latest}" />
3229
```
3330

3431
`{latest}` can be found [here](https://www.nuget.org/packages/AggregateConfigBuildTask#versions-body-tab).

src/AggregateConfigBuildTask.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ EndProject
1212
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{29D0AE56-C184-4741-824F-521198552928}"
1313
ProjectSection(SolutionItems) = preProject
1414
.editorconfig = .editorconfig
15+
Directory.Packages.props = Directory.Packages.props
1516
EndProjectSection
1617
EndProject
1718
Global

src/Contracts/Contracts.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFramework>netstandard2.0</TargetFramework>
5+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
56
</PropertyGroup>
67

78
</Project>

src/Contracts/InputOutputEnums.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace AggregateConfig.Contracts
1+
namespace AggregateConfigBuildTask.Contracts
22
{
33
public enum OutputTypeEnum
44
{

src/Directory.Packages.props

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<Project>
2+
<PropertyGroup>
3+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4+
</PropertyGroup>
5+
<!-- Build packages-->
6+
<ItemGroup>
7+
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" PrivateAssets="all" />
8+
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.11.4" PrivateAssets="all" />
9+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="all" />
10+
</ItemGroup>
11+
<!-- Runtime packages -->
12+
<ItemGroup>
13+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" PrivateAssets="all" />
14+
<PackageVersion Include="System.Text.Json" Version="8.0.4" PrivateAssets="all" />
15+
<PackageVersion Include="YamlDotNet" Version="16.1.0" PrivateAssets="all" GeneratePathProperty="true" />
16+
<PackageVersion Include="YamlDotNet.System.Text.Json" Version="1.5.0" PrivateAssets="all" />
17+
</ItemGroup>
18+
<!-- Test packages -->
19+
<ItemGroup>
20+
<PackageVersion Include="coverlet.collector" Version="6.0.0" />
21+
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
22+
<PackageVersion Include="Moq" Version="4.20.72" />
23+
<PackageVersion Include="MSTest.TestAdapter" Version="3.1.1" />
24+
<PackageVersion Include="MSTest.TestFramework" Version="3.1.1" />
25+
</ItemGroup>
26+
<!-- Global packages -->
27+
<ItemGroup>
28+
<GlobalPackageReference Include="ReferenceTrimmer" Version="3.3.6" />
29+
</ItemGroup>
30+
</Project>

src/Task/AggregateConfig.cs

Lines changed: 18 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
using AggregateConfig.Contracts;
2-
using AggregateConfig.FileHandlers;
3-
using AggregateConfigBuildTask;
1+
using AggregateConfigBuildTask.Contracts;
2+
using AggregateConfigBuildTask.FileHandlers;
43
using Microsoft.Build.Framework;
54
using System;
65
using System.IO;
7-
using System.Linq;
6+
using System.Reflection;
87
using System.Runtime.CompilerServices;
9-
using System.Text.Json;
108
using Task = Microsoft.Build.Utilities.Task;
119

1210
[assembly: InternalsVisibleTo("AggregateConfig.Tests.UnitTests")]
1311

14-
namespace AggregateConfig
12+
namespace AggregateConfigBuildTask
1513
{
1614
public class AggregateConfig : Task
1715
{
@@ -46,8 +44,7 @@ public override bool Execute()
4644
{
4745
try
4846
{
49-
bool hasError = false;
50-
JsonElement? finalResult = null;
47+
EmitHeader();
5148

5249
OutputFile = Path.GetFullPath(OutputFile);
5350

@@ -74,48 +71,7 @@ public override bool Execute()
7471
fileSystem.CreateDirectory(directoryPath);
7572
}
7673

77-
var expectedExtensions = FileHandlerFactory.GetExpectedFileExtensions(inputType);
78-
var files = fileSystem.GetFiles(InputDirectory, "*.*")
79-
.Where(file => expectedExtensions.Contains(Path.GetExtension(file).ToLower()))
80-
.ToList();
81-
82-
foreach (var file in files)
83-
{
84-
Log.LogMessage(MessageImportance.High, "- Found file {0}", file);
85-
86-
IInputReader outputWriter;
87-
try
88-
{
89-
outputWriter = FileHandlerFactory.GetInputReader(fileSystem, inputType);
90-
}
91-
catch (ArgumentException ex)
92-
{
93-
hasError = true;
94-
Log.LogError("No reader found for file {0}: {1} Stacktrace: {2}", file, ex.Message, ex.StackTrace);
95-
continue;
96-
}
97-
98-
JsonElement fileData;
99-
try
100-
{
101-
fileData = outputWriter.ReadInput(file);
102-
}
103-
catch (Exception ex)
104-
{
105-
hasError = true;
106-
Log.LogError("Could not parse {0}: {1}", file, ex.Message);
107-
Log.LogErrorFromException(ex, true, true, file);
108-
continue;
109-
}
110-
111-
// Merge the deserialized object into the final result
112-
finalResult = ObjectManager.MergeObjects(finalResult, fileData, file, AddSourceProperty);
113-
}
114-
115-
if (hasError)
116-
{
117-
return false;
118-
}
74+
var finalResult = ObjectManager.MergeFileObjects(InputDirectory, inputType, AddSourceProperty, fileSystem, Log).GetAwaiter().GetResult();
11975

12076
if (finalResult == null)
12177
{
@@ -124,11 +80,7 @@ public override bool Execute()
12480
}
12581

12682
var additionalPropertiesDictionary = JsonHelper.ParseAdditionalProperties(AdditionalProperties);
127-
if (!ObjectManager.InjectAdditionalProperties(ref finalResult, additionalPropertiesDictionary))
128-
{
129-
Log.LogError("Additional properties could not be injected since the top-level is not a JSON object.");
130-
return false;
131-
}
83+
finalResult = ObjectManager.InjectAdditionalProperties(finalResult, additionalPropertiesDictionary, Log).GetAwaiter().GetResult();
13284

13385
var writer = FileHandlerFactory.GetOutputWriter(fileSystem, outputType);
13486
writer.WriteOutput(finalResult, OutputFile);
@@ -138,10 +90,20 @@ public override bool Execute()
13890
}
13991
catch (Exception ex)
14092
{
141-
Log.LogError("An unknown exception occured: {0}", ex.Message);
93+
Log.LogError("An unknown exception occurred: {0}", ex.Message);
14294
Log.LogErrorFromException(ex, true, true, null);
14395
return false;
14496
}
14597
}
98+
99+
private void EmitHeader()
100+
{
101+
var assembly = Assembly.GetExecutingAssembly();
102+
var informationalVersion = assembly
103+
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?
104+
.InformationalVersion;
105+
106+
Log.LogMessage($"AggregateConfig Version: {informationalVersion}");
107+
}
146108
}
147109
}

src/Task/AggregateConfigBuildTask.csproj

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
<TargetFramework>netstandard2.0</TargetFramework>
55
<GenerateDocumentationFile>true</GenerateDocumentationFile>
66
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
7+
<Deterministic>true</Deterministic>
8+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
9+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
10+
<SourceLinkCreate>true</SourceLinkCreate>
11+
<NoWarn>NU5100</NoWarn>
12+
</PropertyGroup>
13+
14+
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
15+
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
716
</PropertyGroup>
817

918
<PropertyGroup>
@@ -20,6 +29,10 @@
2029
<PackageReleaseNotes>https://github.com/richardsondev/AggregateConfigBuildTask/releases/tag/v$(Version)</PackageReleaseNotes>
2130
<PackageReadmeFile>docs/README.md</PackageReadmeFile>
2231
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
32+
<IncludeSymbols>true</IncludeSymbols>
33+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
34+
<NoPackageAnalysis>true</NoPackageAnalysis>
35+
<BuildOutputTargetFolder>tasks</BuildOutputTargetFolder>
2336
</PropertyGroup>
2437

2538
<ItemGroup>
@@ -28,28 +41,28 @@
2841

2942
<!-- Build time packages-->
3043
<ItemGroup>
31-
<PackageReference Include="Microsoft.Build.Framework" Version="17.11.4" PrivateAssets="all" />
32-
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.11.4" PrivateAssets="all" />
33-
<PackageReference Include="ReferenceTrimmer" Version="3.3.6" PrivateAssets="all" />
44+
<PackageReference Include="Microsoft.Build.Framework" PrivateAssets="all" />
45+
<PackageReference Include="Microsoft.Build.Utilities.Core" PrivateAssets="all" />
46+
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="all" />
3447
</ItemGroup>
3548

3649
<!-- Runtime packages -->
3750
<ItemGroup>
38-
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" PrivateAssets="all" />
39-
<PackageReference Include="System.Text.Json" Version="8.0.4" PrivateAssets="all" />
40-
<PackageReference Include="YamlDotNet" Version="16.1.0" PrivateAssets="all" GeneratePathProperty="true" />
41-
<PackageReference Include="YamlDotNet.System.Text.Json" Version="1.5.0" PrivateAssets="all" />
51+
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" PrivateAssets="all" />
52+
<PackageReference Include="System.Text.Json" PrivateAssets="all" />
53+
<PackageReference Include="YamlDotNet" PrivateAssets="all" GeneratePathProperty="true" />
54+
<PackageReference Include="YamlDotNet.System.Text.Json" PrivateAssets="all" />
4255
</ItemGroup>
4356

4457
<ItemGroup>
45-
<None Include="$(OutputPath)/Contracts.dll" Pack="true" PackagePath="/lib/netstandard2.0/" />
46-
<None Include="$(OutputPath)/Microsoft.Bcl.AsyncInterfaces.dll" Pack="true" PackagePath="/lib/netstandard2.0/" />
47-
<None Include="$(OutputPath)/System.Text.Json.dll" Pack="true" PackagePath="/lib/netstandard2.0/" />
48-
<None Include="$(OutputPath)/YamlDotNet.dll" Pack="true" PackagePath="/lib/netstandard2.0/" />
58+
<None Include="$(OutputPath)/Contracts.dll" Pack="true" PackagePath="/tasks/netstandard2.0/" />
59+
<None Include="$(OutputPath)/Microsoft.Bcl.AsyncInterfaces.dll" Pack="true" PackagePath="/tasks/netstandard2.0/" />
60+
<None Include="$(OutputPath)/System.Text.Json.dll" Pack="true" PackagePath="/tasks/netstandard2.0/" />
61+
<None Include="$(OutputPath)/YamlDotNet.dll" Pack="true" PackagePath="/tasks/netstandard2.0/" />
4962
<None Include="$(PkgYamlDotNet)/LICENSE.txt" Pack="true" PackagePath="/licenses/YamlDotNet">
5063
<Link>licenses/YamlDotNet/LICENSE.txt</Link>
5164
</None>
52-
<None Include="$(OutputPath)/YamlDotNet.System.Text.Json.dll" Pack="true" PackagePath="/lib/netstandard2.0/" />
65+
<None Include="$(OutputPath)/YamlDotNet.System.Text.Json.dll" Pack="true" PackagePath="/tasks/netstandard2.0/" />
5366
<None Include="build/AggregateConfigBuildTask.targets" Pack="true" PackagePath="/build/AggregateConfigBuildTask.targets" />
5467
<None Include="../../LICENSE" Pack="true" PackagePath="/licenses/">
5568
<Link>licenses/LICENSE</Link>

src/Task/FileHandlers/ArmParametersFileHandler.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22
using System.Collections.Generic;
33
using System.Text.Json;
44
using System.Text.Json.Nodes;
5+
using System.Threading.Tasks;
56

6-
namespace AggregateConfig.FileHandlers
7+
namespace AggregateConfigBuildTask.FileHandlers
78
{
89
public class ArmParametersFileHandler : IOutputWriter, IInputReader
910
{
10-
IFileSystem fileSystem;
11+
readonly IFileSystem fileSystem;
1112

1213
internal ArmParametersFileHandler(IFileSystem fileSystem)
1314
{
1415
this.fileSystem = fileSystem;
1516
}
1617

1718
/// <inheritdoc/>
18-
public JsonElement ReadInput(string inputPath)
19+
public ValueTask<JsonElement> ReadInput(string inputPath)
1920
{
2021
using (var stream = fileSystem.OpenRead(inputPath))
2122
{
@@ -40,10 +41,10 @@ public JsonElement ReadInput(string inputPath)
4041
}
4142

4243
var modifiedJson = modifiedParameters.ToJsonString();
43-
return JsonSerializer.Deserialize<JsonElement>(modifiedJson);
44+
return new ValueTask<JsonElement>(Task.FromResult(JsonSerializer.Deserialize<JsonElement>(modifiedJson)));
4445
}
4546

46-
return jsonDoc.RootElement.Clone();
47+
return new ValueTask<JsonElement>(Task.FromResult(jsonDoc.RootElement.Clone()));
4748
}
4849
}
4950
}

src/Task/FileHandlers/FileHandlerFactory.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
using AggregateConfig.Contracts;
1+
using AggregateConfigBuildTask.Contracts;
22
using System;
33
using System.Collections.Generic;
44

5-
namespace AggregateConfig.FileHandlers
5+
namespace AggregateConfigBuildTask.FileHandlers
66
{
77
public static class FileHandlerFactory
88
{

0 commit comments

Comments
 (0)