ADO Markdown

This commit is contained in:
2024-09-11 20:49:14 -07:00
parent 5d679ae04c
commit ba9b7d8d64
27 changed files with 2777 additions and 33 deletions

View File

@ -89,18 +89,24 @@ internal static class HelperDay
Day.Q32024.Helper20240805.RenameFiles(logger, args);
else if (args[1] == "Day-Helper-2024-08-06")
Day.Q32024.Helper20240806.ArchiveFiles(logger, args);
#if WorkItems
else if (args[1] == "Day-Helper-2024-08-09")
Day.Q32024.Helper20240809.CreateWorkItems(logger, args);
#endif
else if (args[1] == "Day-Helper-2024-08-20")
Day.Q32024.Helper20240820.MoveFilesWithSleep(logger, args);
else if (args[1] == "Day-Helper-2024-08-22")
Day.Q32024.Helper20240822.ParseKanbn(logger, args);
else if (args[1] == "Day-Helper-2024-08-28")
Day.Q32024.Helper20240828.MoveWaferCounterToArchive(logger, args);
#if WorkItems
else if (args[1] == "Day-Helper-2024-08-30")
Day.Q32024.Helper20240830.CompareWorkItems(logger, args);
#endif
else if (args[1] == "Day-Helper-2024-09-10")
Day.Q32024.Helper20240910.MoveFilesToWeekOfYear(logger, args);
else if (args[1] == "Day-Helper-2024-09-11")
Day.Q32024.Helper20240911.WriteMarkdown(logger, args);
else
throw new Exception(appSettings.Company);
}

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
@ -141,4 +142,5 @@ internal partial class FIBacklogMesaCollectionSourceGenerationContext : JsonSeri
[JsonSerializable(typeof(FIBacklogMesa))]
internal partial class FIBacklogMesaSourceGenerationContext : JsonSerializerContext
{
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
using File_Folder_Helper.Day.Q32024.WorkItems;
using File_Folder_Helper.Models;
@ -700,4 +701,5 @@ internal static partial class Helper20240809
CreateWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, assignedToNames, requestorNames, reportFullPath, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient);
}
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using File_Folder_Helper.Day.Q32024.WorkItems;
using Microsoft.Extensions.Logging;
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
@ -231,4 +232,5 @@ internal static partial class Helper20240830
CompareWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient);
}
}
}
#endif

View File

