Register cmdlets via source generated extension
This commit is contained in:
parent
68b112d6ce
commit
a67b1953f0
6 changed files with 127 additions and 42 deletions
|
|
@ -0,0 +1,90 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
|
||||
namespace LANCommander.SDK.SourceGenerators;
|
||||
|
||||
[Generator]
|
||||
public class CmdletRegistrationGenerator : IIncrementalGenerator
|
||||
{
|
||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||
{
|
||||
var cmdletClasses = context.SyntaxProvider
|
||||
.ForAttributeWithMetadataName(
|
||||
"System.Management.Automation.CmdletAttribute",
|
||||
predicate: static (node, _) => node is ClassDeclarationSyntax,
|
||||
transform: static (ctx, _) => GetCmdletInfo(ctx))
|
||||
.Where(static info => info is not null)
|
||||
.Select(static (info, _) => info!.Value);
|
||||
|
||||
context.RegisterSourceOutput(
|
||||
cmdletClasses.Collect(),
|
||||
static (spc, cmdlets) => Execute(spc, cmdlets));
|
||||
}
|
||||
|
||||
private static CmdletInfo? GetCmdletInfo(GeneratorAttributeSyntaxContext context)
|
||||
{
|
||||
var typeSymbol = (INamedTypeSymbol)context.TargetSymbol;
|
||||
|
||||
foreach (var attr in typeSymbol.GetAttributes())
|
||||
{
|
||||
if (attr.AttributeClass?.ToDisplayString() != "System.Management.Automation.CmdletAttribute")
|
||||
continue;
|
||||
|
||||
if (attr.ConstructorArguments.Length < 2)
|
||||
continue;
|
||||
|
||||
var verb = attr.ConstructorArguments[0].Value?.ToString();
|
||||
var noun = attr.ConstructorArguments[1].Value?.ToString();
|
||||
|
||||
if (verb is null || noun is null)
|
||||
continue;
|
||||
|
||||
return new CmdletInfo
|
||||
{
|
||||
CmdletName = $"{verb}-{noun}",
|
||||
FullTypeName = typeSymbol.ToDisplayString()
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void Execute(SourceProductionContext context, ImmutableArray<CmdletInfo> cmdlets)
|
||||
{
|
||||
if (cmdlets.IsDefaultOrEmpty)
|
||||
return;
|
||||
|
||||
var sorted = cmdlets.OrderBy(c => c.CmdletName).ToList();
|
||||
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine("// <auto-generated/>");
|
||||
sb.AppendLine("using System.Management.Automation.Runspaces;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("namespace LANCommander.SDK.PowerShell.Extensions;");
|
||||
sb.AppendLine();
|
||||
sb.AppendLine("public static class InitialSessionStateExtensions");
|
||||
sb.AppendLine("{");
|
||||
sb.AppendLine(" public static void AddCustomCmdlets(this InitialSessionState initialSessionState)");
|
||||
sb.AppendLine(" {");
|
||||
|
||||
foreach (var cmdlet in sorted)
|
||||
{
|
||||
sb.AppendLine($" initialSessionState.Commands.Add(new SessionStateCmdletEntry(\"{cmdlet.CmdletName}\", typeof({cmdlet.FullTypeName}), null));");
|
||||
}
|
||||
|
||||
sb.AppendLine(" }");
|
||||
sb.AppendLine("}");
|
||||
|
||||
context.AddSource("InitialSessionStateExtensions.g.cs", sb.ToString());
|
||||
}
|
||||
|
||||
private struct CmdletInfo
|
||||
{
|
||||
public string CmdletName;
|
||||
public string FullTypeName;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
<IsRoslynComponent>true</IsRoslynComponent>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -55,6 +55,9 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LANCommander.Steam\LANCommander.Steam.csproj" />
|
||||
<ProjectReference Include="..\LANCommander.SDK.SourceGenerators\LANCommander.SDK.SourceGenerators.csproj"
|
||||
OutputItemType="Analyzer"
|
||||
ReferenceOutputAssembly="false" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
|||
19
LANCommander.SDK/PowerShell/Cmdlets/Get-SanitizedPath.cs
Normal file
19
LANCommander.SDK/PowerShell/Cmdlets/Get-SanitizedPath.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using LANCommander.SDK.Extensions;
|
||||
using System.IO;
|
||||
using System.Management.Automation;
|
||||
|
||||
namespace LANCommander.SDK.PowerShell.Cmdlets
|
||||
{
|
||||
[Cmdlet(VerbsCommon.Get, "SanitizedPath")]
|
||||
[OutputType(typeof(string))]
|
||||
public class GetSanitizedPathCmdlet : Cmdlet
|
||||
{
|
||||
[Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, HelpMessage = "The path to sanitize.")]
|
||||
public string Path { get; set; }
|
||||
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
WriteObject(Path.SanitizeFilename());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
using System.Management.Automation.Runspaces;
|
||||
using LANCommander.SDK.PowerShell.Cmdlets;
|
||||
|
||||
namespace LANCommander.SDK.PowerShell.Extensions;
|
||||
|
||||
public static class InitialSessionStateExtensions
|
||||
{
|
||||
public static void AddCustomCmdlets(this InitialSessionState initialSessionState)
|
||||
{
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Convert-AspectRatio", typeof(ConvertAspectRatioCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertFrom-SerializedBase64", typeof(ConvertFromSerializedBase64Cmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertTo-SerializedBase64", typeof(ConvertToSerializedBase64Cmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("ConvertTo-StringBytes", typeof(ConvertToStringBytesCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Edit-PatchBinary", typeof(EditPatchBinaryCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Edit-PatchGameSpy", typeof(EditPatchGameSpy), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-GameManifest", typeof(GetGameManifestCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-HorizontalFov", typeof(GetHorizontalFovCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-PrimaryDisplay", typeof(GetPrimaryDisplayCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-UserCustomField", typeof(GetUserCustomFieldCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-VerticalFov", typeof(GetVerticalFovCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Out-PlayerAvatar", typeof(OutPlayerAvatarCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Update-IniValue", typeof(UpdateIniValueCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Update-UserCustomField", typeof(UpdateUserCustomFieldCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Write-GameManifest", typeof(WriteGameManifestCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("New-Package", typeof(NewPackageCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Write-ReplaceContentInFile", typeof(ReplaceContentInFileCmdlet), null));
|
||||
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Connect-SteamCmd", typeof(ConnectSteamCmdCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Disconnect-SteamCmd", typeof(DisconnectSteamCmdCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdConnectionStatus", typeof(GetSteamCmdConnectionStatusCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdPath", typeof(GetSteamCmdPathCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdProfile", typeof(GetSteamCmdProfileCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamCmdProfiles", typeof(GetSteamCmdProfilesCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Install-SteamContent", typeof(InstallSteamContentCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Remove-SteamContent", typeof(RemoveSteamContentCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Remove-SteamCmdProfile", typeof(RemoveSteamCmdProfileCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Set-SteamCmdProfile", typeof(SetSteamCmdProfileCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamAppInfo", typeof(GetSteamAppInfoCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Get-SteamWebAssetUri", typeof(GetSteamWebAssetUriCmdlet), null));
|
||||
initialSessionState.Commands.Add(new SessionStateCmdletEntry("Search-SteamGames", typeof(SearchSteamGamesCmdlet), null));
|
||||
}
|
||||
}
|
||||
|
|
@ -43,4 +43,5 @@
|
|||
<Project Path="LANCommander.Steam\LANCommander.Steam.csproj" />
|
||||
<Project Path="LANCommander.UI\LANCommander.UI.csproj" />
|
||||
<Project Path="LANCommander.CompletionGenerator\LANCommander.CompletionGenerator.csproj" />
|
||||
<Project Path="LANCommander.SDK.SourceGenerators\LANCommander.SDK.SourceGenerators.csproj" />
|
||||
</Solution>
|
||||
Loading…
Add table
Add a link
Reference in a new issue