Skip to content

Commit 5dfaa16

Browse files
author
Sridhar, NIVETHA (ext) (FT D AA IN SGI EA EBT BE)
committed
Code Clean up for Package Identifier and creator
1 parent 679373f commit 5dfaa16

File tree

88 files changed

+4725
-129
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4725
-129
lines changed

src/LCT.Common.UTests/CommonAppSettingsTests.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ private class TestDirectory(IEnvironmentHelper envHelper) : LCT.Common.Directory
1818
{
1919

2020
// Override to always throw DirectoryNotFoundException
21-
protected new void ValidateFolderPath(string value)
21+
protected static void ValidateFolderPath(string value)
2222
{
2323
throw new DirectoryNotFoundException("Test exception");
2424
}
@@ -32,10 +32,11 @@ public void InputFolder_WhenDirectoryNotFoundException_LogsErrorAndCallsExit()
3232
bool exitCalled = false;
3333
envHelperMock.Setup(e => e.CallEnvironmentExit(It.IsAny<int>())).Callback(() => exitCalled = true);
3434

35-
var testDirectory = new TestDirectory(envHelperMock.Object);
36-
37-
// Act
38-
testDirectory.InputFolder = "nonexistent_path";
35+
var testDirectory = new TestDirectory(envHelperMock.Object)
36+
{
37+
// Act
38+
InputFolder = "nonexistent_path"
39+
};
3940

4041
// Assert
4142
Assert.IsTrue(exitCalled, "Environment exit should be called on DirectoryNotFoundException.");

src/LCT.Facade/SW360ApicommunicationFacade.cs

Lines changed: 173 additions & 3 deletions
Large diffs are not rendered by default.

src/LCT.PackageIdentifier.UTest/CargoProcessorTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,6 @@ public void GetArtifactoryRepoName_ReturnsNotFoundInRepo_WhenNoMatch()
240240
var aqlResultList = new List<AqlResult>();
241241
var component = new Component { Name = "Test", Version = "1.0" };
242242
var bomHelper = new Mock<IBomHelper>();
243-
string jfrogPackageName, jfrogRepoPath;
244243
var method = typeof(CargoProcessor).GetMethod("GetArtifactoryRepoName", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
245244

246245
var repoName = (string)method.Invoke(null, new object[] { aqlResultList, component, bomHelper.Object, null, null });

src/LCT.PackageIdentifier.UTest/DisplayInformationTests.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@ public void DisplayIncludeFiles_EmptyInclude_ReturnsEmptyString(string projectTy
6767
Assert.AreEqual(string.Empty, result);
6868
}
6969
private CommonAppSettings appSettings;
70-
private CatoolInfo caToolInformation;
7170
private MemoryAppender memoryAppender;
7271

7372
[SetUp]

src/LCT.PackageIdentifier/AlpineProcesser.cs

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,29 @@ namespace LCT.PackageIdentifier
2626
/// </summary>
2727
public class AlpineProcessor(ICycloneDXBomParser cycloneDXBomParser, ISpdxBomParser spdxBomParser) : IParser
2828
{
29+
#region Fields
2930
private const string ProjectTypeAlpine = "ALPINE";
3031
static readonly ILog Logger = LoggerFactory.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
3132
private readonly ICycloneDXBomParser _cycloneDXBomParser = cycloneDXBomParser;
3233
private readonly ISpdxBomParser _spdxBomParser = spdxBomParser;
3334
private static Bom ListUnsupportedComponentsForBom = new Bom { Components = new List<Component>(), Dependencies = new List<Dependency>() };
35+
#endregion
36+
3437
private readonly IEnvironmentHelper _environmentHelper = new EnvironmentHelper();
35-
#region public method
38+
#region Properties
39+
#endregion
3640

41+
#region Constructors
42+
// Primary constructor parameters are declared on the class.
43+
#endregion
44+
45+
#region Methods
46+
/// <summary>
47+
/// Parses Alpine package files from the configured input folder and builds a BOM.
48+
/// </summary>
49+
/// <param name="appSettings">Application settings with input and processing options.</param>
50+
/// <param name="unSupportedBomList">Reference BOM that will be populated with unsupported components.</param>
51+
/// <returns>BOM built from discovered Alpine packages.</returns>
3752
public Bom ParsePackageFile(CommonAppSettings appSettings, ref Bom unSupportedBomList)
3853
{
3954
List<string> configFiles;
@@ -78,12 +93,26 @@ public Bom ParsePackageFile(CommonAppSettings appSettings, ref Bom unSupportedBo
7893
return bom;
7994
}
8095

96+
/// <summary>
97+
/// Removes components excluded in settings from the provided BOM.
98+
/// </summary>
99+
/// <param name="appSettings">Application settings.</param>
100+
/// <param name="cycloneDXBOM">BOM to filter.</param>
101+
/// <returns>Filtered BOM.</returns>
81102
public static Bom RemoveExcludedComponents(CommonAppSettings appSettings, Bom cycloneDXBOM)
82103
{
83104
return CommonHelper.RemoveExcludedComponentsFromBom(appSettings, cycloneDXBOM,
84105
noOfExcludedComponents => BomCreator.bomKpiData.ComponentsExcludedSW360 += noOfExcludedComponents);
85106
}
86107

108+
/// <summary>
109+
/// Asynchronously retrieves repository details for the provided components and returns a modified list.
110+
/// </summary>
111+
/// <param name="componentsForBOM">List of components to enrich.</param>
112+
/// <param name="appSettings">Application settings.</param>
113+
/// <param name="jFrogService">JFrog service to query (may be null).</param>
114+
/// <param name="bomhelper">BOM helper utilities.</param>
115+
/// <returns>Asynchronously returns the modified list of components.</returns>
87116
public async Task<List<Component>> GetJfrogRepoDetailsOfAComponent(List<Component> componentsForBOM, CommonAppSettings appSettings,
88117
IJFrogService jFrogService,
89118
IBomHelper bomhelper)
@@ -98,24 +127,42 @@ public async Task<List<Component>> GetJfrogRepoDetailsOfAComponent(List<Componen
98127
return modifiedBOM;
99128
}
100129

130+
/// <summary>
131+
/// Asynchronously identifies internal components using JFrog and BOM helper; returns input unchanged in current implementation.
132+
/// </summary>
133+
/// <param name="componentData">Component identification data to analyze.</param>
134+
/// <param name="appSettings">Application settings.</param>
135+
/// <param name="jFrogService">JFrog service to query.</param>
136+
/// <param name="bomhelper">BOM helper utilities.</param>
137+
/// <returns>Asynchronously returns the (possibly modified) component identification data.</returns>
101138
public async Task<ComponentIdentification> IdentificationOfInternalComponents(ComponentIdentification componentData,
102139
CommonAppSettings appSettings, IJFrogService jFrogService, IBomHelper bomhelper)
103140
{
104141
await Task.Yield();
105142
return componentData;
106143
}
107144

108-
#endregion
109-
110-
#region private methods
111-
145+
/// <summary>
146+
/// Parses a CycloneDX SBOM file and returns a list of AlpinePackage entries.
147+
/// </summary>
148+
/// <param name="filePath">Path to the CycloneDX/ SPDX file.</param>
149+
/// <param name="dependenciesForBOM">List to collect BOM dependencies.</param>
150+
/// <param name="appSettings">Application settings.</param>
151+
/// <returns>List of parsed AlpinePackage instances.</returns>
112152
public List<AlpinePackage> ParseCycloneDX(string filePath, List<Dependency> dependenciesForBOM, CommonAppSettings appSettings)
113153
{
114154
List<AlpinePackage> alpinePackages = new List<AlpinePackage>();
115155
ExtractDetailsForJson(filePath, ref alpinePackages, dependenciesForBOM, appSettings);
116156
return alpinePackages;
117157
}
118158

159+
/// <summary>
160+
/// Extracts package details from a BOM file and populates provided collections with packages and dependencies.
161+
/// </summary>
162+
/// <param name="filePath">Path to the BOM file.</param>
163+
/// <param name="alpinePackages">Reference list to append discovered Alpine packages.</param>
164+
/// <param name="dependenciesForBOM">List to collect dependencies discovered in the BOM.</param>
165+
/// <param name="appSettings">Application settings.</param>
119166
private void ExtractDetailsForJson(string filePath, ref List<AlpinePackage> alpinePackages, List<Dependency> dependenciesForBOM, CommonAppSettings appSettings)
120167
{
121168
Bom listUnsupportedComponents = new Bom { Components = new List<Component>(), Dependencies = new List<Dependency>() };
@@ -151,6 +198,11 @@ private void ExtractDetailsForJson(string filePath, ref List<AlpinePackage> alpi
151198
ListUnsupportedComponentsForBom.Components.AddRange(listUnsupportedComponents.Components);
152199
ListUnsupportedComponentsForBom.Dependencies.AddRange(listUnsupportedComponents.Dependencies);
153200
}
201+
202+
/// <summary>
203+
/// Removes duplicate components from the provided list and updates KPI data.
204+
/// </summary>
205+
/// <param name="listofComponents">Reference to the component list to deduplicate.</param>
154206
private static string GetReleaseExternalId(string name, string version)
155207
{
156208
return BomHelper.GetReleaseExternalId(name, version, Dataconstant.PurlCheck()[ProjectTypeAlpine]);
@@ -174,6 +226,11 @@ private static string GetDistro(AlpinePackage alpinePackage)
174226
return alpinePackage.PurlID[distroIndex..];
175227
}
176228

229+
/// <summary>
230+
/// Forms a list of CycloneDX Component objects from parsed Alpine packages, adding PURLs and properties.
231+
/// </summary>
232+
/// <param name="listOfComponents">List of parsed Alpine packages.</param>
233+
/// <returns>List of components ready for BOM insertion.</returns>
177234
private static List<Component> FormComponentReleaseExternalID(List<AlpinePackage> listOfComponents)
178235
{
179236
List<Component> listComponentForBOM = new List<Component>();
@@ -194,6 +251,12 @@ private static List<Component> FormComponentReleaseExternalID(List<AlpinePackage
194251
}
195252
return listComponentForBOM;
196253
}
254+
255+
/// <summary>
256+
/// Adds properties to a CycloneDX component based on SPDX information or discovery metadata.
257+
/// </summary>
258+
/// <param name="prop">Parsed Alpine package information.</param>
259+
/// <param name="component">Component to enrich.</param>
197260
private static void AddComponentProperties(AlpinePackage prop, Component component)
198261
{
199262
if (prop.SpdxComponentDetails.SpdxComponent)
@@ -209,6 +272,13 @@ private static void AddComponentProperties(AlpinePackage prop, Component compone
209272
component.Properties.Add(identifierType);
210273
}
211274
}
275+
276+
/// <summary>
277+
/// Sets SPDX related details on an AlpinePackage when the source file is an SPDX file.
278+
/// </summary>
279+
/// <param name="filePath">Source file path.</param>
280+
/// <param name="package">Alpine package to update.</param>
281+
/// <param name="componentInfo">Component information parsed from the BOM.</param>
212282
private static void SetSpdxComponentDetails(string filePath, AlpinePackage package, Component componentInfo)
213283
{
214284
if (filePath.EndsWith(FileConstant.SPDXFileExtension))
@@ -220,5 +290,8 @@ private static void SetSpdxComponentDetails(string filePath, AlpinePackage packa
220290
}
221291

222292
#endregion
293+
294+
#region Events
295+
#endregion
223296
}
224297
}

src/LCT.PackageIdentifier/BomCreator.cs

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,31 +37,48 @@ namespace LCT.PackageIdentifier
3737
/// </summary>
3838
public class BomCreator : IBomCreator
3939
{
40+
#region Fields
4041
private const string JFrogConnValidationContext = "JFrog Connection Validation";
4142
private const string CheckJFrogConnectionMethod = "Methodname:CheckJFrogConnection()";
4243
static readonly ILog Logger = LoggerFactory.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
4344
public readonly static BomKpiData bomKpiData = new();
4445
ComponentIdentification componentData;
4546
private readonly ICycloneDXBomParser CycloneDXBomParser;
4647
private readonly ISpdxBomParser SpdxBomParser;
47-
public IJFrogService JFrogService { get; set; }
48-
public IBomHelper BomHelper { get; set; }
49-
5048
private readonly IFrameworkPackages _frameworkPackages;
5149
private readonly ICompositionBuilder _compositionBuilder;
5250
private readonly IRuntimeIdentifier _runtimeIdentifier;
5351

5452
public static Jfrog jfrog { get; set; } = new Jfrog();
5553
public static SW360 sw360 { get; set; } = new SW360();
54+
#endregion
55+
56+
#region Properties
57+
public IJFrogService JFrogService { get; set; }
58+
public IBomHelper BomHelper { get; set; }
59+
#endregion
60+
61+
#region Constructors
5662
public BomCreator(ICycloneDXBomParser cycloneDXBomParser, IFrameworkPackages frameworkPackages, ICompositionBuilder compositionBuilder, ISpdxBomParser spdxBomParser, IRuntimeIdentifier runtimeIdentifier)
5763
{
5864
CycloneDXBomParser = cycloneDXBomParser;
59-
_frameworkPackages = frameworkPackages;
65+
_frameworkPackages = frameworkPackages;
6066
_compositionBuilder = compositionBuilder;
6167
SpdxBomParser = spdxBomParser;
6268
_runtimeIdentifier = runtimeIdentifier;
6369
}
70+
#endregion
71+
6472

73+
/// <summary>
74+
/// Asynchronously generates a CycloneDX BOM from configured inputs and writes outputs (BOM, KPI files).
75+
/// </summary>
76+
/// <param name="appSettings">Application settings used for generation.</param>
77+
/// <param name="bomHelper">BOM helper utilities.</param>
78+
/// <param name="fileOperations">File operations helper used to write outputs.</param>
79+
/// <param name="projectReleases">Project releases data used to enrich metadata.</param>
80+
/// <param name="caToolInformation">CA tool information for telemetry/metadata.</param>
81+
/// <returns>Asynchronously completes when generation finishes.</returns>
6582
public async Task GenerateBom(CommonAppSettings appSettings,
6683
IBomHelper bomHelper,
6784
IFileOperations fileOperations,
@@ -128,11 +145,25 @@ public async Task GenerateBom(CommonAppSettings appSettings,
128145
Logger.Debug($"GenerateBom():SBOM generation process has completed.\n");
129146
}
130147

148+
/// <summary>
149+
/// Writes contents to BOM by delegating to CycloneDX writer.
150+
/// </summary>
151+
/// <param name="appSettings">Application settings.</param>
152+
/// <param name="bomKpiData">KPI data structure to update.</param>
153+
/// <param name="listOfComponentsToBom">BOM to write.</param>
154+
/// <param name="defaultProjectName">Default project name used in file naming.</param>
131155
private static void WritecontentsToBOM(CommonAppSettings appSettings, BomKpiData bomKpiData, Bom listOfComponentsToBom, string defaultProjectName)
132156
{
133157
WriteContentToCycloneDxBOM(appSettings, listOfComponentsToBom, ref bomKpiData, defaultProjectName);
134158
}
135159

160+
/// <summary>
161+
/// Writes a CycloneDX BOM file to the output folder, optionally merging with existing BOMs when configured.
162+
/// </summary>
163+
/// <param name="appSettings">Application settings.</param>
164+
/// <param name="listOfComponentsToBom">BOM object containing components and metadata.</param>
165+
/// <param name="bomKpiData">KPI data reference that can be modified.</param>
166+
/// <param name="defaultProjectName">Default project name used for file naming.</param>
136167
private static void WriteContentToCycloneDxBOM(CommonAppSettings appSettings, Bom listOfComponentsToBom, ref BomKpiData bomKpiData, string defaultProjectName)
137168
{
138169
FileOperations fileOperations = new FileOperations();
@@ -161,6 +192,11 @@ private static void WriteContentToCycloneDxBOM(CommonAppSettings appSettings, Bo
161192

162193
}
163194

195+
/// <summary>
196+
/// Asynchronously selects and invokes the appropriate package parser based on project type.
197+
/// </summary>
198+
/// <param name="appSettings">Application settings which include ProjectType.</param>
199+
/// <returns>Asynchronously returns the generated BOM from the selected parser.</returns>
164200
private async Task<Bom> CallPackageParser(CommonAppSettings appSettings)
165201
{
166202
IParser parser;
@@ -202,6 +238,12 @@ private async Task<Bom> CallPackageParser(CommonAppSettings appSettings)
202238
return new Bom();
203239
}
204240

241+
/// <summary>
242+
/// Asynchronously runs component identification and enrichment using the provided parser.
243+
/// </summary>
244+
/// <param name="appSettings">Application settings used by the parser.</param>
245+
/// <param name="parser">Parser that will parse package files and identify components.</param>
246+
/// <returns>Asynchronously returns the composed BOM.</returns>
205247
private async Task<Bom> ComponentIdentification(CommonAppSettings appSettings, IParser parser)
206248
{
207249
Logger.Debug("ComponentIdentification():Component identification process for BOM file has started.");
@@ -256,6 +298,12 @@ private async Task<Bom> ComponentIdentification(CommonAppSettings appSettings, I
256298
Logger.Debug("ComponentIdentification():Component identification process for BOM file has completed.");
257299
return bom;
258300
}
301+
302+
/// <summary>
303+
/// Asynchronously checks connectivity to JFrog using the configured JFrog service.
304+
/// </summary>
305+
/// <param name="appSettings">Application settings containing JFrog configuration.</param>
306+
/// <returns>Asynchronously returns true when connection is successful or JFrog is not configured; otherwise false.</returns>
259307
public async Task<bool> CheckJFrogConnection(CommonAppSettings appSettings)
260308
{
261309
Logger.Debug("CheckJFrogConnection():Validating JFrog Connection has started");
@@ -293,5 +341,9 @@ public async Task<bool> CheckJFrogConnection(CommonAppSettings appSettings)
293341
return true;
294342

295343
}
344+
345+
346+
#region Events
347+
#endregion
296348
}
297349
}

0 commit comments

Comments
 (0)