Skip to content

Commit ea3fd1f

Browse files
committed
Limits process-manifests for a directory
* Also moves the generated bom to a cache location so that it can be accessed by future activities without any worries * Also discovered that `DateTime` was being used instead of `DateTimeOffset` when triggering the `process-manifest` command * Also discovered that `DateTime.Now` was being used instead of the "as of" time from the cached history point
1 parent 62369e3 commit ea3fd1f

File tree

6 files changed

+60
-12
lines changed

6 files changed

+60
-12
lines changed

Corgibytes.Freshli.Cli.Test/Functionality/BillOfMaterials/GenerateBillOfMaterialsActivityTest.cs

+14-3
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ public class GenerateBillOfMaterialsActivityTest
1515
public void Handle()
1616
{
1717
// Arrange
18+
var asOfDateTime = DateTimeOffset.Now;
1819
var javaAgentReader = new Mock<IAgentReader>();
19-
javaAgentReader.Setup(mock => mock.ProcessManifest("/path/to/manifest", It.IsAny<DateTime>()))
20+
javaAgentReader.Setup(mock => mock.ProcessManifest("/path/to/manifest", asOfDateTime))
2021
.Returns("/path/to/bill-of-materials");
2122

2223
const string agentExecutablePath = "/path/to/agent";
@@ -25,10 +26,16 @@ public void Handle()
2526

2627
var cacheManager = new Mock<ICacheManager>();
2728
var cacheDb = new Mock<ICacheDb>();
28-
var historyStopPoint = new CachedHistoryStopPoint { LocalPath = "/path/to/repository" };
29+
var historyStopPoint = new CachedHistoryStopPoint
30+
{
31+
LocalPath = "/path/to/repository",
32+
AsOfDateTime = asOfDateTime
33+
};
2934

3035
var historyStopPointId = 29;
36+
3137
cacheManager.Setup(mock => mock.GetCacheDb()).Returns(cacheDb.Object);
38+
3239
cacheDb.Setup(mock => mock.RetrieveHistoryStopPoint(historyStopPointId)).Returns(historyStopPoint);
3340

3441
var serviceProvider = new Mock<IServiceProvider>();
@@ -40,6 +47,10 @@ public void Handle()
4047

4148
// Act
4249
var analysisId = Guid.NewGuid();
50+
51+
cacheManager.Setup(mock => mock.StoreBomInCache("/path/to/bill-of-materials", analysisId, asOfDateTime))
52+
.Returns("/path/to/bom/in/cache");
53+
4354
var activity =
4455
new GenerateBillOfMaterialsActivity(analysisId, agentExecutablePath, historyStopPointId,
4556
"/path/to/manifest");
@@ -51,6 +62,6 @@ public void Handle()
5162
appEvent.AgentExecutablePath == agentExecutablePath &&
5263
appEvent.AnalysisId == analysisId &&
5364
appEvent.HistoryStopPointId == historyStopPointId &&
54-
appEvent.PathToBillOfMaterials == "/path/to/bill-of-materials")));
65+
appEvent.PathToBillOfMaterials == "/path/to/bom/in/cache")));
5566
}
5667
}

Corgibytes.Freshli.Cli/Functionality/BillOfMaterials/GenerateBillOfMaterialsActivity.cs

+26-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.Collections.Concurrent;
23
using System.IO;
4+
using Corgibytes.Freshli.Cli.DataModel;
35
using Corgibytes.Freshli.Cli.Functionality.Engine;
46
using Corgibytes.Freshli.Cli.Services;
57
using Microsoft.Extensions.DependencyInjection;
@@ -13,6 +15,8 @@ public class GenerateBillOfMaterialsActivity : IApplicationActivity
1315
public readonly int HistoryStopPointId;
1416
public readonly string ManifestPath;
1517

