Skip to content

Commit

Permalink
Change SemanticVersion's PreReleaseTag and BuildMetaData to a non-nul…
Browse files Browse the repository at this point in the history
…lable type

Because they are always set in SemanticVersion's constructor.
They can be null only if explicitly set by the client of the class and
there are plans to forbid this functionality.
  • Loading branch information
AlexPykavy committed Jan 11, 2023
1 parent 4d510b2 commit 9b19750
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,9 @@ public void ValidateVersionParsing(
Assert.AreEqual(major, version.Major);
Assert.AreEqual(minor, version.Minor);
Assert.AreEqual(patch, version.Patch);
version.PreReleaseTag.ShouldNotBeNull();
Assert.AreEqual(tag, version.PreReleaseTag.Name);
Assert.AreEqual(tagNumber, version.PreReleaseTag.Number);

version.BuildMetaData.ShouldNotBeNull();
Assert.AreEqual(numberOfBuilds, version.BuildMetaData.CommitsSinceTag);
Assert.AreEqual(branchName, version.BuildMetaData.Branch);
Assert.AreEqual(sha, version.BuildMetaData.Sha);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ public void VersionSourceSha()

var nextVersion = nextVersionCalculator.FindVersion();

nextVersion.IncrementedVersion.BuildMetaData.ShouldNotBeNull();
nextVersion.IncrementedVersion.BuildMetaData.VersionSourceSha.ShouldBeNull();
nextVersion.IncrementedVersion.BuildMetaData.CommitsSinceVersionSource.ShouldBe(3);
}
Expand All @@ -41,7 +40,6 @@ public void VersionSourceShaOneCommit()

var nextVersion = nextVersionCalculator.FindVersion();

nextVersion.IncrementedVersion.BuildMetaData.ShouldNotBeNull();
nextVersion.IncrementedVersion.BuildMetaData.VersionSourceSha.ShouldBeNull();
nextVersion.IncrementedVersion.BuildMetaData.CommitsSinceVersionSource.ShouldBe(1);
}
Expand All @@ -62,7 +60,6 @@ public void VersionSourceShaUsingTag()

var nextVersion = nextVersionCalculator.FindVersion();

