Beispiel #1
0
        /// <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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
 /// <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)));
 }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        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);
        }
Beispiel #7
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);
        }
Beispiel #8
0
 /// <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));
 }
Beispiel #9
0
 /// <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);