示例#1
0
        public AliasColorScheme(IColorPalette sourceColorPalette, IAliasMapping aliasMapping)
        {
            _sourceColorPalette = sourceColorPalette;
            _aliasMapping       = aliasMapping;

            InitAliasColorMappings();
        }
示例#2
0
        public HierarchicalDataContext AnalyzeKnowledge(IBrushFactory brushFactory, IAliasMapping aliasMapping)
        {
            LoadHistory();
            LoadMetrics();
            LoadContributions(false);

            var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping);

            var summary             = _history.GetArtifactSummary(GetDisplayFilter(), aliasMapping);
            var fileToMainDeveloper = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.GetMainDeveloper());

            // Assign a color to each developer
            var mainDevelopers = fileToMainDeveloper.Select(pair => pair.Value.Developer).Distinct().ToList();

            var legend = new LegendBitmap(mainDevelopers, brushFactory);

            legend.CreateLegendBitmap(Path.Combine(_outputPath, "knowledge_color.bmp"));

            // Build the knowledge data
            var builder          = new KnowledgeBuilder();
            var hierarchicalData = builder.Build(summary, _metrics, fileToMainDeveloper);

            var dataContext = new HierarchicalDataContext(hierarchicalData, brushFactory);

            dataContext.AreaSemantic   = Strings.LinesOfCode;
            dataContext.WeightSemantic = Strings.NotAvailable;
            return(dataContext);
        }
示例#3
0
        internal List <string> GetMainDevelopers(IAliasMapping aliasMapping)
        {
            LoadContributions(false);
            var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping);
            var mainDevelopers          = localFileToContribution.Select(x => x.Value.GetMainDeveloper().Developer).Distinct();

            return(mainDevelopers.ToList());
        }
示例#4
0
        private static Dictionary <string, uint> AliasTransformWork(IAliasMapping aliasMapping, Dictionary <string, uint> developerToWork)
        {
            var aliasToWork = new Dictionary <string, uint>();

            // Group by alias
            var groups = developerToWork.GroupBy(pair => aliasMapping.GetAlias(pair.Key));

            foreach (var group in groups)
            {
                var sumContribution = (uint)group.Sum(g => g.Value);
                var alias           = group.Key;
                aliasToWork.Add(alias, sumContribution);
            }

            return(aliasToWork);
        }
示例#5
0
        /// <summary>
        /// Analyzes the fragmentation per file.
        /// </summary>
        public HierarchicalDataContext AnalyzeFragmentation(IAliasMapping aliasMapping)
        {
            LoadContributions(false);
            var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping);

            var summary            = _history.GetArtifactSummary(_extendedDisplayFilter, aliasMapping);
            var fileToFractalValue = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.CalculateFractalValue());

            var builder          = new FragmentationBuilder();
            var hierarchicalData = builder.Build(summary, _metrics, fileToFractalValue);

            var dataContext = new HierarchicalDataContext(hierarchicalData);

            dataContext.AreaSemantic   = Strings.LinesOfCode;
            dataContext.WeightSemantic = Strings.Fragmentation;
            return(dataContext);
        }
示例#6
0
        public List <object> ExportSummary(IAliasMapping aliasMapping)
        {
            LoadContributions(true); // silent

            var summary           = _history.GetArtifactSummary(_extendedDisplayFilter, aliasMapping);
            var hotspotCalculator = new HotspotCalculator(summary, _metrics);

            var orderedByLocalPath = summary.OrderBy(x => x.LocalPath).ToList();
            var gridData           = new List <object>();

            foreach (var artifact in orderedByLocalPath)
            {
                gridData.Add(CreateDataGridFriendlyArtifact(artifact, hotspotCalculator, aliasMapping));
            }

            var now = DateTime.Now.ToIsoShort();

            Csv.Write(Path.Combine(_outputPath, $"summary-{now}.csv"), gridData);
            return(gridData);
        }
