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); }
/// <summary> /// Load Git Settings from DataBase /// </summary> private void LoadGitSettings() { // Load Git Settings from DataBase this.gitTrayGitSettingsTableAdapter.Fill(this.gitTrayGitSettingsDataSet.GitSettings); gitTraySettingsBindingSource.DataSource = this.gitTrayGitSettingsDataSet.GitSettings; try { _gitSettings.GitLocation = this.gitTrayGitSettingsDataSet.GitSettings[0].GitLocation; _gitSettings.PollTime = this.gitTrayGitSettingsDataSet.GitSettings[0].PollPeriod; _gitSettings.FetchType = this.gitTrayGitSettingsDataSet.GitSettings[0].FetchType; _gitSettings.RecursiveSubmoduleSearch = this.gitTrayGitSettingsDataSet.GitSettings[0].RecursiveSubmoduleSearch; _gitSettings.AutoMerge = this.gitTrayGitSettingsDataSet.GitSettings[0].AutoMerge; _gitSettings.LogFormat = this.gitTrayGitSettingsDataSet.GitSettings[0].LogFormat; GitExtensions.UpdateGitConfiguration(_gitSettings); } catch (Exception e) { var result = MetroMessageBox.Show(this, e.Message, "Git Tray Warining Message", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Exclamation); if (result == DialogResult.Abort) { Application.Exit(); } else if (result == DialogResult.Retry) { SettingsSplitButton_ButtonClick(new object(), new EventArgs()); } else { /*NAR*/ } } }
public static VersionOracle GitVersioningGetVersion(this ICakeContext context, string projectDirectory = ".") { var fullProjectDirectory = (new DirectoryInfo(projectDirectory)).FullName; GitExtensions.HelpFindLibGit2NativeBinaries(Path.GetDirectoryName(Assembly.GetAssembly(typeof(GitVersioningAliases)).Location)); return(VersionOracle.Create(fullProjectDirectory, null, CloudBuild.Active)); }
private int RunGitVersionTool(GitVersionOptions gitVersionOptions) { var mutexName = this.repositoryInfo.DotGitDirectory.Replace(Path.DirectorySeparatorChar.ToString(), ""); using var mutex = new Mutex(true, $@"Global\gitversion{mutexName}", out var acquired); try { if (!acquired) { mutex.WaitOne(); } var variables = this.gitVersionCalculateTool.CalculateVersionVariables(); var configuration = this.configProvider.Provide(overrideConfig: gitVersionOptions.ConfigInfo.OverrideConfig); this.gitVersionOutputTool.OutputVariables(variables, configuration.UpdateBuildNumber ?? true); this.gitVersionOutputTool.UpdateAssemblyInfo(variables); this.gitVersionOutputTool.UpdateWixVersionFile(variables); } catch (WarningException exception) { var error = $"An error occurred:{System.Environment.NewLine}{exception.Message}"; this.log.Warning(error); return(1); } catch (Exception exception) { var error = $"An unexpected error occurred:{System.Environment.NewLine}{exception}"; this.log.Error(error); if (gitVersionOptions == null) { return(1); } this.log.Info("Attempting to show the current git graph (please include in issue): "); this.log.Info("Showing max of 100 commits"); try { GitExtensions.DumpGraph(gitVersionOptions.WorkingDirectory, mess => this.log.Info(mess), 100); } catch (Exception dumpGraphException) { this.log.Error("Couldn't dump the git graph due to the following error: " + dumpGraphException); } return(1); } finally { mutex.ReleaseMutex(); } return(0); }
public void GitInvalidPath() { string path = @"D:\04_SideProjects"; string gitFetchResult = string.Empty; string gitStatus = string.Empty; gitFetchResult = GitExtensions.ProcessGitRepo(ref gitStatus, path); string expectedResult = ""; Assert.That(expectedResult, Is.EqualTo(15)); }
public override bool Execute() { try { GitExtensions.TryHelpFindLibGit2NativeBinaries(this.TargetsPath); var cloudBuild = CloudBuild.Active; var oracle = VersionOracle.Create(Directory.GetCurrentDirectory(), this.GitRepoRoot, cloudBuild); if (!string.IsNullOrEmpty(this.DefaultPublicRelease)) { oracle.PublicRelease = string.Equals(this.DefaultPublicRelease, "true", StringComparison.OrdinalIgnoreCase); } if (this.BuildMetadata != null) { oracle.BuildMetadata.AddRange(this.BuildMetadata); } this.PublicRelease = oracle.PublicRelease; this.Version = oracle.Version.ToString(); this.AssemblyVersion = oracle.AssemblyVersion.ToString(); this.AssemblyFileVersion = oracle.AssemblyFileVersion.ToString(); this.AssemblyInformationalVersion = oracle.AssemblyInformationalVersion; this.SimpleVersion = oracle.SimpleVersion.ToString(); this.MajorMinorVersion = oracle.MajorMinorVersion.ToString(); this.BuildNumber = oracle.BuildNumber; this.PrereleaseVersion = oracle.PrereleaseVersion; this.GitCommitId = oracle.GitCommitId; this.GitCommitIdShort = oracle.GitCommitIdShort; this.GitVersionHeight = oracle.VersionHeight; this.BuildMetadataFragment = oracle.BuildMetadataFragment; this.CloudBuildNumber = oracle.CloudBuildNumberEnabled ? oracle.CloudBuildNumber : null; this.NuGetPackageVersion = oracle.NuGetPackageVersion; this.NpmPackageVersion = oracle.NpmPackageVersion; if (oracle.CloudBuildVersionVarsEnabled) { this.CloudBuildVersionVars = oracle.CloudBuildVersionVars .Select(item => new TaskItem(item.Key, new Dictionary <string, string> { { "Value", item.Value } })) .ToArray(); } } catch (ArgumentOutOfRangeException ex) { Log.LogErrorFromException(ex); return(false); } return(true); }
/// <summary>Gets the swissport repo changelog.</summary> /// <returns>The changes for <see cref="swissportcargodcmrepopath"/> obtained using <see cref="GitExtensions.GetHistory"/></returns> internal static string GetSwissportRepoChangelog() { var path = swissportcargodcmrepopath; Skip.IfNot(Directory.Exists(path) , $"Path {path} does not exist"); Skip.IfNot(Directory.Exists(Path.Combine(path, ".git")) , $"Path {path} is not a git repository"); var log = GitExtensions.GetHistory(path); return(log); }
public void GenerateChangeLogTest() { var solutionPath = Directory .GetParent(Assembly.GetExecutingAssembly().Location) .Parent.Parent.Parent.FullName; Skip.IfNot( Directory.Exists(Path.Combine(solutionPath, ".git")), $"Path {solutionPath} is not a git repository"); var log = GitExtensions.GetHistory(solutionPath); Trace.WriteLine(log); }
/// <summary> /// Normalization of a git directory turns all remote branches into local branches, /// turns pull request refs into a real branch and a few other things. /// This is designed to be run *only on the build server* which checks out repositories in different ways. /// It is not recommended to run normalization against a local repository /// </summary> private void NormalizeGitDirectory(bool noFetch, string?currentBranchName, bool isDynamicRepository) { var authentication = this.options.Value.Authentication; // Need to ensure the HEAD does not move, this is essentially a BugCheck var expectedSha = this.repository.Head.Tip?.Sha; var expectedBranchName = this.repository.Head.Name.Canonical; try { var remote = EnsureOnlyOneRemoteIsDefined(); FetchRemotesIfRequired(remote, noFetch, authentication); EnsureLocalBranchExistsForCurrentBranch(remote, currentBranchName); CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(remote.Name); var currentBranch = this.repository.Branches.FirstOrDefault(x => x.Name.EquivalentTo(currentBranchName)); // Bug fix for https://github.com/GitTools/GitVersion/issues/1754, head maybe have been changed // if this is a dynamic repository. But only allow this in case the branches are different (branch switch) if (expectedSha != this.repository.Head.Tip?.Sha) { if (isDynamicRepository || currentBranch is null || !this.repository.Head.Equals(currentBranch)) { var newExpectedSha = this.repository.Head.Tip?.Sha; var newExpectedBranchName = this.repository.Head.Name.Canonical; this.log.Info($"Head has moved from '{expectedBranchName} | {expectedSha}' => '{newExpectedBranchName} | {newExpectedSha}', allowed since this is a dynamic repository"); expectedSha = newExpectedSha; } } EnsureHeadIsAttachedToBranch(currentBranchName, authentication); } finally { if (this.repository.Head.Tip?.Sha != expectedSha) { if (this.environment.GetEnvironmentVariable("IGNORE_NORMALISATION_GIT_HEAD_MOVE") != "1") { // Whoa, HEAD has moved, it shouldn't have. We need to blow up because there is a bug in normalisation throw new BugException($@"GitVersion has a bug, your HEAD has moved after repo normalisation. To disable this error set an environmental variable called IGNORE_NORMALISATION_GIT_HEAD_MOVE to 1 Please run `git {GitExtensions.CreateGitLogArgs(100)}` and submit it along with your build log (with personal info removed) in a new issue at https://github.com/GitTools/GitVersion"); } } } }
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 int RunGitVersionTool(GitVersionOptions gitVersionOptions) { try { var variables = gitVersionCalculateTool.CalculateVersionVariables(); var configuration = configProvider.Provide(overrideConfig: gitVersionOptions.ConfigInfo.OverrideConfig); gitVersionOutputTool.OutputVariables(variables, configuration.UpdateBuildNumber ?? true); gitVersionOutputTool.UpdateAssemblyInfo(variables); gitVersionOutputTool.UpdateWixVersionFile(variables); } catch (WarningException exception) { var error = $"An error occurred:{System.Environment.NewLine}{exception.Message}"; log.Warning(error); return(1); } catch (Exception exception) { var error = $"An unexpected error occurred:{System.Environment.NewLine}{exception}"; log.Error(error); if (gitVersionOptions == null) { return(1); } log.Info("Attempting to show the current git graph (please include in issue): "); log.Info("Showing max of 100 commits"); try { GitExtensions.DumpGraph(gitVersionOptions.WorkingDirectory, mess => log.Info(mess), 100); } catch (Exception dumpGraphException) { log.Error("Couldn't dump the git graph due to the following error: " + dumpGraphException); } return(1); } return(0); }
public static VersionOracle GitVersioningGetVersion(this ICakeContext context, string projectDirectory = ".") { var fullProjectDirectory = (new DirectoryInfo(projectDirectory)).FullName; string directoryName = Path.GetDirectoryName(Assembly.GetAssembly(typeof(GitVersioningAliases)).Location); if (string.IsNullOrWhiteSpace(directoryName)) { throw new InvalidOperationException("Could not locate the Cake.GitVersioning library"); } // Even after adding the folder containing the native libgit2 DLL to the PATH, DllNotFoundException is still thrown // Workaround this by copying the contents of the found folder to the current directory GitExtensions.HelpFindLibGit2NativeBinaries(directoryName, out var attemptedDirectory); // The HelpFindLibGit2NativeBinaries method throws if the directory does not exist var directoryInfo = new DirectoryInfo(attemptedDirectory); // There should only be a single file in the directory, but we do not know its extension // So, we will just get a list of all files rather than trying to determine the correct name and extension // If there are other files there for some reason, it should not matter as long as we don't overwrite anything in the current directory var fileInfos = directoryInfo.GetFiles(); foreach (var fileInfo in fileInfos) { // Copy the file to the Cake.GitVersioning DLL directory, without overwriting anything string destFileName = Path.Combine(directoryName, fileInfo.Name); if (!File.Exists(destFileName)) { File.Copy(fileInfo.FullName, destFileName); } } return(VersionOracle.Create(fullProjectDirectory, null, CloudBuild.Active)); }
private void RepositoryBrowser_FormClosing(object sender, FormClosingEventArgs e) { Path = repoDirectoryExplorer.mDirPath.Text; //Check is the path a valid git repository. if (!System.IO.Directory.Exists(Path + @"\.git") && !System.IO.File.Exists(Path + @"\.git")) { var result = MetroMessageBox.Show(this, "Path is not a valid git repository !", "Git Tray Warining Message", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning); if (result == DialogResult.Abort || result == DialogResult.Ignore) { Path = string.Empty; } else { e.Cancel = true; //Cancel closing of the form } } else { Cursor.Current = Cursors.WaitCursor; //Check and get the list of submodules SubModules = GitExtensions.PreProcessGitRepo(Path); } }
static void Main(string[] args) { $"CS /webworks changelog generator, version {Constants.Version}".Dump(LogLevel.Info); bool optionsParsed = true; using (var p = new Parser(settings => { settings.CaseSensitive = false; settings.CaseInsensitiveEnumValues = true; settings.HelpWriter = System.Console.Out; })) p.ParseArguments <Options>(args) .WithParsed((opts) => _options = opts) .WithNotParsed((errs) => optionsParsed = false); if (!optionsParsed) { return; } _options.Dump(LogLevel.Info); var firstrun = true; while (firstrun || (!System.Console.IsInputRedirected && System.Console.ReadKey().Key != ConsoleKey.X)) { firstrun = false; var log = GitExtensions.GetHistory( workingDirectory: _options.RepositoryLocation, pathToGit: _options.PathToGit, incremental: !_options.Full, startTag: _options.StartTag); $"Raw log : {log}".Dump(loglevel: LogLevel.Debug); var parseOptions = new ParseOptions() { prefix_feature = _options.Prefix_feature, prefix_hotfix = _options.Prefix_hotfix, prefix_release = _options.Prefix_release, branch_development = _options.Branch_development, branch_master = _options.Branch_master, branch_preview = _options.Branch_preview, category_feature = _options.Category_feature, category_hotfix = _options.Category_hotfix, }; var entries = Parsing.Parse(log, parseOptions); entries.Name = _options.ReleaseName; //A lot of options can only be specific with negative default values when passed as command argument, hence the double negation var exportOptions = new ExportOptions() { Append = !_options.Replace, Reverse = true, ResolveIssueNumbers = !_options.DontLinkifyIssueNumbers, IssueTrackerUrl = _options.IssueTrackerUrl, RepositoryUrl = _options.CommitDetailsUrl, LinkHash = !string.IsNullOrWhiteSpace(_options.CommitDetailsUrl), ShortHash = true, IssueNumberRegex = new Regex(_options.IssueNumberRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled) }; //Always Output to console for now entries.Export(OutputFormat.Console, _options.TargetFile, exportOptions); System.Console.WriteLine(); var file = entries.Export(_options.OutputFormat, _options.TargetFile, exportOptions); if (!System.Console.IsInputRedirected) { if (file.Exists) { if (_options.OpenFile) { $"Opening file: {file.FullName}".Dump(); System.Diagnostics.Process.Start(file.FullName); } else { $"Not opening file: {file.FullName}".Dump(); } } else { $"Changelog does not exist at: {file.FullName}".Dump(); } "Press 'X' to exit (and anything else to run again)".Dump(); } } }
/// <summary> /// Normalization of a git directory turns all remote branches into local branches, /// turns pull request refs into a real branch and a few other things. /// This is designed to be run *only on the build server* which checks out repositories in different ways. /// It is not recommended to run normalization against a local repository /// </summary> private void NormalizeGitDirectory(bool noFetch, string?currentBranchName, bool isDynamicRepository) { var authentication = this.options.Value.Authentication; // Need to ensure the HEAD does not move, this is essentially a BugCheck var expectedSha = this.repository.Head.Tip?.Sha; var expectedBranchName = this.repository.Head.Name.Canonical; try { var remote = EnsureOnlyOneRemoteIsDefined(); //If noFetch is enabled, then GitVersion will assume that the git repository is normalized before execution, so that fetching from remotes is not required. if (noFetch) { this.log.Info("Skipping fetching, if GitVersion does not calculate your version as expected you might need to allow fetching or use dynamic repositories"); } else { var refSpecs = string.Join(", ", remote.FetchRefSpecs.Select(r => r.Specification)); this.log.Info($"Fetching from remote '{remote.Name}' using the following refspecs: {refSpecs}."); this.retryAction.Execute(() => this.repository.Fetch(remote.Name, Enumerable.Empty <string>(), authentication, null)); } EnsureLocalBranchExistsForCurrentBranch(remote, currentBranchName); CreateOrUpdateLocalBranchesFromRemoteTrackingOnes(remote.Name); var currentBranch = this.repositoryStore.FindBranch(currentBranchName); // Bug fix for https://github.com/GitTools/GitVersion/issues/1754, head maybe have been changed // if this is a dynamic repository. But only allow this in case the branches are different (branch switch) if (expectedSha != this.repository.Head.Tip?.Sha && (isDynamicRepository || currentBranch is null || !this.repository.Head.Equals(currentBranch))) { var newExpectedSha = this.repository.Head.Tip?.Sha; var newExpectedBranchName = this.repository.Head.Name.Canonical; this.log.Info($"Head has moved from '{expectedBranchName} | {expectedSha}' => '{newExpectedBranchName} | {newExpectedSha}', allowed since this is a dynamic repository"); expectedSha = newExpectedSha; } var headSha = this.repository.Refs.Head?.TargetIdentifier; if (!this.repository.IsHeadDetached) { this.log.Info($"HEAD points at branch '{headSha}'."); return; } this.log.Info($"HEAD is detached and points at commit '{headSha}'."); this.log.Info($"Local Refs:{System.Environment.NewLine}" + string.Join(System.Environment.NewLine, this.repository.Refs.FromGlob("*").Select(r => $"{r.Name.Canonical} ({r.TargetIdentifier})"))); // In order to decide whether a fake branch is required or not, first check to see if any local branches have the same commit SHA of the head SHA. // If they do, go ahead and checkout that branch // If no, go ahead and check out a new branch, using the known commit SHA as the pointer var localBranchesWhereCommitShaIsHead = this.repository.Branches.Where(b => !b.IsRemote && b.Tip?.Sha == headSha).ToList(); var matchingCurrentBranch = !currentBranchName.IsNullOrEmpty() ? localBranchesWhereCommitShaIsHead.SingleOrDefault(b => b.Name.Canonical.Replace("/heads/", "/") == currentBranchName.Replace("/heads/", "/")) : null; if (matchingCurrentBranch != null) { this.log.Info($"Checking out local branch '{currentBranchName}'."); Checkout(matchingCurrentBranch.Name.Canonical); } else if (localBranchesWhereCommitShaIsHead.Count > 1) { var branchNames = localBranchesWhereCommitShaIsHead.Select(r => r.Name.Canonical); var csvNames = string.Join(", ", branchNames); const string moveBranchMsg = "Move one of the branches along a commit to remove warning"; this.log.Warning($"Found more than one local branch pointing at the commit '{headSha}' ({csvNames})."); var main = localBranchesWhereCommitShaIsHead.SingleOrDefault(n => n.Name.EquivalentTo(Config.MainBranchKey)); if (main != null) { this.log.Warning("Because one of the branches is 'main', will build main." + moveBranchMsg); Checkout(Config.MainBranchKey); } else { var branchesWithoutSeparators = localBranchesWhereCommitShaIsHead.Where(b => !b.Name.Friendly.Contains('/') && !b.Name.Friendly.Contains('-')).ToList(); if (branchesWithoutSeparators.Count == 1) { var branchWithoutSeparator = branchesWithoutSeparators[0]; this.log.Warning($"Choosing {branchWithoutSeparator.Name.Canonical} as it is the only branch without / or - in it. " + moveBranchMsg); Checkout(branchWithoutSeparator.Name.Canonical); } else { throw new WarningException("Failed to try and guess branch to use. " + moveBranchMsg); } } } else if (localBranchesWhereCommitShaIsHead.Count == 0) { this.log.Info($"No local branch pointing at the commit '{headSha}'. Fake branch needs to be created."); this.retryAction.Execute(() => this.repository.CreateBranchForPullRequestBranch(authentication)); } else { this.log.Info($"Checking out local branch 'refs/heads/{localBranchesWhereCommitShaIsHead[0]}'."); Checkout(localBranchesWhereCommitShaIsHead[0].Name.Friendly); } } finally { if (this.repository.Head.Tip?.Sha != expectedSha) { if (this.environment.GetEnvironmentVariable("IGNORE_NORMALISATION_GIT_HEAD_MOVE") != "1") { // Whoa, HEAD has moved, it shouldn't have. We need to blow up because there is a bug in normalisation throw new BugException($@"GitVersion has a bug, your HEAD has moved after repo normalisation. To disable this error set an environmental variable called IGNORE_NORMALISATION_GIT_HEAD_MOVE to 1 Please run `git {GitExtensions.CreateGitLogArgs(100)}` and submit it along with your build log (with personal info removed) in a new issue at https://github.com/GitTools/GitVersion"); } } } }
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); }
private bool HandleNonMainCommand(GitVersionOptions gitVersionOptions, out int exitCode) { if (gitVersionOptions == null) { helpWriter.Write(); exitCode = 1; return(true); } if (gitVersionOptions.IsVersion) { var assembly = Assembly.GetExecutingAssembly(); versionWriter.Write(assembly); exitCode = 0; return(true); } if (gitVersionOptions.IsHelp) { helpWriter.Write(); exitCode = 0; return(true); } if (gitVersionOptions.Diag) { gitVersionOptions.Settings.NoCache = true; gitVersionOptions.Output.Add(OutputType.BuildServer); } ConfigureLogging(gitVersionOptions, log); var workingDirectory = gitVersionOptions.WorkingDirectory; if (gitVersionOptions.Diag) { log.Info("Dumping commit graph: "); GitExtensions.DumpGraph(workingDirectory, mess => log.Info(mess), 100); } if (!Directory.Exists(workingDirectory)) { log.Warning($"The working directory '{workingDirectory}' does not exist."); } else { log.Info("Working directory: " + workingDirectory); } configFileLocator.Verify(gitVersionOptions, repositoryInfo); if (gitVersionOptions.Init) { configProvider.Init(workingDirectory); exitCode = 0; return(true); } if (gitVersionOptions.ConfigInfo.ShowConfig) { var config = configProvider.Provide(workingDirectory); console.WriteLine(config.ToString()); exitCode = 0; return(true); } exitCode = 0; return(false); }
public static void DumpGraph(this IGitRepository repository, Action <string> writer = null, int?maxCommits = null) { GitExtensions.DumpGraph(repository.Path, writer, maxCommits); }
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 void GitTrayNotification(object source, ElapsedEventArgs e) { TrayTimer.Stop(); for (int index = 0; index < gitTrayDataSet.GitTrayTable.Rows.Count; index++) { if (IsTableRefreshed == true) { IsTableRefreshed = false; //Reset the flag _statusHolder.Clear(); //Remove all entries break; // break the loop } if (_trayStatus == GitTrayStatusType.Stopped || _trayStatus == GitTrayStatusType.Sleep) { break; // break the loop } GitTrayDataSet.GitTrayTableRow currRow = (GitTrayDataSet.GitTrayTableRow)gitTrayDataSet.GitTrayTable.Rows[index]; string gitFetchResult = string.Empty; string gitStatus = string.Empty; string gerritResult = string.Empty; currRow.Activity = "Running"; /* Start Processing the row */ #region Setup Threads Thread gitThread = new Thread(() => gitFetchResult = GitExtensions.ProcessGitRepo(ref gitStatus, currRow.Path)) { IsBackground = true }; #endregion gitThread.Start(); #region Git Status gitThread.Join(); currRow.Git_Status = gitStatus; if (!string.IsNullOrEmpty(gitFetchResult) && IsTableRefreshed == false) { bool isPresent = false; if (_statusHolder.ContainsKey(currRow.Path)) { if (gitFetchResult.Equals(_statusHolder[currRow.Path][0])) { isPresent = true; } else { _statusHolder[currRow.Path][0] = gitFetchResult; } } if (isPresent == false && gitFetchResult.Contains("fatal:")) { //GitTray.ShowBalloonTip(1000, "Error", gitFetchResult, ToolTipIcon.Error); } else if (isPresent == false) { GitTray.ShowBalloonTip(1000, "New Software Available!", gitFetchResult, ToolTipIcon.Info); } else { //skip } } #endregion currRow.Activity = "Sleeping"; /* Processing completed */ if (!_statusHolder.ContainsKey(currRow.Path)) { _statusHolder.Add(currRow.Path, new List <string> { gitFetchResult, gerritResult }); } } if (_trayStatus == GitTrayStatusType.Running) { //Restart the timer if user has not requested to stop/halt TrayTimer.Start(); } else { _trayStatus = GitTrayStatusType.Sleep; } }
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); }