Example #1
0
        public GitDataCollector()
        {
            // Gets the Calendar instance associated with a CultureInfo.
            _cultureInfo = new CultureInfo("en-US");
            _calendar    = _cultureInfo.Calendar;

            ActivityByHourOfDay         = new DictionaryWithDefault <int, decimal>();
            ActivityByDayOfWeek         = new DictionaryWithDefault <int, int>();
            ActivityByMonthOfYear       = new DictionaryWithDefault <int, int>();
            ActivityByHourOfWeek        = new DictionaryWithDefault <int, DictionaryWithDefault <int, int> >();
            ActivityByHourOfDayBusiest  = 0;
            ActivityByHourOfWeekBusiest = 0;
            ActivityByYearWeek          = new DictionaryWithDefault <string, int>();
            ActivityByYearWeekPeak      = 0;
            Authors           = new DictionaryWithDefault <string, Author>();
            Domains           = new DictionaryWithDefault <string, Domain>();
            AuthorOfMonth     = new DictionaryWithDefault <string, DictionaryWithDefault <string, int> >();
            AuthorOfYear      = new DictionaryWithDefault <int, DictionaryWithDefault <string, int> >();
            CommitsByMonth    = new DictionaryWithDefault <string, int>();
            CommitsByYear     = new DictionaryWithDefault <int, int>();
            ActiveDays        = new List <DateTime>();
            TotalLines        = 0;
            TotalLinesAdded   = 0;
            TotalLinesRemoved = 0;
            CommitsByTimezone = new DictionaryWithDefault <string, int>();
            Tags = new DictionaryWithDefault <string, Tag>();
        }
Example #2
0
        private void GetExtensions()
        {
            Extensions = new DictionaryWithDefault <string, Extension>();
            var lines = GitStats.GetPipeOutput(new[]
            {
                "git ls-tree -r -z HEAD"
            }).Split("\0").ToList().Where(s => !string.IsNullOrWhiteSpace(s)).ToArray();

            ;
            TotalFiles = lines.Length;
            Console.WriteLine($"Processing {TotalFiles} files in repo");
            foreach (var line in lines)
            {
                if (line.Length == 0)
                {
                    continue;
                }
                var    parts    = Regex.Split(line, "\\s+", RegexOptions.None);
                var    sha1     = parts[2];
                var    filename = parts[3];
                string ext;
                if (filename.IndexOf(".", StringComparison.Ordinal) == -1 ||
                    filename.IndexOf(".", StringComparison.Ordinal) == 0)
                {
                    ext = "";
                }
                else
                {
                    ext = filename.Substring(filename.LastIndexOf(".", StringComparison.Ordinal) + 1);
                }
                if (ext.Length > _configuration.MaxExtensionLength)
                {
                    ext = "";
                }
                if (!Extensions.ContainsKey(ext))
                {
                    Extensions[ext] = new Extension();
                }
                Extensions[ext].Files += 1;
                try
                {
                    Extensions[ext].Lines += GetLinesInBlob(sha1);
                }
                catch
                {
                    Console.WriteLine("Warning: Could not count lines for file \"%s\"", line);
                }
            }
        }
Example #3
0
        private void GetFilesByStampAndTotalCommits(List <string> lines)
        {
            // TODO Optimize this, it's the worst bottleneck
            // outputs "<stamp> <files>" for each revision
            lines.Clear();
            FilesByStamp = new DictionaryWithDefault <DateTime, int>();
            var revLines = GitStats.GetPipeOutput(new[]
            {
                "git rev-list --remotes --pretty=format:\"%at %T\" HEAD",
                "grep -v ^commit"
            }).Trim().Split("\n");

            foreach (var revLine in revLines)
            {
                var tup2      = revLine.Split(" ");
                var time      = tup2[0];
                var rev       = tup2[1];
                var lineCount = GetFilesInCommit(rev);
                lines.Add($"{Convert.ToInt32(time)} {lineCount}");
            }

            TotalCommits = lines.Count;
            foreach (var line in lines)
            {
                var parts = line.Split(" ");
                if (parts.Length != 2)
                {
                    continue;
                }
                try
                {
                    FilesByStamp[DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt32(parts[0])).DateTime] = Convert.ToInt32(parts[1]);
                }
                catch (FormatException)
                {
                    Console.WriteLine("Warning: failed to parse line \"%s\"", line);
                }
            }
        }