示例#7
0
        public void ShowColorEditorViewViewer(IColorSchemeManager colorSchemeManager, IAliasMapping aliasMapping)
        {
            var view      = new ColorEditorView();
            var viewModel = new ColorEditorViewModel(colorSchemeManager, aliasMapping);

            view.Owner                 = _mainWindow;
            view.DataContext           = viewModel;
            view.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            //view.SizeToContent = SizeToContent.WidthAndHeight;
            //view.ResizeMode = ResizeMode.NoResize;
            view.ShowDialog();
        }
示例#8
0
        private object CreateDataGridFriendlyArtifact(Artifact artifact, HotspotCalculator hotspotCalculator, IAliasMapping aliasMapping)
        {
            var linesOfCode = (int)hotspotCalculator.GetLinesOfCode(artifact);

            if (_contributions != null)
            {
                var result = new DataGridFriendlyArtifact();

                var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping);

                var key = artifact.LocalPath.ToLowerInvariant();
                if (localFileToContribution.ContainsKey(key))
                {
                    var contribution = localFileToContribution[key];
                    var mainDev      = contribution.GetMainDeveloper();

                    // Work related information
                    result.FractalValue   = contribution.CalculateFractalValue();
                    result.MainDev        = mainDev.Developer;
                    result.MainDevPercent = mainDev.Percent;
                }
                else
                {
                    result.MainDev = "???";
                    //Warnings.Add(new WarningMessage("", $"Cannot find contribution for file {key}"));
                }

                result.LocalPath    = artifact.LocalPath;
                result.Commits      = artifact.Commits;
                result.Committers   = artifact.Committers.Count;
                result.LOC          = linesOfCode;
                result.WorkItems    = artifact.WorkItems.Count;
                result.CodeAge_Days = (DateTime.Now - artifact.Date).Days;
                result.Hotspot      = hotspotCalculator.GetHotspotValue(artifact);


                return(result);
            }
            else
            {
                var result = new DataGridFriendlyArtifactBasic();
                result.LocalPath    = artifact.LocalPath;
                result.Commits      = artifact.Commits;
                result.Committers   = artifact.Committers.Count;
                result.LOC          = linesOfCode;
                result.WorkItems    = artifact.WorkItems.Count;
                result.CodeAge_Days = (DateTime.Now - artifact.Date).Days;
                result.Hotspot      = hotspotCalculator.GetHotspotValue(artifact);
                return(result);
            }
        }
示例#9
0
        /// <summary>
        /// Same as knowledge but uses a different color scheme
        /// </summary>
        public HierarchicalDataContext AnalyzeKnowledgeLoss(string developer, IBrushFactory brushFactory, IAliasMapping aliasMapping)
        {
            LoadHistory();
            LoadMetrics();
            LoadContributions(false);

            var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping);

            developer = aliasMapping.GetAlias(developer);

            var summary             = _history.GetArtifactSummary(GetDisplayFilter(), aliasMapping);
            var fileToMainDeveloper = localFileToContribution.ToDictionary(pair => pair.Key, pair => pair.Value.GetMainDeveloper());

            // Build the knowledge data
            var builder          = new KnowledgeBuilder(developer);
            var hierarchicalData = builder.Build(summary, _metrics, fileToMainDeveloper);

            var dataContext = new HierarchicalDataContext(hierarchicalData, brushFactory);

            dataContext.AreaSemantic   = Strings.LinesOfCode;
            dataContext.WeightSemantic = Strings.NotAvailable;
            return(dataContext);
        }
示例#10
0
        public string AnalyzeWorkOnSingleFile(string fileName, IBrushFactory brushFactory, IAliasMapping aliasMapping)
        {
            var workByDeveloper = _sourceProvider.CalculateDeveloperWork(fileName);

            var workByAlias = AliasTransformWork(aliasMapping, workByDeveloper);

            var bitmap = new FractionBitmap();

            var fi   = new FileInfo(fileName);
            var path = Path.Combine(_outputPath, fi.Name) + ".bmp";


            // TODO atr bitmap?
            bitmap.Create(path, workByAlias, brushFactory, true);

            return(path);
        }
