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); }
/// <summary> /// Same as knowledge but uses a different color scheme /// </summary> public HierarchicalDataContext AnalyzeKnowledgeLoss(string developer, IBrushFactory brushFactory, IAliasMapping aliasMapping) { LoadContributions(false); var localFileToContribution = AliasTransformContribution(_contributions, aliasMapping); developer = aliasMapping.GetAlias(developer); var summary = _history.GetArtifactSummary(_extendedDisplayFilter, 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); }
private void InitAliasColorMappings() { if (_aliasToColorMapping != null) { return; } _aliasToColorMapping = new Dictionary <string, ColorMapping>(); var allMappings = _sourceColorPalette.GetColorMappings().ToList(); var nameToColor = allMappings.ToDictionary(m => m.Name, m => m.Color); // Convert to alias names foreach (var mapping in allMappings) { var name = mapping.Name; var alias = _aliasMapping.GetAlias(name); var color = mapping.Color; if (_aliasToColorMapping.ContainsKey(alias)) { // We may map more than one name to the same alias. continue; } if (nameToColor.ContainsKey(alias)) { // This alias is an existing developer name, so we use the color instead. // Otherwise we take the color of the first developer mapped to this alias // by default. color = nameToColor[alias]; } _aliasToColorMapping.Add(alias, new ColorMapping { Name = alias, Color = color }); } }
/// <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()); }