예제 #1
0
        /// <summary>
        /// Executes this action.
        /// </summary>
        /// <returns>Returns 0 to indicate success.</returns>
        public int Execute(CancellationToken cancellationToken)
        {
            string repositoryDir = RepoPath;

            while (!Directory.Exists(Path.Combine(repositoryDir, ".git")))
            {
                repositoryDir = Path.GetDirectoryName(repositoryDir);
                if (repositoryDir == null)
                {
                    log.Error("Directory {0} is not a git repository.", RepoPath);
                    return(1);
                }
            }
            RepoPath = repositoryDir;

            if (FieldCount < 1 || FieldCount > 5)
            {
                log.Error("The argument for --fields ({0}) must be an integer between 1 and 5.", FieldCount);
                return(1);
            }

            if (!String.IsNullOrEmpty(PrintLog))
            {
                int nLines = 0;
                if (!int.TryParse(PrintLog, out nLines) || nLines <= 0)
                {
                    log.Error("The argument for --log ({0}) must be an integer greater than 0.", PrintLog);
                    return(1);
                }
                return(DoPrintLog(cancellationToken));
            }

            string versionString = null;

            using (GitVersionCalulator calc = new GitVersionCalulator(RepoPath))
            {
                if (String.IsNullOrEmpty(Sha))
                {
                    versionString = calc.GetVersion().ToString(FieldCount);
                }
                else
                {
                    versionString = calc.GetVersion(Sha).ToString(FieldCount);
                }
            }
            if (!String.IsNullOrEmpty(ReplaceFile))
            {
                if (!File.Exists(ReplaceFile))
                {
                    log.Error("File '{0}' given in --replace argument could not be found.", Path.GetFullPath(ReplaceFile));
                    return(1);
                }
                int replaceLineCount = DoReplaceFile(ReplaceFile, versionString);
                if (replaceLineCount == 0)
                {
                    log.Warning("Nothing to replace. '$(GitVersion)' was not found in {0}.", ReplaceFile);
                }
                else
                {
                    log.Info("Replaced '$(GitVersion)' with '{0}' in {1} line(s) of {2}", versionString, replaceLineCount, ReplaceFile);
                }
                return(0);
            }
            log.Info(versionString);
            return(0);
        }
예제 #2
0
        private static string TryReplaceMacro(string text, string ProjectDirectory)
        {
            if (string.IsNullOrEmpty(text))
            {
                return(text);
            }

            // Find macro
            var match = Regex.Match(text, @"(.*)(?:\$\()(.*)(?:\))(.*)");

            if (match == null || match.Groups.Count < 2)
            {
                return(text);
            }

            // Replace macro
            if (match.Groups[2].ToString() == "GitVersion")
            {
                using (GitVersionCalulator calc = new GitVersionCalulator(ProjectDirectory))
                {
                    SemanticVersion version = calc.GetVersion();
                    text = match.Groups[1].ToString() + version + match.Groups[3].ToString();
                }
            }
            else
            {
                throw new NotSupportedException(string.Format("The macro \"{0}\" is not supported.", match.Groups[2].ToString()));
            }

            // Find "pre-processor funcions"
            match = Regex.Match(text, @"(.*)(?:\$\()(.*?),(.*)(?:\))(.*)"); // With text = "Rolf$(ConvertFourValue,1.0.0.69)Asger", this regex should return 4 matching groups: "Rolf", "ConvertFourValue", "1.0.0.69" and "Asger".

            if (match == null || match.Groups.Count < 4 || !match.Groups[2].Success || !match.Groups[3].Success)
            {
                return(text);
            }

            var             plugins          = PluginManager.GetPlugins <IVersionTryConverter>().Concat(PluginManager.GetPlugins <IVersionConverter>());
            Type            converter        = plugins.FirstOrDefault(pt => pt.GetDisplayAttribute().Name == match.Groups[2].Value);
            SemanticVersion convertedVersion = null;
            var             str = match.Groups[3].Value;

            if (converter != null)
            {
                object conv = Activator.CreateInstance(converter);
                if (conv is IVersionTryConverter cv2)
                {
                    if (cv2.TryConvert(match.Groups[3].Value, out convertedVersion) == false)
                    {
                        throw new FormatException("Unable to convert version format: " + str);
                    }
                }
                else if (conv is IVersionConverter cv1)
                {
                    convertedVersion = cv1.Convert(str);
                }
            }

            if (convertedVersion != null)
            {
                text = match.Groups[1].Value + convertedVersion + match.Groups[4].Value;
                log.Warning("The version was converted from {0} to {1} using the converter '{2}'.",
                            str, convertedVersion, converter.GetDisplayAttribute().Name);
            }
            else
            {
                throw new Exception(string.Format("No IVersionConverter found named \"{0}\". Valid ones are: {1}", match.Groups[2].Value,
                                                  String.Join(", ", plugins.Select(p => $"\"{p.GetDisplayAttribute().Name}\""))));
            }
            return(text);
        }