示例#11
0
        /// <summary>
        /// The contributions are calculated by the source control providers.
        /// In order to use developer aliases we have to transform the contributions, too.
        /// If two developers are mapped to the same alias their contribution is shared.
        /// </summary>
        /// <returns></returns>
        public Dictionary <string, Contribution> AliasTransformContribution(Dictionary <string, Contribution> localFilesToContribution, IAliasMapping aliasMapping)
        {
            var localFileToAliasContribution = new Dictionary <string, Contribution>();

            foreach (var fileToContribution in localFilesToContribution)
            {
                var localFile       = fileToContribution.Key;
                var developerToWork = fileToContribution.Value.DeveloperToContribution;
                var aliasToWork     = AliasTransformWork(aliasMapping, developerToWork);
                localFileToAliasContribution.Add(localFile, new Contribution(aliasToWork));
            }

            // local file -> contribution
            return(localFileToAliasContribution);
        }
 public static IColorScheme ForAlias(this IColorScheme palette, IAliasMapping aliasMapping)
 {
     return(new AliasColorScheme(palette, aliasMapping));
 }
示例#13
0
        /// <summary>
        ///     Returns a flat summary of all artifacts found in the commit history.
        /// </summary>
        public List <Artifact> GetArtifactSummary(IFilter filter, IAliasMapping aliasMapping)
        {
            // Item id -> artifact
            var artifacts = new Dictionary <string, Artifact>();

            var set = new HashSet <string>();

            // Files we already know we skip are not checked again!
            var ignoredIds = new HashSet <string>();

            foreach (var changeset in ChangeSets)
            {
                if (changeset.WorkItems.Count >= Thresholds.MaxWorkItemsPerCommitForSummary)
                {
                    // Ignore monster merges.
                    // Note: We may lose files for the summary when the last merge with many work items contains a final rename.
                    // Maybe write a warning or make further analysis.
                    continue;
                }

                Debug.Assert(set.Add(changeset.Id)); // Change set appears only once
                foreach (var item in changeset.Items)
                {
                    // The first time we see a file (id) it is the latest version of the file.
                    // Either add it to the summary or ignore list.
                    var id = item.Id;
                    if (ignoredIds.Contains(id))
                    {
                        // Files we already know to be skipped are not checked again! (Performance)
                        continue;
                    }

                    if (filter != null && !filter.IsAccepted(item.LocalPath))
                    {
                        ignoredIds.Add(id);
                        continue;
                    }

                    if (!artifacts.ContainsKey(id))
                    {
                        // The changeset where we see the item the first time is the latest revision!

                        if (!Exists(item))
                        {
                            // This may still happen because we skip large merges that may contain a final rename.
                            // So we have a code metric but still believe that the file is at its former location

                            // TODO show as warning!
                            Trace.WriteLine($"Ignored file: '{item.LocalPath}'. It should exist. Possible cause: Ignored commit with too much work items containing a final rename.");
                            ignoredIds.Add(id);
                            continue;
                        }

                        artifacts[id] = CreateArtifact(changeset, item);
                    }
                    else
                    {
                        // Changesets seen first are expected so have newer dates.
                        Debug.Assert(artifacts[id].Date >= changeset.Date);
                    }

                    var artifact       = artifacts[id];
                    var committerAlias = aliasMapping.GetAlias(changeset.Committer);

                    // Aggregate information from earlier commits (for example number of commits etc)
                    // TODO ApplyTeams(teamClassifier, artifact, changeset);
                    ApplyCommits(artifact);
                    ApplyCommitter(artifact, committerAlias);
                    ApplyWorkItems(artifact, changeset);
                }
            }

            // Remove entries that exist on hard disk but are removed form TFS!
            // Flatten the structure and return only the artifacts.
            return(artifacts.Where(pair => !pair.Value.IsDeleted).Select(pair => pair.Value).ToList());
        }