Example #4
0
        private void GetChangesByDateAndTotalLines()
        {
            // line statistics
            // outputs:
            //  N files changed, N insertions (+), N deletions(-)
            // <stamp> <author>
            ChangesByDate = new DictionaryWithDefault <DateTime, Change>();
            var lines = GitStats.GetPipeOutput(new[] { "git log --shortstat --pretty=format:\"%at %an\"" }).Split("\n")
                        .ToList();

            lines.Reverse();
            var files      = 0;
            var inserted   = 0;
            var deleted    = 0;
            var totalLines = 0;

            foreach (var line in lines)
            {
                if (line.Length == 0)
                {
                    files    = 0;
                    inserted = 0;
                    deleted  = 0;
                    continue;
                }
                if (line.IndexOf(" changed,", StringComparison.CurrentCultureIgnoreCase) == -1)
                {
                    var pos = line.IndexOf(" ", StringComparison.CurrentCultureIgnoreCase);
                    if (pos != -1)
                    {
                        try
                        {
                            var datetime = DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt32(line.Substring(0, pos))).DateTime;
                            var author   = line.Substring(pos + 1);
                            ChangesByDate[datetime] = new Change
                            {
                                Files      = files,
                                Inserted   = inserted,
                                Deleted    = deleted,
                                TotalLines = totalLines
                            };
                            if (!Authors.ContainsKey(author))
                            {
                                Authors[author] = new Author();
                            }
                            Authors[author].LinesAdded   += inserted;
                            Authors[author].LinesRemoved += deleted;
                        }
                        catch (Exception)
                        {
                            Console.WriteLine($"Warning: unexpected line \"{line}\"");
                        }
                    }
                    else
                    {
                        Console.WriteLine($"Warning: unexpected line \"{line}\"");
                    }
                }
                else
                {
                    files    = GetIntFromStartOfRegex(line, "\\d+ file");
                    inserted = GetIntFromStartOfRegex(line, "\\d+ insertion");
                    deleted  = GetIntFromStartOfRegex(line, "\\d+ delet");

                    totalLines        += inserted;
                    totalLines        -= deleted;
                    TotalLinesAdded   += inserted;
                    TotalLinesRemoved += deleted;
                }
            }

            TotalLines = totalLines;
        }