nextVersion.IncrementedVersion.BuildMetaData.ShouldNotBeNull();
nextVersion.IncrementedVersion.BuildMetaData.VersionSourceSha.ShouldBe(secondCommit.Sha);
nextVersion.IncrementedVersion.BuildMetaData.CommitsSinceVersionSource.ShouldBe(1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public static class AssemblyVersionsGeneratorExtensions
AssemblyVersioningScheme.Major => $"{sv.Major}.0.0.0",
AssemblyVersioningScheme.MajorMinor => $"{sv.Major}.{sv.Minor}.0.0",
AssemblyVersioningScheme.MajorMinorPatch => $"{sv.Major}.{sv.Minor}.{sv.Patch}.0",
AssemblyVersioningScheme.MajorMinorPatchTag => $"{sv.Major}.{sv.Minor}.{sv.Patch}.{sv.PreReleaseTag?.Number ?? 0}",
AssemblyVersioningScheme.MajorMinorPatchTag => $"{sv.Major}.{sv.Minor}.{sv.Patch}.{sv.PreReleaseTag.Number ?? 0}",
AssemblyVersioningScheme.None => null,
_ => throw new ArgumentException($"Unexpected value ({scheme}).", nameof(scheme))
};
Expand All @@ -19,7 +19,7 @@ public static class AssemblyVersionsGeneratorExtensions
AssemblyFileVersioningScheme.Major => $"{sv.Major}.0.0.0",
AssemblyFileVersioningScheme.MajorMinor => $"{sv.Major}.{sv.Minor}.0.0",
AssemblyFileVersioningScheme.MajorMinorPatch => $"{sv.Major}.{sv.Minor}.{sv.Patch}.0",
AssemblyFileVersioningScheme.MajorMinorPatchTag => $"{sv.Major}.{sv.Minor}.{sv.Patch}.{sv.PreReleaseTag?.Number ?? 0}",
AssemblyFileVersioningScheme.MajorMinorPatchTag => $"{sv.Major}.{sv.Minor}.{sv.Patch}.{sv.PreReleaseTag.Number ?? 0}",
AssemblyFileVersioningScheme.None => null,
_ => throw new ArgumentException($"Unexpected value ({scheme}).", nameof(scheme))
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public MainlineVersionCalculator(ILog log, IRepositoryStore repositoryStore, Laz

public SemanticVersion FindMainlineModeVersion(BaseVersion baseVersion)
{
if (baseVersion.SemanticVersion.PreReleaseTag?.HasTag() == true)
if (baseVersion.SemanticVersion.PreReleaseTag.HasTag() == true)
{
throw new NotSupportedException("Mainline development mode doesn't yet support pre-release tags on main");
}
Expand Down
10 changes: 5 additions & 5 deletions src/GitVersion.Core/VersionCalculation/NextVersionCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public virtual NextVersion FindVersion()
{
var baseVersionBuildMetaData = this.mainlineVersionCalculator.CreateVersionBuildMetaData(baseVersion.BaseVersionSource);

if (baseVersionBuildMetaData.Sha != nextVersion.IncrementedVersion.BuildMetaData?.Sha)
if (baseVersionBuildMetaData.Sha != nextVersion.IncrementedVersion.BuildMetaData.Sha)
{
semver = nextVersion.IncrementedVersion;
}
Expand All @@ -73,8 +73,8 @@ public virtual NextVersion FindVersion()

var lastPrefixedSemver = this.repositoryStore
.GetVersionTagsOnBranch(Context.CurrentBranch, Context.Configuration.LabelPrefix)
.Where(v => MajorMinorPatchEqual(v, semver) && v.PreReleaseTag?.HasTag() == true)
.FirstOrDefault(v => v.PreReleaseTag?.Name?.IsEquivalentTo(preReleaseTagName) == true);
.Where(v => MajorMinorPatchEqual(v, semver) && v.PreReleaseTag.HasTag() == true)
.FirstOrDefault(v => v.PreReleaseTag.Name?.IsEquivalentTo(preReleaseTagName) == true);

if (lastPrefixedSemver != null)
{
Expand All @@ -95,7 +95,7 @@ public virtual NextVersion FindVersion()
{
long? number;

if (semver.PreReleaseTag?.Name == preReleaseTagName)
if (semver.PreReleaseTag.Name == preReleaseTagName)
{
number = semver.PreReleaseTag.Number + 1;
}
Expand Down Expand Up @@ -227,7 +227,7 @@ private IEnumerable<NextVersion> GetNextVersions(IBranch branch, GitVersionConfi

if (configuration.VersioningMode == VersioningMode.Mainline)
{
if (!(incrementedVersion.PreReleaseTag?.HasTag() != true))
if (!(incrementedVersion.PreReleaseTag.HasTag() != true))
{
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public class SemanticVersion : IFormattable, IComparable<SemanticVersion>, IEqua
public long Major;
public long Minor;
public long Patch;
public SemanticVersionPreReleaseTag? PreReleaseTag;
public SemanticVersionBuildMetaData? BuildMetaData;
public SemanticVersionPreReleaseTag PreReleaseTag;
public SemanticVersionBuildMetaData BuildMetaData;

public bool HasPreReleaseTagWithLabel => PreReleaseTag?.HasTag() == true;
public bool HasPreReleaseTagWithLabel => PreReleaseTag.HasTag() == true;

public SemanticVersion(long major = 0, long minor = 0, long patch = 0)
{
Expand Down Expand Up @@ -76,8 +76,8 @@ public override int GetHashCode()
var hashCode = this.Major.GetHashCode();
hashCode = (hashCode * 397) ^ this.Minor.GetHashCode();
hashCode = (hashCode * 397) ^ this.Patch.GetHashCode();
hashCode = (hashCode * 397) ^ (this.PreReleaseTag != null ? this.PreReleaseTag.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (this.BuildMetaData != null ? this.BuildMetaData.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ this.PreReleaseTag.GetHashCode();
hashCode = (hashCode * 397) ^ this.BuildMetaData.GetHashCode();
return hashCode;
}
}
Expand Down Expand Up @@ -278,18 +278,18 @@ public string ToString(string? format, IFormatProvider? formatProvider)
case "j":
return $"{this.Major}.{this.Minor}.{this.Patch}";
case "s":
return this.PreReleaseTag?.HasTag() == true ? $"{ToString("j")}-{this.PreReleaseTag}" : ToString("j");
return this.PreReleaseTag.HasTag() == true ? $"{ToString("j")}-{this.PreReleaseTag}" : ToString("j");
case "t":
return this.PreReleaseTag?.HasTag() == true ? $"{ToString("j")}-{this.PreReleaseTag.ToString("t")}" : ToString("j");
return this.PreReleaseTag.HasTag() == true ? $"{ToString("j")}-{this.PreReleaseTag.ToString("t")}" : ToString("j");
case "f":
{
var buildMetadata = this.BuildMetaData?.ToString();
var buildMetadata = this.BuildMetaData.ToString();

return !buildMetadata.IsNullOrEmpty() ? $"{ToString("s")}+{buildMetadata}" : ToString("s");
}
case "i":
{
var buildMetadata = this.BuildMetaData?.ToString("f");
var buildMetadata = this.BuildMetaData.ToString("f");

return !buildMetadata.IsNullOrEmpty() ? $"{ToString("s")}+{buildMetadata}" : ToString("s");
}
Expand All @@ -301,7 +301,7 @@ public string ToString(string? format, IFormatProvider? formatProvider)
public SemanticVersion IncrementVersion(VersionField incrementStrategy)
{
var incremented = new SemanticVersion(this);
if (incremented.PreReleaseTag?.HasTag() != true)
if (incremented.PreReleaseTag.HasTag() != true)
{
switch (incrementStrategy)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,19 @@ public SemanticVersionFormatValues(SemanticVersion semver, EffectiveConfiguratio

public string? PreReleaseTag => this.semver.PreReleaseTag;

public string? PreReleaseTagWithDash => this.semver.PreReleaseTag?.HasTag() == true ? "-" + this.semver.PreReleaseTag : null;
public string? PreReleaseTagWithDash => this.semver.PreReleaseTag.HasTag() == true ? "-" + this.semver.PreReleaseTag : null;

public string? PreReleaseLabel => this.semver.PreReleaseTag?.HasTag() == true ? this.semver.PreReleaseTag.Name : null;
public string? PreReleaseLabel => this.semver.PreReleaseTag.HasTag() == true ? this.semver.PreReleaseTag.Name : null;

public string? PreReleaseLabelWithDash => this.semver.PreReleaseTag?.HasTag() == true ? "-" + this.semver.PreReleaseTag.Name : null;
public string? PreReleaseLabelWithDash => this.semver.PreReleaseTag.HasTag() == true ? "-" + this.semver.PreReleaseTag.Name : null;

public string? PreReleaseNumber => this.semver.PreReleaseTag?.HasTag() == true ? this.semver.PreReleaseTag.Number.ToString() : null;
public string? PreReleaseNumber => this.semver.PreReleaseTag.HasTag() == true ? this.semver.PreReleaseTag.Number.ToString() : null;

public string WeightedPreReleaseNumber => GetWeightedPreReleaseNumber();

public string? BuildMetaData => this.semver.BuildMetaData;

public string? FullBuildMetaData => this.semver.BuildMetaData?.ToString("f");
public string? FullBuildMetaData => this.semver.BuildMetaData.ToString("f");

public string MajorMinorPatch => $"{this.semver.Major}.{this.semver.Minor}.{this.semver.Patch}";

Expand All @@ -47,28 +47,28 @@ public SemanticVersionFormatValues(SemanticVersion semver, EffectiveConfiguratio

public string FullSemVer => this.semver.ToString("f");

public string? BranchName => this.semver.BuildMetaData?.Branch;
public string? BranchName => this.semver.BuildMetaData.Branch;

public string? EscapedBranchName => this.semver.BuildMetaData?.Branch?.RegexReplace("[^a-zA-Z0-9-]", "-");
public string? EscapedBranchName => this.semver.BuildMetaData.Branch?.RegexReplace("[^a-zA-Z0-9-]", "-");

public string? Sha => this.semver.BuildMetaData?.Sha;
public string? Sha => this.semver.BuildMetaData.Sha;

public string? ShortSha => this.semver.BuildMetaData?.ShortSha;
public string? ShortSha => this.semver.BuildMetaData.ShortSha;

public string? CommitDate => this.semver.BuildMetaData?.CommitDate?.UtcDateTime.ToString(this.configuration.CommitDateFormat, CultureInfo.InvariantCulture);
public string? CommitDate => this.semver.BuildMetaData.CommitDate?.UtcDateTime.ToString(this.configuration.CommitDateFormat, CultureInfo.InvariantCulture);

public string InformationalVersion => this.semver.ToString("i");

public string? VersionSourceSha => this.semver.BuildMetaData?.VersionSourceSha;
public string? VersionSourceSha => this.semver.BuildMetaData.VersionSourceSha;

public string? CommitsSinceVersionSource => this.semver.BuildMetaData?.CommitsSinceVersionSource?.ToString(CultureInfo.InvariantCulture);
public string? CommitsSinceVersionSource => this.semver.BuildMetaData.CommitsSinceVersionSource?.ToString(CultureInfo.InvariantCulture);

public string? UncommittedChanges => this.semver.BuildMetaData?.UncommittedChanges.ToString(CultureInfo.InvariantCulture);
public string? UncommittedChanges => this.semver.BuildMetaData.UncommittedChanges.ToString(CultureInfo.InvariantCulture);

private string GetWeightedPreReleaseNumber()
{
var weightedPreReleaseNumber =
this.semver.PreReleaseTag?.HasTag() == true ? (this.semver.PreReleaseTag.Number + this.configuration.PreReleaseWeight).ToString() : null;
this.semver.PreReleaseTag.HasTag() == true ? (this.semver.PreReleaseTag.Number + this.configuration.PreReleaseWeight).ToString() : null;

return weightedPreReleaseNumber.IsNullOrEmpty()
? $"{this.configuration.LabelPreReleaseWeight}"
Expand Down
41 changes: 19 additions & 22 deletions src/GitVersion.Core/VersionCalculation/VariableProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ public VersionVariables GetVariablesFor(SemanticVersion semanticVersion, Effecti
{
semanticVersion = new SemanticVersion(semanticVersion);
// Continuous Deployment always requires a pre-release tag unless the commit is tagged
if (semanticVersion.PreReleaseTag != null && semanticVersion.PreReleaseTag.HasTag() != true)
if (semanticVersion.PreReleaseTag.HasTag() != true)
{
semanticVersion.PreReleaseTag.Name = configuration.GetBranchSpecificTag(this.log, semanticVersion.BuildMetaData?.Branch, null);
semanticVersion.PreReleaseTag.Name = configuration.GetBranchSpecificTag(this.log, semanticVersion.BuildMetaData.Branch, null);
if (semanticVersion.PreReleaseTag.Name.IsNullOrEmpty())
{
// TODO: Why do we manipulating the semantic version here in the VariableProvider? The method name is GET not MANIPULATE.
Expand All @@ -38,14 +38,14 @@ public VersionVariables GetVariablesFor(SemanticVersion semanticVersion, Effecti
}

// Evaluate tag number pattern and append to prerelease tag, preserving build metadata
var appendTagNumberPattern = !configuration.LabelNumberPattern.IsNullOrEmpty() && semanticVersion.PreReleaseTag?.HasTag() == true;
var appendTagNumberPattern = !configuration.LabelNumberPattern.IsNullOrEmpty() && semanticVersion.PreReleaseTag.HasTag() == true;
if (appendTagNumberPattern)
{
if (semanticVersion.BuildMetaData?.Branch != null && configuration.LabelNumberPattern != null)
if (semanticVersion.BuildMetaData.Branch != null && configuration.LabelNumberPattern != null)
{
var match = Regex.Match(semanticVersion.BuildMetaData.Branch, configuration.LabelNumberPattern);
var numberGroup = match.Groups["number"];
if (numberGroup.Success && semanticVersion.PreReleaseTag != null)
if (numberGroup.Success)
{
// TODO: Why do we manipulating the semantic version here in the VariableProvider? The method name is GET not MANIPULATE.
// What is about the separation of concern and single-responsibility principle?
Expand Down Expand Up @@ -101,29 +101,26 @@ public VersionVariables GetVariablesFor(SemanticVersion semanticVersion, Effecti

private static void PromoteNumberOfCommitsToTagNumber(SemanticVersion semanticVersion)
{
if (semanticVersion.PreReleaseTag != null && semanticVersion.BuildMetaData != null)
// For continuous deployment the commits since tag gets promoted to the pre-release number
if (!semanticVersion.BuildMetaData.CommitsSinceTag.HasValue)
{
// For continuous deployment the commits since tag gets promoted to the pre-release number
if (!semanticVersion.BuildMetaData.CommitsSinceTag.HasValue)
semanticVersion.PreReleaseTag.Number = null;
semanticVersion.BuildMetaData.CommitsSinceVersionSource = 0;
}
else
{
// Number of commits since last tag should be added to PreRelease number if given. Remember to deduct automatic version bump.
if (semanticVersion.PreReleaseTag.Number.HasValue)
{
semanticVersion.PreReleaseTag.Number = null;
semanticVersion.BuildMetaData.CommitsSinceVersionSource = 0;
semanticVersion.PreReleaseTag.Number += semanticVersion.BuildMetaData.CommitsSinceTag - 1;
}
else
{
// Number of commits since last tag should be added to PreRelease number if given. Remember to deduct automatic version bump.
if (semanticVersion.PreReleaseTag.Number.HasValue)
{
semanticVersion.PreReleaseTag.Number += semanticVersion.BuildMetaData.CommitsSinceTag - 1;
}
else
{
semanticVersion.PreReleaseTag.Number = semanticVersion.BuildMetaData.CommitsSinceTag;
semanticVersion.PreReleaseTag.PromotedFromCommits = true;
}
semanticVersion.BuildMetaData.CommitsSinceVersionSource = semanticVersion.BuildMetaData.CommitsSinceTag.Value;
semanticVersion.BuildMetaData.CommitsSinceTag = null; // why is this set to null ?
semanticVersion.PreReleaseTag.Number = semanticVersion.BuildMetaData.CommitsSinceTag;
semanticVersion.PreReleaseTag.PromotedFromCommits = true;
}
semanticVersion.BuildMetaData.CommitsSinceVersionSource = semanticVersion.BuildMetaData.CommitsSinceTag.Value;
semanticVersion.BuildMetaData.CommitsSinceTag = null; // why is this set to null ?
}
}

Expand Down

0 comments on commit 9b19750

Please sign in to comment.