Example #1
0
        static void Process(string path, SearchOptions options, SearchRange range, ActionType action, IEnumerable <ParsedCommit> commitsToIgnore)
        {
            IEnumerable <CommitInfo> commits = CommitFinder.Parse(path, range);

            Explain.Print($"Found {commits.Count ()} commits.");

            switch (action)
            {
            case ActionType.ListConsideredCommits:
                PrintCommits(commits);
                return;

            case ActionType.ListBugs:
                var parsedCommits = CommitParser.Parse(commits, options).ToList();
                var bugCollection = BugCollector.ClassifyCommits(parsedCommits, options, commitsToIgnore);
                PrintBugs(bugCollection, options);

                if (options.ValidateBugStatus)
                {
                    BugValidator.Validate(bugCollection, options);
                }

                return;

            default:
                throw new InvalidOperationException($"Internal Error - Unknown action requested {action}");
            }
        }
Example #2
0
        static void PrintCommits(IEnumerable <CommitInfo> commits)
        {
            foreach (var commit in commits)
            {
                Console.WriteLine($"{commit.Hash} {commit.Title}");
            }

            Explain.Print($"Only listing of commits was requested. Exiting.");
        }
Example #3
0
        public static IEnumerable <ParsedCommit> ParseSingle(CommitInfo commit, SearchOptions options)
        {
            Explain.Indent();
            Explain.Print($"Analyzing {commit.Hash}.");

            var textToSearch = commit.Description.SplitLines();

            foreach (var match in textToSearch.Select(x => ParseLine(x, options)).Where(x => x.Confidence != ParsingConfidence.Invalid))
            {
                yield return(new ParsedCommit(commit, match.Link, match.ID, match.Confidence, match.BugzillaSummary, match.TargetMilestone, match.Status, match.Importance));
            }
            Explain.Deindent();
        }
Example #4
0
        public void Run(ActionType action)
        {
            // This can mutage Range so must be done first.
            var commitsToIgnore = ProcessOldestBranch();

            Process(Path, Options, Range, action, commitsToIgnore);

            if (Options.Submodules)
            {
                string oldest = Range.Oldest.ValueOr("");
                var    initialSubmoduleStatus = CommitFinder.FindSubmodulesStatus(Path, oldest);

                string newest = Range.Newest.ValueOr("HEAD");
                var    finalSubmoduleStatus = CommitFinder.FindSubmodulesStatus(Path, newest);

                Explain.Print($"Processing {initialSubmoduleStatus.Count} submodules for change as well");
                Explain.Indent();

                foreach (var submodule in initialSubmoduleStatus.Keys)
                {
                    string initialHash = initialSubmoduleStatus[submodule];
                    string finalHash   = finalSubmoduleStatus[submodule];

                    if (initialHash == finalHash)
                    {
                        Explain.Print($"Submodule {submodule} had zero changes ({finalHash}).");
                        continue;
                    }

                    Console.WriteLine($"\nSubmodule: {submodule}");

                    Explain.Print($"Processing {submodule} submodule from {initialHash} to {finalHash}.");

                    SearchRange submoduleRange = new SearchRange()
                    {
                        Oldest = initialHash.Some(), Newest = finalHash.Some()
                    };

                    Explain.Indent();
                    Process(System.IO.Path.Combine(Path, submodule), Options, submoduleRange, action, Enumerable.Empty <ParsedCommit> ());
                    Explain.Deindent();
                }

                Explain.Deindent();
            }
        }
Example #5
0
        static void ProcessBugStatus(BugCollection bugs)
        {
            foreach (var bug in bugs.Bugs)
            {
                switch (bug.BugInfo.Status)
                {
                case "CLOSED":
                case "VERIFIED":
                case "RESOLVED":
                    break;

                default:
                    Explain.Print($"{bug.ID} status may not be set correctly: {bug.BugInfo.Status}.");
                    break;
                }
            }
        }
Example #6
0
        static void ProcessTargetMilestones(BugCollection bugs, SearchOptions options)
        {
            string targetMilestone = options.ExpectedTargetMilestone ?? GuessTargetMilestone(bugs);

            var unmatchingBugs = bugs.Bugs.Where(x => x.BugInfo.TargetMilestone != targetMilestone);

            if (unmatchingBugs.Any())
            {
                Explain.Print($"The following bugs do not match the expected {targetMilestone}:");
                Explain.Indent();

                foreach (var bug in unmatchingBugs)
                {
                    Explain.Print($"{bug.ID} - {bug.BugInfo.TargetMilestone}");
                }
            }
            Explain.Deindent();
        }
