Skip to content

Commit

Permalink
Adding dependencies to the SBOM
Browse files Browse the repository at this point in the history
  • Loading branch information
adityanarayanp committed Oct 26, 2023
1 parent 12395ab commit 3c1ac4f
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 66 deletions.
111 changes: 46 additions & 65 deletions src/LCT.PackageIdentifier/ConanProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,12 @@ public Bom ParsePackageFile(CommonAppSettings appSettings)
{
List<Component> componentsForBOM = new List<Component>();
Bom bom = new Bom();
List<Dependency> dependencies = new List<Dependency>();
int totalComponentsIdentified = 0;

ParsingInputFileForBOM(appSettings, ref componentsForBOM, ref bom);

ParsingInputFileForBOM(appSettings, ref componentsForBOM, ref dependencies);
totalComponentsIdentified = componentsForBOM.Count;

componentsForBOM = GetExcludedComponentsList(componentsForBOM);
componentsForBOM = componentsForBOM.Distinct(new ComponentEqualityComparer()).ToList();

Expand All @@ -73,6 +74,7 @@ public Bom ParsePackageFile(CommonAppSettings appSettings)
}
}
bom.Components = componentsForBOM;
bom.Dependencies = dependencies;
Logger.Debug($"ParsePackageFile():End");
return bom;
}
Expand Down Expand Up @@ -149,10 +151,10 @@ public async Task<List<Component>> GetJfrogRepoDetailsOfAComponent(List<Componen
return modifiedBOM;
}

