Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        /// <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));
        }
Пример #5
0
    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);
    }
Пример #6
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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        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);
        }
Пример #10
0
    /// <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");
                }
            }
        }
    }
Пример #11
0
        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);
        }
Пример #12
0
        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));
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        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();
                }
            }
        }
Пример #16
0
    /// <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");
                }
            }
        }
    }
Пример #17
0
        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);
        }
Пример #18
0
        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);
 }
Пример #20
0
        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);
        }
Пример #21
0
        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;
            }
        }
Пример #22
0
        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);
        }
Пример #23
0
        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);
        }