Ejemplo n.º 1
0
        public static async Task <int> Diff(
            string fromFile, string toFile, InputFormat fromFormat, InputFormat toFormat, StandardOutputFormat outputFormat,
            bool componentVersions)
        {
            var fromBomFormat = InputFormatHelper(fromFile, fromFormat);
            var toBomFormat   = InputFormatHelper(toFile, toFormat);

            if (fromBomFormat == BomFormat.Unsupported || toBomFormat == BomFormat.Unsupported)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var fromBomString = await File.ReadAllTextAsync(fromFile);

            var toBomString = await File.ReadAllTextAsync(toFile);

            var fromBom = CLIUtils.BomDeserializer(fromBomString, fromBomFormat);
            var toBom   = CLIUtils.BomDeserializer(toBomString, toBomFormat);

            var result = new DiffResult();

            if (componentVersions)
            {
                result.ComponentVersions = CycloneDXUtils.ComponentVersionDiff(fromBom, toBom);
            }

            if (outputFormat == StandardOutputFormat.json)
            {
                var options = new JsonSerializerOptions
                {
                    WriteIndented        = true,
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    IgnoreNullValues     = true,
                };

                options.Converters.Add(new Json.Converters.v1_2.ComponentTypeConverter());
                options.Converters.Add(new Json.Converters.v1_2.DataFlowConverter());
                options.Converters.Add(new Json.Converters.v1_2.DateTimeConverter());
                options.Converters.Add(new Json.Converters.v1_2.DependencyConverter());
                options.Converters.Add(new Json.Converters.v1_2.ExternalReferenceTypeConverter());
                options.Converters.Add(new Json.Converters.v1_2.HashAlgorithmConverter());
                options.Converters.Add(new Json.Converters.v1_2.IssueClassificationConverter());
                options.Converters.Add(new Json.Converters.v1_2.LicenseConverter());
                options.Converters.Add(new Json.Converters.v1_2.PatchClassificationConverter());

                Console.WriteLine(JsonSerializer.Serialize(result, options));
            }
            else
            {
                if (result.ComponentVersions != null)
                {
                    Console.WriteLine("Component versions that have changed:");
                    Console.WriteLine();

                    var changes = false;
                    foreach (var entry in result.ComponentVersions)
                    {
                        var componentDiffItem = entry.Value;
                        if (componentDiffItem.Added.Count > 0 || componentDiffItem.Removed.Count > 0)
                        {
                            changes = true;
                            foreach (var component in componentDiffItem.Removed)
                            {
                                Console.WriteLine($"- {component.Group} {component.Name} @ {component.Version}");
                            }
                            foreach (var component in componentDiffItem.Unchanged)
                            {
                                Console.WriteLine($"= {component.Group} {component.Name} @ {component.Version}");
                            }
                            foreach (var component in componentDiffItem.Added)
                            {
                                Console.WriteLine($"+ {component.Group} {component.Name} @ {component.Version}");
                            }
                            Console.WriteLine();
                        }
                    }

                    if (!changes)
                    {
                        Console.WriteLine("None");
                    }

                    Console.WriteLine();
                }
            }

            return((int)ExitCode.Ok);
        }
Ejemplo n.º 2
0
        public static async Task <int> Analyze(
            string inputFile, InputFormat inputFormat, StandardOutputFormat outputFormat,
            bool multipleComponentVersions)
        {
            var inputBomFormat = InputFormatHelper(inputFile, inputFormat);

            if (inputBomFormat == BomFormat.Unsupported)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var inputBomString = InputFileHelper(inputFile);

            if (inputBomString == null)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var inputBom = Utils.BomDeserializer(inputBomString, inputBomFormat);

            var result = new AnalyzeResult();

            if (multipleComponentVersions)
            {
                result.MultipleComponentVersions = new List <List <Component> >();

                var componentCache = new Dictionary <string, List <Component> >();
                foreach (var component in inputBom.Components)
                {
                    if (!componentCache.ContainsKey(component.Name))
                    {
                        componentCache[component.Name] = new List <Component>();
                    }
                    componentCache[component.Name].Add(component);
                }

                foreach (var componentEntry in componentCache)
                {
                    if (componentEntry.Value.Count > 1)
                    {
                        var firstVersion = componentEntry.Value.First().Version;
                        foreach (var component in componentEntry.Value)
                        {
                            if (component.Version != firstVersion)
                            {
                                result.MultipleComponentVersions.Add(componentEntry.Value);
                                break;
                            }
                        }
                    }
                }
            }

            string outputString;

            if (outputFormat == StandardOutputFormat.json)
            {
                var options = new JsonSerializerOptions
                {
                    WriteIndented        = true,
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    IgnoreNullValues     = true,
                };

                options.Converters.Add(new Json.v1_2.Converters.ComponentTypeConverter());
                options.Converters.Add(new Json.v1_2.Converters.DataFlowConverter());
                options.Converters.Add(new Json.v1_2.Converters.DateTimeConverter());
                options.Converters.Add(new Json.v1_2.Converters.DependencyConverter());
                options.Converters.Add(new Json.v1_2.Converters.ExternalReferenceTypeConverter());
                options.Converters.Add(new Json.v1_2.Converters.HashAlgorithmConverter());
                options.Converters.Add(new Json.v1_2.Converters.IssueClassificationConverter());
                options.Converters.Add(new Json.v1_2.Converters.LicenseConverter());
                options.Converters.Add(new Json.v1_2.Converters.PatchClassificationConverter());

                outputString = JsonSerializer.Serialize(result, options);
            }
            else
            {
                var sb = new StringBuilder();

                if (result.MultipleComponentVersions != null)
                {
                    sb.AppendLine("Components with multiple versions:");
                    sb.AppendLine();
                    if (result.MultipleComponentVersions.Count == 0)
                    {
                        sb.AppendLine("None");
                    }
                    else
                    {
                        foreach (var componentEntry in result.MultipleComponentVersions)
                        {
                            sb.Append(componentEntry.First().Name);
                            sb.Append(" versions:");
                            foreach (var component in componentEntry)
                            {
                                sb.Append(" ");
                                sb.Append(component.Version);
                            }
                        }
                    }
                    sb.AppendLine();
                }

                outputString = sb.ToString();
            }

            Console.Write(outputString);

            return((int)ExitCode.Ok);
        }
