private static ExitCodes OnGetVersionCommand(string projectPath, string format, string versionOrRef) { if (string.IsNullOrEmpty(format)) { format = DefaultVersionInfoFormat; } if (string.IsNullOrEmpty(versionOrRef)) { versionOrRef = DefaultRef; } string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath); var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } LibGit2Sharp.GitObject refObject = null; try { repository.RevParse(versionOrRef, out var reference, out refObject); } catch (LibGit2Sharp.NotFoundException) { } var commit = refObject as LibGit2Sharp.Commit; if (commit == null) { Console.Error.WriteLine("rev-parse produced no commit for {0}", versionOrRef); return(ExitCodes.BadGitRef); } var oracle = new VersionOracle(searchPath, repository, commit, CloudBuild.Active); switch (format.ToLowerInvariant()) { case "text": Console.WriteLine("Version: {0}", oracle.Version); Console.WriteLine("AssemblyVersion: {0}", oracle.AssemblyVersion); Console.WriteLine("AssemblyInformationalVersion: {0}", oracle.AssemblyInformationalVersion); Console.WriteLine("NuGet package Version: {0}", oracle.NuGetPackageVersion); Console.WriteLine("NPM package Version: {0}", oracle.NpmPackageVersion); break; case "json": Console.WriteLine(JsonConvert.SerializeObject(oracle, Formatting.Indented)); break; default: Console.Error.WriteLine("Unsupported format: {0}", format); return(ExitCodes.UnsupportedFormat); } return(ExitCodes.OK); }
private static ExitCodes OnGetCommitsCommand(string projectPath, string version, bool quiet) { if (!Version.TryParse(version, out Version parsedVersion)) { Console.Error.WriteLine($"\"{version}\" is not a simple a.b.c[.d] version spec."); return(ExitCodes.InvalidVersionSpec); } string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath); var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } string repoRelativeProjectDir = GetRepoRelativePath(searchPath, repository); var candidateCommits = GitExtensions.GetCommitsFromVersion(repository, parsedVersion, repoRelativeProjectDir).ToList(); PrintCommits(quiet, searchPath, repository, candidateCommits); return(ExitCodes.OK); }
private static ExitCodes OnSetVersionCommand(string projectPath, string version) { if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver)) { Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec."); return(ExitCodes.InvalidVersionSpec); } var defaultOptions = new VersionOptions { Version = semver, }; string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath); var repository = GitExtensions.OpenGitRepo(searchPath); var existingOptions = VersionFile.GetVersion(searchPath, out string actualDirectory); string versionJsonPath; if (existingOptions != null) { existingOptions.Version = semver; versionJsonPath = VersionFile.SetVersion(actualDirectory, existingOptions); } else if (string.IsNullOrEmpty(projectPath)) { if (repository == null) { Console.Error.WriteLine("No version file and no git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } versionJsonPath = VersionFile.SetVersion(repository.Info.WorkingDirectory, defaultOptions); } else { versionJsonPath = VersionFile.SetVersion(projectPath, defaultOptions); } if (repository != null) { LibGit2Sharp.Commands.Stage(repository, versionJsonPath); } return(ExitCodes.OK); }
private static ExitCodes OnTagCommand(string projectPath, string versionOrRef) { if (string.IsNullOrEmpty(versionOrRef)) { versionOrRef = DefaultRef; } string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath); var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } LibGit2Sharp.GitObject refObject = null; try { repository.RevParse(versionOrRef, out var reference, out refObject); } catch (LibGit2Sharp.NotFoundException) { } var commit = refObject as LibGit2Sharp.Commit; if (commit == null) { if (!Version.TryParse(versionOrRef, out Version parsedVersion)) { Console.Error.WriteLine($"\"{versionOrRef}\" is not a simple a.b.c[.d] version spec or git reference."); return(ExitCodes.InvalidVersionSpec); } string repoRelativeProjectDir = GetRepoRelativePath(searchPath, repository); var candidateCommits = GitExtensions.GetCommitsFromVersion(repository, parsedVersion, repoRelativeProjectDir).ToList(); if (candidateCommits.Count == 0) { Console.Error.WriteLine("No commit with that version found."); return(ExitCodes.NoMatchingVersion); } else if (candidateCommits.Count > 1) { PrintCommits(false, searchPath, repository, candidateCommits, includeOptions: true); int selection; do { Console.Write("Enter selection: "); }while (!int.TryParse(Console.ReadLine(), out selection) || selection > candidateCommits.Count || selection < 1); commit = candidateCommits[selection - 1]; } else { commit = candidateCommits.Single(); } } var oracle = new VersionOracle(searchPath, repository, commit, CloudBuild.Active); if (!oracle.VersionFileFound) { Console.Error.WriteLine("No version.json file found in or above \"{0}\" in commit {1}.", searchPath, commit.Sha); return(ExitCodes.NoVersionJsonFound); } oracle.PublicRelease = true; // assume a public release so we don't get a redundant -gCOMMITID in the tag name string tagName = $"v{oracle.SemVer2}"; try { repository.Tags.Add(tagName, commit); } catch (LibGit2Sharp.NameConflictException) { var taggedCommit = repository.Tags[tagName].Target as LibGit2Sharp.Commit; bool correctTag = taggedCommit?.Sha == commit.Sha; Console.Error.WriteLine("The tag {0} is already defined ({1}).", tagName, correctTag ? "to the right commit" : $"expected {commit.Sha} but was on {taggedCommit.Sha}"); return(correctTag ? ExitCodes.OK : ExitCodes.TagConflict); } Console.WriteLine("{0} tag created at {1}.", tagName, commit.Sha); Console.WriteLine("Remember to push to a remote: git push origin {0}", tagName); return(ExitCodes.OK); }
private static ExitCodes OnGetVersionCommand(string projectPath, string format, string singleVariable, string versionOrRef) { if (string.IsNullOrEmpty(format)) { format = DefaultOutputFormat; } if (string.IsNullOrEmpty(versionOrRef)) { versionOrRef = DefaultRef; } string searchPath = GetSpecifiedOrCurrentDirectoryPath(projectPath); var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } LibGit2Sharp.GitObject refObject = null; try { repository.RevParse(versionOrRef, out var reference, out refObject); } catch (LibGit2Sharp.NotFoundException) { } var commit = refObject as LibGit2Sharp.Commit; if (commit == null) { Console.Error.WriteLine("rev-parse produced no commit for {0}", versionOrRef); return(ExitCodes.BadGitRef); } var oracle = new VersionOracle(searchPath, repository, commit, CloudBuild.Active); // Take the PublicRelease environment variable into account, since the build would as well. if (!string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("PublicRelease")) && bool.TryParse(Environment.GetEnvironmentVariable("PublicRelease"), out bool publicRelease)) { oracle.PublicRelease = publicRelease; } if (string.IsNullOrEmpty(singleVariable)) { switch (format.ToLowerInvariant()) { case "text": Console.WriteLine("Version: {0}", oracle.Version); Console.WriteLine("AssemblyVersion: {0}", oracle.AssemblyVersion); Console.WriteLine("AssemblyInformationalVersion: {0}", oracle.AssemblyInformationalVersion); Console.WriteLine("NuGetPackageVersion: {0}", oracle.NuGetPackageVersion); Console.WriteLine("NpmPackageVersion: {0}", oracle.NpmPackageVersion); break; case "json": var converters = new JsonConverter[] { new Newtonsoft.Json.Converters.VersionConverter(), }; Console.WriteLine(JsonConvert.SerializeObject(oracle, Formatting.Indented, converters)); break; default: Console.Error.WriteLine("Unsupported format: {0}", format); return(ExitCodes.UnsupportedFormat); } } else { if (format != "text") { Console.Error.WriteLine("Format must be \"text\" when querying for an individual variable's value."); return(ExitCodes.UnsupportedFormat); } var property = oracle.GetType().GetProperty(singleVariable, CaseInsensitiveFlags); if (property == null) { Console.Error.WriteLine("Variable \"{0}\" not a version property.", singleVariable); return(ExitCodes.BadVariable); } Console.WriteLine(property.GetValue(oracle)); } return(ExitCodes.OK); }
private static ExitCodes OnInstallCommand(string versionJsonRoot, string version) { if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver)) { Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec."); return(ExitCodes.InvalidVersionSpec); } var options = new VersionOptions { Version = semver, PublicReleaseRefSpec = new string[] { @"^refs/heads/master$", @"^refs/heads/v\d+(?:\.\d+)?$", }, CloudBuild = new VersionOptions.CloudBuildOptions { BuildNumber = new VersionOptions.CloudBuildNumberOptions { Enabled = true, }, }, }; string searchPath = GetSpecifiedOrCurrentDirectoryPath(versionJsonRoot); if (!Directory.Exists(searchPath)) { Console.Error.WriteLine("\"{0}\" is not an existing directory.", searchPath); return(ExitCodes.NoGitRepo); } var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } if (string.IsNullOrEmpty(versionJsonRoot)) { versionJsonRoot = repository.Info.WorkingDirectory; } var existingOptions = VersionFile.GetVersion(versionJsonRoot); if (existingOptions != null) { if (!string.IsNullOrEmpty(version)) { var setVersionExitCode = OnSetVersionCommand(versionJsonRoot, version); if (setVersionExitCode != ExitCodes.OK) { return(setVersionExitCode); } } } else { string versionJsonPath = VersionFile.SetVersion(versionJsonRoot, options); LibGit2Sharp.Commands.Stage(repository, versionJsonPath); } // Create/update the Directory.Build.props file in the directory of the version.json file to add the NB.GV package. string directoryBuildPropsPath = Path.Combine(versionJsonRoot, "Directory.Build.props"); MSBuild.Project propsFile; if (File.Exists(directoryBuildPropsPath)) { propsFile = new MSBuild.Project(directoryBuildPropsPath); } else { propsFile = new MSBuild.Project(); } const string PackageReferenceItemType = "PackageReference"; const string PackageId = "Nerdbank.GitVersioning"; if (!propsFile.GetItemsByEvaluatedInclude(PackageId).Any(i => i.ItemType == "PackageReference")) { string packageVersion = GetLatestPackageVersionAsync(PackageId).GetAwaiter().GetResult(); propsFile.AddItem( PackageReferenceItemType, PackageId, new Dictionary <string, string> { { "Version", packageVersion }, // TODO: use the latest version... somehow... { "PrivateAssets", "all" }, }); propsFile.Save(directoryBuildPropsPath); } LibGit2Sharp.Commands.Stage(repository, directoryBuildPropsPath); return(ExitCodes.OK); }
private static ExitCodes OnInstallCommand(string versionJsonRoot, string version, IReadOnlyList <string> sources) { if (!SemanticVersion.TryParse(string.IsNullOrEmpty(version) ? DefaultVersionSpec : version, out var semver)) { Console.Error.WriteLine($"\"{version}\" is not a semver-compliant version spec."); return(ExitCodes.InvalidVersionSpec); } var options = new VersionOptions { Version = semver, PublicReleaseRefSpec = new string[] { @"^refs/heads/master$", @"^refs/heads/v\d+(?:\.\d+)?$", }, CloudBuild = new VersionOptions.CloudBuildOptions { BuildNumber = new VersionOptions.CloudBuildNumberOptions { Enabled = true, }, }, }; string searchPath = GetSpecifiedOrCurrentDirectoryPath(versionJsonRoot); if (!Directory.Exists(searchPath)) { Console.Error.WriteLine("\"{0}\" is not an existing directory.", searchPath); return(ExitCodes.NoGitRepo); } var repository = GitExtensions.OpenGitRepo(searchPath); if (repository == null) { Console.Error.WriteLine("No git repo found at or above: \"{0}\"", searchPath); return(ExitCodes.NoGitRepo); } if (string.IsNullOrEmpty(versionJsonRoot)) { versionJsonRoot = repository.Info.WorkingDirectory; } var existingOptions = VersionFile.GetVersion(versionJsonRoot); if (existingOptions != null) { if (!string.IsNullOrEmpty(version)) { var setVersionExitCode = OnSetVersionCommand(versionJsonRoot, version); if (setVersionExitCode != ExitCodes.OK) { return(setVersionExitCode); } } } else { string versionJsonPath = VersionFile.SetVersion(versionJsonRoot, options); LibGit2Sharp.Commands.Stage(repository, versionJsonPath); } // Create/update the Directory.Build.props file in the directory of the version.json file to add the NB.GV package. string directoryBuildPropsPath = Path.Combine(versionJsonRoot, "Directory.Build.props"); MSBuild.Project propsFile; if (File.Exists(directoryBuildPropsPath)) { propsFile = new MSBuild.Project(directoryBuildPropsPath); } else { propsFile = new MSBuild.Project(); } const string PackageReferenceItemType = "PackageReference"; if (!propsFile.GetItemsByEvaluatedInclude(PackageId).Any(i => i.ItemType == "PackageReference")) { // Validate given sources foreach (var source in sources) { if (!Uri.TryCreate(source, UriKind.Absolute, out var _)) { Console.Error.WriteLine($"\"{source}\" is not a valid NuGet package source."); return(ExitCodes.InvalidNuGetPackageSource); } } string packageVersion = GetLatestPackageVersionAsync(PackageId, versionJsonRoot, sources).GetAwaiter().GetResult(); if (string.IsNullOrEmpty(packageVersion)) { string verifyPhrase = sources.Any() ? "Please verify the given 'source' option(s)." : "Please verify the package sources in the NuGet.Config files."; Console.Error.WriteLine($"Latest stable version of the {PackageId} package could not be determined. " + verifyPhrase); return(ExitCodes.PackageIdNotFound); } propsFile.AddItem( PackageReferenceItemType, PackageId, new Dictionary <string, string> { { "Version", packageVersion }, { "PrivateAssets", "all" }, }); propsFile.Save(directoryBuildPropsPath); } LibGit2Sharp.Commands.Stage(repository, directoryBuildPropsPath); return(ExitCodes.OK); }