Ready to start loading backlog
This commit is contained in:
parent
29bec0cb9a
commit
754cc1ee2b
24
.vscode/launch.json
vendored
24
.vscode/launch.json
vendored
@ -13,17 +13,19 @@
|
|||||||
"args": [
|
"args": [
|
||||||
"s",
|
"s",
|
||||||
"X",
|
"X",
|
||||||
"D:/5-Other-Small/Kanban-mestsa003/FI-Backlog-Mesa-Request-List/859-FI-Backlog-Mesa-Request-List/.vscode",
|
"T:/MESAFIBACKLOG/06_SourceCode/MESAFIBACKLOG/Adaptation/.vscode/helper",
|
||||||
"Day-Helper-2024-08-06",
|
"Day-Helper-2024-08-09",
|
||||||
"1000",
|
"MES",
|
||||||
"D:/Logs",
|
"https://tfs.intra.infineon.com",
|
||||||
"*.txt",
|
"/tfs/FactoryIntegration",
|
||||||
"25",
|
"ART SPS",
|
||||||
"4",
|
"/_apis/wit",
|
||||||
"D:/IFXApps/Logs",
|
"/wiql/3373b300-8de3-4301-9795-e990c3b226f9",
|
||||||
"8888",
|
"4n7d2jcql6bkq32f66tohddonfxajkypq66lm5y3zqemtlohawsa",
|
||||||
"9999"
|
"FI Backlog Mesa - Request List.json",
|
||||||
],
|
"Chase|infineon\\TuckerC,Dakota(SRP)|infineon\\Mitchem,Daniel|infineon\\StieberD,Jonathan|infineon\\Ouellette,Mike|infineon\\Phares",
|
||||||
|
"Chad B|infineon\\cbecker1,Debra Q|infineon\\Quinones,Jeanne M|infineon\\jmcinty2,Jessica F|infineon\\jfuente1,Jonathon S|infineon\\jsperli1,Justin H|infineon\\jhollan2,Kelly C|infineon\\kclark1,Mark C|infineon\\mcouste1,Marti J|infineon\\mjarsey1,Nik C|infineon\\nclark1,Peyton M|infineon\\McChesne,Ron O|infineon\\Olmstead,Susan H|infineon\\HendersS,Tiffany M|infineon\\tmunoz1,Todd C|infineon\\tcarrie1"
|
||||||
|
],
|
||||||
"cwd": "${workspaceFolder}",
|
"cwd": "${workspaceFolder}",
|
||||||
"console": "integratedTerminal",
|
"console": "integratedTerminal",
|
||||||
"stopAtEntry": false
|
"stopAtEntry": false
|
||||||
|
@ -89,6 +89,8 @@ internal static class HelperDay
|
|||||||
Day.Q32024.Helper20240805.RenameFiles(logger, args);
|
Day.Q32024.Helper20240805.RenameFiles(logger, args);
|
||||||
else if (args[1] == "Day-Helper-2024-08-06")
|
else if (args[1] == "Day-Helper-2024-08-06")
|
||||||
Day.Q32024.Helper20240806.ArchiveFiles(logger, args);
|
Day.Q32024.Helper20240806.ArchiveFiles(logger, args);
|
||||||
|
else if (args[1] == "Day-Helper-2024-08-09")
|
||||||
|
Day.Q32024.Helper20240809.CreateWorkItems(logger, args);
|
||||||
else
|
else
|
||||||
throw new Exception(appSettings.Company);
|
throw new Exception(appSettings.Company);
|
||||||
}
|
}
|
||||||
|
144
Day/Q32024/ConvertExcelToJson/FIBacklogMesa.cs
Normal file
144
Day/Q32024/ConvertExcelToJson/FIBacklogMesa.cs
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
|
||||||
|
|
||||||
|
public class FIBacklogMesa
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public FIBacklogMesa(string req,
|
||||||
|
string submitted,
|
||||||
|
string requestor,
|
||||||
|
string assignedTo,
|
||||||
|
string secondResource,
|
||||||
|
string subject,
|
||||||
|
string systemS,
|
||||||
|
string priority,
|
||||||
|
string training,
|
||||||
|
string prioritySubset,
|
||||||
|
string status,
|
||||||
|
string definition,
|
||||||
|
string updates,
|
||||||
|
string estEffortDays,
|
||||||
|
string commitDate,
|
||||||
|
string reCommitDate,
|
||||||
|
string uATAsOf,
|
||||||
|
string cmpDate,
|
||||||
|
string f20,
|
||||||
|
string f21,
|
||||||
|
string f22,
|
||||||
|
string f23,
|
||||||
|
string f24,
|
||||||
|
string f25,
|
||||||
|
string f26,
|
||||||
|
string f27,
|
||||||
|
string f28,
|
||||||
|
string f29,
|
||||||
|
string f30,
|
||||||
|
string f31,
|
||||||
|
string f32,
|
||||||
|
string f33)
|
||||||
|
{
|
||||||
|
Req = req;
|
||||||
|
Submitted = submitted;
|
||||||
|
Requestor = requestor;
|
||||||
|
AssignedTo = assignedTo;
|
||||||
|
SecondResource = secondResource;
|
||||||
|
Subject = subject;
|
||||||
|
SystemS = systemS;
|
||||||
|
Priority = priority;
|
||||||
|
Training = training;
|
||||||
|
PrioritySubset = prioritySubset;
|
||||||
|
Status = status;
|
||||||
|
Definition = definition;
|
||||||
|
Updates = updates;
|
||||||
|
EstEffortDays = estEffortDays;
|
||||||
|
CommitDate = commitDate;
|
||||||
|
ReCommitDate = reCommitDate;
|
||||||
|
UATAsOf = uATAsOf;
|
||||||
|
CMPDate = cmpDate;
|
||||||
|
F20 = f20;
|
||||||
|
F21 = f21;
|
||||||
|
F22 = f22;
|
||||||
|
F23 = f23;
|
||||||
|
F24 = f24;
|
||||||
|
F25 = f25;
|
||||||
|
F26 = f26;
|
||||||
|
F27 = f27;
|
||||||
|
F28 = f28;
|
||||||
|
F29 = f29;
|
||||||
|
F30 = f30;
|
||||||
|
F31 = f31;
|
||||||
|
F32 = f32;
|
||||||
|
F33 = f33;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Req { get; set; } // { init; get; }
|
||||||
|
public string Submitted { get; set; } // { init; get; }
|
||||||
|
public string Requestor { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Assigned To")]
|
||||||
|
public string AssignedTo { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Second Resource")]
|
||||||
|
public string SecondResource { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Subject - from Requestor")]
|
||||||
|
public string Subject { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System(s)")]
|
||||||
|
public string SystemS { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
public string Priority { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Spec/ECN/Training")]
|
||||||
|
public string Training { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Qual/Eff")]
|
||||||
|
public string PrioritySubset { get; set; } // { init; get; }
|
||||||
|
public string Status { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Definition - from FI")]
|
||||||
|
public string Definition { get; set; } // { init; get; }
|
||||||
|
public string Updates { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Est Effort _(days)")]
|
||||||
|
public string EstEffortDays { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Commit Date")]
|
||||||
|
public string CommitDate { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Re-Commit Date")]
|
||||||
|
public string ReCommitDate { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("UAT as of")]
|
||||||
|
public string UATAsOf { get; set; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("CMP _Date")]
|
||||||
|
public string CMPDate { get; set; } // { init; get; }
|
||||||
|
public string F20 { get; set; } // { init; get; }
|
||||||
|
public string F21 { get; set; } // { init; get; }
|
||||||
|
public string F22 { get; set; } // { init; get; }
|
||||||
|
public string F23 { get; set; } // { init; get; }
|
||||||
|
public string F24 { get; set; } // { init; get; }
|
||||||
|
public string F25 { get; set; } // { init; get; }
|
||||||
|
public string F26 { get; set; } // { init; get; }
|
||||||
|
public string F27 { get; set; } // { init; get; }
|
||||||
|
public string F28 { get; set; } // { init; get; }
|
||||||
|
public string F29 { get; set; } // { init; get; }
|
||||||
|
public string F30 { get; set; } // { init; get; }
|
||||||
|
public string F31 { get; set; } // { init; get; }
|
||||||
|
public string F32 { get; set; } // { init; get; }
|
||||||
|
public string F33 { get; set; } // { init; get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
|
||||||
|
[JsonSerializable(typeof(FIBacklogMesa[]))]
|
||||||
|
internal partial class FIBacklogMesaCollectionSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
|
||||||
|
[JsonSerializable(typeof(FIBacklogMesa))]
|
||||||
|
internal partial class FIBacklogMesaSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
560
Day/Q32024/Helper-2024-08-09.cs
Normal file
560
Day/Q32024/Helper-2024-08-09.cs
Normal file
@ -0,0 +1,560 @@
|
|||||||
|
using File_Folder_Helper.Day.Q32024.ConvertExcelToJson;
|
||||||
|
using File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.TeamFoundation.WorkItemTracking.WebApi;
|
||||||
|
using Microsoft.TeamFoundation.WorkItemTracking.WebApi.Models;
|
||||||
|
using Microsoft.VisualStudio.Services.Common;
|
||||||
|
using Microsoft.VisualStudio.Services.WebApi;
|
||||||
|
using Microsoft.VisualStudio.Services.WebApi.Patch;
|
||||||
|
using Microsoft.VisualStudio.Services.WebApi.Patch.Json;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Net.Http.Headers;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Web;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024;
|
||||||
|
|
||||||
|
internal static partial class Helper20240809
|
||||||
|
{
|
||||||
|
|
||||||
|
private static void AddPatch(JsonPatchDocument document, string path, object value) =>
|
||||||
|
document.Add(new JsonPatchOperation { From = null, Operation = Operation.Add, Path = path, Value = value });
|
||||||
|
|
||||||
|
private static Dictionary<string, FIBacklogMesa> GetFIBacklogMesaCollection(string json)
|
||||||
|
{
|
||||||
|
Dictionary<string, FIBacklogMesa> results = [];
|
||||||
|
string key;
|
||||||
|
FIBacklogMesa[]? fiBacklogMesaCollection;
|
||||||
|
fiBacklogMesaCollection = JsonSerializer.Deserialize(json, FIBacklogMesaCollectionSourceGenerationContext.Default.FIBacklogMesaArray);
|
||||||
|
if (fiBacklogMesaCollection is null || fiBacklogMesaCollection.Length == 0)
|
||||||
|
throw new NullReferenceException();
|
||||||
|
foreach (FIBacklogMesa fiBacklogMesa in fiBacklogMesaCollection)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(fiBacklogMesa.Req))
|
||||||
|
continue;
|
||||||
|
if (string.IsNullOrEmpty(fiBacklogMesa.Submitted))
|
||||||
|
continue;
|
||||||
|
if (string.IsNullOrEmpty(fiBacklogMesa.Requestor))
|
||||||
|
continue;
|
||||||
|
key = $"{fiBacklogMesa.Req} - ";
|
||||||
|
if (results.ContainsKey(key))
|
||||||
|
continue;
|
||||||
|
results.Add(key, fiBacklogMesa);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetIds(HttpClient httpClient, string basePage, string api, string query)
|
||||||
|
{
|
||||||
|
StringBuilder result = new();
|
||||||
|
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, query));
|
||||||
|
httpResponseMessageTask.Wait();
|
||||||
|
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
|
||||||
|
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
|
||||||
|
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
|
||||||
|
streamTask.Wait();
|
||||||
|
if (!streamTask.Result.CanRead)
|
||||||
|
throw new NullReferenceException(nameof(streamTask));
|
||||||
|
WIQL.Root? root = JsonSerializer.Deserialize(streamTask.Result, WIQL.WIQLRootSourceGenerationContext.Default.Root);
|
||||||
|
streamTask.Result.Dispose();
|
||||||
|
if (root is null || root.WorkItems is null)
|
||||||
|
throw new NullReferenceException(nameof(root));
|
||||||
|
foreach (WIQL.WorkItem workItem in root.WorkItems)
|
||||||
|
_ = result.Append(workItem.Id).Append(',');
|
||||||
|
if (result.Length > 0)
|
||||||
|
_ = result.Remove(result.Length - 1, 1);
|
||||||
|
return result.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<ValueWithReq> GetWorkItems(HttpClient httpClient, string sourceDirectory, string basePage, string api, string ids)
|
||||||
|
{
|
||||||
|
List<ValueWithReq> results = [];
|
||||||
|
int req;
|
||||||
|
string json;
|
||||||
|
string file;
|
||||||
|
Value? value;
|
||||||
|
string[] segments;
|
||||||
|
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.GetAsync(string.Concat(basePage, api, $"/workitems?ids={ids}"));
|
||||||
|
httpResponseMessageTask.Wait();
|
||||||
|
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
|
||||||
|
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
|
||||||
|
Task<Stream> streamTask = httpResponseMessageTask.Result.Content.ReadAsStreamAsync();
|
||||||
|
streamTask.Wait();
|
||||||
|
if (!streamTask.Result.CanRead)
|
||||||
|
throw new NullReferenceException(nameof(streamTask));
|
||||||
|
JsonElement? result = JsonSerializer.Deserialize<JsonElement>(streamTask.Result);
|
||||||
|
if (result is null || result.Value.ValueKind != JsonValueKind.Object)
|
||||||
|
throw new NullReferenceException(nameof(result));
|
||||||
|
JsonElement[] jsonElements = result.Value.EnumerateObject().Last().Value.EnumerateArray().ToArray();
|
||||||
|
foreach (JsonElement jsonElement in jsonElements)
|
||||||
|
{
|
||||||
|
json = jsonElement.GetRawText();
|
||||||
|
value = JsonSerializer.Deserialize(json, ValueSourceGenerationContext.Default.Value);
|
||||||
|
if (value is null)
|
||||||
|
continue;
|
||||||
|
segments = value.Fields.SystemTitle.Split('-');
|
||||||
|
if (segments.Length < 2)
|
||||||
|
continue;
|
||||||
|
if (!int.TryParse(segments[0], out req) || req == 0)
|
||||||
|
continue;
|
||||||
|
file = Path.Combine(sourceDirectory, $"{req}.json");
|
||||||
|
File.WriteAllText(file, json);
|
||||||
|
results.Add(new(value, req, json));
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyCollection<ValueWithReq> RemoveFrom(Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa, ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
|
||||||
|
{
|
||||||
|
List<ValueWithReq> results = [];
|
||||||
|
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
|
||||||
|
{
|
||||||
|
if (keyToFIBacklogMesa.Remove($"{valueWithReq.Req} - "))
|
||||||
|
continue;
|
||||||
|
results.Add(valueWithReq);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DateTime? GetCommitDate(FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
DateTime? result;
|
||||||
|
DateTime dateTime;
|
||||||
|
DateTime minDateTime = DateTime.MinValue.AddYears(10);
|
||||||
|
string commitDate = fiBacklogMesa.CommitDate.Split(' ')[0];
|
||||||
|
if (string.IsNullOrEmpty(commitDate))
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DateTime.TryParseExact(commitDate, "MM/dd/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
|
||||||
|
result = dateTime.AddHours(12).ToUniversalTime();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DateTime.TryParseExact(commitDate, "dd-MMM-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
|
||||||
|
result = dateTime.AddHours(12).ToUniversalTime();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (DateTime.TryParse(commitDate, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime) && dateTime >= minDateTime)
|
||||||
|
result = dateTime.AddHours(12).ToUniversalTime();
|
||||||
|
else
|
||||||
|
result = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetPriority(FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
if (string.IsNullOrEmpty(fiBacklogMesa.Priority) || !int.TryParse(fiBacklogMesa.Priority[..1], out int priority) || priority == 0 || priority > 3)
|
||||||
|
result = 4;
|
||||||
|
else
|
||||||
|
result = priority;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int? GetPrioritySubset(FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
int? result;
|
||||||
|
if (string.IsNullOrEmpty(fiBacklogMesa.PrioritySubset) || !int.TryParse(fiBacklogMesa.PrioritySubset[..1], out int prioritySubset) || prioritySubset == 0 || prioritySubset > 3)
|
||||||
|
result = null;
|
||||||
|
else
|
||||||
|
result = prioritySubset;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetIterationPath(string project, DateTime submittedDateTime) =>
|
||||||
|
submittedDateTime.Year != 2024 ? project : string.Concat(project, "\\", submittedDateTime.Year);
|
||||||
|
|
||||||
|
private static string GetTitle(FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
string result = $"{fiBacklogMesa.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
|
||||||
|
if (result.Length > 128)
|
||||||
|
result = result[..127];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string GetTitle(FIBacklogMesa fiBacklogMesa, ValueWithReq valueWithReq)
|
||||||
|
{
|
||||||
|
string result = $"{valueWithReq.Req} - {fiBacklogMesa.Subject.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)[0]}";
|
||||||
|
if (result.Length > 128)
|
||||||
|
result = result[..127];
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string? GetMappedState(FIBacklogMesa fiBacklogMesa) =>
|
||||||
|
fiBacklogMesa.Status == "CMP" ? "Closed" : fiBacklogMesa.Status == "UAT" ? "Resolved" : fiBacklogMesa.Status == "In process" ? "Active" : null;
|
||||||
|
|
||||||
|
private static JsonPatchDocument GetBugDocument(string project, string site, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, Task<WorkItem>? uatWorkItemTask, FIBacklogMesa fiBacklogMesa, DateTime submittedDateTime)
|
||||||
|
{
|
||||||
|
JsonPatchDocument result = [];
|
||||||
|
string title = GetTitle(fiBacklogMesa);
|
||||||
|
string iterationPath = GetIterationPath(project, submittedDateTime);
|
||||||
|
if (uatWorkItemTask?.Result.Id is not null)
|
||||||
|
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = uatWorkItemTask.Result.Url });
|
||||||
|
AddPatch(result, "/fields/System.AreaPath", string.Concat(project, "\\", site));
|
||||||
|
AddPatch(result, "/fields/System.IterationPath", iterationPath);
|
||||||
|
AddPatch(result, "/fields/System.Title", title);
|
||||||
|
string? state = GetMappedState(fiBacklogMesa);
|
||||||
|
if (!string.IsNullOrEmpty(state))
|
||||||
|
AddPatch(result, "/fields/System.State", state);
|
||||||
|
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
|
||||||
|
AddPatch(result, "/fields/System.Description", $"{fiBacklogMesa.Subject}<br> <br>{fiBacklogMesa.Definition}");
|
||||||
|
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
|
||||||
|
AddPatch(result, "/fields/System.AssignedTo", assignedToUser);
|
||||||
|
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
|
||||||
|
AddPatch(result, "/fields/Custom.Requester", requestorUser);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JsonPatchDocument GetFeatureDocument(string project, string site, ReadOnlyDictionary<string, string> requestorNameToUser, ReadOnlyDictionary<string, string> assignedToNameToUser, List<string> tags, Task<WorkItem>? userStoryWorkItemTask, FIBacklogMesa fiBacklogMesa, DateTime submittedDateTime)
|
||||||
|
{
|
||||||
|
JsonPatchDocument result = [];
|
||||||
|
string title = GetTitle(fiBacklogMesa);
|
||||||
|
int priority = GetPriority(fiBacklogMesa);
|
||||||
|
string? state = GetMappedState(fiBacklogMesa);
|
||||||
|
int? prioritySubset = GetPrioritySubset(fiBacklogMesa);
|
||||||
|
if (prioritySubset is not null)
|
||||||
|
AddPatch(result, "/fields/Microsoft.VSTS.Common.TimeCriticality", prioritySubset);
|
||||||
|
string iterationPath = GetIterationPath(project, submittedDateTime);
|
||||||
|
if (userStoryWorkItemTask?.Result.Id is not null)
|
||||||
|
AddPatch(result, "/relations/-", new WorkItemRelation() { Rel = "System.LinkTypes.Hierarchy-Forward", Url = userStoryWorkItemTask.Result.Url });
|
||||||
|
AddPatch(result, "/fields/System.AreaPath", string.Concat(project, "\\", site));
|
||||||
|
if (tags.Count > 0)
|
||||||
|
{
|
||||||
|
AddPatch(result, "/fields/System.Tags", tags.Last());
|
||||||
|
tags.RemoveAt(tags.Count - 1);
|
||||||
|
}
|
||||||
|
AddPatch(result, "/fields/System.IterationPath", iterationPath);
|
||||||
|
AddPatch(result, "/fields/Microsoft.VSTS.Common.Priority", priority);
|
||||||
|
if (!string.IsNullOrEmpty(fiBacklogMesa.Definition))
|
||||||
|
AddPatch(result, "/fields/System.Description", $"{fiBacklogMesa.Subject}<br> <br>{fiBacklogMesa.Definition}");
|
||||||
|
if (!string.IsNullOrEmpty(state))
|
||||||
|
AddPatch(result, "/fields/System.State", state);
|
||||||
|
if (!string.IsNullOrEmpty(fiBacklogMesa.EstEffortDays) && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && estEffortDays != 0)
|
||||||
|
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.Effort", estEffortDays);
|
||||||
|
DateTime? dateTime = GetCommitDate(fiBacklogMesa);
|
||||||
|
if (dateTime is not null)
|
||||||
|
AddPatch(result, "/fields/Microsoft.VSTS.Scheduling.TargetDate", dateTime);
|
||||||
|
if (!string.IsNullOrEmpty(fiBacklogMesa.Updates))
|
||||||
|
AddPatch(result, "/fields/System.History", fiBacklogMesa.Updates);
|
||||||
|
AddPatch(result, "/fields/System.Title", title);
|
||||||
|
if (assignedToNameToUser.TryGetValue(fiBacklogMesa.AssignedTo, out string? assignedToUser))
|
||||||
|
AddPatch(result, "/fields/System.AssignedTo", assignedToUser);
|
||||||
|
if (requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser))
|
||||||
|
AddPatch(result, "/fields/Custom.Requester", requestorUser);
|
||||||
|
// https://tfs.intra.infineon.com/tfs/ManufacturingIT/Mesa_FI/_apis/wit/workitemtypes/feature/fields?api-version=7.0
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<string> GetTags(FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
List<string> results = [];
|
||||||
|
foreach (string tag in fiBacklogMesa.SystemS.Split('/'))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(tag.Trim()))
|
||||||
|
continue;
|
||||||
|
results.Add(tag.Trim());
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<string> GetTags(Fields fields)
|
||||||
|
{
|
||||||
|
List<string> results = [];
|
||||||
|
if (!string.IsNullOrEmpty(fields.SystemTags))
|
||||||
|
{
|
||||||
|
foreach (string tag in fields.SystemTags.Split(';'))
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(tag.Trim()))
|
||||||
|
continue;
|
||||||
|
results.Add(tag.Trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateWorkItem(WorkItemTrackingHttpClient workItemTrackingHttpClient, string project, string site, ReadOnlyDictionary<string, string> assignedToNameToUser, ReadOnlyDictionary<string, string> requestorNameToUser, FIBacklogMesa fiBacklogMesa)
|
||||||
|
{
|
||||||
|
DateTime submittedDateTime;
|
||||||
|
JsonPatchDocument tagDocument;
|
||||||
|
Task<WorkItem>? workItem = null;
|
||||||
|
List<string> tags = GetTags(fiBacklogMesa);
|
||||||
|
bool isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
|
||||||
|
if (assignedToNameToUser.Count > requestorNameToUser.Count)
|
||||||
|
throw new Exception();
|
||||||
|
if (!DateTime.TryParse(fiBacklogMesa.Submitted, out submittedDateTime))
|
||||||
|
submittedDateTime = DateTime.MinValue;
|
||||||
|
if (isBugFix)
|
||||||
|
{
|
||||||
|
Task<WorkItem>? uatWorkItemTask = null;
|
||||||
|
JsonPatchDocument bugDocument = GetBugDocument(project, site, requestorNameToUser, assignedToNameToUser, uatWorkItemTask, fiBacklogMesa, submittedDateTime);
|
||||||
|
workItem = workItemTrackingHttpClient.CreateWorkItemAsync(bugDocument, project, "Bug");
|
||||||
|
workItem.Wait();
|
||||||
|
}
|
||||||
|
if (!isBugFix)
|
||||||
|
{
|
||||||
|
Task<WorkItem>? userStoryWorkItemTask = null;
|
||||||
|
JsonPatchDocument featureDocument = GetFeatureDocument(project, site, requestorNameToUser, assignedToNameToUser, tags, userStoryWorkItemTask, fiBacklogMesa, submittedDateTime);
|
||||||
|
workItem = workItemTrackingHttpClient.CreateWorkItemAsync(featureDocument, project, "Feature");
|
||||||
|
workItem.Wait();
|
||||||
|
}
|
||||||
|
for (int i = tags.Count - 1; i > -1; i--)
|
||||||
|
{
|
||||||
|
if (workItem is null)
|
||||||
|
continue;
|
||||||
|
if (workItem.Result.Id is null)
|
||||||
|
throw new NotSupportedException();
|
||||||
|
tagDocument = [];
|
||||||
|
AddPatch(tagDocument, "/fields/System.Tags", tags[i]);
|
||||||
|
tags.RemoveAt(i);
|
||||||
|
workItem = workItemTrackingHttpClient.UpdateWorkItemAsync(tagDocument, workItem.Result.Id.Value);
|
||||||
|
workItem.Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void KillTime(int loops)
|
||||||
|
{
|
||||||
|
for (int i = 1; i < loops; i++)
|
||||||
|
Thread.Sleep(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Update(HttpClient httpClient, string basePage, string api, string query, HttpContent httpContent)
|
||||||
|
{
|
||||||
|
#if Windows
|
||||||
|
Task<HttpResponseMessage> httpResponseMessageTask = httpClient.PatchAsync(string.Concat(basePage, api, query), httpContent);
|
||||||
|
httpResponseMessageTask.Wait();
|
||||||
|
if (!httpResponseMessageTask.Result.IsSuccessStatusCode)
|
||||||
|
throw new Exception(httpResponseMessageTask.Result.StatusCode.ToString());
|
||||||
|
Task<string> stringTask = httpResponseMessageTask.Result.Content.ReadAsStringAsync();
|
||||||
|
stringTask.Wait();
|
||||||
|
#endif
|
||||||
|
KillTime(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Update(HttpClient httpClient, string basePage, string api, WorkItemTrackingHttpClient workItemTrackingHttpClient, string sync, ValueWithReq valueWithReq)
|
||||||
|
{
|
||||||
|
JsonPatchDocument result = [];
|
||||||
|
AddPatch(result, "/fields/System.Tags", sync);
|
||||||
|
Task<WorkItem> workItem = workItemTrackingHttpClient.UpdateWorkItemAsync(result, valueWithReq.Value.Id);
|
||||||
|
workItem.Wait();
|
||||||
|
if (result is null)
|
||||||
|
{
|
||||||
|
var payload = new
|
||||||
|
{
|
||||||
|
op = "replace",
|
||||||
|
path = "/fields/System.IterationPath",
|
||||||
|
value = "Mesa_FI"
|
||||||
|
};
|
||||||
|
string stringPayload = JsonSerializer.Serialize(payload);
|
||||||
|
HttpContent httpContent = new StringContent($"[{stringPayload}]", Encoding.UTF8, "application/json-patch+json");
|
||||||
|
Update(httpClient, basePage, api, $"/workitems/{valueWithReq.Value.Id}?api-version=1.0", httpContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int SetSyncTag(HttpClient httpClient,
|
||||||
|
string basePage,
|
||||||
|
string api,
|
||||||
|
WorkItemTrackingHttpClient workItemTrackingHttpClient,
|
||||||
|
ReadOnlyDictionary<string, string> assignedToNameToUser,
|
||||||
|
ReadOnlyDictionary<string, string> requestorNameToUser,
|
||||||
|
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa,
|
||||||
|
ReadOnlyCollection<ValueWithReq> valueWithReqCollection)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
string key;
|
||||||
|
string title;
|
||||||
|
int priority;
|
||||||
|
bool isBugFix;
|
||||||
|
string? state;
|
||||||
|
List<string> tags;
|
||||||
|
TimeSpan timeSpan;
|
||||||
|
DateTime? dateTime;
|
||||||
|
List<string> compareTags;
|
||||||
|
const string sync = "Sync";
|
||||||
|
FIBacklogMesa? fiBacklogMesa;
|
||||||
|
foreach (ValueWithReq valueWithReq in valueWithReqCollection)
|
||||||
|
{
|
||||||
|
key = $"{valueWithReq.Req} - ";
|
||||||
|
compareTags = GetTags(valueWithReq.Value.Fields);
|
||||||
|
if (compareTags.Contains(sync))
|
||||||
|
continue;
|
||||||
|
if (!keyToFIBacklogMesa.TryGetValue(key, out fiBacklogMesa))
|
||||||
|
continue;
|
||||||
|
tags = GetTags(fiBacklogMesa);
|
||||||
|
title = GetTitle(fiBacklogMesa, valueWithReq);
|
||||||
|
isBugFix = fiBacklogMesa.Priority == "0 - BugFix";
|
||||||
|
_ = requestorNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? requestorUser);
|
||||||
|
if (!string.IsNullOrEmpty(requestorUser) && (valueWithReq.Value.Fields.CustomRequester is null || !valueWithReq.Value.Fields.CustomRequester.UniqueName.Equals(requestorUser, StringComparison.CurrentCultureIgnoreCase)))
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_ = assignedToNameToUser.TryGetValue(fiBacklogMesa.Requestor, out string? assignedToUser);
|
||||||
|
if (!string.IsNullOrEmpty(assignedToUser) && (valueWithReq.Value.Fields.SystemAssignedTo is null || !valueWithReq.Value.Fields.SystemAssignedTo.UniqueName.Equals(assignedToUser, StringComparison.CurrentCultureIgnoreCase)))
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (valueWithReq.Value.Fields.SystemTitle != title)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
foreach (string tag in tags)
|
||||||
|
{
|
||||||
|
if (compareTags.Contains(tag))
|
||||||
|
continue;
|
||||||
|
_ = tags.Remove(tag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tags.Count != compareTags.Count)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((isBugFix && valueWithReq.Value.Fields.SystemWorkItemType != "Bug") || (!isBugFix && valueWithReq.Value.Fields.SystemWorkItemType == "Bug"))
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isBugFix)
|
||||||
|
{
|
||||||
|
priority = GetPriority(fiBacklogMesa);
|
||||||
|
if (valueWithReq.Value.Fields.MicrosoftVSTSCommonPriority != priority)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state = GetMappedState(fiBacklogMesa);
|
||||||
|
if (!string.IsNullOrEmpty(state) && valueWithReq.Value.Fields.SystemState != state)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!isBugFix && int.TryParse(fiBacklogMesa.EstEffortDays, out int estEffortDays) && valueWithReq.Value.Fields.Effort != estEffortDays)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
dateTime = GetCommitDate(fiBacklogMesa);
|
||||||
|
if (dateTime is not null)
|
||||||
|
{
|
||||||
|
timeSpan = new(valueWithReq.Value.Fields.TargetDate.Ticks - dateTime.Value.Ticks);
|
||||||
|
if (timeSpan.Hours is > 32 or < -32)
|
||||||
|
{
|
||||||
|
result += 1;
|
||||||
|
Update(httpClient, basePage, api, workItemTrackingHttpClient, sync, valueWithReq);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateWorkItems(HttpClient httpClient,
|
||||||
|
string sourceDirectory,
|
||||||
|
string basePage,
|
||||||
|
string api,
|
||||||
|
string query,
|
||||||
|
WorkItemTrackingHttpClient workItemTrackingHttpClient,
|
||||||
|
string project,
|
||||||
|
string site,
|
||||||
|
ReadOnlyDictionary<string, string> assignedToNameToUser,
|
||||||
|
ReadOnlyDictionary<string, string> requestorNameToUser,
|
||||||
|
string json)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
string ids = GetIds(httpClient, basePage, api, query);
|
||||||
|
Dictionary<string, FIBacklogMesa> keyToFIBacklogMesa = GetFIBacklogMesaCollection(json);
|
||||||
|
ReadOnlyCollection<ValueWithReq> valueWithReqCollection = string.IsNullOrEmpty(ids) ? new([]) : GetWorkItems(httpClient, sourceDirectory, basePage, api, ids);
|
||||||
|
int updated = SetSyncTag(httpClient, basePage, api, workItemTrackingHttpClient, assignedToNameToUser, requestorNameToUser, keyToFIBacklogMesa, valueWithReqCollection);
|
||||||
|
if (updated == 0)
|
||||||
|
{
|
||||||
|
ReadOnlyCollection<ValueWithReq> extra = RemoveFrom(keyToFIBacklogMesa, valueWithReqCollection);
|
||||||
|
foreach (KeyValuePair<string, FIBacklogMesa> keyValuePair in keyToFIBacklogMesa)
|
||||||
|
{
|
||||||
|
if (keyToFIBacklogMesa.Count == extra.Count)
|
||||||
|
break;
|
||||||
|
CreateWorkItem(workItemTrackingHttpClient, project, site, assignedToNameToUser, requestorNameToUser, keyValuePair.Value);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CreateWorkItems(ILogger<Worker> logger, string sourceDirectory, string api, string site, string query, string project, string basePage, string baseAddress, byte[] bytes, string[] assignedToNames, string[] requestorNames, string reportFullPath, MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue, WorkItemTrackingHttpClient workItemTrackingHttpClient, HttpClient httpClient)
|
||||||
|
{
|
||||||
|
string base64 = Convert.ToBase64String(bytes);
|
||||||
|
string json = File.ReadAllText(reportFullPath);
|
||||||
|
httpClient.DefaultRequestHeaders.Authorization = new("Basic", base64);
|
||||||
|
httpClient.DefaultRequestHeaders.Accept.Add(mediaTypeWithQualityHeaderValue);
|
||||||
|
ReadOnlyDictionary<string, string> requestorNameToUser = GetRequestorNameToUser(requestorNames);
|
||||||
|
ReadOnlyDictionary<string, string> assignedToNameToUser = GetAssignedToNameToUser(assignedToNames);
|
||||||
|
logger.LogInformation("{baseAddress}{basePage}/{project}{api}{query}", baseAddress, basePage, HttpUtility.HtmlEncode(project), api, query);
|
||||||
|
CreateWorkItems(httpClient, sourceDirectory, basePage, api, query, workItemTrackingHttpClient, project, site, new(assignedToNameToUser), new(requestorNameToUser), json);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, string> GetAssignedToNameToUser(string[] assignedToNames)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> results = [];
|
||||||
|
string[] segments;
|
||||||
|
foreach (string assignedToName in assignedToNames)
|
||||||
|
{
|
||||||
|
segments = assignedToName.Split('|');
|
||||||
|
if (segments.Length != 2)
|
||||||
|
continue;
|
||||||
|
results.Add(segments[0], segments[1]);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ReadOnlyDictionary<string, string> GetRequestorNameToUser(string[] requestorNames)
|
||||||
|
{
|
||||||
|
Dictionary<string, string> results = [];
|
||||||
|
string[] segments;
|
||||||
|
foreach (string requestorName in requestorNames)
|
||||||
|
{
|
||||||
|
segments = requestorName.Split('|');
|
||||||
|
if (segments.Length != 2)
|
||||||
|
continue;
|
||||||
|
results.Add(segments[0], segments[1]);
|
||||||
|
}
|
||||||
|
return new(results);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void CreateWorkItems(ILogger<Worker> logger, List<string> args)
|
||||||
|
{
|
||||||
|
string api = args[6];
|
||||||
|
string pat = args[8];
|
||||||
|
string site = args[2];
|
||||||
|
string query = args[7];
|
||||||
|
string project = args[5];
|
||||||
|
string basePage = args[4];
|
||||||
|
string baseAddress = args[3];
|
||||||
|
string sourceDirectory = args[0];
|
||||||
|
VssBasicCredential credential = new("", pat);
|
||||||
|
string[] requestorNames = args[11].Split(',');
|
||||||
|
string[] assignedToNames = args[10].Split(',');
|
||||||
|
byte[] bytes = Encoding.ASCII.GetBytes($":{pat}");
|
||||||
|
string reportFullPath = Path.GetFullPath(Path.Combine(sourceDirectory, args[9]));
|
||||||
|
VssConnection connection = new(new(string.Concat(baseAddress, basePage)), credential);
|
||||||
|
MediaTypeWithQualityHeaderValue mediaTypeWithQualityHeaderValue = new("application/json");
|
||||||
|
WorkItemTrackingHttpClient workItemTrackingHttpClient = connection.GetClient<WorkItemTrackingHttpClient>();
|
||||||
|
HttpClient httpClient = new(new HttpClientHandler() { UseDefaultCredentials = true }) { BaseAddress = new(baseAddress) };
|
||||||
|
CreateWorkItems(logger, sourceDirectory, api, site, query, project, basePage, baseAddress, bytes, assignedToNames, requestorNames, reportFullPath, mediaTypeWithQualityHeaderValue, workItemTrackingHttpClient, httpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
Day/Q32024/WIQL/Column.cs
Normal file
22
Day/Q32024/WIQL/Column.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WIQL;
|
||||||
|
|
||||||
|
public class Column
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Column(
|
||||||
|
string referenceName,
|
||||||
|
string name,
|
||||||
|
string url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReferenceName = referenceName;
|
||||||
|
Name = name;
|
||||||
|
Url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReferenceName { get; set; } // { init; get; }
|
||||||
|
public string Name { get; set; } // { init; get; }
|
||||||
|
public string Url { get; set; } // { init; get; }
|
||||||
|
}
|
22
Day/Q32024/WIQL/Field.cs
Normal file
22
Day/Q32024/WIQL/Field.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WIQL;
|
||||||
|
|
||||||
|
public class Field
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Field(
|
||||||
|
string referenceName,
|
||||||
|
string name,
|
||||||
|
string url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
ReferenceName = referenceName;
|
||||||
|
Name = name;
|
||||||
|
Url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ReferenceName { get; set; } // { init; get; }
|
||||||
|
public string Name { get; set; } // { init; get; }
|
||||||
|
public string Url { get; set; } // { init; get; }
|
||||||
|
}
|
37
Day/Q32024/WIQL/Root.cs
Normal file
37
Day/Q32024/WIQL/Root.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WIQL;
|
||||||
|
|
||||||
|
public class Root
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Root(
|
||||||
|
string queryType,
|
||||||
|
string queryResultType,
|
||||||
|
DateTime asOf,
|
||||||
|
Column[] columns,
|
||||||
|
SortColumn[] sortColumns,
|
||||||
|
WorkItem[] workItems
|
||||||
|
)
|
||||||
|
{
|
||||||
|
QueryType = queryType;
|
||||||
|
QueryResultType = queryResultType;
|
||||||
|
AsOf = asOf;
|
||||||
|
Columns = columns;
|
||||||
|
SortColumns = sortColumns;
|
||||||
|
WorkItems = workItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string QueryType { get; set; } // { init; get; }
|
||||||
|
public string QueryResultType { get; set; } // { init; get; }
|
||||||
|
public DateTime AsOf { get; set; } // { init; get; }
|
||||||
|
public Column[] Columns { get; set; } // { init; get; }
|
||||||
|
public SortColumn[] SortColumns { get; set; } // { init; get; }
|
||||||
|
public WorkItem[] WorkItems { get; set; } // { init; get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
|
||||||
|
[JsonSerializable(typeof(Root))]
|
||||||
|
internal partial class WIQLRootSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
19
Day/Q32024/WIQL/SortColumn.cs
Normal file
19
Day/Q32024/WIQL/SortColumn.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WIQL;
|
||||||
|
|
||||||
|
public class SortColumn
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public SortColumn(
|
||||||
|
Field field,
|
||||||
|
bool descending
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Field = field;
|
||||||
|
Descending = descending;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Field Field { get; set; } // { init; get; }
|
||||||
|
public bool Descending { get; set; } // { init; get; }
|
||||||
|
}
|
19
Day/Q32024/WIQL/WorkItem.cs
Normal file
19
Day/Q32024/WIQL/WorkItem.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WIQL;
|
||||||
|
|
||||||
|
public class WorkItem
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public WorkItem(
|
||||||
|
int id,
|
||||||
|
string url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Id { get; set; } // { init; get; }
|
||||||
|
public string Url { get; set; } // { init; get; }
|
||||||
|
}
|
13
Day/Q32024/WorkItems/Avatar.cs
Normal file
13
Day/Q32024/WorkItems/Avatar.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class Avatar
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Avatar(
|
||||||
|
string href
|
||||||
|
) => Href = href;
|
||||||
|
|
||||||
|
public string Href { get; } // { init; get; }
|
||||||
|
}
|
27
Day/Q32024/WorkItems/CommentVersionRef.cs
Normal file
27
Day/Q32024/WorkItems/CommentVersionRef.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class CommentVersionRef
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public CommentVersionRef(
|
||||||
|
int commentId,
|
||||||
|
int version,
|
||||||
|
string url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
CommentId = commentId;
|
||||||
|
Version = version;
|
||||||
|
URL = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("commentId")]
|
||||||
|
public int CommentId { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("version")]
|
||||||
|
public int Version { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string URL { get; } // { init; get; }
|
||||||
|
}
|
47
Day/Q32024/WorkItems/CustomRequester.cs
Normal file
47
Day/Q32024/WorkItems/CustomRequester.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class CustomRequester
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public CustomRequester(
|
||||||
|
string displayName,
|
||||||
|
string url,
|
||||||
|
Links links,
|
||||||
|
string id,
|
||||||
|
string uniqueName,
|
||||||
|
string imageUrl,
|
||||||
|
string descriptor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DisplayName = displayName;
|
||||||
|
Url = url;
|
||||||
|
Links = links;
|
||||||
|
Id = id;
|
||||||
|
UniqueName = uniqueName;
|
||||||
|
ImageUrl = imageUrl;
|
||||||
|
Descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("displayName")]
|
||||||
|
public string DisplayName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string Url { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("_links")]
|
||||||
|
public Links Links { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public string Id { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("uniqueName")]
|
||||||
|
public string UniqueName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("imageUrl")]
|
||||||
|
public string ImageUrl { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("descriptor")]
|
||||||
|
public string Descriptor { get; }
|
||||||
|
}
|
117
Day/Q32024/WorkItems/Fields.cs
Normal file
117
Day/Q32024/WorkItems/Fields.cs
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class Fields
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Fields(
|
||||||
|
string systemAreaPath,
|
||||||
|
string systemTeamProject,
|
||||||
|
string systemIterationPath,
|
||||||
|
string systemWorkItemType,
|
||||||
|
string systemState,
|
||||||
|
string systemReason,
|
||||||
|
CustomRequester customRequester,
|
||||||
|
SystemAssignedTo systemAssignedTo,
|
||||||
|
DateTime systemCreatedDate,
|
||||||
|
SystemCreatedBy systemCreatedBy,
|
||||||
|
DateTime systemChangedDate,
|
||||||
|
SystemChangedBy systemChangedBy,
|
||||||
|
int systemCommentCount,
|
||||||
|
string systemTitle,
|
||||||
|
DateTime microsoftVSTSCommonStateChangeDate,
|
||||||
|
int microsoftVSTSCommonPriority,
|
||||||
|
string systemDescription,
|
||||||
|
string systemTags,
|
||||||
|
string systemHistory,
|
||||||
|
float? effort,
|
||||||
|
DateTime targetDate
|
||||||
|
)
|
||||||
|
{
|
||||||
|
SystemAreaPath = systemAreaPath;
|
||||||
|
SystemTeamProject = systemTeamProject;
|
||||||
|
SystemIterationPath = systemIterationPath;
|
||||||
|
SystemWorkItemType = systemWorkItemType;
|
||||||
|
SystemState = systemState;
|
||||||
|
SystemReason = systemReason;
|
||||||
|
CustomRequester = customRequester;
|
||||||
|
SystemAssignedTo = systemAssignedTo;
|
||||||
|
SystemCreatedDate = systemCreatedDate;
|
||||||
|
SystemCreatedBy = systemCreatedBy;
|
||||||
|
SystemChangedDate = systemChangedDate;
|
||||||
|
SystemChangedBy = systemChangedBy;
|
||||||
|
SystemCommentCount = systemCommentCount;
|
||||||
|
SystemTitle = systemTitle;
|
||||||
|
MicrosoftVSTSCommonStateChangeDate = microsoftVSTSCommonStateChangeDate;
|
||||||
|
MicrosoftVSTSCommonPriority = microsoftVSTSCommonPriority;
|
||||||
|
SystemDescription = systemDescription;
|
||||||
|
SystemTags = systemTags;
|
||||||
|
SystemHistory = systemHistory;
|
||||||
|
Effort = effort;
|
||||||
|
TargetDate = targetDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("System.AreaPath")]
|
||||||
|
public string SystemAreaPath { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.TeamProject")]
|
||||||
|
public string SystemTeamProject { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.IterationPath")]
|
||||||
|
public string SystemIterationPath { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.WorkItemType")]
|
||||||
|
public string SystemWorkItemType { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.State")]
|
||||||
|
public string SystemState { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.Reason")]
|
||||||
|
public string SystemReason { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Custom.Requester")]
|
||||||
|
public CustomRequester CustomRequester { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.AssignedTo")]
|
||||||
|
public SystemAssignedTo SystemAssignedTo { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.CreatedDate")]
|
||||||
|
public DateTime SystemCreatedDate { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.CreatedBy")]
|
||||||
|
public SystemCreatedBy SystemCreatedBy { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.ChangedDate")]
|
||||||
|
public DateTime SystemChangedDate { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.ChangedBy")]
|
||||||
|
public SystemChangedBy SystemChangedBy { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.CommentCount")]
|
||||||
|
public int SystemCommentCount { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.Title")]
|
||||||
|
public string SystemTitle { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Microsoft.VSTS.Common.StateChangeDate")]
|
||||||
|
public DateTime MicrosoftVSTSCommonStateChangeDate { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Microsoft.VSTS.Common.Priority")]
|
||||||
|
public int MicrosoftVSTSCommonPriority { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.Description")]
|
||||||
|
public string SystemDescription { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.Tags")]
|
||||||
|
public string SystemTags { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("System.History")]
|
||||||
|
public string SystemHistory { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Microsoft.VSTS.Scheduling.Effort")]
|
||||||
|
public float? Effort { get; } // { init; get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("Microsoft.VSTS.Scheduling.TargetDate")]
|
||||||
|
public DateTime TargetDate { get; } // { init; get; }
|
||||||
|
}
|
13
Day/Q32024/WorkItems/Html.cs
Normal file
13
Day/Q32024/WorkItems/Html.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class Html
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Html(
|
||||||
|
string href
|
||||||
|
) => Href = href;
|
||||||
|
|
||||||
|
public string Href { get; } // { init; get; }
|
||||||
|
}
|
14
Day/Q32024/WorkItems/Links.cs
Normal file
14
Day/Q32024/WorkItems/Links.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class Links
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Links(
|
||||||
|
Avatar avatar
|
||||||
|
) => Avatar = avatar;
|
||||||
|
|
||||||
|
[JsonPropertyName("avatar")]
|
||||||
|
public Avatar Avatar { get; }
|
||||||
|
}
|
47
Day/Q32024/WorkItems/SystemAssignedTo.cs
Normal file
47
Day/Q32024/WorkItems/SystemAssignedTo.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class SystemAssignedTo
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public SystemAssignedTo(
|
||||||
|
string displayName,
|
||||||
|
string url,
|
||||||
|
Links links,
|
||||||
|
string id,
|
||||||
|
string uniqueName,
|
||||||
|
string imageUrl,
|
||||||
|
string descriptor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DisplayName = displayName;
|
||||||
|
Url = url;
|
||||||
|
Links = links;
|
||||||
|
Id = id;
|
||||||
|
UniqueName = uniqueName;
|
||||||
|
ImageUrl = imageUrl;
|
||||||
|
Descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("displayName")]
|
||||||
|
public string DisplayName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string Url { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("_links")]
|
||||||
|
public Links Links { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public string Id { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("uniqueName")]
|
||||||
|
public string UniqueName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("imageUrl")]
|
||||||
|
public string ImageUrl { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("descriptor")]
|
||||||
|
public string Descriptor { get; }
|
||||||
|
}
|
47
Day/Q32024/WorkItems/SystemChangedBy.cs
Normal file
47
Day/Q32024/WorkItems/SystemChangedBy.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class SystemChangedBy
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public SystemChangedBy(
|
||||||
|
string displayName,
|
||||||
|
string url,
|
||||||
|
Links links,
|
||||||
|
string id,
|
||||||
|
string uniqueName,
|
||||||
|
string imageUrl,
|
||||||
|
string descriptor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DisplayName = displayName;
|
||||||
|
Url = url;
|
||||||
|
Links = links;
|
||||||
|
Id = id;
|
||||||
|
UniqueName = uniqueName;
|
||||||
|
ImageUrl = imageUrl;
|
||||||
|
Descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("displayName")]
|
||||||
|
public string DisplayName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string Url { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("_links")]
|
||||||
|
public Links Links { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public string Id { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("uniqueName")]
|
||||||
|
public string UniqueName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("imageUrl")]
|
||||||
|
public string ImageUrl { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("descriptor")]
|
||||||
|
public string Descriptor { get; }
|
||||||
|
}
|
47
Day/Q32024/WorkItems/SystemCreatedBy.cs
Normal file
47
Day/Q32024/WorkItems/SystemCreatedBy.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class SystemCreatedBy
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public SystemCreatedBy(
|
||||||
|
string displayName,
|
||||||
|
string url,
|
||||||
|
Links links,
|
||||||
|
string id,
|
||||||
|
string uniqueName,
|
||||||
|
string imageUrl,
|
||||||
|
string descriptor
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DisplayName = displayName;
|
||||||
|
Url = url;
|
||||||
|
Links = links;
|
||||||
|
Id = id;
|
||||||
|
UniqueName = uniqueName;
|
||||||
|
ImageUrl = imageUrl;
|
||||||
|
Descriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("displayName")]
|
||||||
|
public string DisplayName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string Url { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("_links")]
|
||||||
|
public Links Links { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public string Id { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("uniqueName")]
|
||||||
|
public string UniqueName { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("imageUrl")]
|
||||||
|
public string ImageUrl { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("descriptor")]
|
||||||
|
public string Descriptor { get; }
|
||||||
|
}
|
49
Day/Q32024/WorkItems/Value.cs
Normal file
49
Day/Q32024/WorkItems/Value.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class Value
|
||||||
|
{
|
||||||
|
[JsonConstructor]
|
||||||
|
public Value(
|
||||||
|
int id,
|
||||||
|
int rev,
|
||||||
|
Fields fields,
|
||||||
|
CommentVersionRef commentVersionRef,
|
||||||
|
string url
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Id = id;
|
||||||
|
Rev = rev;
|
||||||
|
Fields = fields;
|
||||||
|
CommentVersionRef = commentVersionRef;
|
||||||
|
Url = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonPropertyName("id")]
|
||||||
|
public int Id { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("rev")]
|
||||||
|
public int Rev { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("fields")]
|
||||||
|
public Fields Fields { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("commentVersionRef")]
|
||||||
|
public CommentVersionRef CommentVersionRef { get; }
|
||||||
|
|
||||||
|
[JsonPropertyName("url")]
|
||||||
|
public string Url { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
|
||||||
|
[JsonSerializable(typeof(Value[]))]
|
||||||
|
internal partial class ValueCollectionSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonSourceGenerationOptions(WriteIndented = true, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, PropertyNameCaseInsensitive = true)]
|
||||||
|
[JsonSerializable(typeof(Value))]
|
||||||
|
internal partial class ValueSourceGenerationContext : JsonSerializerContext
|
||||||
|
{
|
||||||
|
}
|
19
Day/Q32024/WorkItems/ValueWithReq.cs
Normal file
19
Day/Q32024/WorkItems/ValueWithReq.cs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
namespace File_Folder_Helper.Day.Q32024.WorkItems;
|
||||||
|
|
||||||
|
public class ValueWithReq
|
||||||
|
{
|
||||||
|
public ValueWithReq(
|
||||||
|
Value value,
|
||||||
|
int req,
|
||||||
|
string json
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Value = value;
|
||||||
|
Req = req;
|
||||||
|
Json = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Value Value { get; set; } // { init; get; }
|
||||||
|
public int Req { get; set; } // { init; get; }
|
||||||
|
public string Json { get; set; } // { init; get; }
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
<PackageReference Include="DiscUtils.Iso9660" Version="0.16.13" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.205.1" />
|
||||||
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.7" />
|
<PackageReference Include="runtime.win-x64.Microsoft.DotNet.ILCompiler" Version="8.0.7" />
|
||||||
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
<PackageReference Include="System.Text.Json" Version="8.0.4" />
|
||||||
<PackageReference Include="TextCopy" Version="6.2.1" />
|
<PackageReference Include="TextCopy" Version="6.2.1" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user