@ -0,0 +1,179 @@
using Microsoft.Extensions.Logging;
using System.Collections.ObjectModel;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024;
internal static partial class Helper20240911
{
public record Attribute([property: JsonPropertyName("isLocked")] bool IsLocked,
[property: JsonPropertyName("name")] string Name);
public record Relation([property: JsonPropertyName("rel")] string Type,
[property: JsonPropertyName("url")] string URL,
[property: JsonPropertyName("attributes")] Attribute Attribute);
public record Record(WorkItem WorkItem, ReadOnlyDictionary<int, Record> Children);
public record WorkItem(string AreaPath,
string? AssignedTo,
int? BusinessValue,
DateTime ChangedDate,
DateTime? ClosedDate,
int CommentCount,
DateTime CreatedDate,
string Description,
float? Effort,
int Id,
string IterationPath,
int? Parent,
int? Priority,
Relation[] Relations,
string? Requester,
DateTime? ResolvedDate,
int Revision,
int? RiskReductionMinusOpportunityEnablement,
DateTime? StartDate,
string State,
string Tags,
DateTime? TargetDate,
float? TimeCriticality,
string Title,
string WorkItemType,
float? WeightedShortestJobFirst);
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WorkItem))]
internal partial class WorkItemSourceGenerationContext : JsonSerializerContext
{
}
private static ReadOnlyDictionary<int, WorkItem> GetWorkItems(string filterDirectory, string[] files)
{
Dictionary<int, WorkItem> results = [];
string json;
WorkItem? workItem;
string? directoryName;
foreach (string file in files)
{
directoryName = Path.GetDirectoryName(file);
if (string.IsNullOrEmpty(directoryName))
continue;
if (!directoryName.EndsWith(filterDirectory))
continue;
json = File.ReadAllText(file);
workItem = JsonSerializer.Deserialize(json, WorkItemSourceGenerationContext.Default.WorkItem);
if (workItem is null)
continue;
results.Add(workItem.Id, workItem);
}
return new(results);
}
private static int? GetIdFromUrlIfChild(Relation relation)
{
int? result;
string[] segments = relation.Attribute.Name != "Child" ? [] : 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;
}
private static Dictionary<int, Record> GetKeyValuePairs(ReadOnlyDictionary<int, WorkItem> workItems, WorkItem workItem)
{
Dictionary<int, Record> results = [];
int? childId;
WorkItem? childWorkItem;
Dictionary<int, Record> keyValuePairs;
if (workItem.Relations is not null && workItem.Relations.Length > 0)
{
foreach (Relation relation in workItem.Relations)
{
childId = GetIdFromUrlIfChild(relation);
if (childId is null || !workItems.TryGetValue(childId.Value, out childWorkItem))
continue;
keyValuePairs = GetKeyValuePairs(workItems, childWorkItem);
results.Add(childId.Value, new(childWorkItem, new(keyValuePairs)));
}
}
return results;
}
private static ReadOnlyDictionary<int, Record> GetWorkItemAndChildren(ReadOnlyDictionary<int, WorkItem> workItems)
{
Dictionary<int, Record> results = [];
Dictionary<int, Record> keyValuePairs;
foreach (KeyValuePair<int, WorkItem> keyValuePair in workItems)
{
// if (keyValuePair.Key != 119185)
// continue;
keyValuePairs = GetKeyValuePairs(workItems, keyValuePair.Value);
results.Add(keyValuePair.Key, new(keyValuePair.Value, new(keyValuePairs)));
}
return new(results);
}
private static string GetClosed(WorkItem workItem)
{
string result = workItem.ClosedDate is null ? "[ ]" : "[x]";
return result;
}
private static void AppendLines(List<char> spaces, List<string> lines, Record record)
{
spaces.Add('\t');
WorkItem workItem;
foreach (KeyValuePair<int, Record> keyValuePair in record.Children)
{
workItem = keyValuePair.Value.WorkItem;
lines.Add($"{new string(spaces.ToArray())}- {GetClosed(workItem)} {keyValuePair.Key} - {workItem.Title} - {workItem.ClosedDate}");
AppendLines(spaces, lines, keyValuePair.Value);
}
spaces.RemoveAt(0);
}
private static void AppendLines(List<char> spaces, List<string> lines, ReadOnlyDictionary<int, Record> workItemAndChildren)
{
WorkItem workItem;
foreach (KeyValuePair<int, Record> keyValuePair in workItemAndChildren)
{
workItem = keyValuePair.Value.WorkItem;
lines.Add($"## {keyValuePair.Key} - {workItem.Title}");
lines.Add(string.Empty);
lines.Add($"{new string(spaces.ToArray())}- {GetClosed(workItem)} {keyValuePair.Key} - {workItem.Title} - {workItem.ClosedDate}");
AppendLines(spaces, lines, keyValuePair.Value);
lines.Add(string.Empty);
}
}
internal static void WriteMarkdown(ILogger<Worker> logger, List<string> args)
{
List<char> spaces = [];
string searchPattern = args[2];
string filterDirectory = args[3];
List<string> lines = ["# WorkItems", string.Empty];
string sourceDirectory = Path.GetFullPath(args[0]);
string[] files = Directory.GetFiles(sourceDirectory, searchPattern, SearchOption.AllDirectories);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} file(s)", searchPattern, files.Length);
ReadOnlyDictionary<int, WorkItem> workItems = GetWorkItems(filterDirectory, files);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} workItem(s)", searchPattern, workItems.Count);
ReadOnlyDictionary<int, Record> workItemAndChildren = GetWorkItemAndChildren(workItems);
logger.LogInformation("With search pattern '{SearchPattern}' found {files} workItemAndChildren", searchPattern, workItemAndChildren.Count);
if (workItemAndChildren.Count == -1)
{
string json = JsonSerializer.Serialize(workItemAndChildren, new JsonSerializerOptions() { WriteIndented = true });
File.WriteAllText(".json", json);
}
AppendLines(spaces, lines, workItemAndChildren);
File.WriteAllText(".md", string.Join(Environment.NewLine, lines));
}
}

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
@ -19,4 +20,5 @@ public class Column
public string ReferenceName { get; set; } // { init; get; }
public string Name { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
@ -19,4 +20,5 @@ public class Field
public string ReferenceName { get; set; } // { init; get; }
public string Name { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
@ -34,4 +35,5 @@ public class Root
[JsonSerializable(typeof(Root))]
internal partial class WIQLRootSourceGenerationContext : JsonSerializerContext
{
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
@ -16,4 +17,5 @@ public class SortColumn
public Field Field { get; set; } // { init; get; }
public bool Descending { get; set; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WIQL;
@ -16,4 +17,5 @@ public class WorkItem
public int Id { get; set; } // { init; get; }
public string Url { get; set; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -10,4 +11,5 @@ public class Avatar
) => Href = href;
public string Href { get; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -24,4 +25,5 @@ public class CommentVersionRef
[JsonPropertyName("url")]
public string URL { get; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -31,4 +32,5 @@ public class CustomRequester
[JsonPropertyName("_links")] public Links Links { get; }
[JsonPropertyName("uniqueName")] public string UniqueName { get; }
[JsonPropertyName("url")] public string Url { get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -96,4 +97,5 @@ public class Fields
[JsonPropertyName("System.Title")] public string SystemTitle { get; } // { init; get; }
[JsonPropertyName("System.WorkItemType")] public string SystemWorkItemType { get; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -10,4 +11,5 @@ public class Html
) => Href = href;
public string Href { get; } // { init; get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -11,4 +12,5 @@ public class Links
[JsonPropertyName("avatar")]
public Avatar Avatar { get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -44,4 +45,5 @@ public class SystemAssignedTo
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -44,4 +45,5 @@ public class SystemChangedBy
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -44,4 +45,5 @@ public class SystemCreatedBy
[JsonPropertyName("descriptor")]
public string Descriptor { get; }
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
using System.Text.Json.Serialization;
namespace File_Folder_Helper.Day.Q32024.WorkItems;
@ -51,4 +52,5 @@ internal partial class ValueCollectionSourceGenerationContext : JsonSerializerCo
[JsonSerializable(typeof(Value))]
internal partial class ValueSourceGenerationContext : JsonSerializerContext
{
}
}
#endif

View File

@ -1,3 +1,4 @@
#if WorkItems
namespace File_Folder_Helper.Day.Q32024.WorkItems;
public class ValueWithReq
@ -16,4 +17,5 @@ public class ValueWithReq
public Value Value { get; set; } // { init; get; }
public int Req { get; set; } // { init; get; }
public string Json { get; set; } // { init; get; }
}
}
#endif