internal BasicCommitInfo(ITagCommit thisCommit, ITagCommit best, BasicCommitInfo parent) { UnfilteredThisCommit = thisCommit; if (best != null) { BestCommit = best; if (parent != null) { var maxBelow = parent.MaxCommit; if (best.ThisTag > maxBelow.ThisTag) { BelowDepth = 0; } else { BelowDepth = parent.BelowDepth + 1; BestCommitBelow = maxBelow; } } } else { Debug.Assert(parent != null, "Not both can be null."); BelowDepth = parent.BelowDepth + 1; BestCommitBelow = parent.MaxCommit; } Debug.Assert(MaxCommit != null); }
RepositoryInfo( Repository r, RepositoryInfoOptions options, string gitSolutionDir ) : this() { if( options == null ) options = new RepositoryInfoOptions(); Options = options; if( r == null ) RepositoryError = "No Git repository."; else { Debug.Assert( gitSolutionDir != null && gitSolutionDir[gitSolutionDir.Length-1] == Path.DirectorySeparatorChar ); GitSolutionDirectory = gitSolutionDir; Commit commit; CIBranchVersionMode ciVersionMode; string ciBuildName; RepositoryError = TryFindCommit( options, r, out commit, out ciVersionMode, out ciBuildName ); Debug.Assert( (ciVersionMode != CIBranchVersionMode.None) == (ciBuildName != null) ); if( commit != null ) { CommitSha = commit.Sha; CommitDateUtc = commit.Author.When.ToUniversalTime().DateTime; IsDirtyExplanations = ComputeIsDirty( r, commit, options ); if( !IsDirty || options.IgnoreDirtyWorkingFolder ) { StringBuilder errors = new StringBuilder(); TagCollector collector = new TagCollector( errors, r, options.StartingVersionForCSemVer, c => c.Sha == CommitSha ? ReleaseTagParsingMode.RaiseErrorOnMalformedTag : ReleaseTagParsingMode.IgnoreMalformedTag, options.OverriddenTags ); if( errors.Length == 0 ) { CommitVersionInfo info = collector.GetVersionInfo( commit ); ExistingVersions = collector.ExistingVersions.TagCommits; PossibleVersions = info.PossibleVersions; PossibleVersionsStrict = info.PossibleVersionsStrict; PreviousRelease = info.PreviousCommit; PreviousMaxRelease = info.PreviousMaxCommit; if( info.ThisCommit != null ) { bool strictMode = options.PossibleVersionsMode.IsStrict(); var possibleSet = strictMode ? info.PossibleVersionsStrict : info.PossibleVersions; if( possibleSet.Contains( info.ThisCommit.ThisTag ) ) { ValidReleaseTag = info.ThisCommit.ThisTag; } else { ReleaseTagIsNotPossibleError = true; errors.Append( "Release tag '" ) .Append( info.ThisCommit.ThisTag.OriginalTagText ) .Append( "' is not valid here. Valid tags are: " ) .Append( string.Join( ", ", possibleSet ) ) .AppendLine(); if( strictMode && info.PossibleVersions.Contains( info.ThisCommit.ThisTag )) { if( options.PossibleVersionsMode == PossibleVersionsMode.Default ) { errors.Append( "Consider setting <PossibleVersionsMode>AllSuccessors</PossibleVersionsMode> in RepositoryInfo.xml to allow this version." ); } else { errors.Append( "Current <PossibleVersionsMode>Restricted</PossibleVersionsMode> in RepositoryInfo.xml forbids this version." ); } } } } else { if( ciBuildName != null ) { CIRelease = CIReleaseInfo.Create( commit, ciVersionMode, ciBuildName, errors, info ); } } } if( errors.Length > 0 ) SetError( errors, out ReleaseTagErrorLines, out ReleaseTagErrorText ); } } } }
/// <summary> /// Initializes a new <see cref="RepositoryInfo"/> on a <see cref="Repository"/>. /// </summary> /// <param name="r">The rpository (can be invalid and even null).</param> /// <param name="options">Optional options.</param> public RepositoryInfo(Repository r, RepositoryInfoOptions options = null) { Options = options ?? new RepositoryInfoOptions(); CommitDateUtc = InformationalVersion.ZeroCommitDate; if (r == null) { RepositoryError = "No Git repository."; } else { Commit commit; CIBranchVersionMode ciVersionMode; string ciBuildName; RepositoryError = TryFindCommit(options, r, out commit, out ciVersionMode, out ciBuildName); Debug.Assert((ciVersionMode != CIBranchVersionMode.None) == (ciBuildName != null)); if (commit != null) { CommitSha = commit.Sha; CommitDateUtc = commit.Author.When.UtcDateTime; IsDirtyExplanations = ComputeIsDirty(r, commit, options); if (!IsDirty || options.IgnoreDirtyWorkingFolder) { StringBuilder errors = new StringBuilder(); TagCollector collector = new TagCollector(errors, r, options.StartingVersionForCSemVer, options.OverriddenTags, options.SingleMajor); if (errors.Length == 0) { ExistingVersions = collector.ExistingVersions.TagCommits; var info = collector.GetCommitInfo(commit); Debug.Assert(info != null); CommitInfo = info; var rawPossible = info.PossibleVersions; IEnumerable <CSVersion> possibles = rawPossible; if (options.OnlyPatch) { possibles = possibles.Where(v => v.IsPatch); } if (options.SingleMajor.HasValue) { possibles = possibles.Where(v => v.Major == options.SingleMajor.Value); } PossibleVersions = possibles != rawPossible?possibles.ToList() : rawPossible; var rawNextPossible = info.NextPossibleVersions; IEnumerable <CSVersion> nextPossibles = rawNextPossible; if (options.OnlyPatch) { nextPossibles = nextPossibles.Where(v => v.IsPatch); } if (options.SingleMajor.HasValue) { nextPossibles = nextPossibles.Where(v => v.Major == options.SingleMajor.Value); } NextPossibleVersions = nextPossibles != rawNextPossible?nextPossibles.ToList() : rawNextPossible; var thisCommit = info.BasicInfo?.UnfilteredThisCommit; if (info.BasicInfo?.BestCommit?.ThisTag > thisCommit?.ThisTag) { BetterExistingVersion = info.BasicInfo.BestCommit; } if (thisCommit != null) { if (PossibleVersions.Contains(thisCommit.ThisTag)) { ValidReleaseTag = thisCommit.ThisTag; } else { ReleaseTagIsNotPossibleError = true; errors.Append("Release tag '") .Append(thisCommit.ThisTag.ParsedText) .AppendLine("' is not valid here. "); errors.Append("Valid tags are: ") .Append(string.Join(", ", PossibleVersions)) .AppendLine(); if (PossibleVersions != rawPossible && rawPossible.Contains(thisCommit.ThisTag)) { errors.AppendLine("Note: this version is invalid because of <SingleMajor> or <OnlyPatch> setting in RepositoryInfo.xml."); } } } else { // There is no release tag on the commit point. if (ciBuildName != null) { CIRelease = CIReleaseInfo.Create(commit, ciVersionMode, ciBuildName, errors, info.BasicInfo); } } } if (errors.Length > 0) { ReleaseTagError = errors.ToString(); } } // Conclusion: if (CIRelease != null) { //ContentOrFinalNuGetVersion = FinalNuGetVersion = CIRelease.BuildVersionNuGet; FinalSemVersion = CIRelease.BuildVersion; } else if (ValidReleaseTag != null) { FinalNuGetVersion = SVersion.Parse(ValidReleaseTag.ToString(CSVersionFormat.NuGetPackage), false); FinalSemVersion = ValidReleaseTag; } } } // Handles FinalInformationalVersion and SVersion.ZeroVersion for versions if needed. if (FinalSemVersion == null) { FinalSemVersion = SVersion.ZeroVersion; FinalNuGetVersion = SVersion.ZeroVersion; FinalInformationalVersion = InformationalVersion.ZeroInformationalVersion; } else { FinalInformationalVersion = InformationalVersion.BuildInformationalVersion(FinalSemVersion.NormalizedText, FinalNuGetVersion.NormalizedText, CommitSha, CommitDateUtc); } }
RepositoryInfo(Repository r, RepositoryInfoOptions options, string gitSolutionDir) : this() { if (options == null) { options = new RepositoryInfoOptions(); } Options = options; if (r == null) { RepositoryError = "No Git repository."; } else { Debug.Assert(gitSolutionDir != null && gitSolutionDir[gitSolutionDir.Length - 1] == Path.DirectorySeparatorChar); GitSolutionDirectory = gitSolutionDir; Commit commit; CIBranchVersionMode ciVersionMode; string ciBuildName; RepositoryError = TryFindCommit(options, r, out commit, out ciVersionMode, out ciBuildName); Debug.Assert((ciVersionMode != CIBranchVersionMode.None) == (ciBuildName != null)); if (commit != null) { CommitSha = commit.Sha; CommitDateUtc = commit.Author.When.ToUniversalTime().DateTime; IsDirtyExplanations = ComputeIsDirty(r, commit, options); if (!IsDirty || options.IgnoreDirtyWorkingFolder) { StringBuilder errors = new StringBuilder(); TagCollector collector = new TagCollector(errors, r, options.StartingVersionForCSemVer, c => c.Sha == CommitSha ? ReleaseTagParsingMode.RaiseErrorOnMalformedTag : ReleaseTagParsingMode.IgnoreMalformedTag, options.OverriddenTags); if (errors.Length == 0) { CommitVersionInfo info = collector.GetVersionInfo(commit); ExistingVersions = collector.ExistingVersions.TagCommits; PossibleVersions = info.PossibleVersions; PossibleVersionsStrict = info.PossibleVersionsStrict; PreviousRelease = info.PreviousCommit; PreviousMaxRelease = info.PreviousMaxCommit; if (info.ThisCommit != null) { bool strictMode = options.PossibleVersionsMode.IsStrict(); var possibleSet = strictMode ? info.PossibleVersionsStrict : info.PossibleVersions; if (possibleSet.Contains(info.ThisCommit.ThisTag)) { ValidReleaseTag = info.ThisCommit.ThisTag; } else { ReleaseTagIsNotPossibleError = true; errors.Append("Release tag '") .Append(info.ThisCommit.ThisTag.OriginalTagText) .Append("' is not valid here. Valid tags are: ") .Append(string.Join(", ", possibleSet)) .AppendLine(); if (strictMode && info.PossibleVersions.Contains(info.ThisCommit.ThisTag)) { if (options.PossibleVersionsMode == PossibleVersionsMode.Default) { errors.Append("Consider setting <PossibleVersionsMode>AllSuccessors</PossibleVersionsMode> in RepositoryInfo.xml to allow this version."); } else { errors.Append("Current <PossibleVersionsMode>Restricted</PossibleVersionsMode> in RepositoryInfo.xml forbids this version."); } } } } else { if (ciBuildName != null) { CIRelease = CIReleaseInfo.Create(commit, ciVersionMode, ciBuildName, errors, info); } } } if (errors.Length > 0) { SetError(errors, out ReleaseTagErrorLines, out ReleaseTagErrorText); } } } } }