Ejemplo n.º 3
0
        public static async Task <int> Diff(
            string fromFile, string toFile, InputFormat fromFormat, InputFormat toFormat, StandardOutputFormat outputFormat,
            bool componentVersions)
        {
            var fromBomFormat = InputFormatHelper(fromFile, fromFormat);
            var toBomFormat   = InputFormatHelper(toFile, toFormat);

            if (fromBomFormat == BomFormat.Unsupported || toBomFormat == BomFormat.Unsupported)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var fromBomString = File.ReadAllText(fromFile);
            var toBomString   = File.ReadAllText(toFile);

            var fromBom = Utils.BomDeserializer(fromBomString, fromBomFormat);
            var toBom   = Utils.BomDeserializer(toBomString, toBomFormat);

            var result = new DiffResult();

            if (componentVersions)
            {
                result.ComponentVersions = new DiffItem <Component>();

                // there is some complexity here, components could be included
                // multiple times, with the same or different versions

                // make a copy of components that are still to be processed
                var fromComponents = new List <Component>(fromBom.Components);
                var toComponents   = new List <Component>(toBom.Components);

                // ditch component versions that are in both
                foreach (var component in fromBom.Components)
                {
                    if (toBom.Components.Count(c => c.Name == component.Name && c.Version == component.Version) > 0)
                    {
                        fromComponents.RemoveAll(c => c.Name == component.Name && c.Version == component.Version);
                        toComponents.RemoveAll(c => c.Name == component.Name && c.Version == component.Version);
                    }
                }

                // find obviously added components
                // take a copy of toComponents as we are modifying it
                foreach (var component in new List <Component>(toComponents))
                {
                    if (fromComponents.Count(c => c.Name == component.Name) == 0)
                    {
                        result.ComponentVersions.Added.Add(component);
                        toComponents.RemoveAll(c => c.Name == component.Name && c.Version == component.Version);
                    }
                }

                // find obviously removed components
                // take a copy of fromComponents as we are modifying it
                foreach (var component in new List <Component>(fromComponents))
                {
                    if (toComponents.Count(c => c.Name == component.Name) == 0)
                    {
                        result.ComponentVersions.Removed.Add(component);
                        fromComponents.RemoveAll(c => c.Name == component.Name && c.Version == component.Version);
                    }
                }

                // now we should have modified components left over
                //
                // but this situation is possible (or the reverse)
                //
                // From:
                // Component A v1.0.0
                //
                // To:
                // Component A v1.0.1
                // Component A v1.0.2
                //
                // (╯°□°)╯︵ ┻━┻
                //
                // we'll treat the first match as modified, and any others as
                // added or removed

                foreach (var fromComponent in new List <Component>(fromComponents))
                {
                    var toComponent = toComponents.First(c => c.Name == fromComponent.Name);
                    if (toComponent != null)
                    {
                        result.ComponentVersions.Modified.Add(new ModifiedDiffItem <Component>
                        {
                            From = fromComponent,
                            To   = toComponent
                        });

                        fromComponents.RemoveAll(c => c.Name == fromComponent.Name && c.Version == fromComponent.Version);
                        toComponents.RemoveAll(c => c.Name == toComponent.Name && c.Version == toComponent.Version);
                    }
                }
                // now everything left over we'll treat as added or removed
                result.ComponentVersions.Removed.AddRange(fromComponents);
                result.ComponentVersions.Added.AddRange(toComponents);
            }

            if (outputFormat == StandardOutputFormat.json)
            {
                var options = new JsonSerializerOptions
                {
                    WriteIndented        = true,
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    IgnoreNullValues     = true,
                };

                options.Converters.Add(new Json.v1_2.Converters.ComponentTypeConverter());
                options.Converters.Add(new Json.v1_2.Converters.DataFlowConverter());
                options.Converters.Add(new Json.v1_2.Converters.DateTimeConverter());
                options.Converters.Add(new Json.v1_2.Converters.DependencyConverter());
                options.Converters.Add(new Json.v1_2.Converters.ExternalReferenceTypeConverter());
                options.Converters.Add(new Json.v1_2.Converters.HashAlgorithmConverter());
                options.Converters.Add(new Json.v1_2.Converters.IssueClassificationConverter());
                options.Converters.Add(new Json.v1_2.Converters.LicenseConverter());
                options.Converters.Add(new Json.v1_2.Converters.PatchClassificationConverter());

                Console.WriteLine(JsonSerializer.Serialize(result, options));
            }
            else
            {
                if (result.ComponentVersions != null)
                {
                    Console.WriteLine("Component versions that have changed:");
                    Console.WriteLine();
                    if (
                        result.ComponentVersions.Removed.Count == 0 &&
                        result.ComponentVersions.Modified.Count == 0 &&
                        result.ComponentVersions.Removed.Count == 0
                        )
                    {
                        Console.WriteLine("None");
                    }
                    else
                    {
                        foreach (var component in result.ComponentVersions.Added)
                        {
                            Console.WriteLine($"+ {component.Name}@{component.Version}");
                            Console.WriteLine();
                        }
                        foreach (var component in result.ComponentVersions.Modified)
                        {
                            Console.WriteLine($"- {component.From.Name}@{component.From.Version}");
                            Console.WriteLine($"+ {component.To.Name}@{component.To.Version}");
                            Console.WriteLine();
                        }
                        foreach (var component in result.ComponentVersions.Removed)
                        {
                            Console.WriteLine($"- {component.Name}@{component.Version}");
                            Console.WriteLine();
                        }
                    }
                    Console.WriteLine();
                }
            }

            return((int)ExitCode.Ok);
        }
