FeatureCheckTag

This commit is contained in:
Mike Phares 2024-10-04 18:10:14 -07:00
parent 8558f883cf
commit 41933b98d2

View File

@ -18,6 +18,7 @@ namespace Adaptation.FileHandlers.json;
public class FileRead : Shared.FileRead, IFileRead public class FileRead : Shared.FileRead, IFileRead
{ {
private readonly string _URL;
private readonly Timer _Timer; private readonly Timer _Timer;
private readonly ReadOnlyCollection<string> _WorkItemTypes; private readonly ReadOnlyCollection<string> _WorkItemTypes;
@ -34,6 +35,7 @@ public class FileRead : Shared.FileRead, IFileRead
if (_IsDuplicator) if (_IsDuplicator)
throw new Exception(cellInstanceConnectionName); throw new Exception(cellInstanceConnectionName);
string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType); string cellInstanceNamed = string.Concat("CellInstance.", _EquipmentType);
_URL = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.URL");
string workItemTypes = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.WorkItemTypes"); string workItemTypes = GetPropertyValue(cellInstanceConnectionName, modelObjectParameters, $"{cellInstanceNamed}.WorkItemTypes");
_WorkItemTypes = new(workItemTypes.Split('|')); _WorkItemTypes = new(workItemTypes.Split('|'));
NestExistingFiles(_FileConnectorConfiguration); NestExistingFiles(_FileConnectorConfiguration);
@ -290,8 +292,9 @@ public class FileRead : Shared.FileRead, IFileRead
spaces.RemoveAt(0); spaces.RemoveAt(0);
} }
private static void AppendLines(List<char> spaces, List<string> lines, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType) private static void AppendLines(string url, List<char> spaces, List<string> lines, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{ {
List<string> results = new();
WorkItem workItem; WorkItem workItem;
string? maxIterationPath; string? maxIterationPath;
List<string> distinct = new(); List<string> distinct = new();
@ -302,53 +305,210 @@ public class FileRead : Shared.FileRead, IFileRead
// continue; // continue;
if (workItem.WorkItemType != workItemType) if (workItem.WorkItemType != workItemType)
continue; continue;
lines.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}"); results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
lines.Add(string.Empty); results.Add(string.Empty);
lines.Add($"- [{workItem.Id}](https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/{workItem.Id})"); results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
if (keyValuePair.Value.Children.Count == 0) if (keyValuePair.Value.Children.Count == 0)
lines.Add(string.Empty); results.Add(string.Empty);
else else
{ {
AppendLines(spaces, lines, keyValuePair.Value, condensed: true, sprintOnly: false); AppendLines(spaces, results, keyValuePair.Value, condensed: true, sprintOnly: false);
lines.Add(string.Empty); results.Add(string.Empty);
distinct.Clear(); distinct.Clear();
AppendLines(spaces, distinct, keyValuePair.Value, condensed: false, sprintOnly: true); AppendLines(spaces, distinct, keyValuePair.Value, condensed: false, sprintOnly: true);
if (distinct.Count > 1) if (distinct.Count > 1)
{ {
lines.Add($"## Distinct Iteration Path(s) - {workItem.WorkItemType} - {workItem.AssignedTo} - {workItem.Id} - {workItem.Title} - {workItem.IterationPath}"); results.Add($"## Distinct Iteration Path(s) - {workItem.WorkItemType} - {workItem.AssignedTo} - {workItem.Id} - {workItem.Title} - {workItem.IterationPath}");
lines.Add(string.Empty); results.Add(string.Empty);
lines.Add($"- [{workItem.Id}](https://tfs.intra.infineon.com/tfs/FactoryIntegration/ART%20SPS/_workitems/edit/{workItem.Id})"); results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
distinct.Sort(); distinct.Sort();
distinct = (from l in distinct select l.Trim()).Distinct().ToList(); distinct = (from l in distinct select l.Trim()).Distinct().ToList();
lines.AddRange(distinct); results.AddRange(distinct);
lines.Add(string.Empty); results.Add(string.Empty);
maxIterationPath = distinct.Max(); maxIterationPath = distinct.Max();
if (!string.IsNullOrEmpty(maxIterationPath) && maxIterationPath.Contains("] ") && maxIterationPath.Split(']')[1].Trim() != workItem.IterationPath) if (!string.IsNullOrEmpty(maxIterationPath) && maxIterationPath.Contains("] ") && maxIterationPath.Split(']')[1].Trim() != workItem.IterationPath)
{ {
lines.Add($"### Sync to Distinct Max Iteration Path => {maxIterationPath} - {workItem.Id} - {workItem.Title}"); results.Add($"### Sync to Distinct Max Iteration Path => {maxIterationPath} - {workItem.Id} - {workItem.Title}");
lines.Add(string.Empty); results.Add(string.Empty);
} }
} }
lines.Add($"## Extended - {workItem.Id} - {workItem.Title}"); results.Add($"## Extended - {workItem.Id} - {workItem.Title}");
lines.Add(string.Empty); results.Add(string.Empty);
AppendLines(spaces, lines, keyValuePair.Value, condensed: false, sprintOnly: false); AppendLines(spaces, results, keyValuePair.Value, condensed: false, sprintOnly: false);
lines.Add(string.Empty); results.Add(string.Empty);
} }
lines.AddRange(results);
results.Clear();
} }
} }
private static void WriteMarkdownFile(FileConnectorConfiguration fileConnectorConfiguration, string[] alternateTargetFolders, ReadOnlyCollection<WorkItem> workItems, ReadOnlyCollection<string> workItemTypes) private static void WriteFiles(string destinationDirectory, string fileName, ReadOnlyCollection<string> lines)
{
string text = string.Join(Environment.NewLine, lines);
string markdownFile = Path.Combine(destinationDirectory, $"{fileName}.md");
string textOld = !File.Exists(markdownFile) ? string.Empty : File.ReadAllText(markdownFile);
if (text != textOld)
File.WriteAllText(markdownFile, text);
string html = CommonMark.CommonMarkConverter.Convert(text);
string htmlFile = Path.Combine(destinationDirectory, $"{fileName}.html");
string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile);
if (html != htmlOld)
File.WriteAllText(htmlFile, html);
}
private static ReadOnlyCollection<WorkItem> FilterChildren(Record record, ReadOnlyCollection<string> workItemTypes)
{
List<WorkItem> results = new();
WorkItem workItem;
foreach (KeyValuePair<int, Record> keyValuePair in record.Children)
{
workItem = keyValuePair.Value.WorkItem;
if (!workItemTypes.Contains(workItem.WorkItemType))
continue;
results.Add(workItem);
}
return new(results);
}
private static string? GetMaxIterationPath(ReadOnlyCollection<WorkItem> workItems)
{
string? result;
List<string> results = new();
foreach (WorkItem workItem in workItems)
{
if (results.Contains(workItem.IterationPath))
continue;
results.Add(workItem.IterationPath);
}
result = results.Count == 0 ? null : results.Max();
return result;
}
private static void FeatureCheckIterationPath(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
string? maxIterationPath;
List<string> results = new();
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
maxIterationPath = GetMaxIterationPath(workItems);
if (string.IsNullOrEmpty(maxIterationPath) || workItem.IterationPath == maxIterationPath)
continue;
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
results.Add($"- [ ] {workItem.Id} => {workItem.IterationPath} != {maxIterationPath}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
private static ReadOnlyCollection<int> GetIdsNotMatching(string tags, ReadOnlyCollection<WorkItem> workItems)
{
List<int> results = new();
string[] segments;
string[] parentTags = tags.Split(';');
foreach (WorkItem workItem in workItems)
{
segments = tags.Split(';');
if (segments.Length > 0 && parentTags.Any(l => segments.Contains(l)))
continue;
results.Add(workItem.Id);
}
return new(results);
}
private static void FeatureCheckTag(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
List<string> results = new();
ReadOnlyCollection<int> idsNotMatching;
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
if (string.IsNullOrEmpty(workItem.Tags))
idsNotMatching = new(new int[] { workItem.Id });
else
{
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
idsNotMatching = GetIdsNotMatching(workItem.Tags, workItems);
if (!string.IsNullOrEmpty(workItem.Tags) && idsNotMatching.Count == 0)
continue;
}
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
foreach (int id in idsNotMatching)
results.Add($"- [ ] {id} {nameof(workItem.Tags)} != {workItem.Tags}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
private static ReadOnlyCollection<int> GetIdsNotMatching(int? priority, ReadOnlyCollection<WorkItem> workItems)
{
List<int> results = new();
foreach (WorkItem workItem in workItems)
{
if (workItem.Priority == priority)
continue;
results.Add(workItem.Id);
}
return new(results);
}
private static void FeatureCheckPriority(string url, List<string> lines, ReadOnlyCollection<string> workItemTypes, ReadOnlyDictionary<int, Record> workItemAndChildren, string workItemType)
{
WorkItem workItem;
List<string> results = new();
ReadOnlyCollection<int> idsNotMatching;
ReadOnlyCollection<WorkItem> workItems;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
if (workItem.WorkItemType != workItemType)
continue;
results.Clear();
if (keyValuePair.Value.Children.Count == 0)
continue;
workItems = FilterChildren(keyValuePair.Value, workItemTypes);
idsNotMatching = GetIdsNotMatching(workItem.Priority, workItems);
if (idsNotMatching.Count == 0)
continue;
results.Add($"## {workItem.AssignedTo} - {workItem.Id} - {workItem.Title}");
results.Add(string.Empty);
results.Add($"- [{workItem.Id}]({url}{workItem.Id})");
foreach (int id in idsNotMatching)
results.Add($"- [ ] {id} {nameof(workItem.Priority)} != {workItem.Priority}");
results.Add(string.Empty);
lines.AddRange(results);
}
}
private static void WriteMarkdownFile(FileConnectorConfiguration fileConnectorConfiguration, string url, string[] alternateTargetFolders, ReadOnlyCollection<WorkItem> workItems, ReadOnlyCollection<string> workItemTypes)
{ {
string old;
string html;
string text;
string json; string json;
string checkFile;
string? pathRoot; string? pathRoot;
List<char> spaces = new(); List<char> spaces = new();
List<string> lines = new(); List<string> lines = new();
ReadOnlyDictionary<int, WorkItem> keyValuePairs = GetWorkItems(workItems); ReadOnlyDictionary<int, WorkItem> keyValuePairs = GetWorkItems(workItems);
ReadOnlyCollection<string> userStoryWorkItemTypes = new(new string[] { "User Story" });
ReadOnlyDictionary<int, Record> workItemAndChildren = GetWorkItemAndChildren(keyValuePairs); ReadOnlyDictionary<int, Record> workItemAndChildren = GetWorkItemAndChildren(keyValuePairs);
ReadOnlyCollection<string> userStoryTaskWorkItemTypes = new(new string[] { "User Story", "Task" });
foreach (string alternateTargetFolder in alternateTargetFolders) foreach (string alternateTargetFolder in alternateTargetFolders)
{ {
if (alternateTargetFolder == fileConnectorConfiguration.TargetFileLocation) if (alternateTargetFolder == fileConnectorConfiguration.TargetFileLocation)
@ -375,22 +535,37 @@ public class FileRead : Shared.FileRead, IFileRead
lines.Clear(); lines.Clear();
lines.Add("# WorkItems"); lines.Add("# WorkItems");
lines.Add(string.Empty); lines.Add(string.Empty);
AppendLines(spaces, lines, workItemAndChildren, workItemType); AppendLines(url, spaces, lines, workItemAndChildren, workItemType);
checkFile = Path.Combine(alternateTargetFolder, $"{workItemType}.md"); WriteFiles(alternateTargetFolder, workItemType, new(lines));
text = string.Join(Environment.NewLine, lines); }
old = !File.Exists(checkFile) ? string.Empty : File.ReadAllText(checkFile); {
if (text != old) lines.Clear();
File.WriteAllText(checkFile, text); string workItemType = "Feature";
checkFile = Path.Combine(alternateTargetFolder, $"{workItemType}.html"); lines.Add($"# {nameof(FeatureCheckIterationPath)}");
html = CommonMark.CommonMarkConverter.Convert(text); lines.Add(string.Empty);
old = !File.Exists(checkFile) ? string.Empty : File.ReadAllText(checkFile); FeatureCheckIterationPath(url, lines, userStoryTaskWorkItemTypes, workItemAndChildren, workItemType);
if (html != old) WriteFiles(alternateTargetFolder, $"{nameof(FeatureCheckIterationPath)}", new(lines));
File.WriteAllText(checkFile, html); }
{
lines.Clear();
string workItemType = "Feature";
lines.Add($"# {nameof(FeatureCheckTag)}");
lines.Add(string.Empty);
FeatureCheckTag(url, lines, userStoryWorkItemTypes, workItemAndChildren, workItemType);
WriteFiles(alternateTargetFolder, $"{nameof(FeatureCheckTag)}", new(lines));
}
{
lines.Clear();
string workItemType = "Feature";
lines.Add($"# {nameof(FeatureCheckPriority)}");
lines.Add(string.Empty);
FeatureCheckPriority(url, lines, userStoryWorkItemTypes, workItemAndChildren, workItemType);
WriteFiles(alternateTargetFolder, $"{nameof(FeatureCheckPriority)}", new(lines));
} }
} }
} }
private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, string[] alternateTargetFolders, ReadOnlyCollection<string> workItemTypes) private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, string url, string[] alternateTargetFolders, ReadOnlyCollection<string> workItemTypes)
{ {
if (!Directory.Exists(fileConnectorConfiguration.TargetFileLocation)) if (!Directory.Exists(fileConnectorConfiguration.TargetFileLocation))
_ = Directory.CreateDirectory(fileConnectorConfiguration.TargetFileLocation); _ = Directory.CreateDirectory(fileConnectorConfiguration.TargetFileLocation);
@ -400,15 +575,15 @@ public class FileRead : Shared.FileRead, IFileRead
if (workItems.Count > 0) if (workItems.Count > 0)
{ {
ParseWorkItemsAsync(fileConnectorConfiguration, alternateTargetFolders, workItems); ParseWorkItemsAsync(fileConnectorConfiguration, alternateTargetFolders, workItems);
WriteMarkdownFile(fileConnectorConfiguration, alternateTargetFolders, workItems, workItemTypes); WriteMarkdownFile(fileConnectorConfiguration, url, alternateTargetFolders, workItems, workItemTypes);
} }
} }
private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, ReadOnlyCollection<string> workItemTypes) private static void ParseWorkItemsAsync(FileConnectorConfiguration fileConnectorConfiguration, string url, ReadOnlyCollection<string> workItemTypes)
{ {
string[] alternateTargetFolders = fileConnectorConfiguration.AlternateTargetFolder.Split('|'); string[] alternateTargetFolders = fileConnectorConfiguration.AlternateTargetFolder.Split('|');
if (alternateTargetFolders.Length > 0) if (alternateTargetFolders.Length > 0)
ParseWorkItemsAsync(fileConnectorConfiguration, alternateTargetFolders, workItemTypes); ParseWorkItemsAsync(fileConnectorConfiguration, url, alternateTargetFolders, workItemTypes);
} }
private void Callback(object state) private void Callback(object state)
@ -416,7 +591,7 @@ public class FileRead : Shared.FileRead, IFileRead
try try
{ {
if (_IsEAFHosted) if (_IsEAFHosted)
ParseWorkItemsAsync(_FileConnectorConfiguration, _WorkItemTypes); ParseWorkItemsAsync(_FileConnectorConfiguration, _URL, _WorkItemTypes);
} }
catch (Exception exception) catch (Exception exception)
{ {