Example #7
0
        public static ValueTuple <IEnumerable <CommitInfo>, string> FindCommitsOnBranchToIgnore(string path, string branchName, SearchOptions options)
        {
            var merge = FindMergeBase(path, branchName);

            if (!merge.HasValue)
            {
                EntryPoint.Die($"Unable to find merge-base with {branchName} on {path}. Do you need to get fetch?");
                return(new ValueTuple <IEnumerable <CommitInfo>, string> ());
            }

            var mergeBase = merge.ValueOrFailure();

            Explain.Print($"Found merge base for {branchName} at {mergeBase}.");

            var commitToIgnoreOnBranch = ParseSpecificRange(path, mergeBase, $"origin/{branchName}");

            Explain.Print($"Found {commitToIgnoreOnBranch.Count ()} commits on {branchName} after branch.");

            return(new ValueTuple <IEnumerable <CommitInfo>, string> (commitToIgnoreOnBranch, mergeBase));
        }
Example #8
0
        public static void Validate(BugCollection bugs, SearchOptions options)
        {
            bool explainStatus = Explain.Enabled;

            Explain.Enabled = true;

            Explain.Print("Validating Bug Status:");
            if (options.Bugzilla != BugzillaLevel.Private)
            {
                Explain.Print("This will only cover public bugs as private as --bugzilla:private is not set.");
            }

            Explain.Indent();

            ProcessBugStatus(bugs);
            Explain.Print("");
            ProcessTargetMilestones(bugs, options);

            Explain.Deindent();
            Explain.Enabled = explainStatus;
        }
Example #9
0
        IEnumerable <ParsedCommit> ProcessOldestBranch()
        {
            if (Range.OldestBranch.HasValue)
            {
                var branchName = Range.OldestBranch.ValueOrFailure();
                if (branchName.StartsWith("origin/", StringComparison.InvariantCulture))
                {
                    branchName = branchName.Remove(0, 7);
                }

                var commitInfo = CommitFinder.FindCommitsOnBranchToIgnore(Path, branchName, Options);

                IEnumerable <ParsedCommit> commitsToIgnore = CommitParser.Parse(commitInfo.Item1, Options);

                Explain.Print($"Found {commitsToIgnore.Count ()} bugs on {branchName} after branch to ignore.");

                Range.Oldest        = commitInfo.Item2.Some();
                Range.IncludeOldest = false;
                return(commitsToIgnore);
            }
            return(Enumerable.Empty <ParsedCommit> ());
        }
Example #10
0
        static string GuessTargetMilestone(BugCollection bugs)
        {
            Explain.Print("--expected-target-milestone was not set, so finding the most common Target Milestone.");
            var targetMilestoneCount = new Dictionary <string, int> ();

            foreach (var bug in bugs.Bugs)
            {
                if (targetMilestoneCount.ContainsKey(bug.BugInfo.TargetMilestone))
                {
                    targetMilestoneCount[bug.BugInfo.TargetMilestone] += 1;
                }
                else
                {
                    targetMilestoneCount[bug.BugInfo.TargetMilestone] = 1;
                }
            }
            var targetMilestones = targetMilestoneCount.Keys.OrderByDescending(x => targetMilestoneCount[x]).ToList();

            string guess = targetMilestones.FirstOrDefault();

            Explain.Print($"{guess} is the most common Target Milestone.");
            return(guess);
        }
Example #11
0
        static ParseResults ParseLine(string line, SearchOptions options)
        {
            try
            {
                Explain.Indent();
                foreach (Regex regex in AllRegex)
                {
                    var match = regex.Match(line);
                    if (match.Success)
                    {
                        int id;
                        if (int.TryParse(match.Groups[match.Groups.Count - 1].Value, out id))
                        {
                            Explain.Print($"Line \"{StripNewLine (line)}\" matched pattern {regex}.");

                            if (id < 1000 || id > 250000)
                            {
                                Explain.Print($"Had an invalid id {id}.");
                                return(new ParseResults {
                                    Confidence = ParsingConfidence.Invalid
                                });
                            }

                            Explain.Print($"Had a valid id {id}.");

                            ParsingConfidence confidence = ParsingConfidence.High;

                            if (line.StartsWith("Context", StringComparison.InvariantCultureIgnoreCase))
                            {
                                confidence = ParsingConfidence.Invalid;
                            }

                            Explain.Print($"Default Confidence was {confidence}.");
                            if (options.Bugzilla != BugzillaLevel.Disable)
                            {
                                var bugzillaSummary = GetTitle(id, options);
                                if (bugzillaSummary == null)
                                {
                                    confidence = ParsingConfidence.Low;
                                    Explain.Print($"Given low confidence due to lack of a matching bugzilla bug.");
                                    return(new ParseResults(confidence, match.Value, id));
                                }
                                var status     = GetStatus(id, options);
                                var milestone  = GetMilestone(id, options);
                                var importance = GetImportance(id, options);

                                return(new ParseResults(confidence, match.Value, id)
                                {
                                    BugzillaSummary = bugzillaSummary,
                                    Status = status,
                                    TargetMilestone = milestone,
                                    Importance = importance
                                });
                            }
                            return(new ParseResults(confidence, match.Value, id));
                        }
                    }
                }
                return(new ParseResults {
                    Confidence = ParsingConfidence.Invalid
                });
            }
            finally
            {
                Explain.Deindent();
            }
        }