From c73a2bd9b7591c72d6ec6cb3861d41900f8e93d1 Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Sun, 7 Sep 2025 20:07:11 -0600 Subject: [PATCH] Fix `nbgv set-version` to write to the best version.json file in scope This required reworking how version.json files are discovered to report back on where certain version.json files were. In particular, we had these requirements that were not previously being met: * We have to know where the nearest version.json file is _that specifies a `version` property_, since that's the file that `nbgv set-version` will be writing to. * We have to get a deserialized `VersionOptions` object that has _not_ been merged with its parent when `inherit: true` is set. This is so that when we rewrite the file, we only serialize the same properties that came from that file rather than 'flattening' the inheritance hierarchy by including properties brought in from the parent. Rather than special case these particular requirements, I updated the version.json search algorithm to allow the caller to specify different combinations of requirements and get locations of potentially multiple files. Fixes #1257 --- .../DisabledGit/DisabledGitVersionFile.cs | 4 +- .../LibGit2/LibGit2GitExtensions.cs | 2 +- .../LibGit2/LibGit2VersionFile.cs | 40 +++-- .../Managed/GitExtensions.cs | 2 +- .../Managed/ManagedVersionFile.cs | 30 ++-- .../NoGit/NoGitVersionFile.cs | 2 +- src/NerdBank.GitVersioning/VersionFile.cs | 157 ++++++++++++++---- .../VersionFileLocations.cs | 18 ++ .../VersionFileRequirements.cs | 29 ++++ src/NerdBank.GitVersioning/VersionOracle.cs | 2 +- src/nbgv/Program.cs | 16 +- .../VersionFileTests.cs | 15 +- 12 files changed, 232 insertions(+), 85 deletions(-) create mode 100644 src/NerdBank.GitVersioning/VersionFileLocations.cs create mode 100644 src/NerdBank.GitVersioning/VersionFileRequirements.cs diff --git a/src/NerdBank.GitVersioning/DisabledGit/DisabledGitVersionFile.cs b/src/NerdBank.GitVersioning/DisabledGit/DisabledGitVersionFile.cs index 33fb50992..8e96a835b 100644 --- a/src/NerdBank.GitVersioning/DisabledGit/DisabledGitVersionFile.cs +++ b/src/NerdBank.GitVersioning/DisabledGit/DisabledGitVersionFile.cs @@ -14,9 +14,9 @@ public DisabledGitVersionFile(GitContext context) protected new DisabledGitContext Context => (DisabledGitContext)base.Context; - protected override VersionOptions? GetVersionCore(out string? actualDirectory) + protected override VersionOptions? GetVersionCore(VersionFileRequirements requirements, out VersionFileLocations locations) { - actualDirectory = null; + locations = default; return null; } } diff --git a/src/NerdBank.GitVersioning/LibGit2/LibGit2GitExtensions.cs b/src/NerdBank.GitVersioning/LibGit2/LibGit2GitExtensions.cs index e4221cd92..afbd7f284 100644 --- a/src/NerdBank.GitVersioning/LibGit2/LibGit2GitExtensions.cs +++ b/src/NerdBank.GitVersioning/LibGit2/LibGit2GitExtensions.cs @@ -594,7 +594,7 @@ internal GitWalkTracker(LibGit2Context context) { try { - options = ((LibGit2VersionFile)this.context.VersionFile).GetVersion(commit, this.context.RepoRelativeProjectDirectory, this.blobVersionCache, out string? actualDirectory); + options = ((LibGit2VersionFile)this.context.VersionFile).GetVersion(commit, this.context.RepoRelativeProjectDirectory, this.blobVersionCache, VersionFileRequirements.Default, out _); } catch (Exception ex) { diff --git a/src/NerdBank.GitVersioning/LibGit2/LibGit2VersionFile.cs b/src/NerdBank.GitVersioning/LibGit2/LibGit2VersionFile.cs index 1c2127339..7f09c9104 100644 --- a/src/NerdBank.GitVersioning/LibGit2/LibGit2VersionFile.cs +++ b/src/NerdBank.GitVersioning/LibGit2/LibGit2VersionFile.cs @@ -32,10 +32,14 @@ internal LibGit2VersionFile(LibGit2Context context) /// The commit to read from. /// The directory to consider when searching for the version.txt file. /// An optional blob cache for storing the raw parse results of a version.txt or version.json file (before any inherit merge operations are applied). - /// Receives the full path to the directory in which the version file was found. + /// + /// /// The version information read from the file. - internal VersionOptions? GetVersion(Commit commit, string repoRelativeProjectDirectory, Dictionary? blobVersionCache, out string? actualDirectory) + internal VersionOptions? GetVersion(Commit commit, string repoRelativeProjectDirectory, Dictionary? blobVersionCache, VersionFileRequirements requirements, out VersionFileLocations locations) { + repoRelativeProjectDirectory = TrimTrailingPathSeparator(repoRelativeProjectDirectory); + locations = default; + string? searchDirectory = repoRelativeProjectDirectory ?? string.Empty; while (searchDirectory is object) { @@ -58,8 +62,8 @@ internal LibGit2VersionFile(LibGit2Context context) if (result is object) { IBelongToARepository commitAsRepoMember = commit; - actualDirectory = Path.Combine(commitAsRepoMember.Repository.Info.WorkingDirectory, searchDirectory); - return result; + this.ApplyLocations(result, Path.Combine(commitAsRepoMember.Repository.Info.WorkingDirectory, searchDirectory), ref locations); + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } } @@ -95,12 +99,19 @@ internal LibGit2VersionFile(LibGit2Context context) } } - if (result?.Inherit ?? false) + this.ApplyLocations(result, Path.Combine(this.Context.WorkingTreePath, searchDirectory), ref locations); + if (VersionOptionsSatisfyRequirements(result, requirements)) + { + return result; + } + + if (result?.Inherit is true) { if (parentDirectory is object) { - result = this.GetVersion(commit, parentDirectory, blobVersionCache, out actualDirectory); - if (result is object) + result = this.GetVersion(commit, parentDirectory, blobVersionCache, requirements, out VersionFileLocations parentLocations); + this.MergeLocations(ref locations, parentLocations); + if (!requirements.HasFlag(VersionFileRequirements.NonMergedResult) && result is not null) { if (versionJsonContent is null) { @@ -115,27 +126,30 @@ internal LibGit2VersionFile(LibGit2Context context) } JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings(repoRelativeBaseDirectory: searchDirectory)); - return result; + result.Inherit = false; } } + else + { + throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); + } - throw new InvalidOperationException($"\"{candidatePath}\" inherits from a parent directory version.json file but none exists."); + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } else if (result is object) { IBelongToARepository commitAsRepoMember = commit; - actualDirectory = Path.Combine(commitAsRepoMember.Repository.Info.WorkingDirectory, searchDirectory); - return result; + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } } searchDirectory = parentDirectory; } - actualDirectory = null; + locations = default; return null; } /// - protected override VersionOptions? GetVersionCore(out string? actualDirectory) => this.GetVersion(this.Context.Commit!, this.Context.RepoRelativeProjectDirectory, null, out actualDirectory); + protected override VersionOptions? GetVersionCore(VersionFileRequirements requirements, out VersionFileLocations locations) => this.GetVersion(this.Context.Commit!, this.Context.RepoRelativeProjectDirectory, null, requirements, out locations); } diff --git a/src/NerdBank.GitVersioning/Managed/GitExtensions.cs b/src/NerdBank.GitVersioning/Managed/GitExtensions.cs index 173ffaf3c..240537261 100644 --- a/src/NerdBank.GitVersioning/Managed/GitExtensions.cs +++ b/src/NerdBank.GitVersioning/Managed/GitExtensions.cs @@ -329,7 +329,7 @@ internal GitWalkTracker(ManagedGitContext context) { try { - options = ((ManagedVersionFile)this.context.VersionFile).GetVersion(commit, this.context.RepoRelativeProjectDirectory, this.blobVersionCache, out string? actualDirectory); + options = ((ManagedVersionFile)this.context.VersionFile).GetVersion(commit, this.context.RepoRelativeProjectDirectory, this.blobVersionCache, VersionFileRequirements.Default, out _); } catch (Exception ex) { diff --git a/src/NerdBank.GitVersioning/Managed/ManagedVersionFile.cs b/src/NerdBank.GitVersioning/Managed/ManagedVersionFile.cs index bf15cfb01..292054bb2 100644 --- a/src/NerdBank.GitVersioning/Managed/ManagedVersionFile.cs +++ b/src/NerdBank.GitVersioning/Managed/ManagedVersionFile.cs @@ -36,16 +36,22 @@ public ManagedVersionFile(GitContext context) protected new ManagedGitContext Context => (ManagedGitContext)base.Context; + protected override bool VersionSearchRootToBranch => true; + /// /// Reads the version.json file and returns the deserialized from it. /// /// The commit to read from. /// The directory to consider when searching for the version.txt file. /// An optional blob cache for storing the raw parse results of a version.txt or version.json file (before any inherit merge operations are applied). - /// Receives the full path to the directory in which the version file was found. + /// + /// /// The version information read from the file. - internal VersionOptions? GetVersion(GitCommit commit, string repoRelativeProjectDirectory, Dictionary? blobVersionCache, out string? actualDirectory) + internal VersionOptions? GetVersion(GitCommit commit, string repoRelativeProjectDirectory, Dictionary? blobVersionCache, VersionFileRequirements requirements, out VersionFileLocations locations) { + repoRelativeProjectDirectory = TrimTrailingPathSeparator(repoRelativeProjectDirectory); + locations = default; + var directories = new Stack(); string? currentDirectory = repoRelativeProjectDirectory; @@ -61,8 +67,6 @@ public ManagedVersionFile(GitContext context) string? parentDirectory = null; VersionOptions? finalResult = null; - actualDirectory = null; - while (tree != GitObjectId.Empty) { GitObjectId versionTxtBlob = this.Context.Repository.GetTreeEntry(tree, TxtFileNameBytes); @@ -81,7 +85,7 @@ public ManagedVersionFile(GitContext context) if (result is object) { finalResult = result; - actualDirectory = Path.Combine(this.Context.WorkingTreePath, searchDirectory); + this.ApplyLocations(result, Path.Combine(this.Context.WorkingTreePath, searchDirectory), ref locations); } } @@ -116,12 +120,13 @@ public ManagedVersionFile(GitContext context) } } - if (result?.Inherit ?? false) + if (result?.Inherit is true) { if (parentDirectory is object) { - result = this.GetVersion(commit, parentDirectory, blobVersionCache, out string? resultingDirectory); - if (result is object) + result = this.GetVersion(commit, parentDirectory, blobVersionCache, requirements, out VersionFileLocations parentLocations); + this.MergeLocations(ref locations, parentLocations); + if (!requirements.HasFlag(VersionFileRequirements.NonMergedResult) && result is not null) { if (versionJsonContent is null) { @@ -136,7 +141,7 @@ public ManagedVersionFile(GitContext context) } JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings(repoRelativeBaseDirectory: searchDirectory)); - finalResult = result; + result.Inherit = false; } else { @@ -153,8 +158,8 @@ public ManagedVersionFile(GitContext context) if (result is object) { - actualDirectory = Path.Combine(this.Context.WorkingTreePath, searchDirectory); finalResult = result; + this.ApplyLocations(result, Path.Combine(this.Context.WorkingTreePath, searchDirectory), ref locations); } } @@ -174,9 +179,10 @@ public ManagedVersionFile(GitContext context) } } - return finalResult; + return VersionOptionsSatisfyRequirements(finalResult, requirements) ? finalResult : null; } /// - protected override VersionOptions? GetVersionCore(out string? actualDirectory) => this.GetVersion(this.Context.Commit!.Value, this.Context.RepoRelativeProjectDirectory, null, out actualDirectory); + protected override VersionOptions? GetVersionCore(VersionFileRequirements requirements, out VersionFileLocations locations) + => this.GetVersion(this.Context.Commit!.Value, this.Context.RepoRelativeProjectDirectory, null, requirements, out locations); } diff --git a/src/NerdBank.GitVersioning/NoGit/NoGitVersionFile.cs b/src/NerdBank.GitVersioning/NoGit/NoGitVersionFile.cs index 98aca3a42..7833b7e45 100644 --- a/src/NerdBank.GitVersioning/NoGit/NoGitVersionFile.cs +++ b/src/NerdBank.GitVersioning/NoGit/NoGitVersionFile.cs @@ -13,5 +13,5 @@ public NoGitVersionFile(GitContext context) } /// - protected override VersionOptions GetVersionCore(out string actualDirectory) => throw Assumes.NotReachable(); + protected override VersionOptions GetVersionCore(VersionFileRequirements requirements, out VersionFileLocations locations) => throw Assumes.NotReachable(); } diff --git a/src/NerdBank.GitVersioning/VersionFile.cs b/src/NerdBank.GitVersioning/VersionFile.cs index 818fd7a1f..92d77d482 100644 --- a/src/NerdBank.GitVersioning/VersionFile.cs +++ b/src/NerdBank.GitVersioning/VersionFile.cs @@ -37,21 +37,28 @@ protected VersionFile(GitContext context) /// protected GitContext Context { get; } + /// + /// Gets a value indicating whether merging paths with and + /// prefer the new locations over the old ones. + /// + protected virtual bool VersionSearchRootToBranch => false; + /// /// Checks whether a version file is defined. /// /// if the version file is found; otherwise . public bool IsVersionDefined() => this.GetVersion() is object; - /// - public VersionOptions? GetWorkingCopyVersion() => this.GetWorkingCopyVersion(out _); + /// + public VersionOptions? GetWorkingCopyVersion(VersionFileRequirements requirements) => this.GetWorkingCopyVersion(requirements, out _); /// /// Reads the version file from the working tree and returns the deserialized from it. /// - /// Set to the actual directory that the version file was found in, which may be or one of its ancestors. + /// + /// /// The version information read from the file, or if the file wasn't found. - public VersionOptions? GetWorkingCopyVersion(out string? actualDirectory) => this.GetWorkingCopyVersion(this.Context.AbsoluteProjectDirectory, out actualDirectory); + public VersionOptions? GetWorkingCopyVersion(VersionFileRequirements requirements, out VersionFileLocations locations) => this.GetWorkingCopyVersion(this.Context.AbsoluteProjectDirectory, requirements, out locations); /// /// The optional unstable tag to include in the file. @@ -107,19 +114,18 @@ public string SetVersion(string projectDirectory, VersionOptions version, bool i return versionJsonPath; } - /// - public VersionOptions? GetVersion() => this.GetVersion(out string? actualDirectory); + /// + public VersionOptions? GetVersion() => this.GetVersion(VersionFileRequirements.Default, out _); /// /// Reads the version file from the selected git commit (or working copy if no commit is selected) and returns the deserialized from it. /// - /// Receives the absolute path to the directory where the version file was found, if any. + /// + /// /// The version information read from the file, or if the file wasn't found. - public VersionOptions? GetVersion(out string? actualDirectory) + public VersionOptions? GetVersion(VersionFileRequirements requirements, out VersionFileLocations locations) { - return this.Context.GitCommitId is null - ? this.GetWorkingCopyVersion(out actualDirectory) - : this.GetVersionCore(out actualDirectory); + return this.Context.GitCommitId is null ? this.GetWorkingCopyVersion(requirements, out locations) : this.GetVersionCore(requirements, out locations); } /// @@ -166,22 +172,108 @@ protected static VersionOptions TryReadVersionFile(TextReader versionTextContent }; } + protected static bool VersionOptionsSatisfyRequirements(VersionOptions? options, VersionFileRequirements requirements) + { + Requires.Argument( + !requirements.HasFlag(VersionFileRequirements.AcceptInheritingFile) || requirements.HasFlag(VersionFileRequirements.NonMergedResult), + nameof(requirements), + "Clients that accept an inheriting file must not want a merged result."); + + if (options is null) + { + return false; + } + + if (options.Version is null && requirements.HasFlag(VersionFileRequirements.VersionSpecified)) + { + return false; + } + + if (options.Inherit && !requirements.HasFlag(VersionFileRequirements.AcceptInheritingFile)) + { + return false; + } + + return true; + } + + protected static string TrimTrailingPathSeparator(string path) + => path.Length > 0 && (path[^1] == Path.DirectorySeparatorChar || path[^1] == Path.AltDirectorySeparatorChar) ? path[..^1] : path; + + protected void MergeLocations(ref VersionFileLocations target, VersionFileLocations input) + { + if (this.VersionSearchRootToBranch && input.VersionSpecifyingVersionDirectory is not null) + { + target.VersionSpecifyingVersionDirectory = input.VersionSpecifyingVersionDirectory; + } + else + { + target.VersionSpecifyingVersionDirectory ??= input.VersionSpecifyingVersionDirectory; + } + + if (this.VersionSearchRootToBranch && input.NonInheritingVersionDirectory is not null) + { + target.NonInheritingVersionDirectory = input.NonInheritingVersionDirectory; + } + else + { + target.NonInheritingVersionDirectory ??= input.NonInheritingVersionDirectory; + } + } + + protected void ApplyLocations(VersionOptions? options, string currentLocation, ref VersionFileLocations locations) + { + if (options is null) + { + return; + } + + if (options.Version is not null) + { + if (this.VersionSearchRootToBranch) + { + locations.VersionSpecifyingVersionDirectory = currentLocation; + } + else + { + locations.VersionSpecifyingVersionDirectory ??= currentLocation; + } + } + + if (!options.Inherit) + { + if (this.VersionSearchRootToBranch) + { + locations.NonInheritingVersionDirectory = currentLocation; + } + else + { + locations.NonInheritingVersionDirectory ??= currentLocation; + } + } + } + /// /// Reads the version file from in the and returns the deserialized from it. /// - /// Receives the absolute path to the directory where the version file was found, if any. + /// + /// /// The version information read from the file, or if the file wasn't found. /// This method is only called if is not null. - protected abstract VersionOptions? GetVersionCore(out string? actualDirectory); + protected abstract VersionOptions? GetVersionCore(VersionFileRequirements requirements, out VersionFileLocations locations); /// /// Reads a version file from the working tree, without any regard to a git repo. /// /// The path to start the search from. - /// Receives the directory where the version file was found. + /// + /// /// The version options, if found. - protected VersionOptions? GetWorkingCopyVersion(string startingDirectory, out string? actualDirectory) + protected VersionOptions? GetWorkingCopyVersion(string startingDirectory, VersionFileRequirements requirements, out VersionFileLocations locations) { + startingDirectory = TrimTrailingPathSeparator(startingDirectory); + locations = default; + string? searchDirectory = startingDirectory; while (searchDirectory is object) { @@ -196,8 +288,8 @@ protected static VersionOptions TryReadVersionFile(TextReader versionTextContent VersionOptions? result = TryReadVersionFile(sr); if (result is object) { - actualDirectory = searchDirectory; - return result; + this.ApplyLocations(result, searchDirectory, ref locations); + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } } @@ -207,38 +299,45 @@ protected static VersionOptions TryReadVersionFile(TextReader versionTextContent string versionJsonContent = File.ReadAllText(versionJsonPath); string? repoRelativeBaseDirectory = this.Context.GetRepoRelativePath(searchDirectory); - VersionOptions? result = - TryReadVersionJsonContent(versionJsonContent, repoRelativeBaseDirectory); - if (result?.Inherit ?? false) + VersionOptions? result = TryReadVersionJsonContent(versionJsonContent, repoRelativeBaseDirectory); + + this.ApplyLocations(result, searchDirectory, ref locations); + if (VersionOptionsSatisfyRequirements(result, requirements)) + { + return result; + } + + if (result?.Inherit is true) { if (parentDirectory is object) { - result = this.GetWorkingCopyVersion(parentDirectory, out _); - if (result is object) + result = this.GetWorkingCopyVersion(parentDirectory, requirements, out VersionFileLocations parentLocations); + this.MergeLocations(ref locations, parentLocations); + if (!requirements.HasFlag(VersionFileRequirements.NonMergedResult) && result is not null) { JsonConvert.PopulateObject( versionJsonContent, result, VersionOptions.GetJsonSettings(repoRelativeBaseDirectory: repoRelativeBaseDirectory)); - actualDirectory = searchDirectory; - return result; + result.Inherit = false; } } + else + { + throw new InvalidOperationException($"\"{searchDirectory}\" inherits from a parent directory version.json file but none exists."); + } - throw new InvalidOperationException( - $"\"{versionJsonPath}\" inherits from a parent directory version.json file but none exists."); + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } else if (result is object) { - actualDirectory = searchDirectory; - return result; + return VersionOptionsSatisfyRequirements(result, requirements) ? result : null; } } searchDirectory = parentDirectory; } - actualDirectory = null; return null; } } diff --git a/src/NerdBank.GitVersioning/VersionFileLocations.cs b/src/NerdBank.GitVersioning/VersionFileLocations.cs new file mode 100644 index 000000000..8b7911b8c --- /dev/null +++ b/src/NerdBank.GitVersioning/VersionFileLocations.cs @@ -0,0 +1,18 @@ +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#nullable enable + +namespace Nerdbank.GitVersioning; + +/// +/// Describes locations of version files found during a search. +/// +public struct VersionFileLocations +{ + /// Gets or sets the absolute path to the directory where the first non-inheriting version file was found, if any. + public string? NonInheritingVersionDirectory { get; set; } + + /// Gets or sets the absolute path to the directory where the first version.json file with an actual version property set was found, if any. + public string? VersionSpecifyingVersionDirectory { get; set; } +} diff --git a/src/NerdBank.GitVersioning/VersionFileRequirements.cs b/src/NerdBank.GitVersioning/VersionFileRequirements.cs new file mode 100644 index 000000000..75fc88c8f --- /dev/null +++ b/src/NerdBank.GitVersioning/VersionFileRequirements.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and Contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Nerdbank.GitVersioning; + +[Flags] +public enum VersionFileRequirements +{ + /// + /// No flags. Default behavior. + /// + Default = 0x0, + + /// + /// We want a version options object initialized with only one version.json file (the one that matches other requirements), + /// rather than the merge the result of all relevant version.json files. + /// + NonMergedResult = 0x1, + + /// + /// We require a version.json file that specifies a version (i.e. has a "version" property). + /// + VersionSpecified = 0x2, + + /// + /// Stop search at the first version.json found, even if it inherits from another. + /// + AcceptInheritingFile = 0x4, +} diff --git a/src/NerdBank.GitVersioning/VersionOracle.cs b/src/NerdBank.GitVersioning/VersionOracle.cs index 64bdfe084..04815d350 100644 --- a/src/NerdBank.GitVersioning/VersionOracle.cs +++ b/src/NerdBank.GitVersioning/VersionOracle.cs @@ -45,7 +45,7 @@ public VersionOracle(GitContext context, ICloudBuild? cloudBuild = null, int? ov // Consider the working version only if the commit being inspected is HEAD. // Otherwise we're looking at historical data and should not consider the state of the working tree at all. - this.WorkingVersion = context.IsHead ? context.VersionFile.GetWorkingCopyVersion() : this.CommittedVersion; + this.WorkingVersion = context.IsHead ? context.VersionFile.GetWorkingCopyVersion(VersionFileRequirements.Default) : this.CommittedVersion; if (overrideVersionHeightOffset.HasValue) { diff --git a/src/nbgv/Program.cs b/src/nbgv/Program.cs index 2414b95d7..d6a143989 100644 --- a/src/nbgv/Program.cs +++ b/src/nbgv/Program.cs @@ -1,18 +1,9 @@ // Copyright (c) .NET Foundation and Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Invocation; -using System.CommandLine.Parsing; using System.Globalization; -using System.IO; -using System.Linq; using System.Reflection; -using System.Text.RegularExpressions; -using System.Threading; -using System.Threading.Tasks; using Microsoft.Build.Construction; using Nerdbank.GitVersioning.Commands; using Nerdbank.GitVersioning.LibGit2; @@ -20,7 +11,6 @@ using NuGet.Common; using NuGet.Configuration; using NuGet.PackageManagement; -using NuGet.Protocol; using NuGet.Protocol.Core.Types; using NuGet.Resolver; using Validation; @@ -692,12 +682,12 @@ private static Task OnSetVersionCommand(string project, string version) string searchPath = GetSpecifiedOrCurrentDirectoryPath(project); using var context = GitContext.Create(searchPath, engine: GitContext.Engine.ReadWrite); - VersionOptions existingOptions = context.VersionFile.GetVersion(out string actualDirectory); + VersionOptions existingOptions = context.VersionFile.GetVersion(VersionFileRequirements.NonMergedResult | VersionFileRequirements.VersionSpecified | VersionFileRequirements.AcceptInheritingFile, out VersionFileLocations locations); string versionJsonPath; - if (existingOptions is not null) + if (existingOptions is not null && locations.VersionSpecifyingVersionDirectory is not null) { existingOptions.Version = semver; - versionJsonPath = context.VersionFile.SetVersion(actualDirectory, existingOptions); + versionJsonPath = context.VersionFile.SetVersion(locations.VersionSpecifyingVersionDirectory, existingOptions); } else if (string.IsNullOrEmpty(project)) { diff --git a/test/Nerdbank.GitVersioning.Tests/VersionFileTests.cs b/test/Nerdbank.GitVersioning.Tests/VersionFileTests.cs index 7106a9fd2..5e644ccf5 100644 --- a/test/Nerdbank.GitVersioning.Tests/VersionFileTests.cs +++ b/test/Nerdbank.GitVersioning.Tests/VersionFileTests.cs @@ -1,13 +1,6 @@ // Copyright (c) .NET Foundation and Contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using LibGit2Sharp; using Nerdbank.GitVersioning; using Newtonsoft.Json; using Xunit; @@ -570,7 +563,6 @@ VersionOptions GetOption(string path) Assert.Equal(level1.Version.Version.Major, level2Options.Version.Version.Major); Assert.Equal(level1.Version.Version.Minor, level2Options.Version.Version.Minor); Assert.Equal(level2.AssemblyVersion.Precision, level2Options.AssemblyVersion.Precision); - Assert.True(level2Options.Inherit); VersionOptions level3Options = GetOption("foo/bar"); Assert.Equal(level1.Version.Version.Major, level3Options.Version.Version.Major); @@ -578,7 +570,6 @@ VersionOptions GetOption(string path) Assert.Equal(level2.AssemblyVersion.Precision, level3Options.AssemblyVersion.Precision); Assert.Equal(level2.AssemblyVersion.Precision, level3Options.AssemblyVersion.Precision); Assert.Equal(level3.VersionHeightOffset, level3Options.VersionHeightOffset); - Assert.True(level3Options.Inherit); VersionOptions level2NoInheritOptions = GetOption("noInherit"); Assert.Equal(level2NoInherit.Version, level2NoInheritOptions.Version); @@ -587,7 +578,6 @@ VersionOptions GetOption(string path) VersionOptions level2InheritButResetVersionOptions = GetOption("inheritWithVersion"); Assert.Equal(level2InheritButResetVersion.Version, level2InheritButResetVersionOptions.Version); - Assert.True(level2InheritButResetVersionOptions.Inherit); if (commitInSourceControl) { @@ -610,8 +600,9 @@ public void GetVersion_ProducesAbsolutePath() { this.InitializeSourceControl(); this.WriteVersionFile(); - Assert.NotNull(this.Context.VersionFile.GetVersion(out string actualDirectory)); - Assert.True(Path.IsPathRooted(actualDirectory)); + Assert.NotNull(this.Context.VersionFile.GetVersion(VersionFileRequirements.Default, out VersionFileLocations locations)); + Assert.True(Path.IsPathRooted(locations.NonInheritingVersionDirectory)); + Assert.True(Path.IsPathRooted(locations.VersionSpecifyingVersionDirectory)); } [Theory]