/// <summary> /// Gets the version options from HEAD and the working copy (if applicable), /// and tests their equality. /// </summary> /// <param name="repo">The repo to scan for version info.</param> /// <param name="repoRelativeProjectDirectory">The path to the directory of the project whose version is being queried, relative to the repo root.</param> /// <param name="committedVersion">Receives the version options from the HEAD commit.</param> /// <param name="workingCopyVersion">Receives the version options from the working copy, when applicable.</param> /// <returns><c>true</c> if <paramref name="committedVersion"/> and <paramref name="workingCopyVersion"/> are not equal.</returns> private static bool IsVersionFileChangedInWorkingCopy(Repository repo, string repoRelativeProjectDirectory, out VersionOptions committedVersion, out VersionOptions workingCopyVersion) { Commit headCommit = repo.Head.Commits.FirstOrDefault(); committedVersion = VersionFile.GetVersion(headCommit, repoRelativeProjectDirectory); if (!repo.Info.IsBare) { string fullDirectory = Path.Combine(repo.Info.WorkingDirectory, repoRelativeProjectDirectory ?? string.Empty); workingCopyVersion = VersionFile.GetVersion(fullDirectory); return(!EqualityComparer <VersionOptions> .Default.Equals(workingCopyVersion, committedVersion)); } workingCopyVersion = null; return(false); }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="projectDirectory">The path to the directory which may (or its ancestors may) define the version.txt file.</param> /// <returns>The version information read from the file, or <c>null</c> if the file wasn't found.</returns> public static VersionOptions GetVersion(string projectDirectory) { Requires.NotNullOrEmpty(projectDirectory, nameof(projectDirectory)); string searchDirectory = projectDirectory; while (searchDirectory != null) { string parentDirectory = Path.GetDirectoryName(searchDirectory); string versionTxtPath = Path.Combine(searchDirectory, TxtFileName); if (File.Exists(versionTxtPath)) { using (var sr = new StreamReader(File.OpenRead(versionTxtPath))) { var result = TryReadVersionFile(sr, isJsonFile: false); if (result != null) { return(result); } } } string versionJsonPath = Path.Combine(searchDirectory, JsonFileName); if (File.Exists(versionJsonPath)) { string versionJsonContent = File.ReadAllText(versionJsonPath); VersionOptions result = TryReadVersionJsonContent(versionJsonContent); if (result?.Inherit ?? false) { if (parentDirectory != null) { result = GetVersion(parentDirectory); if (result != null) { JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings()); return(result); } } throw new InvalidOperationException($"\"{versionJsonPath}\" inherits from a parent directory version.json file but none exists."); } else if (result != null) { return(result); } } searchDirectory = parentDirectory; } return(null); }
private static bool IsVersionFileChangedInWorkingTree(VersionOptions committedVersion, VersionOptions workingVersion) { if (workingVersion != null) { return(!EqualityComparer <VersionOptions> .Default.Equals(workingVersion, committedVersion)); } // A missing working version is a change only if it was previously commited. return(committedVersion != null); }
/// <summary> /// Writes the version.txt file to a directory within a repo with the specified version information. /// </summary> /// <param name="projectDirectory"> /// The path to the directory in which to write the version.txt file. /// The file's impact will be all descendent projects and directories from this specified directory, /// except where any of those directories have their own version.txt file. /// </param> /// <param name="version">The version information to write to the file.</param> /// <param name="unstableTag">The optional unstable tag to include in the file.</param> /// <returns>The path to the file written.</returns> public static string SetVersion(string projectDirectory, Version version, string unstableTag = null) { return(SetVersion(projectDirectory, VersionOptions.FromVersion(version, unstableTag))); }
private static Version GetIdAsVersion(LibGit2Sharp.Commit headCommit, VersionOptions committedVersion, VersionOptions workingVersion, int versionHeight) { var version = IsVersionFileChangedInWorkingTree(committedVersion, workingVersion) ? workingVersion : committedVersion; return(headCommit.GetIdAsVersionHelper(version, versionHeight)); }
private static int CalculateVersionHeight(string relativeRepoProjectDirectory, LibGit2Sharp.Commit headCommit, VersionOptions committedVersion, VersionOptions workingVersion) { var headCommitVersion = committedVersion?.Version ?? SemVer0; if (IsVersionFileChangedInWorkingTree(committedVersion, workingVersion)) { var workingCopyVersion = workingVersion?.Version?.Version; if (workingCopyVersion == null || !workingCopyVersion.Equals(headCommitVersion)) { // The working copy has changed the major.minor version. // So by definition the version height is 0, since no commit represents it yet. return(0); } } return(headCommit?.GetVersionHeight(relativeRepoProjectDirectory) ?? 0); }
/// <summary> /// Reads the version.txt file and returns the <see cref="Version"/> and prerelease tag from it. /// </summary> /// <param name="commit">The commit to read the version file from.</param> /// <param name="repoRelativeProjectDirectory">The directory to consider when searching for the version.txt file.</param> /// <returns>The version information read from the file.</returns> public static VersionOptions GetVersion(LibGit2Sharp.Commit commit, string repoRelativeProjectDirectory = null) { if (commit == null) { return(null); } string searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory != null) { string parentDirectory = searchDirectory.Length > 0 ? Path.GetDirectoryName(searchDirectory) : null; string candidatePath = Path.Combine(searchDirectory, TxtFileName).Replace('\\', '/'); var versionTxtBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionTxtBlob != null) { var result = TryReadVersionFile(new StreamReader(versionTxtBlob.GetContentStream()), isJsonFile: false); if (result != null) { return(result); } } candidatePath = Path.Combine(searchDirectory, JsonFileName).Replace('\\', '/'); var versionJsonBlob = commit.Tree[candidatePath]?.Target as LibGit2Sharp.Blob; if (versionJsonBlob != null) { string versionJsonContent; using (var sr = new StreamReader(versionJsonBlob.GetContentStream())) { versionJsonContent = sr.ReadToEnd(); } VersionOptions result; try { result = TryReadVersionJsonContent(versionJsonContent); } catch (FormatException ex) { throw new FormatException( $"Failure while reading {JsonFileName} from commit {commit.Sha}. " + "Fix this commit with rebase if this is an error, or review this doc on how to migrate to Nerdbank.GitVersioning: " + "https://github.com/AArnott/Nerdbank.GitVersioning/blob/master/doc/migrating.md", ex); } if (result?.Inherit ?? false) { if (parentDirectory != null) { result = GetVersion(commit, parentDirectory); if (result != null) { JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings()); return(result); } } throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); } else if (result != null) { return(result); } } searchDirectory = parentDirectory; } return(null); }
/// <summary> /// Writes the version.txt file to a directory within a repo with the specified version information. /// </summary> /// <param name="projectDirectory"> /// The path to the directory in which to write the version.txt file. /// The file's impact will be all descendent projects and directories from this specified directory, /// except where any of those directories have their own version.txt file. /// </param> /// <param name="version">The version information to write to the file.</param> /// <param name="unstableTag">The optional unstable tag to include in the file.</param> /// <returns>The path to the file written.</returns> public static string SetVersion(string projectDirectory, Version version, string unstableTag = null) { return(SetVersion(projectDirectory, VersionOptions.FromVersion(version, unstableTag), includeSchemaProperty: false)); }
/// <summary> /// Writes the version.json file to a directory within a repo with the specified version information. /// The $schema property is included. /// </summary> /// <param name="projectDirectory"> /// The path to the directory in which to write the version.json file. /// The file's impact will be all descendent projects and directories from this specified directory, /// except where any of those directories have their own version.json file. /// </param> /// <param name="version">The version information to write to the file.</param> /// <returns>The path to the file written.</returns> public static string SetVersion(string projectDirectory, VersionOptions version) => SetVersion(projectDirectory, version, includeSchemaProperty: true);