18+
private static readonly ConcurrentDictionary<string, object> s_lockPoints = new();
19+
1620
public GenerateBillOfMaterialsActivity(Guid analysisId, string agentExecutablePath,
1721
int historyStopPointId, string manifestPath)
1822
{
@@ -29,13 +33,30 @@ public void Handle(IApplicationEventEngine eventClient)
2933

3034
var cacheManager = eventClient.ServiceProvider.GetRequiredService<ICacheManager>();
3135
var cacheDb = cacheManager.GetCacheDb();
36+
3237
var historyStopPoint = cacheDb.RetrieveHistoryStopPoint(HistoryStopPointId);
38+
_ = historyStopPoint ?? throw new Exception($"Failed to retrieve history stop point {HistoryStopPointId}");
39+
40+
var historyPointPath = historyStopPoint.LocalPath;
41+
var asOfDateTime = historyStopPoint.AsOfDateTime;
3342

34-
var asOfDateTime = DateTime.Now;
35-
var pathToBillOfMaterials =
36-
agentReader.ProcessManifest(Path.Combine(historyStopPoint?.LocalPath!, ManifestPath), asOfDateTime);
43+
EnsureLockPointExists(historyPointPath);
44+
lock (s_lockPoints[historyPointPath])
45+
{
46+
var fullManifestPath = Path.Combine(historyPointPath, ManifestPath);
47+
var bomFilePath = agentReader.ProcessManifest(fullManifestPath, asOfDateTime);
48+
var cachedBomFilePath = cacheManager.StoreBomInCache(bomFilePath, AnalysisId, asOfDateTime);
3749

38-
eventClient.Fire(new BillOfMaterialsGeneratedEvent(AnalysisId, HistoryStopPointId, pathToBillOfMaterials,
39-
AgentExecutablePath));
50+
eventClient.Fire(new BillOfMaterialsGeneratedEvent(
51+
AnalysisId, HistoryStopPointId, cachedBomFilePath, AgentExecutablePath));
52+
}
53+
}
54+
55+
private void EnsureLockPointExists(string path)
56+
{
57+
if (!s_lockPoints.ContainsKey(path))
58+
{
59+
s_lockPoints[path] = new object();
60+
}
4061
}
4162
}

Corgibytes.Freshli.Cli/Functionality/CacheManager.cs

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.IO;
23
using System.Linq;
34
using Corgibytes.Freshli.Cli.DataModel;
@@ -54,7 +55,7 @@ public bool Prepare()
5455
return true;
5556
}
5657

57-
public DirectoryInfo GetDirectoryInCache(string[] directoryStructure)
58+
public DirectoryInfo GetDirectoryInCache(params string[] directoryStructure)
5859
{
5960
var cacheDir = new DirectoryInfo(_configuration.CacheDir);
6061
Prepare();
@@ -82,6 +83,18 @@ public DirectoryInfo GetDirectoryInCache(string[] directoryStructure)
8283
return focus;
8384
}
8485

86+
public string StoreBomInCache(string bomFilePath, Guid analysisId, DateTimeOffset asOfDateTime)
87+
{
88+
var bomFileInfo = new FileInfo(bomFilePath);
89+
90+
var bomCacheDirInfo = GetDirectoryInCache("boms", analysisId.ToString(), asOfDateTime.ToString("u"));
91+
var cachedBomFilePath = Path.Combine(bomCacheDirInfo.FullName, bomFileInfo.Name);
92+
93+
File.Copy(bomFilePath, cachedBomFilePath);
94+
95+
return cachedBomFilePath;
96+
}
97+
8598
public bool Destroy()
8699
{
87100
var cacheDir = new DirectoryInfo(_configuration.CacheDir);

Corgibytes.Freshli.Cli/Functionality/ICacheManager.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.IO;
23

34
namespace Corgibytes.Freshli.Cli.Functionality;
@@ -7,7 +8,9 @@ public interface ICacheManager
78
public bool ValidateCacheDirectory();
89
public bool Prepare();
910
public bool Destroy();
10-
public DirectoryInfo GetDirectoryInCache(string[] directoryStructure);
11+
public DirectoryInfo GetDirectoryInCache(params string[] directoryStructure);
12+
13+
public string StoreBomInCache(string pathToBom, Guid analysisId, DateTimeOffset asOfDateTime);
1114

1215
public ICacheDb GetCacheDb();
1316
}

Corgibytes.Freshli.Cli/Services/AgentReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public List<string> DetectManifests(string projectPath)
5757
return manifests.IsEmpty() ? new List<string>() : manifests.TrimEnd('\n', '\r').Split("\n").ToList();
5858
}
5959

60-
public string ProcessManifest(string manifestPath, DateTime asOfDateTime)
60+
public string ProcessManifest(string manifestPath, DateTimeOffset asOfDateTime)
6161
{
6262
var billOfMaterialsPath =
6363
_invoke.Command(AgentExecutablePath, $"process-manifest {manifestPath} {asOfDateTime:o}", ".");

Corgibytes.Freshli.Cli/Services/IAgentReader.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ public interface IAgentReader
1010
public string AgentExecutablePath { get; }
1111
public List<Package> RetrieveReleaseHistory(PackageURL packageUrl);
1212
public List<string> DetectManifests(string projectPath);
13-
public string ProcessManifest(string manifestPath, DateTime asOfDateTime);
13+
public string ProcessManifest(string manifestPath, DateTimeOffset asOfDateTime);
1414
}

0 commit comments

Comments
 (0)