public CommitVersionInfo GetVersionInfo( Commit c ) { string commitSha = c.Sha; CommitVersionInfo info; if( _versionsCache.TryGetValue( commitSha, out info ) ) { return info; } IFullTagCommit thisCommit = GetCommit( commitSha ); IFullTagCommit contentCommit = thisCommit ?? GetCommit( c.Tree.Sha ); CommitVersionInfo prevCommitParent, prevMaxCommitParent; ReadParentInfo( c, out prevCommitParent, out prevMaxCommitParent ); info = new CommitVersionInfo( this, commitSha, thisCommit, contentCommit, prevCommitParent, prevMaxCommitParent ); _versionsCache.Add( commitSha, info ); return info; }
public CommitVersionInfo GetVersionInfo(Commit c) { string commitSha = c.Sha; CommitVersionInfo info; if (_versionsCache.TryGetValue(commitSha, out info)) { return(info); } IFullTagCommit thisCommit = GetCommit(commitSha); IFullTagCommit contentCommit = thisCommit ?? GetCommit(c.Tree.Sha); CommitVersionInfo prevCommitParent, prevMaxCommitParent; ReadParentInfo(c, out prevCommitParent, out prevMaxCommitParent); info = new CommitVersionInfo(this, commitSha, thisCommit, contentCommit, prevCommitParent, prevMaxCommitParent); _versionsCache.Add(commitSha, info); return(info); }
void ReadParentInfo(Commit c, out CommitVersionInfo prevCommitParent, out CommitVersionInfo prevMaxCommitParent) { Debug.Assert(!_versionsCache.ContainsKey(c.Sha)); prevCommitParent = prevMaxCommitParent = null; foreach (var p in c.Parents) { var pV = GetVersionInfo(p); var prevTag = pV.ThisTag ?? pV.PreviousTag; if (prevTag != null) { if (prevCommitParent == null || (prevCommitParent.ThisTag ?? prevCommitParent.PreviousTag) < prevTag) { prevCommitParent = pV; } } if (prevMaxCommitParent == null) { prevMaxCommitParent = pV; } else { var prevMaxTag = prevMaxCommitParent.MaxTag; var maxTag = pV.MaxTag; if (prevMaxTag == null) { if (maxTag != null || prevMaxCommitParent.PreviousMaxCommitDepth < pV.PreviousMaxCommitDepth) { prevMaxCommitParent = pV; } } else { int cmp = prevMaxTag.CompareTo(maxTag); if (cmp < 0 || (cmp == 0 && prevMaxCommitParent.PreviousMaxCommitDepth < pV.PreviousMaxCommitDepth)) { prevMaxCommitParent = pV; } } } } }
internal CommitVersionInfo( TagCollector tagCollector, string commitSha, IFullTagCommit thisCommit, IFullTagCommit contentCommit, CommitVersionInfo prevCommitParent, CommitVersionInfo prevMaxCommitParent ) { Debug.Assert( thisCommit == null || thisCommit.ThisTag != null ); Debug.Assert( thisCommit == null || contentCommit == thisCommit, "this commit exists => content commit is this commit" ); _tagCollector = tagCollector; _commitSha = commitSha; _thisCommit = thisCommit; _contentCommit = contentCommit; if( prevCommitParent != null ) { _prevCommit = prevCommitParent._thisCommit != null ? prevCommitParent : prevCommitParent._prevCommit; } if( prevMaxCommitParent != null ) { Debug.Assert( prevMaxCommitParent.PreviousMaxTag == null || prevMaxCommitParent._prevMaxCommit != null ); if( prevMaxCommitParent._prevMaxCommit == null || prevMaxCommitParent.BestContentTag > prevMaxCommitParent.PreviousMaxTag ) { Debug.Assert( prevMaxCommitParent.MaxTag == prevMaxCommitParent.BestContentTag ); _prevMaxCommit = prevMaxCommitParent; _maxCommitDepth = 1; } else { Debug.Assert( prevMaxCommitParent.MaxTag == prevMaxCommitParent.PreviousMaxTag ); _prevMaxCommit = prevMaxCommitParent._prevMaxCommit; _maxCommitDepth = prevMaxCommitParent._maxCommitDepth + 1; } Debug.Assert( _prevMaxCommit != null ); } _maxCommit = BestContentTag >= PreviousMaxTag ? (_contentCommit != null ? _contentCommit.BestCommit : null) : (_prevMaxCommit._contentCommit != null ? _prevMaxCommit._contentCommit.BestCommit : null); }
internal CommitVersionInfo( TagCollector tagCollector, string commitSha, IFullTagCommit thisCommit, IFullTagCommit contentCommit, CommitVersionInfo prevCommitParent, CommitVersionInfo prevMaxCommitParent) { Debug.Assert(thisCommit == null || thisCommit.ThisTag != null); Debug.Assert(thisCommit == null || contentCommit == thisCommit, "this commit exists => content commit is this commit"); _tagCollector = tagCollector; _commitSha = commitSha; _thisCommit = thisCommit; _contentCommit = contentCommit; if (prevCommitParent != null) { _prevCommit = prevCommitParent._thisCommit != null ? prevCommitParent : prevCommitParent._prevCommit; } if (prevMaxCommitParent != null) { Debug.Assert(prevMaxCommitParent.PreviousMaxTag == null || prevMaxCommitParent._prevMaxCommit != null); if (prevMaxCommitParent._prevMaxCommit == null || prevMaxCommitParent.BestContentTag > prevMaxCommitParent.PreviousMaxTag) { Debug.Assert(prevMaxCommitParent.MaxTag == prevMaxCommitParent.BestContentTag); _prevMaxCommit = prevMaxCommitParent; _maxCommitDepth = 1; } else { Debug.Assert(prevMaxCommitParent.MaxTag == prevMaxCommitParent.PreviousMaxTag); _prevMaxCommit = prevMaxCommitParent._prevMaxCommit; _maxCommitDepth = prevMaxCommitParent._maxCommitDepth + 1; } Debug.Assert(_prevMaxCommit != null); } _maxCommit = BestContentTag >= PreviousMaxTag ? (_contentCommit != null ? _contentCommit.BestCommit : null) : (_prevMaxCommit._contentCommit != null ? _prevMaxCommit._contentCommit.BestCommit : null); }
internal static CIReleaseInfo Create( Commit commit, CIBranchVersionMode ciVersionMode, string ciVersionName, StringBuilder errors, CommitVersionInfo info ) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if( ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null ) { string suffix = actualBaseTag != null ? '+' + actualBaseTag.ToString() : null; var name = string.Format( "0.0.0--ci-{0}.{1:yyyy-MM-ddTHH-mm-ss-ff}", ciVersionName, commit.Committer.When ); ciBuildVersion = name + suffix; TimeSpan delta200 = commit.Committer.When.ToUniversalTime() - new DateTime( 2015, 1, 1, 0, 0, 0, DateTimeKind.Utc ); Debug.Assert( Math.Log( 1000 * 366 * 24 * 60 * (long)60, 62 ) < 7, "Using Base62: 1000 years in seconds on 7 chars!" ); long second = (long)delta200.TotalSeconds; string b62 = ToBase62( second ); string ver = new string( '0', 7 - b62.Length ) + b62; ciBuildVersionNuGet = string.Format( "0.0.0-C{0}-{1}", ciVersionName, ver ); } else { Debug.Assert( ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null ); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciVersionName, BuildIndex = info.PreviousMaxCommitDepth }; if( !ci.IsValidForNuGetV2 ) { errors.AppendLine( "Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. " ); errors.Append( "Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: " ) .AppendFormat( @"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring( 0, 8 ) ) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString( ReleaseTagFormat.SemVer, ci ); ciBuildVersionNuGet = actualBaseTag.ToString( ReleaseTagFormat.NuGetPackage, ci ); } } Debug.Assert( ciBuildVersion == null || errors.Length == 0 ); return ciBuildVersion != null ? new CIReleaseInfo( ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet ) : null; }
void ReadParentInfo( Commit c, out CommitVersionInfo prevCommitParent, out CommitVersionInfo prevMaxCommitParent ) { Debug.Assert( !_versionsCache.ContainsKey( c.Sha ) ); prevCommitParent = prevMaxCommitParent = null; foreach( var p in c.Parents ) { var pV = GetVersionInfo( p ); var prevTag = pV.ThisTag ?? pV.PreviousTag; if( prevTag != null ) { if( prevCommitParent == null || (prevCommitParent.ThisTag ?? prevCommitParent.PreviousTag) < prevTag ) { prevCommitParent = pV; } } if( prevMaxCommitParent == null ) prevMaxCommitParent = pV; else { var prevMaxTag = prevMaxCommitParent.MaxTag; var maxTag = pV.MaxTag; if( prevMaxTag == null ) { if( maxTag != null || prevMaxCommitParent.PreviousMaxCommitDepth < pV.PreviousMaxCommitDepth ) { prevMaxCommitParent = pV; } } else { int cmp = prevMaxTag.CompareTo( maxTag ); if( cmp < 0 || (cmp == 0 && prevMaxCommitParent.PreviousMaxCommitDepth < pV.PreviousMaxCommitDepth) ) { prevMaxCommitParent = pV; } } } } }
internal static CIReleaseInfo Create( Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, CommitVersionInfo info ) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if( ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null ) { DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime; ciBuildVersion = CreateSemVerZeroTimed( ciBuildName, timeRelease, actualBaseTag?.ToString() ); ciBuildVersionNuGet = CreateNuGetZeroTimed( ciBuildName, timeRelease ); } else { Debug.Assert( ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null ); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciBuildName, BuildIndex = info.PreviousMaxCommitDepth }; if( !ci.IsValidForNuGetV2 ) { errors.AppendLine( "Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. " ); errors.Append( "Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: " ) .AppendFormat( @"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring( 0, 8 ) ) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString( ReleaseTagFormat.SemVer, ci ); ciBuildVersionNuGet = actualBaseTag.ToString( ReleaseTagFormat.NuGetPackage, ci ); } } Debug.Assert( ciBuildVersion == null || errors.Length == 0 ); return ciBuildVersion != null ? new CIReleaseInfo( ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet ) : null; }
internal static CIReleaseInfo Create(Commit commit, CIBranchVersionMode ciVersionMode, string ciBuildName, StringBuilder errors, CommitVersionInfo info) { var actualBaseTag = info.PreviousMaxTag; ReleaseTagVersion ciBaseTag = actualBaseTag ?? ReleaseTagVersion.VeryFirstVersion; string ciBuildVersionNuGet = null, ciBuildVersion = null; // If there is no base release found, we fall back to ZeroTimedBased mode. if (ciVersionMode == CIBranchVersionMode.ZeroTimed || actualBaseTag == null) { DateTime timeRelease = commit.Committer.When.ToUniversalTime().UtcDateTime; ciBuildVersion = CreateSemVerZeroTimed(ciBuildName, timeRelease, actualBaseTag?.ToString()); ciBuildVersionNuGet = CreateNuGetZeroTimed(ciBuildName, timeRelease); } else { Debug.Assert(ciVersionMode == CIBranchVersionMode.LastReleaseBased && actualBaseTag != null); CIBuildDescriptor ci = new CIBuildDescriptor { BranchName = ciBuildName, BuildIndex = info.PreviousMaxCommitDepth }; if (!ci.IsValidForNuGetV2) { errors.AppendLine("Due to NuGet V2 limitation, the branch name must not be longer than 8 characters. "); errors.Append("Adds a VersionName attribute to the branch element in RepositoryInfo.xml with a shorter name: ") .AppendFormat(@"<Branch Name=""{0}"" VersionName=""{1}"" ... />.", ci.BranchName, ci.BranchName.Substring(0, 8)) .AppendLine(); } else { ciBuildVersion = actualBaseTag.ToString(ReleaseTagFormat.SemVer, ci); ciBuildVersionNuGet = actualBaseTag.ToString(ReleaseTagFormat.NuGetPackage, ci); } } Debug.Assert(ciBuildVersion == null || errors.Length == 0); return(ciBuildVersion != null ? new CIReleaseInfo(ciBaseTag, info.PreviousMaxCommitDepth, ciBuildVersion, ciBuildVersionNuGet) : 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); } } } } }