Example #5
0
        // Collect revision statistics
        // Outputs "<stamp> <date> <time> <timezone> <author> '<' <mail> '>'"
        private List <string> GetActivityDataAndAuthors()
        {
            var lines = GitStats.GetPipeOutput(new[]
            {
                "git rev-list --remotes --pretty=format:\"%at %ai %an <%aE>\" HEAD",
                "grep -v ^commit"
            }, PipingLevel.Full, true).Split("\n").ToList();

            foreach (var line in lines)
            {
                var parts = Regex.Split(line, "([01-9-:+]+ )").Where(x => !string.IsNullOrEmpty(x)).Select(s => s.Trim())
                            .ToArray();
                DateTime stamp;
                try
                {
                    stamp = DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt32(parts[0])).DateTime;
                }
                catch (FormatException)
                {
                    stamp = DateTime.MinValue;
                }

                var timezone = parts[3];
                var tup1     = parts[4].Split("<");
                var author   = tup1[0];
                var mail     = tup1[1];
                author = author.TrimEnd();
                mail   = mail.TrimEnd('>');
                var domain = "?";
                if (mail.IndexOf("@", StringComparison.CurrentCultureIgnoreCase) != -1)
                {
                    domain = mail.Split("@")[1];
                }
                var date = stamp;
                // First and last commit stamp
                if (LastCommitStamp == DateTime.MinValue)
                {
                    LastCommitStamp = stamp;
                }
                FirstCommitStamp = stamp;
                // activity
                // hour
                var hour = date.Hour;
                ActivityByHourOfDay[hour] = ActivityByHourOfDay[hour] + 1;
                // most active hour?
                if (ActivityByHourOfDay[hour] > ActivityByHourOfDayBusiest)
                {
                    ActivityByHourOfDayBusiest = ActivityByHourOfDay[hour];
                }
                // day of week
                var day = (int)date.DayOfWeek - 1;
                ActivityByDayOfWeek[day] = ActivityByDayOfWeek[day] + 1;
                // domain stats
                if (!Domains.ContainsKey(domain))
                {
                    Domains[domain] = new Domain();
                }
                // commits
                Domains[domain].Commits = Domains[domain].Commits + 1;
                // hour of week
                if (!ActivityByHourOfWeek.ContainsKey(day))
                {
                    ActivityByHourOfWeek[day] = new DictionaryWithDefault <int, int>();
                }

                ActivityByHourOfWeek[day][hour] = ActivityByHourOfWeek[day][hour] + 1;
                // most active hour?
                if (ActivityByHourOfWeek[day][hour] > ActivityByHourOfWeekBusiest)
                {
                    ActivityByHourOfWeekBusiest = ActivityByHourOfWeek[day][hour];
                }
                // month of year
                var month = date.Month;
                ActivityByMonthOfYear[month] = ActivityByMonthOfYear[month] + 1;
                // yearly/weekly activity
                var yyw =
                    $"{date.Year}-{_calendar.GetWeekOfYear(date, _cultureInfo.DateTimeFormat.CalendarWeekRule, _cultureInfo.DateTimeFormat.FirstDayOfWeek)}";
                ActivityByYearWeek[yyw] = ActivityByYearWeek[yyw] + 1;
                if (ActivityByYearWeekPeak < ActivityByYearWeek[yyw])
                {
                    ActivityByYearWeekPeak = ActivityByYearWeek[yyw];
                }
                // author stats
                if (!Authors.ContainsKey(author))
                {
                    Authors[author] = new Author();
                }
                // commits
                if (Authors[author].LastCommitStamp == DateTime.MinValue)
                {
                    Authors[author].LastCommitStamp = stamp;
                }

                Authors[author].FirstCommitStamp = stamp;
                Authors[author].Commits          = Authors[author].Commits + 1;
                // author of the month/year
                var yymm = $"{date.Year}-{date.Month:D2}";
                if (AuthorOfMonth.ContainsKey(yymm))
                {
                    AuthorOfMonth[yymm][author] = AuthorOfMonth[yymm][author] + 1;
                }
                else
                {
                    AuthorOfMonth[yymm] = new DictionaryWithDefault <string, int> {
                        [author] = 1
                    }
                };
                CommitsByMonth[yymm] = CommitsByMonth[yymm] + 1;
                var yy = date.Year;
                if (AuthorOfYear.ContainsKey(yy))
                {
                    AuthorOfYear[yy][author] = AuthorOfYear[yy][author] + 1;
                }
                else
                {
                    AuthorOfYear[yy] = new DictionaryWithDefault <string, int> {
                        [author] = 1
                    }
                };
                CommitsByYear[yy] = CommitsByYear[yy] + 1;
                // authors: active days
                var yymmdd = date;
                if (Authors[author].LastActiveDay == DateTime.MinValue)
                {
                    Authors[author].LastActiveDay = yymmdd;
                    Authors[author].ActiveDays    = 1;
                }
                else if (yymmdd != Authors[author].LastActiveDay)
                {
                    Authors[author].LastActiveDay = yymmdd;
                    Authors[author].ActiveDays   += 1;
                }

                // project: active days
                if (yymmdd != LastActiveDay)
                {
                    LastActiveDay = yymmdd;
                    ActiveDays.Add(yymmdd);
                }

                // timezone
                CommitsByTimezone[timezone] = CommitsByTimezone[timezone] + 1;
            }

            return(lines);
        }