Files
git.stella-ops.org/src/Concelier/__Libraries/StellaOps.Concelier.Models/AffectedVersionRangeExtensions.cs

287 lines
9.5 KiB
C#

using System;
namespace StellaOps.Concelier.Models;
/// <summary>
/// Helpers for deriving normalized version rules from affected version ranges.
/// </summary>
public static class AffectedVersionRangeExtensions
{
public static NormalizedVersionRule? ToNormalizedVersionRule(this AffectedVersionRange? range, string? notes = null)
{
if (range is null)
{
return null;
}
var primitives = range.Primitives;
var semVerRule = primitives?.SemVer?.ToNormalizedVersionRule(notes);
if (semVerRule is not null)
{
return semVerRule;
}
var nevraRule = primitives?.Nevra?.ToNormalizedVersionRule(notes);
if (nevraRule is not null)
{
return nevraRule;
}
var evrRule = primitives?.Evr?.ToNormalizedVersionRule(notes);
if (evrRule is not null)
{
return evrRule;
}
var scheme = Validation.TrimToNull(range.RangeKind)?.ToLowerInvariant();
return scheme switch
{
NormalizedVersionSchemes.SemVer => BuildSemVerFallback(range, notes),
NormalizedVersionSchemes.Nevra => BuildNevraFallback(range, notes),
NormalizedVersionSchemes.Evr => BuildEvrFallback(range, notes),
NormalizedVersionSchemes.Apk => BuildApkFallback(range, notes),
_ => null,
};
}
private static NormalizedVersionRule? BuildSemVerFallback(AffectedVersionRange range, string? notes)
{
var min = Validation.TrimToNull(range.IntroducedVersion);
var max = Validation.TrimToNull(range.FixedVersion);
var last = Validation.TrimToNull(range.LastAffectedVersion);
var resolvedNotes = Validation.TrimToNull(notes);
if (string.IsNullOrEmpty(min) && string.IsNullOrEmpty(max) && string.IsNullOrEmpty(last))
{
return null;
}
if (!string.IsNullOrEmpty(max))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.SemVer,
NormalizedVersionRuleTypes.Range,
min: min,
minInclusive: min is null ? null : true,
max: max,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(last))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.SemVer,
NormalizedVersionRuleTypes.LessThanOrEqual,
max: last,
maxInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(min))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.SemVer,
NormalizedVersionRuleTypes.GreaterThanOrEqual,
min: min,
minInclusive: true,
notes: resolvedNotes);
}
return null;
}
private static NormalizedVersionRule? BuildNevraFallback(AffectedVersionRange range, string? notes)
{
var resolvedNotes = Validation.TrimToNull(notes);
var introduced = Validation.TrimToNull(range.IntroducedVersion);
var fixedVersion = Validation.TrimToNull(range.FixedVersion);
var lastAffected = Validation.TrimToNull(range.LastAffectedVersion);
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Nevra,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Nevra,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Nevra,
NormalizedVersionRuleTypes.GreaterThanOrEqual,
min: introduced,
minInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Nevra,
NormalizedVersionRuleTypes.LessThan,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Nevra,
NormalizedVersionRuleTypes.LessThanOrEqual,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
return null;
}
private static NormalizedVersionRule? BuildEvrFallback(AffectedVersionRange range, string? notes)
{
var resolvedNotes = Validation.TrimToNull(notes);
var introduced = Validation.TrimToNull(range.IntroducedVersion);
var fixedVersion = Validation.TrimToNull(range.FixedVersion);
var lastAffected = Validation.TrimToNull(range.LastAffectedVersion);
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Evr,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Evr,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Evr,
NormalizedVersionRuleTypes.GreaterThanOrEqual,
min: introduced,
minInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Evr,
NormalizedVersionRuleTypes.LessThan,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Evr,
NormalizedVersionRuleTypes.LessThanOrEqual,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
return null;
}
private static NormalizedVersionRule? BuildApkFallback(AffectedVersionRange range, string? notes)
{
var resolvedNotes = Validation.TrimToNull(notes);
var introduced = Validation.TrimToNull(range.IntroducedVersion);
var fixedVersion = Validation.TrimToNull(range.FixedVersion);
var lastAffected = Validation.TrimToNull(range.LastAffectedVersion);
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Apk,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced) && !string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Apk,
NormalizedVersionRuleTypes.Range,
min: introduced,
minInclusive: true,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(introduced))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Apk,
NormalizedVersionRuleTypes.GreaterThanOrEqual,
min: introduced,
minInclusive: true,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(fixedVersion))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Apk,
NormalizedVersionRuleTypes.LessThan,
max: fixedVersion,
maxInclusive: false,
notes: resolvedNotes);
}
if (!string.IsNullOrEmpty(lastAffected))
{
return new NormalizedVersionRule(
NormalizedVersionSchemes.Apk,
NormalizedVersionRuleTypes.LessThanOrEqual,
max: lastAffected,
maxInclusive: true,
notes: resolvedNotes);
}
return null;
}
}