public static bool IsDevDependency(ConanPackage component, ConanPackage rootNode, ref int noOfDevDependent)
public static bool IsDevDependency(ConanPackage component, List<string> buildNodeIds, ref int noOfDevDependent)
{
var isDev = false;
if (buildNodeIds!= null && buildNodeIds.Contains(component.Id))
if (buildNodeIds != null && buildNodeIds.Contains(component.Id))
{
isDev = true;
noOfDevDependent++;
Expand All @@ -164,51 +166,23 @@ public static bool IsDevDependency(ConanPackage component, ConanPackage rootNode
#endregion

#region private methods
private void ParsingInputFileForBOM(CommonAppSettings appSettings, ref List<Component> listComponentForBOM, ref Bom bom)
private void ParsingInputFileForBOM(CommonAppSettings appSettings, ref List<Component> componentsForBOM, ref List<Dependency> dependenciesForBom)
{
List<string> configFiles;
List<Component> componentsForBOM = new List<Component>();
List<Dependency> dependencies = new List<Dependency>();
configFiles = FolderScanner.FileScanner(appSettings.PackageFilePath, appSettings.Conan);

foreach (string filepath in configFiles)
{
if (filepath.ToLower().EndsWith("conan.lock"))
{
Logger.Debug($"ParsingInputFileForBOM():FileName: " + filepath);
var components = ParsePackageLockJson(filepath, appSettings);
AddingIdentifierType(components, "PackageFile");
componentsForBOM.AddRange(components);
}
else if (filepath.EndsWith(FileConstant.CycloneDXFileExtension) && !filepath.EndsWith(FileConstant.SBOMTemplateFileExtension))
{
Logger.Debug($"ParsingInputFileForBOM():Found as CycloneDXFile");
bom = cycloneDXBomParser.ParseCycloneDXBom(filepath);
CheckValidComponentsForProjectType(bom.Components, appSettings.ProjectType);
componentsForBOM.AddRange(bom.Components);
CommonHelper.GetDetailsforManuallyAdded(componentsForBOM, listComponentForBOM);
}
Logger.Debug($"ParsingInputFileForBOM():FileName: " + filepath);
var components = ParsePackageLockJson(filepath, appSettings, ref dependencies);
AddingIdentifierType(components, "PackageFile");
componentsForBOM.AddRange(components);
dependenciesForBom.AddRange(dependencies);
}

int initialCount = componentsForBOM.Count;
GetDistinctComponentList(ref componentsForBOM);
BomCreator.bomKpiData.DuplicateComponents = initialCount - listComponentForBOM.Count;
BomCreator.bomKpiData.ComponentsinPackageLockJsonFile = listComponentForBOM.Count;
BomCreator.bomKpiData.DevDependentComponents = listComponentForBOM.Count(s => s.Properties[0].Value == "true");
bom.Components = listComponentForBOM;

if (File.Exists(appSettings.CycloneDxSBomTemplatePath) && appSettings.CycloneDxSBomTemplatePath.EndsWith(FileConstant.SBOMTemplateFileExtension))
{
//Adding Template Component Details
Bom templateDetails;
templateDetails = ExtractSBOMDetailsFromTemplate(cycloneDXBomParser.ParseCycloneDXBom(appSettings.CycloneDxSBomTemplatePath));
CheckValidComponentsForProjectType(templateDetails.Components, appSettings.ProjectType);
SbomTemplate.AddComponentDetails(bom.Components, templateDetails);
}

bom = RemoveExcludedComponents(appSettings, bom);
}

private List<Component> ParsePackageLockJson(string filepath, CommonAppSettings appSettings)
private List<Component> ParsePackageLockJson(string filepath, CommonAppSettings appSettings, ref List<Dependency> dependencies)
{
List<Component> lstComponentForBOM = new List<Component>();
int noOfDevDependent = 0;
Expand Down Expand Up @@ -238,6 +212,8 @@ private List<Component> ParsePackageLockJson(string filepath, CommonAppSettings

}

GetDependecyDetails(lstComponentForBOM, nodePackages, dependencies);

BomCreator.bomKpiData.DevDependentComponents += noOfDevDependent;
}
catch (JsonReaderException ex)
Expand All @@ -259,10 +235,38 @@ private List<Component> ParsePackageLockJson(string filepath, CommonAppSettings
return lstComponentForBOM;
}

private static void GetDependecyDetails(List<Component> componentsForBOM, List<ConanPackage> nodePackages, List<Dependency> dependencies)
{
foreach (Component component in componentsForBOM)
{
var node = nodePackages.Find(x => x.Reference.Contains($"{component.Name}/{component.Version}"));
var dependencyNodes = new List<ConanPackage>();
if (node.Dependencies != null && node.Dependencies.Count > 0)
{
dependencyNodes.AddRange(nodePackages.Where(x => node.Dependencies.Contains(x.Id)).ToList());
}
if (node.DevDependencies != null && node.DevDependencies.Count > 0)
{
dependencyNodes.AddRange(nodePackages.Where(x => node.DevDependencies.Contains(x.Id)).ToList());
}
var dependency = new Dependency();
var subDependencies = componentsForBOM.Where(x => dependencyNodes.Exists(y => y.Reference.Contains($"{x.Name}/{x.Version}")))
.Select(x => new Dependency { Ref = x.Purl }).ToList();

dependency.Ref = component.Purl;
dependency.Dependencies = subDependencies;

if(subDependencies.Count > 0)
{
dependencies.Add(dependency);
}
}
}

private static void GetPackagesForBom(ref List<Component> lstComponentForBOM, ref int noOfDevDependent, List<ConanPackage> nodePackages)
{
var rootNode = nodePackages.FirstOrDefault();
if (rootNode == null || !rootNode.Dependencies.Any() || rootNode.Dependencies == null)
if (!rootNode.Dependencies.Any() || rootNode.Dependencies == null)
{
throw new ArgumentNullException(nameof(nodePackages), "Dependency(requires) node name details not present in the root node.");
}
Expand Down Expand Up @@ -303,7 +307,6 @@ private static void GetPackagesForBom(ref List<Component> lstComponentForBOM, re

components.Purl = $"{ApiConstant.ConanExternalID}{components.Name}@{components.Version}";
components.BomRef = $"{ApiConstant.ConanExternalID}{components.Name}@{components.Version}";

components.Properties = new List<Property>();
components.Properties.Add(isdev);
lstComponentForBOM.Add(components);
Expand Down Expand Up @@ -353,7 +356,7 @@ private static List<Component> GetExcludedComponentsList(List<Component> compone
else
{
BomCreator.bomKpiData.ComponentsExcluded++;
Logger.Debug($"GetExcludedComponentsList():InvalidComponent For CONAN : Component Details : {componentsInfo.Name} @ {componentsInfo.Version} @ {componentsInfo.Purl}");
Logger.Debug($"GetExcludedComponentsList():InvalidComponent For CONAN : Component Details : {componentsInfo?.Name} @ {componentsInfo?.Version} @ {componentsInfo?.Purl}");
}
}
return components;
Expand Down Expand Up @@ -385,28 +388,6 @@ private static void AddingIdentifierType(List<Component> components, string iden
}
}

private static Bom RemoveExcludedComponents(CommonAppSettings appSettings, Bom cycloneDXBOM)
{
List<Component> componentForBOM = cycloneDXBOM.Components.ToList();
int noOfExcludedComponents = 0;
if (appSettings.Conan.ExcludedComponents != null)
{
componentForBOM = CommonHelper.RemoveExcludedComponents(componentForBOM, appSettings.Conan.ExcludedComponents, ref noOfExcludedComponents);
BomCreator.bomKpiData.ComponentsExcluded += noOfExcludedComponents;
}
cycloneDXBOM.Components = componentForBOM;
return cycloneDXBOM;
}

private static void GetDistinctComponentList(ref List<Component> listofComponents)
{
int initialCount = listofComponents.Count;
listofComponents = listofComponents.GroupBy(x => new { x.Name, x.Version, x.Purl }).Select(y => y.First()).ToList();

if (listofComponents.Count != initialCount)
BomCreator.bomKpiData.DuplicateComponents = initialCount - listofComponents.Count;
}

#endregion
}
}
2 changes: 1 addition & 1 deletion src/LCT.PackageIdentifier/Model/ConanPackage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class ConanPackage
{
public string Id { get; set; }
[JsonProperty("ref")]
public string Reference { get; set; }
public string Reference { get; set; } = string.Empty;
[JsonProperty("requires")]
public List<string> Dependencies { get; set; }
[JsonProperty("build_requires")]
Expand Down

0 comments on commit 3c1ac4f

Please sign in to comment.