Still Testing
This commit is contained in:
parent
68c2a34096
commit
dc9327274b
16
.vscode/launch.json
vendored
16
.vscode/launch.json
vendored
@ -13,12 +13,24 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"D:/Tmp/phares/Production__v2_57_0__HGCV1__pcl__Normal",
|
"D:/5-Other-Small/Kanban-mestsa003/ART-SPS/2024/PI4/Sprint-4.1/126996-User-Story",
|
||||||
|
"Day-Helper-2024-11-08",
|
||||||
|
"Bug|User Story",
|
||||||
|
"D:/5-Other-Small/Kanban-mestsa003/ART-SPS",
|
||||||
|
"444",
|
||||||
|
"555",
|
||||||
|
"666",
|
||||||
|
"777",
|
||||||
|
"888",
|
||||||
|
"999",
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"D:/5-Other-Small/Kanban-mestsa003/ART-SPS/2024/PI4/Sprint-4.1/126448-User-Story/.files/Production__v2_57_0__HGCV1__pcl__Normal",
|
||||||
"Day-Helper-2024-10-30",
|
"Day-Helper-2024-10-30",
|
||||||
"*.txt",
|
"*.txt",
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"D:/Tmp/phares/Production__v2_57_0__CDE6__RsM__Normal",
|
"D:/5-Other-Small/Kanban-mestsa003/ART-SPS/2024/PI4/Sprint-4.1/126448-User-Story/.files/Production__v2_57_0__CDE6__RsM__Normal",
|
||||||
"Day-Helper-2024-10-31",
|
"Day-Helper-2024-10-31",
|
||||||
"*.RsM",
|
"*.RsM",
|
||||||
"s",
|
"s",
|
||||||
|
8
.vscode/mklink.md
vendored
8
.vscode/mklink.md
vendored
@ -18,11 +18,11 @@ mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.kanbn" "D:\5-Other-Small\Kanban
|
|||||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode"
|
||||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss"
|
||||||
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
del "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders"
|
||||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode" "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.7.0"
|
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode" "C:\Users\phares\.vscode\extensions\ifx.type-script-helper-1.8.0"
|
||||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss" "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.7.0"
|
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-oss" "C:\Users\phares\.vscode-oss\extensions\ifx.type-script-helper-1.8.0"
|
||||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders" "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.7.0"
|
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.extensions-vscode-insiders" "C:\Users\phares\.vscode-insiders\extensions\ifx.type-script-helper-1.8.0"
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash Thu Jul 18 2024 13:47:40 GMT-0700 (Mountain Standard Time)
|
```bash Thu Jul 18 2024 13:47:40 GMT-0700 (Mountain Standard Time)
|
||||||
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.UserSecrets" "L:\Git\Notes-User-Secrets\.UserSecrets\8da397d4-13ec-4576-9722-3c79cad25563"
|
mklink /J "L:\DevOps\Mesa_FI\File-Folder-Helper\.vscode\.UserSecrets" "C:\Users\phares\AppData\Roaming\Microsoft\UserSecrets\8da397d4-13ec-4576-9722-3c79cad25563"
|
||||||
```
|
```
|
||||||
|
5
.vscode/tasks.json
vendored
5
.vscode/tasks.json
vendored
@ -132,6 +132,11 @@
|
|||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
|
"command": "L:/DevOps/Mesa_FI/File-Folder-Helper/bin/Release/net8.0/win-x64/publish/File-Folder-Helper.exe",
|
||||||
"args": [
|
"args": [
|
||||||
|
"s",
|
||||||
|
"X",
|
||||||
|
"T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG",
|
||||||
|
"Day-Helper-2024-01-08",
|
||||||
|
"T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG/Adaptation/FileHandlers/ADO",
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG",
|
"T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#if WorkItems
|
#if WorkItems
|
||||||
using File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
|
using File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
|
||||||
using File_Folder_Helper.Day.Q32024.WorkItems;
|
using File_Folder_Helper.ADO2024.PI3.WorkItems;
|
||||||
using File_Folder_Helper.Models;
|
using File_Folder_Helper.Models;
|
||||||
#endif
|
#endif
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
@ -78,7 +78,7 @@ internal static partial class Helper20240911
|
|||||||
|
|
||||||
[JsonSourceGenerationOptions(WriteIndented = true)]
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
[JsonSerializable(typeof(WorkItem[]))]
|
[JsonSerializable(typeof(WorkItem[]))]
|
||||||
private partial class WorkItemSourceGenerationContext : JsonSerializerContext
|
private partial class WorkItemCollectionSourceGenerationContext : JsonSerializerContext
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,7 +355,7 @@ internal static partial class Helper20240911
|
|||||||
if (productionJSON.Result != developmentJSON.Result)
|
if (productionJSON.Result != developmentJSON.Result)
|
||||||
logger.LogWarning("productionJSON doesn't match developmentJSON");
|
logger.LogWarning("productionJSON doesn't match developmentJSON");
|
||||||
}
|
}
|
||||||
WorkItem[]? workItems = JsonSerializer.Deserialize(developmentJSON.Result, WorkItemSourceGenerationContext.Default.WorkItemArray);
|
WorkItem[]? workItems = JsonSerializer.Deserialize(developmentJSON.Result, WorkItemCollectionSourceGenerationContext.Default.WorkItemArray);
|
||||||
if (workItems is null)
|
if (workItems is null)
|
||||||
logger.LogWarning("workItems is null");
|
logger.LogWarning("workItems is null");
|
||||||
else
|
else
|
||||||
@ -400,7 +400,7 @@ internal static partial class Helper20240911
|
|||||||
string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile);
|
string htmlOld = !File.Exists(htmlFile) ? string.Empty : File.ReadAllText(htmlFile);
|
||||||
if (html != htmlOld)
|
if (html != htmlOld)
|
||||||
File.WriteAllText(htmlFile, html);
|
File.WriteAllText(htmlFile, html);
|
||||||
string json = JsonSerializer.Serialize(workItems.ToArray(), WorkItemSourceGenerationContext.Default.WorkItemArray);
|
string json = JsonSerializer.Serialize(workItems.ToArray(), WorkItemCollectionSourceGenerationContext.Default.WorkItemArray);
|
||||||
string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json");
|
string jsonFile = Path.Combine(destinationDirectory, $"{fileName}.json");
|
||||||
string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
string jsonOld = !File.Exists(jsonFile) ? string.Empty : File.ReadAllText(jsonFile);
|
||||||
if (json != jsonOld)
|
if (json != jsonOld)
|
||||||
@ -704,7 +704,6 @@ internal static partial class Helper20240911
|
|||||||
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(logger, args[2], args[3]);
|
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(logger, args[2], args[3]);
|
||||||
WriteFileStructure(destinationDirectory, keyValuePairs);
|
WriteFileStructure(destinationDirectory, keyValuePairs);
|
||||||
ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray());
|
ReadOnlyCollection<Record> records = new(keyValuePairs.Values.ToArray());
|
||||||
logger.LogInformation("Found {workItems} workItemAndChildren", records.Count);
|
|
||||||
ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" });
|
ReadOnlyCollection<string> bugUserStoryWorkItemTypes = new(new string[] { "Bug", "User Story" });
|
||||||
ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" });
|
ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" });
|
||||||
WriteFiles(destinationDirectory, records, "with-parents");
|
WriteFiles(destinationDirectory, records, "with-parents");
|
||||||
|
@ -420,8 +420,12 @@ internal static partial class Helper20241030
|
|||||||
|
|
||||||
internal static void GetComplete(ILogger<Worker> logger, List<string> args)
|
internal static void GetComplete(ILogger<Worker> logger, List<string> args)
|
||||||
{
|
{
|
||||||
logger.LogError("GetComplete is not available in CDE {args[0]}", args[0]);
|
string searchPattern = args[2];
|
||||||
logger.LogError("GetComplete is not available in CDE {args[1]}", args[1]);
|
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||||
|
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
if (files.Length != 1)
|
||||||
|
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
|
||||||
|
logger.LogError("GetComplete is not available in HgCV {args[1]}", args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -546,7 +546,11 @@ internal static partial class Helper20241031
|
|||||||
|
|
||||||
internal static void GetComplete(ILogger<Worker> logger, List<string> args)
|
internal static void GetComplete(ILogger<Worker> logger, List<string> args)
|
||||||
{
|
{
|
||||||
logger.LogError("GetComplete is not available in CDE {args[0]}", args[0]);
|
string searchPattern = args[2];
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||||
|
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.TopDirectoryOnly);
|
||||||
|
if (files.Length != 1)
|
||||||
|
logger.LogError("No files found in {sourceDirectory} with search pattern {searchPattern}", sourceDirectory, searchPattern);
|
||||||
logger.LogError("GetComplete is not available in CDE {args[1]}", args[1]);
|
logger.LogError("GetComplete is not available in CDE {args[1]}", args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
393
ADO2024/PI4/Helper-2024-11-08.cs
Normal file
393
ADO2024/PI4/Helper-2024-11-08.cs
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.ADO2024.PI4;
|
||||||
|
|
||||||
|
internal static partial class Helper20241108
|
||||||
|
{
|
||||||
|
|
||||||
|
private record Attribute([property: JsonPropertyName("isLocked")] bool IsLocked,
|
||||||
|
[property: JsonPropertyName("name")] string Name);
|
||||||
|
|
||||||
|
private record Relation([property: JsonPropertyName("rel")] string Type,
|
||||||
|
[property: JsonPropertyName("url")] string URL,
|
||||||
|
[property: JsonPropertyName("attributes")] Attribute Attributes);
|
||||||
|
|
||||||
|
private record WorkItem(DateTime? ActivatedDate,
|
||||||
|
string AreaPath,
|
||||||
|
string? AssignedTo,
|
||||||
|
long? BusinessValue,
|
||||||
|
DateTime ChangedDate,
|
||||||
|
DateTime? ClosedDate,
|
||||||
|
int CommentCount,
|
||||||
|
DateTime CreatedDate,
|
||||||
|
string Description,
|
||||||
|
long? Effort,
|
||||||
|
int Id,
|
||||||
|
string IterationPath,
|
||||||
|
int? Parent,
|
||||||
|
int? Priority,
|
||||||
|
Relation[]? Relations,
|
||||||
|
string? Requester,
|
||||||
|
DateTime? ResolvedDate,
|
||||||
|
int Revision,
|
||||||
|
long? RiskReductionMinusOpportunityEnablement,
|
||||||
|
DateTime? StartDate,
|
||||||
|
string State,
|
||||||
|
string Tags,
|
||||||
|
DateTime? TargetDate,
|
||||||
|
long? TimeCriticality,
|
||||||
|
string Title,
|
||||||
|
string? Violation,
|
||||||
|
long? WeightedShortestJobFirst,
|
||||||
|
string WorkItemType)
|
||||||
|
{
|
||||||
|
|
||||||
|
public override string ToString() => $"{Id} - {WorkItemType} - {Title}";
|
||||||
|
|
||||||
|
public static WorkItem? GetWithOutRelations(WorkItem? workItem)
|
||||||
|
{
|
||||||
|
WorkItem? result = workItem is null ? null : new(workItem.ActivatedDate,
|
||||||
|
workItem.AreaPath,
|
||||||
|
workItem.AssignedTo,
|
||||||
|
workItem.BusinessValue,
|
||||||
|
workItem.ChangedDate,
|
||||||
|
workItem.ClosedDate,
|
||||||
|
workItem.CommentCount,
|
||||||
|
workItem.CreatedDate,
|
||||||
|
workItem.Description,
|
||||||
|
workItem.Effort,
|
||||||
|
workItem.Id,
|
||||||
|
workItem.IterationPath,
|
||||||
|
workItem.Parent,
|
||||||
|
workItem.Priority,
|
||||||
|
Array.Empty<Relation>(),
|
||||||
|
workItem.Requester,
|
||||||
|
workItem.ResolvedDate,
|
||||||
|
workItem.Revision,
|
||||||
|
workItem.RiskReductionMinusOpportunityEnablement,
|
||||||
|
workItem.StartDate,
|
||||||
|
workItem.State,
|
||||||
|
workItem.Tags,
|
||||||
|
workItem.TargetDate,
|
||||||
|
workItem.TimeCriticality,
|
||||||
|
workItem.Title,
|
||||||
|
workItem.Violation,
|
||||||
|
workItem.WeightedShortestJobFirst,
|
||||||
|
workItem.WorkItemType);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(WorkItem))]
|
||||||
|
private partial class WorkItemSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Record(WorkItem WorkItem, WorkItem? Parent, Record[] Children, Record[] Related, Record[] Successors)
|
||||||
|
{
|
||||||
|
|
||||||
|
internal static Record GetWithoutNesting(Record record, string? violation)
|
||||||
|
{
|
||||||
|
Record result;
|
||||||
|
WorkItem workItem = new(record.WorkItem.ActivatedDate,
|
||||||
|
record.WorkItem.AreaPath,
|
||||||
|
record.WorkItem.AssignedTo,
|
||||||
|
record.WorkItem.BusinessValue,
|
||||||
|
record.WorkItem.ChangedDate,
|
||||||
|
record.WorkItem.ClosedDate,
|
||||||
|
record.WorkItem.CommentCount,
|
||||||
|
record.WorkItem.CreatedDate,
|
||||||
|
record.WorkItem.Description,
|
||||||
|
record.WorkItem.Effort,
|
||||||
|
record.WorkItem.Id,
|
||||||
|
record.WorkItem.IterationPath,
|
||||||
|
record.WorkItem.Parent,
|
||||||
|
record.WorkItem.Priority,
|
||||||
|
record.WorkItem.Relations,
|
||||||
|
record.WorkItem.Requester,
|
||||||
|
record.WorkItem.ResolvedDate,
|
||||||
|
record.WorkItem.Revision,
|
||||||
|
record.WorkItem.RiskReductionMinusOpportunityEnablement,
|
||||||
|
record.WorkItem.StartDate,
|
||||||
|
record.WorkItem.State,
|
||||||
|
record.WorkItem.Tags,
|
||||||
|
record.WorkItem.TargetDate,
|
||||||
|
record.WorkItem.TimeCriticality,
|
||||||
|
record.WorkItem.Title,
|
||||||
|
record.WorkItem.Violation is null ? violation : record.WorkItem.Violation,
|
||||||
|
record.WorkItem.WeightedShortestJobFirst,
|
||||||
|
record.WorkItem.WorkItemType);
|
||||||
|
result = new(workItem, record.Parent, [], [], []);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Record Get(Record record, bool keepRelations)
|
||||||
|
{
|
||||||
|
Record result;
|
||||||
|
WorkItem? parentWorkItem = keepRelations ? record.Parent : WorkItem.GetWithOutRelations(record.Parent);
|
||||||
|
WorkItem? workItem = keepRelations ? record.WorkItem : WorkItem.GetWithOutRelations(record.WorkItem) ?? throw new Exception();
|
||||||
|
List<Record> childRecords = [];
|
||||||
|
List<Record> relatedRecords = [];
|
||||||
|
List<Record> successorRecords = [];
|
||||||
|
foreach (Record r in record.Children)
|
||||||
|
childRecords.Add(Get(r, keepRelations));
|
||||||
|
foreach (Record r in record.Related)
|
||||||
|
relatedRecords.Add(Get(r, keepRelations));
|
||||||
|
foreach (Record r in record.Successors)
|
||||||
|
successorRecords.Add(Get(r, keepRelations));
|
||||||
|
result = new(workItem, parentWorkItem, childRecords.ToArray(), relatedRecords.ToArray(), successorRecords.ToArray());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static Record Get(WorkItem workItem, WorkItem? parent, ReadOnlyCollection<Record> children, ReadOnlyCollection<Record> related, ReadOnlyCollection<Record> successors, bool keepRelations)
|
||||||
|
{
|
||||||
|
Record result;
|
||||||
|
Record record = new(workItem, parent, children.ToArray(), related.ToArray(), successors.ToArray());
|
||||||
|
result = Get(record, keepRelations);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? GetIdFromUrl(string relationName, Relation relation)
|
||||||
|
{
|
||||||
|
int? result;
|
||||||
|
string[] segments = relation?.Attributes is null || relation.Attributes.Name != relationName ? [] : relation.URL.Split('/');
|
||||||
|
if (segments.Length < 2)
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!int.TryParse(segments[^1], out int id))
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
result = id;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static ReadOnlyCollection<Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, WorkItem workItem, string relationName, List<bool> nests, bool keepRelations)
|
||||||
|
{
|
||||||
|
List<Record> results = [];
|
||||||
|
int? childId;
|
||||||
|
Record record;
|
||||||
|
nests.Add(true);
|
||||||
|
WorkItem? childWorkItem;
|
||||||
|
WorkItem? parentWorkItem;
|
||||||
|
List<WorkItem> collection = [];
|
||||||
|
ReadOnlyCollection<Record> childRecords;
|
||||||
|
ReadOnlyCollection<Record> relatedRecords;
|
||||||
|
ReadOnlyCollection<Record> successorRecords;
|
||||||
|
if (workItem.Relations is not null && workItem.Relations.Length > 0)
|
||||||
|
{
|
||||||
|
collection.Clear();
|
||||||
|
foreach (Relation relation in workItem.Relations)
|
||||||
|
{
|
||||||
|
childId = GetIdFromUrl(relationName, relation);
|
||||||
|
if (childId is not null && workItem.Parent is not null && relation?.URL is not null && relation.URL.Contains(workItem.Parent.Value.ToString()))
|
||||||
|
continue;
|
||||||
|
if (childId is null || !keyValuePairs.TryGetValue(childId.Value, out childWorkItem))
|
||||||
|
continue;
|
||||||
|
collection.Add(childWorkItem);
|
||||||
|
}
|
||||||
|
collection = (from l in collection orderby l.State != "Closed", l.Id select l).ToList();
|
||||||
|
foreach (WorkItem w in collection)
|
||||||
|
{
|
||||||
|
if (nests.Count > 99)
|
||||||
|
break;
|
||||||
|
if (w.Parent is null)
|
||||||
|
parentWorkItem = null;
|
||||||
|
else
|
||||||
|
_ = keyValuePairs.TryGetValue(w.Parent.Value, out parentWorkItem);
|
||||||
|
childRecords = GetKeyValuePairs(keyValuePairs, w, "Child", nests, keepRelations); // Forward
|
||||||
|
// records = GetKeyValuePairs(keyValuePairs, w, "Predecessor", nests); // Reverse
|
||||||
|
// successorRecords = GetKeyValuePairs(keyValuePairs, w, "Successor", nests); // Forward
|
||||||
|
// if (successorRecords.Count > 0)
|
||||||
|
// {
|
||||||
|
// if (successorRecords.Count > 0)
|
||||||
|
// { }
|
||||||
|
// }
|
||||||
|
successorRecords = new([]);
|
||||||
|
relatedRecords = GetKeyValuePairs(keyValuePairs, w, "Related", nests, keepRelations); // Related
|
||||||
|
record = Get(w, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||||
|
results.Add(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true)]
|
||||||
|
[JsonSerializable(typeof(Record[]))]
|
||||||
|
private partial class RecordCollectionBCommonSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> keyValuePairs, bool keepRelations)
|
||||||
|
{
|
||||||
|
Dictionary<int, Record> results = [];
|
||||||
|
Record record;
|
||||||
|
List<bool> nests = [];
|
||||||
|
WorkItem? parentWorkItem;
|
||||||
|
ReadOnlyCollection<Record> childRecords;
|
||||||
|
ReadOnlyCollection<Record> relatedRecords;
|
||||||
|
ReadOnlyCollection<Record> successorRecords;
|
||||||
|
foreach (KeyValuePair<int, WorkItem> keyValuePair in keyValuePairs)
|
||||||
|
{
|
||||||
|
nests.Clear();
|
||||||
|
if (keyValuePair.Value.Parent is null)
|
||||||
|
parentWorkItem = null;
|
||||||
|
else
|
||||||
|
_ = keyValuePairs.TryGetValue(keyValuePair.Value.Parent.Value, out parentWorkItem);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
childRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Child", nests, keepRelations); // Forward
|
||||||
|
// records = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Predecessor", nests, keepRelations); // Reverse
|
||||||
|
relatedRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Related", nests, keepRelations); // Related
|
||||||
|
successorRecords = Record.GetKeyValuePairs(keyValuePairs, keyValuePair.Value, "Successor", nests, keepRelations); // Forward
|
||||||
|
record = Record.Get(keyValuePair.Value, parentWorkItem, childRecords, relatedRecords, successorRecords, keepRelations);
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
record = new(keyValuePair.Value, parentWorkItem, [], [], []);
|
||||||
|
}
|
||||||
|
results.Add(keyValuePair.Key, record);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<int, Record> GetWorkItems(ReadOnlyCollection<WorkItem> workItems, bool keepRelations)
|
||||||
|
{
|
||||||
|
ReadOnlyDictionary<int, Record> results;
|
||||||
|
Dictionary<int, WorkItem> keyValuePairs = [];
|
||||||
|
foreach (WorkItem workItem in workItems)
|
||||||
|
keyValuePairs.Add(workItem.Id, workItem);
|
||||||
|
results = GetKeyValuePairs(new(keyValuePairs), keepRelations);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<int, string> GetCurrentDirectories(string destinationDirectory, ReadOnlyCollection<string> bugUserStoryWorkItemTypes)
|
||||||
|
{
|
||||||
|
Dictionary<int, string> results = [];
|
||||||
|
int id;
|
||||||
|
string idCheck;
|
||||||
|
string? fileName;
|
||||||
|
string[] directories;
|
||||||
|
string[] split = ["-"];
|
||||||
|
foreach (string w in bugUserStoryWorkItemTypes)
|
||||||
|
{
|
||||||
|
directories = Directory.GetDirectories(destinationDirectory, $"*-{w.Replace(" ", "-")}", SearchOption.AllDirectories);
|
||||||
|
foreach (string directory in directories)
|
||||||
|
{
|
||||||
|
fileName = Path.GetFileName(directory);
|
||||||
|
if (string.IsNullOrEmpty(fileName))
|
||||||
|
continue;
|
||||||
|
idCheck = fileName.Split(split, StringSplitOptions.None)[0];
|
||||||
|
if (!int.TryParse(idCheck, out id))
|
||||||
|
continue;
|
||||||
|
if (!results.ContainsKey(id))
|
||||||
|
results.Add(id, directory);
|
||||||
|
else
|
||||||
|
MoveToDuplicate(destinationDirectory, directory);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MoveToDuplicate(string destinationDirectory, string directory)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(destinationDirectory))
|
||||||
|
throw new ArgumentException($"'{nameof(destinationDirectory)}' cannot be null or empty.", nameof(destinationDirectory));
|
||||||
|
if (string.IsNullOrEmpty(directory))
|
||||||
|
throw new ArgumentException($"'{nameof(directory)}' cannot be null or empty.", nameof(directory));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<WorkItem> GetWorkItems(string sourceDirectory, ReadOnlyCollection<string> bugUserStoryWorkItemTypes)
|
||||||
|
{
|
||||||
|
List<WorkItem> results = [];
|
||||||
|
string json;
|
||||||
|
string checkFile;
|
||||||
|
WorkItem? workItem;
|
||||||
|
string directoryName;
|
||||||
|
string? checkDirectory = null;
|
||||||
|
foreach (string w in bugUserStoryWorkItemTypes)
|
||||||
|
{
|
||||||
|
directoryName = Path.GetFileName(sourceDirectory);
|
||||||
|
if (!directoryName.EndsWith(w.Replace(" ", "-")))
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(sourceDirectory, directoryName.Split('-')[0]);
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
{
|
||||||
|
checkDirectory = null;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(checkDirectory))
|
||||||
|
{
|
||||||
|
checkFile = Path.Combine(checkDirectory, ".json");
|
||||||
|
if (File.Exists(checkFile))
|
||||||
|
{
|
||||||
|
json = File.ReadAllText(checkFile);
|
||||||
|
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
|
||||||
|
if (workItem is not null)
|
||||||
|
results.Add(workItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<WorkItem> GetWorkItems(ReadOnlyDictionary<int, string> collection)
|
||||||
|
{
|
||||||
|
List<WorkItem> results = [];
|
||||||
|
string json;
|
||||||
|
string checkFile;
|
||||||
|
string? directory;
|
||||||
|
WorkItem? workItem;
|
||||||
|
string? checkDirectory;
|
||||||
|
foreach (KeyValuePair<int, string> keyValuePair in collection)
|
||||||
|
{
|
||||||
|
if (!collection.TryGetValue(keyValuePair.Key, out directory) || string.IsNullOrEmpty(directory))
|
||||||
|
continue;
|
||||||
|
checkDirectory = Path.Combine(directory, $"{keyValuePair.Key}");
|
||||||
|
if (!Directory.Exists(checkDirectory))
|
||||||
|
continue;
|
||||||
|
checkFile = Path.Combine(checkDirectory, ".json");
|
||||||
|
if (!File.Exists(checkFile))
|
||||||
|
continue;
|
||||||
|
json = File.ReadAllText(checkFile);
|
||||||
|
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
|
||||||
|
if (workItem is null)
|
||||||
|
continue;
|
||||||
|
results.Add(workItem);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<WorkItem> GetWorkItems(string sourceDirectory, ReadOnlyCollection<string> bugUserStoryWorkItemTypes, ReadOnlyDictionary<int, string> collection)
|
||||||
|
{
|
||||||
|
ReadOnlyCollection<WorkItem> results;
|
||||||
|
if (collection.Count > 0)
|
||||||
|
results = GetWorkItems(collection);
|
||||||
|
else
|
||||||
|
results = GetWorkItems(sourceDirectory, bugUserStoryWorkItemTypes);
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args)
|
||||||
|
{
|
||||||
|
// string url = args[5];
|
||||||
|
bool keepRelations = true;
|
||||||
|
string sourceDirectory = Path.GetFullPath(args[0]);
|
||||||
|
ReadOnlyCollection<string> bugUserStoryWorkItemTypes = args[2].Split('|').ToArray().AsReadOnly();
|
||||||
|
// ReadOnlyCollection<string> bugUserStoryTaskWorkItemTypes = new(new string[] { "Bug", "User Story", "Task" });
|
||||||
|
ReadOnlyDictionary<int, string> collection = GetCurrentDirectories(sourceDirectory, bugUserStoryWorkItemTypes);
|
||||||
|
ReadOnlyCollection<WorkItem> workItems = GetWorkItems(sourceDirectory, bugUserStoryWorkItemTypes, collection);
|
||||||
|
ReadOnlyDictionary<int, Record> keyValuePairs = GetWorkItems(workItems, keepRelations);
|
||||||
|
logger.LogInformation("Found {keyValuePairs}", keyValuePairs.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -115,6 +115,8 @@ internal static class HelperDay
|
|||||||
ADO2024.PI3.Helper20241030.GetComplete(logger, args);
|
ADO2024.PI3.Helper20241030.GetComplete(logger, args);
|
||||||
else if (args[1] == "Day-Helper-2024-10-31")
|
else if (args[1] == "Day-Helper-2024-10-31")
|
||||||
ADO2024.PI3.Helper20241031.GetComplete(logger, args);
|
ADO2024.PI3.Helper20241031.GetComplete(logger, args);
|
||||||
|
else if (args[1] == "Day-Helper-2024-11-08")
|
||||||
|
ADO2024.PI4.Helper20241108.WriteMarkdown(logger, args);
|
||||||
else
|
else
|
||||||
throw new Exception(appSettings.Company);
|
throw new Exception(appSettings.Company);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#if WorkItems
|
#if WorkItems
|
||||||
using File_Folder_Helper.Day.Q32024.WorkItems;
|
using File_Folder_Helper.ADO2024.PI3.WorkItems;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models;
|
namespace File_Folder_Helper.Models;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#if WorkItems
|
#if WorkItems
|
||||||
using File_Folder_Helper.Day.Q32024.WorkItems;
|
using File_Folder_Helper.ADO2024.PI3.WorkItems;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace File_Folder_Helper.Models;
|
namespace File_Folder_Helper.Models;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user