forked from Azure/azure-sdk-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCommandFactory.cs
More file actions
104 lines (85 loc) · 4.25 KB
/
CommandFactory.cs
File metadata and controls
104 lines (85 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
using System.CommandLine;
using Azure.Sdk.Tools.Cli.Contract;
namespace Azure.Sdk.Tools.Cli.Commands
{
public static class CommandFactory
{
/// <summary>
/// Creates the primary parsing entry point for the application. Uses the registered service providers
/// to initialize whichever MCP tools we need to add to the configuration and pass on to HostTool.
/// </summary>
/// <returns></returns>
public static RootCommand CreateRootCommand(string[] args, IServiceProvider serviceProvider)
{
var rootCommand = new RootCommand("TEST1 - azsdk cli - A Model Context Protocol (MCP) server that enables various tasks for the Azure SDK Engineering System.");
rootCommand.AddOption(SharedOptions.ToolOption);
rootCommand.AddGlobalOption(SharedOptions.Debug);
SharedOptions.Format.AddValidator(result =>
{
var value = result.GetValueForOption(SharedOptions.Format);
if (value != "plain" && value != "json")
{
result.ErrorMessage = $"Invalid output format '{value}'. Supported formats are: plain, json";
}
});
rootCommand.AddGlobalOption(SharedOptions.Format);
var toolTypes = SharedOptions.GetFilteredToolTypes(args);
var toolInstances = toolTypes
.Select(t => (MCPTool)ActivatorUtilities.CreateInstance(serviceProvider, t))
.ToList();
PopulateToolHierarchy(rootCommand, toolInstances);
return rootCommand;
}
private static void PopulateToolHierarchy(RootCommand rootCommand, List<MCPTool> toolList)
{
var parentMap = new Dictionary<string, Command>(StringComparer.OrdinalIgnoreCase);
foreach (MCPTool tool in toolList)
{
var leaf = tool.GetCommand();
var hierarchy = tool.CommandHierarchy;
Command previousParent = rootCommand;
if (hierarchy.Length == 0)
{
// if there is no hierarchy, add the command directly to the root command
rootCommand.AddCommand(leaf);
continue;
}
for (int i = 0; i < hierarchy.Length; i++)
{
var segment = hierarchy[i];
// populate the dictionary lookup for the command so we don't create it multiple times as we walk the hieararchy across multiple tools
if (!parentMap.ContainsKey(segment.Verb))
{
var groupCommand = new Command(segment.Verb, segment.Description);
if (segment.Options != null && segment.Options.Count > 0)
{
foreach (var option in segment.Options)
{
groupCommand.AddGlobalOption(option);
}
}
parentMap[segment.Verb] = groupCommand;
}
// now access the node from the dictionary that we're currently on. the previous step populated the parentMap with the Command representing this verb if it didn't already exist
var currentNode = parentMap[segment.Verb];
// if the previous parent doesn't already have this node, add it, gotta maintain that hierarchy!
if (!previousParent.Children.Contains(currentNode))
{
previousParent.AddCommand(currentNode);
}
// if we are on the last segment of the hierarchy, add the leaf command to the current node
if (i == hierarchy.Length - 1)
{
// if we're at the end of the hierarchy, add the leaf command
currentNode.AddCommand(leaf);
}
else
{
// our previous parent is now the current node for the next iteration
previousParent = currentNode;
}
}
}
}
}
}