Skip to content

Commit

Permalink
Merge pull request #191 from AArnott/fix181
Browse files Browse the repository at this point in the history
Add dotnet tool: nbgv
  • Loading branch information
AArnott authored Jun 25, 2018
2 parents e0ccd4c + 9a409f0 commit 63e0ff3
Show file tree
Hide file tree
Showing 15 changed files with 704 additions and 72 deletions.
2 changes: 2 additions & 0 deletions doc/dotnet-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

The dotnet CLI works very much like [full MSBuild](msbuild.md). Just use `dotnet build` instead of `msbuild.exe`.

Check out our [nbgv .NET Core CLI tool](nbgv-cli.md) to install Nerdbank.GitVersioning and maintain your repos/projects more easily.

[DNX never supported extensible versioning systems](https://github.com/aspnet/dnx/issues/3178). But DNX is dead now, so you probably don't care.
49 changes: 49 additions & 0 deletions doc/nbgv-cli.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Using the nbgv .NET Core CLI tool

Perform a one-time install of the `nbgv` tool using the following dotnet CLI command:

```ps1
dotnet tool install -g nbgv
```

You may then use the `nbgv` tool to install Nerdbank.GitVersioning into your repos, as well as query and update version information for your repos and projects.

Install Nerdbank.GitVersioning into your repo using this command from within your repo:

```ps1
nbgv install
```

This will create your initial `version.json` file.
It will also add/modify your `Directory.Build.props` file in the root of your repo to add the `PackageReference` to the latest `Nerdbank.GitVersioning` package available on nuget.org.

## CI Builds

If scripting for running in a CI build where global impact from installing a tool is undesirable, you can localize the tool installation:

```ps1
dotnet tool install --tool-path . nbgv
```

At this point you can launch the tool using `.\nbgv` in your build script.

## Learn more

There are several more sub-commands and switches to each to help you build and maintain your projects, find a commit that built a particular version later on, create tags, etc.

Use the `--help` switch on the `nbgv` command or one of its sub-commands to learn about the sub-commands available and how to use them. For example, this is the basic usage help text:

```cmd
nbgv --help
usage: nbgv <command> [<args>]
install Prepares a project to have version stamps applied
using Nerdbank.GitVersioning.
get-version Gets the version information for a project.
set-version Updates the version stamp that is applied to a
project.
tag Creates a git tag to mark a version.
get-commits Gets the commit(s) that match a given version.
cloud Communicates with the ambient cloud build to set the
build number and/or other cloud build variables.
```
8 changes: 4 additions & 4 deletions doc/nuget-acquisition.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Nerdbank.GitVersioning installation via NuGet
# Nerdbank.GitVersioning installation via NuGet

Install the Nerdbank.GitVersioning package using the Visual Studio
NuGet Package Manager GUI, or the NuGet Package Manager Console:
NuGet Package Manager GUI, or the NuGet Package Manager Console:

```
Install-Package Nerdbank.GitVersioning
Expand Down Expand Up @@ -57,7 +57,7 @@ Note: After first installing the package, you need to commit the version file so
it will be picked up during the build's version generation. If you build prior to committing,
the version number produced will be 0.0.x.

# Next steps
# Next steps

You must also create [a version.json file](versionJson.md) in your repo.
You must also create [a version.json file](versionJson.md) in your repo.
Learn more about [how .NET projects are stamped with version information](dotnet.md).
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ What sets this package apart from other git-based versioning projects is:

You can install Nerdbank.GitVersioning into your projects via NuGet or NPM.

* Use the [nbgv .NET Core CLI tool](doc/nbgv-cli.md) (recommended)
* [NuGet installation instructions](doc/nuget-acquisition.md)
* [NPM installation instructions](doc/npm-acquisition.md)

Expand Down
10 changes: 10 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,15 @@
<OutputPath>$(MSBuildThisFileDirectory)..\bin\$(MSBuildProjectName)\$(Configuration)\</OutputPath>
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>$(MSBuildThisFileDirectory)strongname.snk</AssemblyOriginatorKeyFile>

<authors>Andrew Arnott</authors>
<owners>aarnott</owners>
<PackageTags>git commit versioning version assemblyinfo</PackageTags>
</PropertyGroup>

<Target Name="SetNuSpecProperties" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion">
<PropertyGroup>
<PackageLicenseUrl>https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/$(GitCommitIdShort)/LICENSE.txt</PackageLicenseUrl>
</PropertyGroup>
</Target>
</Project>
57 changes: 57 additions & 0 deletions src/NerdBank.GitVersioning/GitExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,23 @@ public static string FindLibGit2NativeBinaries(string basePath)
#endif
}

/// <summary>
/// Opens a <see cref="Repository"/> found at or above a specified path.
/// </summary>
/// <param name="pathUnderGitRepo">The path at or beneath the git repo root.</param>
/// <returns>The <see cref="Repository"/> found for the specified path, or <c>null</c> if no git repo is found.</returns>
public static Repository OpenGitRepo(string pathUnderGitRepo)
{
Requires.NotNullOrEmpty(pathUnderGitRepo, nameof(pathUnderGitRepo));
var gitDir = FindGitDir(pathUnderGitRepo);

// Override Config Search paths to empty path to avoid new Repository instance to lookup for Global\System .gitconfig file
GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.Global, string.Empty);
GlobalSettings.SetConfigSearchPaths(ConfigurationLevel.System, string.Empty);

return gitDir == null ? null : new Repository(gitDir);
}

/// <summary>
/// Tests whether a commit is of a specified version, comparing major and minor components
/// with the version.txt file defined by that commit.
Expand All @@ -394,6 +411,46 @@ internal static bool CommitMatchesMajorMinorVersion(this Commit commit, Version
return majorMinorFromFile?.Major == expectedVersion.Major && majorMinorFromFile?.Minor == expectedVersion.Minor;
}

private static string FindGitDir(string startingDir)
{
while (startingDir != null)
{
var dirOrFilePath = Path.Combine(startingDir, ".git");
if (Directory.Exists(dirOrFilePath))
{
return dirOrFilePath;
}
else if (File.Exists(dirOrFilePath))
{
var relativeGitDirPath = ReadGitDirFromFile(dirOrFilePath);
if (!string.IsNullOrWhiteSpace(relativeGitDirPath))
{
var fullGitDirPath = Path.GetFullPath(Path.Combine(startingDir, relativeGitDirPath));
if (Directory.Exists(fullGitDirPath))
{
return fullGitDirPath;
}
}
}

startingDir = Path.GetDirectoryName(startingDir);
}

return null;
}

private static string ReadGitDirFromFile(string fileName)
{
const string expectedPrefix = "gitdir: ";
var firstLineOfFile = File.ReadLines(fileName).FirstOrDefault();
if (firstLineOfFile?.StartsWith(expectedPrefix) ?? false)
{
return firstLineOfFile.Substring(expectedPrefix.Length); // strip off the prefix, leaving just the path
}

return null;
}

/// <summary>
/// Tests whether an object's ID starts with the specified 16-bits, or a subset of them.
/// </summary>
Expand Down
30 changes: 22 additions & 8 deletions src/NerdBank.GitVersioning/VersionFile.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
namespace Nerdbank.GitVersioning
{
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using Validation;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using Validation;

/// <summary>
/// Extension methods for interacting with the version.txt file.
/// </summary>
Expand Down Expand Up @@ -122,7 +124,15 @@ public static VersionOptions GetVersion(LibGit2Sharp.Repository repo, string rep
/// </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)
public static VersionOptions GetVersion(string projectDirectory) => GetVersion(projectDirectory, out string _);

/// <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>
/// <param name="actualDirectory">Set to the actual directory that the version file was found in, which may be <paramref name="projectDirectory"/> or one of its ancestors.</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, out string actualDirectory)
{
Requires.NotNullOrEmpty(projectDirectory, nameof(projectDirectory));

Expand All @@ -138,6 +148,7 @@ public static VersionOptions GetVersion(string projectDirectory)
var result = TryReadVersionFile(sr, isJsonFile: false);
if (result != null)
{
actualDirectory = searchDirectory;
return result;
}
}
Expand All @@ -156,6 +167,7 @@ public static VersionOptions GetVersion(string projectDirectory)
if (result != null)
{
JsonConvert.PopulateObject(versionJsonContent, result, VersionOptions.GetJsonSettings());
actualDirectory = searchDirectory;
return result;
}
}
Expand All @@ -164,13 +176,15 @@ public static VersionOptions GetVersion(string projectDirectory)
}
else if (result != null)
{
actualDirectory = searchDirectory;
return result;
}
}

searchDirectory = parentDirectory;
}

actualDirectory = null;
return null;
}

Expand Down Expand Up @@ -199,12 +213,12 @@ public static bool IsVersionDefined(string projectDirectory)
}

/// <summary>
/// Writes the version.txt file to a directory within a repo with the specified version information.
/// Writes the version.json 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 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.txt file.
/// 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>
Expand Down
6 changes: 6 additions & 0 deletions src/NerdBank.GitVersioning/VersionOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public class VersionOptions : IEquatable<VersionOptions>
/// </summary>
private const int DefaultSemVer1NumericIdentifierPadding = 4;

/////// <summary>
/////// The $schema field that should be serialized when writing
/////// </summary>
////[JsonProperty(PropertyName = "$schema")]
////private string Schema => "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json";

/// <summary>
/// Gets or sets the default version to use.
/// </summary>
Expand Down
68 changes: 12 additions & 56 deletions src/NerdBank.GitVersioning/VersionOracle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,24 @@ public static VersionOracle Create(string projectDirectory, string gitRepoDirect
gitRepoDirectory = projectDirectory;
}

using (var git = OpenGitRepo(gitRepoDirectory))
using (var git = GitExtensions.OpenGitRepo(gitRepoDirectory))
{
return new VersionOracle(projectDirectory, git, cloudBuild, overrideBuildNumberOffset, projectPathRelativeToGitRepoRoot);
return new VersionOracle(projectDirectory, git, null, cloudBuild, overrideBuildNumberOffset, projectPathRelativeToGitRepoRoot);
}
}

/// <summary>
/// Initializes a new instance of the <see cref="VersionOracle"/> class.
/// </summary>
public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, ICloudBuild cloudBuild, int? overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null)
: this(projectDirectory, repo, null, cloudBuild, overrideBuildNumberOffset, projectPathRelativeToGitRepoRoot)
{
}

/// <summary>
/// Initializes a new instance of the <see cref="VersionOracle"/> class.
/// </summary>
public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, LibGit2Sharp.Commit head, ICloudBuild cloudBuild, int? overrideBuildNumberOffset = null, string projectPathRelativeToGitRepoRoot = null)
{
var repoRoot = repo?.Info?.WorkingDirectory?.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var relativeRepoProjectDirectory = !string.IsNullOrWhiteSpace(repoRoot)
Expand All @@ -53,11 +61,11 @@ public VersionOracle(string projectDirectory, LibGit2Sharp.Repository repo, IClo
: projectDirectory.Substring(repoRoot.Length).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
: null;

var commit = repo?.Head.Commits.FirstOrDefault();
var commit = head ?? repo?.Head.Commits.FirstOrDefault();

var committedVersion = VersionFile.GetVersion(commit, relativeRepoProjectDirectory);

var workingVersion = VersionFile.GetVersion(projectDirectory);
var workingVersion = head != null ? VersionFile.GetVersion(head, relativeRepoProjectDirectory) : VersionFile.GetVersion(projectDirectory);

if (overrideBuildNumberOffset.HasValue)
{
Expand Down Expand Up @@ -356,58 +364,6 @@ private static string FormatBuildMetadata(IEnumerable<string> identifiers) =>
private static string FormatBuildMetadataSemVerV1(IEnumerable<string> identifiers) =>
(identifiers?.Any() ?? false) ? "-" + string.Join("-", identifiers) : string.Empty;

private static LibGit2Sharp.Repository OpenGitRepo(string repoRoot)
{
Requires.NotNullOrEmpty(repoRoot, nameof(repoRoot));
var gitDir = FindGitDir(repoRoot);

// Override Config Search paths to empty path to avoid new Repository instance to lookup for Global\System .gitconfig file
LibGit2Sharp.GlobalSettings.SetConfigSearchPaths(LibGit2Sharp.ConfigurationLevel.Global, string.Empty);
LibGit2Sharp.GlobalSettings.SetConfigSearchPaths(LibGit2Sharp.ConfigurationLevel.System, string.Empty);

return gitDir == null ? null : new LibGit2Sharp.Repository(gitDir);
}

private static string FindGitDir(string startingDir)
{
while (startingDir != null)
{
var dirOrFilePath = Path.Combine(startingDir, ".git");
if (Directory.Exists(dirOrFilePath))
{
return dirOrFilePath;
}
else if (File.Exists(dirOrFilePath))
{
var relativeGitDirPath = ReadGitDirFromFile(dirOrFilePath);
if (!string.IsNullOrWhiteSpace(relativeGitDirPath))
{
var fullGitDirPath = Path.GetFullPath(Path.Combine(startingDir, relativeGitDirPath));
if (Directory.Exists(fullGitDirPath))
{
return fullGitDirPath;
}
}
}

startingDir = Path.GetDirectoryName(startingDir);
}

return null;
}

private static string ReadGitDirFromFile(string fileName)
{
const string expectedPrefix = "gitdir: ";
var firstLineOfFile = File.ReadLines(fileName).FirstOrDefault();
if (firstLineOfFile?.StartsWith(expectedPrefix) ?? false)
{
return firstLineOfFile.Substring(expectedPrefix.Length); // strip off the prefix, leaving just the path
}

return null;
}

private static Version GetAssemblyVersion(Version version, VersionOptions versionOptions)
{
// If there is no repo, "version" could have uninitialized components (-1).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
</PropertyGroup>

<Target Name="SetNuSpecProperties" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion">
<Target Name="SetNuSpecPropertiesFinal" BeforeTargets="GenerateNuspec" DependsOnTargets="GetBuildVersion;SetNuSpecProperties">
<PropertyGroup>
<PackageLicenseUrl>https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/$(GitCommitIdShort)/LICENSE.txt</PackageLicenseUrl>
<LibGit2SharpNativeBinaries>$(NuGetPackageRoot)libgit2sharp.nativebinaries\1.0.165\</LibGit2SharpNativeBinaries>
<NuspecProperties>$(NuspecProperties);LicenseUrl=$(PackageLicenseUrl);Version=$(Version);BaseOutputPath=$(OutputPath);LibGit2SharpNativeBinaries=$(LibGit2SharpNativeBinaries)</NuspecProperties>
</PropertyGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Nerdbank.GitVersioning.Tasks/SetCloudBuildVariables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ public override bool Execute()

if (isUnitTest)
{
PipeOutputToMSBuildLog(testStdOut.ToString(), warning: false);
PipeOutputToMSBuildLog(testStdErr.ToString(), warning: true);
this.PipeOutputToMSBuildLog(testStdOut.ToString(), warning: false);
this.PipeOutputToMSBuildLog(testStdErr.ToString(), warning: true);
}
}
else
Expand Down
Loading

0 comments on commit 63e0ff3

Please sign in to comment.