Ejemplo n.º 4
0
        public static async Task <int> Analyze(
            string inputFile, InputFormat inputFormat, StandardOutputFormat outputFormat,
            bool multipleComponentVersions)
        {
            var inputBomFormat = InputFormatHelper(inputFile, inputFormat);

            if (inputBomFormat == BomFormat.Unsupported)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var inputBomString = await InputFileHelper(inputFile);

            if (inputBomString == null)
            {
                return((int)ExitCode.ParameterValidationError);
            }

            var inputBom = CLIUtils.BomDeserializer(inputBomString, inputBomFormat);

            var result = new AnalyzeResult();

            if (multipleComponentVersions)
            {
                result.MultipleComponentVersions = CycloneDXUtils.MultipleComponentVersions(inputBom);
            }

            if (outputFormat == StandardOutputFormat.json)
            {
                var options = new JsonSerializerOptions
                {
                    WriteIndented        = true,
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                    IgnoreNullValues     = true,
                };

                options.Converters.Add(new Json.Converters.v1_2.ComponentTypeConverter());
                options.Converters.Add(new Json.Converters.v1_2.DataFlowConverter());
                options.Converters.Add(new Json.Converters.v1_2.DateTimeConverter());
                options.Converters.Add(new Json.Converters.v1_2.DependencyConverter());
                options.Converters.Add(new Json.Converters.v1_2.ExternalReferenceTypeConverter());
                options.Converters.Add(new Json.Converters.v1_2.HashAlgorithmConverter());
                options.Converters.Add(new Json.Converters.v1_2.IssueClassificationConverter());
                options.Converters.Add(new Json.Converters.v1_2.LicenseConverter());
                options.Converters.Add(new Json.Converters.v1_2.PatchClassificationConverter());

                Console.WriteLine(JsonSerializer.Serialize(result, options));
            }
            else
            {
                if (inputBom.Metadata?.Component != null)
                {
                    var component = inputBom.Metadata.Component;
                    Console.WriteLine($"Analysis results for {component.Name}@{component.Version}:");
                }
                else
                {
                    Console.WriteLine("Analysis results:");
                }
                Console.WriteLine();

                if (result.MultipleComponentVersions != null)
                {
                    Console.WriteLine("Components with multiple versions:");
                    Console.WriteLine();
                    if (result.MultipleComponentVersions.Count == 0)
                    {
                        Console.WriteLine("None");
                    }
                    else
                    {
                        foreach (var componentEntry in result.MultipleComponentVersions)
                        {
                            Console.Write(componentEntry.Key);
                            Console.Write(" versions:");
                            foreach (var component in componentEntry.Value)
                            {
                                Console.Write(" ");
                                Console.Write(component.Version);
                            }
                            Console.WriteLine();
                        }
                    }
                    Console.WriteLine();
                }
            }

            return((int)ExitCode.Ok);
        }