예제 #3
0
        private int DoPrintLog(CancellationToken cancellationToken)
        {
            ConsoleColor defaultColor = Console.ForegroundColor;
            ConsoleColor graphColor   = ConsoleColor.DarkYellow;
            ConsoleColor versionColor = ConsoleColor.DarkRed;

            using (GitVersionCalulator versionCalculater = new GitVersionCalulator(RepoPath))
                using (LibGit2Sharp.Repository repo = new LibGit2Sharp.Repository(RepoPath))
                {
                    Commit tip = repo.Head.Tip;
                    if (!string.IsNullOrEmpty(Sha))
                    {
                        tip = repo.Lookup <Commit>(Sha);
                        if (tip == null)
                        {
                            log.Error($"The commit with reference {Sha} does not exist in the repository.");
                            return(1);
                        }
                    }
                    IEnumerable <Commit> History = repo.Commits.QueryBy(new CommitFilter()
                    {
                        IncludeReachableFrom = tip, SortBy = CommitSortStrategies.Topological
                    });


                    // Run through to determine max Position (number of concurrent branches) to be able to indent correctly later
                    int maxLines  = int.Parse(PrintLog);
                    int lineCount = 0;
                    Dictionary <Commit, int> commitPosition = new Dictionary <Commit, int>();
                    commitPosition.Add(History.First(), 0);
                    int maxPosition = 0;
                    foreach (Commit c in History)
                    {
                        cancellationToken.ThrowIfCancellationRequested();

                        if (maxPosition < commitPosition[c])
                        {
                            maxPosition = commitPosition[c];
                        }

                        if (!c.Parents.Any())
                        {
                            // this is the very first commit in the repo. Stop here.
                            maxLines = ++lineCount;
                            break;
                        }
                        Commit p1 = c.Parents.First();
                        if (c.Parents.Count() > 1)
                        {
                            Commit p2 = c.Parents.Last();

                            if (commitPosition.ContainsKey(p1))
                            {
                                if (commitPosition[p1] != commitPosition[c])
                                {
                                    int startPos = Math.Min(commitPosition[p1], commitPosition[c]);
                                    int endPos   = Math.Max(commitPosition[p1], commitPosition[c]);

                                    commitPosition[c] = startPos;

                                    foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == endPos).ToList())
                                    {
                                        commitPosition.Remove(kvp.Key);
                                    }
                                }
                            }

                            if (!commitPosition.ContainsKey(p2))
                            {
                                // move out to an position out for the new branch
                                int newPosition = commitPosition[c] + 1;
                                while (commitPosition.ContainsValue(newPosition) &&
                                       (newPosition <= commitPosition.Values.Max()))
                                {
                                    newPosition++;
                                }
                                commitPosition[p2] = newPosition;

                                commitPosition[p1] = commitPosition[c];
                            }
                            else if (!commitPosition.ContainsKey(p1))
                            {
                                commitPosition[p1] = commitPosition[c];
                            }
                        }
                        else
                        {
                            if (!commitPosition.ContainsKey(p1))
                            {
                                commitPosition[p1] = commitPosition[c];
                            }

                            if (commitPosition[p1] != commitPosition[c])
                            {
                                int startPos = Math.Min(commitPosition[p1], commitPosition[c]);
                                int endPos   = Math.Max(commitPosition[p1], commitPosition[c]);

                                // c is now merged back, no need to keep track of it (or any other commit on this branch)
                                // this way we can reuse the position for another branch
                                foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == endPos).ToList())
                                {
                                    commitPosition.Remove(kvp.Key);
                                }
                                commitPosition[p1] = startPos;
                                foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == startPos).ToList())
                                {
                                    if (kvp.Key != p1)
                                    {
                                        commitPosition.Remove(kvp.Key);
                                    }
                                }
                            }
                        }
                        if (++lineCount >= maxLines)
                        {
                            break;
                        }
                    }
                    {
                        maxPosition++;
                    }

                    {
                        // Run through again to print
                        lineCount      = 0;
                        commitPosition = new Dictionary <Commit, int>();
                        commitPosition.Add(History.First(), 0);
                        HashSet <Commit> taggedCommits = repo.Tags.Select(t => t.Target.Peel <Commit>()).ToHashSet();
                        foreach (Commit c in History)
                        {
                            cancellationToken.ThrowIfCancellationRequested();
                            void DrawPositionSpacer(int fromPos, int toPos)
                            {
                                for (int i = fromPos; i < toPos; i++)
                                {
                                    if (commitPosition.ContainsValue(i))
                                    {
                                        Console.Write("\u2502 ");
                                    }
                                    else
                                    {
                                        Console.Write("  ");
                                    }
                                }
                            }

                            void DrawMergePositionSpacer(int fromPos, int toPos)
                            {
                                for (int i = fromPos; i < toPos; i++)
                                {
                                    if (commitPosition.ContainsValue(i))
                                    {
                                        Console.Write("\u2502\u2500");
                                    }
                                    else
                                    {
                                        Console.Write("\u2500\u2500");
                                    }
                                }
                            }

                            Console.ForegroundColor = graphColor;
                            DrawPositionSpacer(0, commitPosition[c]);
                            Console.ForegroundColor = defaultColor;
                            if (taggedCommits.Contains(c))
                            {
                                Console.Write("v ");
                            }
                            else
                            {
                                Console.Write("* ");
                            }
                            Console.ForegroundColor = graphColor;
                            DrawPositionSpacer(commitPosition[c] + 1, maxPosition);

                            Console.ForegroundColor = versionColor;
                            Console.Write(versionCalculater.GetVersion(c).ToString(FieldCount));
                            Console.ForegroundColor = defaultColor;

                            Console.Write(" - ");
                            Console.Write(c.MessageShort.Trim());

                            if (++lineCount >= maxLines)
                            {
                                Console.WriteLine();
                                break;
                            }

                            if (c.Parents.Any())
                            {
                                Commit p1 = c.Parents.First();
                                //Console.Write("Parent1: " + p1.Sha.Substring(0,8));
                                Console.WriteLine();
                                Console.ForegroundColor = graphColor;
                                if (c.Parents.Count() > 1)
                                {
                                    Commit p2 = c.Parents.Last();

                                    int startPos;
                                    int endPos;

                                    if (commitPosition.ContainsKey(p1))
                                    {
                                        if (commitPosition[p1] != commitPosition[c])
                                        {
                                            startPos = Math.Min(commitPosition[p1], commitPosition[c]);
                                            // something we already printed has the current commit as its parent, draw the line to that commit now
                                            DrawPositionSpacer(0, startPos);
                                            // Draw ├─┘
                                            Console.Write("\u251C\u2500");
                                            endPos = Math.Max(commitPosition[p1], commitPosition[c]);
                                            DrawMergePositionSpacer(startPos + 1, endPos);
                                            Console.Write("\u2518 ");
                                            DrawPositionSpacer(endPos + 1, maxPosition);
                                            Console.WriteLine();
                                            commitPosition[c] = startPos;
                                            foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == endPos).ToList())
                                            {
                                                commitPosition.Remove(kvp.Key);
                                            }
                                        }
                                    }

                                    if (!commitPosition.ContainsKey(p2))
                                    {
                                        DrawPositionSpacer(0, commitPosition[c]);
                                        // move out to an position out for the new branch
                                        int newPosition = commitPosition[c] + 1;
                                        while (commitPosition.ContainsValue(newPosition) &&
                                               (newPosition <= commitPosition.Values.Max()))
                                        {
                                            newPosition++;
                                        }
                                        commitPosition[p2] = newPosition;

                                        commitPosition[p1] = commitPosition[c];
                                        // Draw ├─┐
                                        Console.Write("\u251C\u2500");
                                        DrawMergePositionSpacer(commitPosition[c] + 1, commitPosition[p2]);
                                        Console.Write("\u2510 ");
                                        DrawPositionSpacer(commitPosition[p2] + 1, maxPosition);
                                        Console.WriteLine();
                                    }
                                    else if (!commitPosition.ContainsKey(p1))
                                    {
                                        commitPosition[p1] = commitPosition[c];
                                        // this branch is merged several times
                                        startPos = Math.Min(commitPosition[p2], commitPosition[c]);
                                        DrawPositionSpacer(0, startPos);
                                        // draws something like: ├─┤
                                        Console.Write("\u251C\u2500");
                                        endPos = Math.Max(commitPosition[p2], commitPosition[c]);
                                        DrawMergePositionSpacer(startPos + 1, endPos);
                                        Console.Write("\u2524 ");
                                        DrawPositionSpacer(endPos + 1, maxPosition);
                                        Console.WriteLine();
                                    }
                                    //else
                                    //{
                                    //    DrawPositionSpacer(0, commitPosition[p2]);
                                    //    Console.Write("\u251C\u2500");
                                    //    DrawMergePositionSpacer(commitPosition[p2] + 1, commitPosition[c]);
                                    //    Console.WriteLine("\u2524");
                                    //}
                                }
                                else
                                {
                                    if (!commitPosition.ContainsKey(p1))
                                    {
                                        commitPosition[p1] = commitPosition[c];
                                    }

                                    if (commitPosition[p1] != commitPosition[c])
                                    {
                                        int startPos = Math.Min(commitPosition[p1], commitPosition[c]);
                                        DrawPositionSpacer(0, startPos);
                                        // Draw ├─┘
                                        Console.Write("\u251C\u2500");
                                        int endPos = Math.Max(commitPosition[p1], commitPosition[c]);
                                        DrawMergePositionSpacer(startPos + 1, endPos);
                                        Console.Write("\u2518 ");
                                        DrawPositionSpacer(endPos + 1, maxPosition);
                                        Console.WriteLine();
                                        // c is now merged back, no need to keep track of it (or any other commit on this branch)
                                        // this way we can reuse the position for another branch
                                        foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == endPos).ToList())
                                        {
                                            commitPosition.Remove(kvp.Key);
                                        }
                                        commitPosition[p1] = startPos;
                                        foreach (var kvp in commitPosition.Where((KeyValuePair <Commit, int> kvp) => kvp.Value == startPos).ToList())
                                        {
                                            if (kvp.Key != p1)
                                            {
                                                commitPosition.Remove(kvp.Key);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            return(0);
        }