diff --git a/powershell/cmdlets/class.ts b/powershell/cmdlets/class.ts index 37a384a4681..415a8288809 100644 --- a/powershell/cmdlets/class.ts +++ b/powershell/cmdlets/class.ts @@ -15,7 +15,7 @@ import { Switch, System, TerminalCase, toExpression, Try, Using, valueOf, Field, IsNull, Or, ExpressionOrLiteral, TerminalDefaultCase, xmlize, TypeDeclaration, And, IsNotNull, PartialMethod, Case, While, LiteralStatement, Not, ElseIf } from '@azure-tools/codegen-csharp'; import { ClientRuntime, EventListener, Schema, ArrayOf, EnumImplementation } from '../llcsharp/exports'; -import { NullableBoolean, Alias, ArgumentCompleterAttribute, PSArgumentCompleterAttribute, AsyncCommandRuntime, AsyncJob, CmdletAttribute, ErrorCategory, ErrorRecord, Events, InvocationInfo, OutputTypeAttribute, ParameterAttribute, PSCmdlet, PSCredential, SwitchParameter, ValidateNotNull, verbEnum, GeneratedAttribute, DescriptionAttribute, ExternalDocsAttribute, CategoryAttribute, ParameterCategory, ProfileAttribute, PSObject, InternalExportAttribute, ExportAsAttribute, DefaultRunspace, RunspaceFactory, AllowEmptyCollectionAttribute, DoNotExportAttribute, HttpPathAttribute, NotSuggestDefaultParameterSetAttribute } from '../internal/powershell-declarations'; +import { NullableBoolean, Alias, ArgumentCompleterAttribute, PSArgumentCompleterAttribute, AsyncCommandRuntime, AsyncJob, CmdletAttribute, ErrorCategory, ErrorRecord, Events, IDynamicParameters, InvocationInfo, OutputTypeAttribute, ParameterAttribute, PSCmdlet, PSCredential, SwitchParameter, ValidateNotNull, verbEnum, GeneratedAttribute, DescriptionAttribute, ExternalDocsAttribute, CategoryAttribute, ParameterCategory, ProfileAttribute, PSObject, InternalExportAttribute, ExportAsAttribute, DefaultRunspace, RunspaceFactory, AllowEmptyCollectionAttribute, DoNotExportAttribute, HttpPathAttribute, NotSuggestDefaultParameterSetAttribute } from '../internal/powershell-declarations'; import { State } from '../internal/state'; import { Channel } from '@autorest/extension-base'; import { IParameter } from '@azure-tools/codemodel-v3/dist/code-model/components'; @@ -460,6 +460,9 @@ export class CmdletClass extends Class { // implement part of the IContext this.implementIContext(); + // Change Safety: emit codegen-owned inline dynamic parameters on write-verb cmdlets + this.implementChangeSafetyParameters(); + // add constructors this.implementConstructors(); @@ -1622,6 +1625,56 @@ export class CmdletClass extends Class { extensibleParametersProp.get = toExpression(`${extensibleParameters.value} `); this.add(extensibleParametersProp); } + private implementChangeSafetyParameters() { + // Change Safety (codegen-owned inline dynamic parameters): only azure management-plane (ARM) + // write cmdlets expose the opt-in Change Safety parameters. They are surfaced via an inline + // IDynamicParameters implementation (the same dynamic-parameter mechanism SDK cmdlets use), + // emitted directly in the generated cmdlet -- no runtime-wired VTable delegate. PowerShell + // binds the returned parameters into BoundParameters, where the module-level HTTP pipeline + // step (in Az.Accounts) reads them. + // Opt-in per module via `enable-change-safety: true` in the module readme (default off), so + // the 180+ module rollout is deliberate rather than triggered by any unrelated regeneration. + if (!this.state.project.enableChangeSafety) { + return; + } + if (!this.state.project.azure) { + return; + } + // Change Safety is a management-plane concept; skip data-plane modules, which target a + // custom service endpoint (identified by an endpoint-resource-id-key-name). This matches + // the data-plane detection used in module-class.ts (isDataPlane). + if (this.state.project.endpointResourceIdKeyName) { + return; + } + // Gate on the PowerShell verb rather than sniffing the HTTP method off requests[0]. A cmdlet's + // callGraph can contain multiple operations (e.g. a GetPut Update = GET + PUT) and a single + // operation can carry multiple requests, so requests[0] is not a reliable signal for whether + // the cmdlet mutates. The verb encodes the mutating intent computed across the whole call graph + // and, unlike the raw HTTP method, correctly treats POST "list"-style operations (surfaced as + // Get) as reads. + const verb = (this.operation.details.csharp.verb ?? '').toLowerCase(); + const readOnlyVerbs = ['get', 'test', 'find', 'search', 'measure', 'show', 'ping', 'trace', 'resolve', 'read']; + if (readOnlyVerbs.includes(verb)) { + return; + } + + // Emit an inline IDynamicParameters implementation. GetDynamicParameters builds the + // RuntimeDefinedParameterDictionary locally with names + help text that mirror + // azure-powershell-common's ChangeSafetyParameters (there is no compile-time link across repos; + // a contract pin test in Accounts.Test keeps these literals in sync). This matches how SDK + // cmdlets surface -AcquirePolicyToken / -ChangeReference, so the two are indistinguishable. + this.interfaces.push(IDynamicParameters); + const getDynamicParameters = this.add(new Method('GetDynamicParameters', dotnet.Object, { + description: 'Returns the Change Safety dynamic parameters (-AcquirePolicyToken / -ChangeReference) for this write cmdlet.', + returnsDescription: 'A containing the Change Safety parameters.' + })); + getDynamicParameters.add(function* () { + yield 'var parameters = new global::System.Management.Automation.RuntimeDefinedParameterDictionary();'; + yield 'parameters.Add("AcquirePolicyToken", new global::System.Management.Automation.RuntimeDefinedParameter("AcquirePolicyToken", typeof(global::System.Management.Automation.SwitchParameter), new global::System.Collections.ObjectModel.Collection { new global::System.Management.Automation.ParameterAttribute { HelpMessage = "Acquire an Azure Policy token automatically for this resource operation.", ParameterSetName = global::System.Management.Automation.ParameterAttribute.AllParameterSets } }));'; + yield 'parameters.Add("ChangeReference", new global::System.Management.Automation.RuntimeDefinedParameter("ChangeReference", typeof(string), new global::System.Collections.ObjectModel.Collection { new global::System.Management.Automation.ParameterAttribute { HelpMessage = "The change reference resource ID for this resource operation.", ParameterSetName = global::System.Management.Automation.ParameterAttribute.AllParameterSets } }));'; + yield 'return parameters;'; + }); + } private implementIEventListener() { const $this = this; const cts = this.add(new Field('_cancellationTokenSource', System.Threading.CancellationTokenSource, { diff --git a/powershell/generators/psm1.ts b/powershell/generators/psm1.ts index 01985a80f31..23b66a586f7 100644 --- a/powershell/generators/psm1.ts +++ b/powershell/generators/psm1.ts @@ -48,6 +48,11 @@ export async function generatePsm1(project: Project) { let requestHandler = ` # Tweaks the pipeline per call $instance.OnNewRequest = $VTable.OnNewRequest`; + if (project.enableChangeSafety) { + requestHandler += ` + # Tweaks the pipeline per call (Change Safety policy-token step) + $instance.AddChangeSafetyPolicyTokenHandler = $VTable.AddChangeSafetyPolicyTokenHandler`; + } if (project.endpointResourceIdKeyName) { // for data plane, we should append different functions instead. requestHandler = ` diff --git a/powershell/internal/powershell-declarations.ts b/powershell/internal/powershell-declarations.ts index 0cbb0c67b76..50e17598232 100644 --- a/powershell/internal/powershell-declarations.ts +++ b/powershell/internal/powershell-declarations.ts @@ -32,6 +32,7 @@ export const ErrorRecord: TypeDeclaration = new ClassType(sma, 'ErrorRecord'); export const SwitchParameter: TypeDeclaration = new ClassType(sma, 'SwitchParameter'); export const NullableBoolean: TypeDeclaration = new ClassType(new Namespace('System'), 'Boolean?'); export const IArgumentCompleter: IInterface = { allProperties: [], declaration: 'System.Management.Automation.IArgumentCompleter' }; +export const IDynamicParameters: IInterface = { allProperties: [], declaration: 'System.Management.Automation.IDynamicParameters' }; export const CompletionResult: TypeDeclaration = new ClassType(sma, 'CompletionResult'); export const CommandAst: TypeDeclaration = new ClassType(`${sma}.Language`, 'CommandAst'); export const CompletionResultType: TypeDeclaration = new ClassType(sma, 'CompletionResultType'); diff --git a/powershell/internal/project.ts b/powershell/internal/project.ts index 4d61fa74bf5..b0d91956c76 100644 --- a/powershell/internal/project.ts +++ b/powershell/internal/project.ts @@ -128,6 +128,7 @@ export class Project extends codeDomProject { public modelCmdletFolder!: string; public endpointResourceIdKeyName!: string; public endpointSuffixKeyName!: string; + public enableChangeSafety!: boolean; public customFolder!: string; public utilsFolder!: string; @@ -334,6 +335,11 @@ export class Project extends codeDomProject { // configuration for whether to use fixed array in generated code of model, default is false this.fixedArray = await this.state.getValue('fixed-array', false); + // Change Safety: opt-in per module. When true, azure management-plane write-verb cmdlets get the + // -AcquirePolicyToken / -ChangeReference parameters. Default false so the rollout is controlled + // (a module opts in, alongside bumping its Az.Accounts minimum), not organic on every regeneration. + this.enableChangeSafety = await this.state.getValue('enable-change-safety', false); + // File paths this.csproj = await this.state.getValue('csproj'); this.dll = await this.state.getValue('dll'); diff --git a/powershell/module/module-class.ts b/powershell/module/module-class.ts index 1c552107e1b..e8950fd6d49 100644 --- a/powershell/module/module-class.ts +++ b/powershell/module/module-class.ts @@ -252,6 +252,11 @@ export class NewModuleClass extends Class { pipelineChangeDelegate.fullDefinition, /* prependStep */ pipelineChangeDelegate.fullDefinition)); /* appendStep */ + // Change Safety: dedicated append-only delegate for the policy-token pipeline step. + const changeSafetyPolicyTokenDelegate = new Alias('ChangeSafetyPolicyTokenDelegate', System.Action( + InvocationInfo, /* invocationInfo */ + pipelineChangeDelegate.fullDefinition)); /* appendStep */ + const argumentCompleterDelegate = namespace.add(new Alias('ArgumentCompleterDelegate', System.Func( dotnet.String, /* completerName */ InvocationInfo, /* invocationInfo */ @@ -305,6 +310,9 @@ export class NewModuleClass extends Class { } namespace.add(newRequestPipelineDelegate); + if (!isDataPlane && this.state.project.enableChangeSafety) { + namespace.add(changeSafetyPolicyTokenDelegate); + } const incomingSignalDelegate = namespace.add(new Alias('SignalDelegate', this.incomingSignalFunc)); const eventListenerDelegate = namespace.add(new Alias('EventListenerDelegate', this.eventListenerFunc)); @@ -314,6 +322,7 @@ export class NewModuleClass extends Class { /* AzAccounts VTable properties */ const OnModuleLoad = this.add(new Property('OnModuleLoad', moduleLoadPipelineDelegate, { description: 'The delegate to call when this module is loaded (supporting a commmon module).' })); const OnNewRequest = new Property('OnNewRequest', newRequestPipelineDelegate, { description: 'The delegate to call before each new request (supporting a commmon module).' }); + const AddChangeSafetyPolicyTokenHandler = new Property('AddChangeSafetyPolicyTokenHandler', changeSafetyPolicyTokenDelegate, { description: 'Change Safety: delegate called after OnNewRequest to (conditionally) add the policy-token pipeline step.' }); const AddRequestUserAgentHandler = new Property('AddRequestUserAgentHandler', newRequestPipelineDelegate, { description: 'The delegate to call before each new request to add request user agent.' }); const AddPatchRequestUriHandler = new Property('AddPatchRequestUriHandler', newRequestPipelineDelegate, { description: 'The delegate to call before each new request to patch request uri.' }); const AddAuthorizeRequestHandler = new Property('AddAuthorizeRequestHandler', authorizeRequestDelegate, { description: 'The delegate to call before each new request to add authorization.' }); @@ -329,6 +338,9 @@ export class NewModuleClass extends Class { this.add(AddAuthorizeRequestHandler); } else { this.add(OnNewRequest); + if (this.state.project.enableChangeSafety) { + this.add(AddChangeSafetyPolicyTokenHandler); + } } const GetParameterValue = this.add(new Property('GetParameterValue', getParameterDelegate, { description: 'The delegate to call to get parameter data from a common module.' })); const EventListener = this.add(new Property('EventListener', eventListenerDelegate, { description: 'A delegate that gets called for each signalled event' })); @@ -402,6 +414,9 @@ export class NewModuleClass extends Class { yield `${AddAuthorizeRequestHandler.value}?.Invoke( ${$this.pInvocationInfo.use}, ${fendpointResourceIdKeyName},${fEndpointSuffixKeyName}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); }, ${fTokenAudienceConverter}, ${$this.pExtensibleParameters} );`; } else { yield `${OnNewRequest.value}?.Invoke( ${$this.pInvocationInfo.use}, ${$this.pCorrelationId},${$this.pProcessRecordId}, (step)=> { ${pip}.Prepend(step); } , (step)=> { ${pip}.Append(step); } );`; + if ($this.state.project.enableChangeSafety) { + yield `${AddChangeSafetyPolicyTokenHandler.value}?.Invoke( ${$this.pInvocationInfo.use}, (step)=> { ${pip}.Append(step); } );`; + } } yield Return(pip); }); diff --git a/powershell/resources/psruntime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/powershell/resources/psruntime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index f36346b8291..38d7cbe28a5 100644 --- a/powershell/resources/psruntime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/powershell/resources/psruntime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -128,6 +128,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/powershell/resources/psruntime/BuildTime/Models/PsProxyOutputs.cs b/powershell/resources/psruntime/BuildTime/Models/PsProxyOutputs.cs index 52400e58df7..a8c96120c1b 100644 --- a/powershell/resources/psruntime/BuildTime/Models/PsProxyOutputs.cs +++ b/powershell/resources/psruntime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 86a8fc56062..8cc034ae94b 100644 --- a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 5c6bf7647e1..74e85ae5cd0 100644 --- a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/Context.cs index 04cd8850269..eba90899f42 100644 --- a/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/AppComplianceAutomation.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.AppComplianceAutomation.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index cd21c8a4e33..0b487ee847b 100644 --- a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index c4076757d01..25e5a8d0a14 100644 --- a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/Context.cs index 530755c9dc7..e848350cbb3 100644 --- a/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Astronomer.Astro.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.Astro.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index f3f4d5950ce..44d03b6d4f8 100644 --- a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 6d5b86ee48b..ec9a944ddfc 100644 --- a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/Context.cs index 9f187d47a68..03b5f7a5955 100644 --- a/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/AzureAI.Assets/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.MachineLearningServices.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 225883f1848..89cb4477a5f 100644 --- a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 688d13e0d37..841d854aa70 100644 --- a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/Context.cs index c97fab38e19..5313634b42e 100644 --- a/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/AzureFleet.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.ComputeFleet.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index fc97ba61683..3c73b28f5b3 100644 --- a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 40d94b824d5..05d10464990 100644 --- a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/Context.cs index 85f5e07de9d..75756f17529 100644 --- a/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/AzureLargeInstance.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.AzureLargeInstance.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 45da2e89bf1..81e8252046b 100644 --- a/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index ebee2e81a52..2028b076fd6 100644 --- a/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Chaos.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 11037706a67..36e0bac503d 100644 --- a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 6af759169a5..13122ae82bd 100644 --- a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/Context.cs index 2bb02dcf8fb..5dea3b0a81c 100644 --- a/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/CodeSigning.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.CodeSigning.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 274801feab0..2c94e6d21ed 100644 --- a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index da123eba07d..1350d32cb5b 100644 --- a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/Context.cs index 6bd0c3e3dd6..33ef633abb1 100644 --- a/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/ComputeSchedule.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.ComputeSchedule.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index ffa31e7e143..15799f98739 100644 --- a/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index e93d4439f2d..87776f8467d 100644 --- a/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Dashboard.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 929a6f35538..3b7ec76dcb3 100644 --- a/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index f3aa7093525..9dc4753e1b2 100644 --- a/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DataBox.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 7a38e76c636..a9535ea8be3 100644 --- a/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index b62245114b4..052a44fc480 100644 --- a/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DataProtection.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 8dc76de5109..bdb360e9d8a 100644 --- a/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index fa2468a5524..8f3d7d60eb9 100644 --- a/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DataReplication.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 2f03fa914b7..f66de7715c4 100644 --- a/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index de8d7f6ccb4..77ad1a7b1a0 100644 --- a/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DeviceProvisioningServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index d786435d4c7..3b7f15cdcd3 100644 --- a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index e91f5c16a1d..ffe9eab60fe 100644 --- a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/Context.cs index 78fee63f527..e0533d3c912 100644 --- a/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/DeviceRegistry.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.DeviceRegistry.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 8346546be21..c1d970a66ae 100644 --- a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index e1dbc585b0a..7e3b3351b0b 100644 --- a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/Context.cs index 681b15d10c3..e140484a149 100644 --- a/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/DocumentDB.MongoCluster.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.MongoCluster.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index ca3991e754a..a1aa544dafd 100644 --- a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index ed2e7ca410d..e1d96a16cfe 100644 --- a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/Context.cs index 3f1cfb62c9a..627807a7c70 100644 --- a/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/EdgeZones.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.EdgeZones.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 671557b98f1..e15a31bba03 100644 --- a/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index c114540da69..5f988dbfcac 100644 --- a/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/ElasticSan.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index feebc934563..d9a37cc99da 100644 --- a/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 17861883c80..fc0304cfdbd 100644 --- a/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Fleet.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index e9d7d1895e7..bf3c1225c35 100644 --- a/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 12f9dfe7159..770d0ac3660 100644 --- a/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/HardwareSecurityModules.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index efbd9cb2b7b..421dd80fd28 100644 --- a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 5e484a2c6c0..f4c2cee574e 100644 --- a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/Context.cs index a3d4937fae8..f59d9da03b0 100644 --- a/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/HealthDataAIServices.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.HealthDataAIServices.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index ecc1a44b82e..aab08d68521 100644 --- a/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 5fae0d9caf6..f5f1127bad2 100644 --- a/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Help.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 11d0861e061..cd489ee3b67 100644 --- a/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 634e19a2448..dd5894604dd 100644 --- a/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/HybridKubernetes.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index d9296de871b..a4d3c8a51f3 100644 --- a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 01aaf2f8f83..fb8b9e2ed6c 100644 --- a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/Context.cs index 3a060ab4884..80e8f0a7dbf 100644 --- a/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Informatica.DataManagement.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.Informatica.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 22aaa204b2e..06d21d0e642 100644 --- a/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index c8dd17bf5a9..b12d04e2a00 100644 --- a/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/KeyVault.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 7a9e23683ae..4a3650f8016 100644 --- a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 80d6dc6c38b..bc860569275 100644 --- a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/Context.cs index 232414c8053..ac87b2ddb7f 100644 --- a/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/KubernetesRuntime.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.ContainerOrchestratorRuntime.Runtim /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 8354079954a..ef5182ff2df 100644 --- a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 80323decb8a..43ab621fe36 100644 --- a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/Context.cs index b1de6306571..ae90b69e708 100644 --- a/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/LambdaTest.HyperExecute.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.LambdaTest.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 0e44d7aae4c..7eadbe542e5 100644 --- a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 7e52a8404e6..7640a8a9924 100644 --- a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/Context.cs index 35b70bc8850..8d802fa12ac 100644 --- a/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Liftr.WeightsAndBiases.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.WeightsBiases.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 9f00efc3bef..d0f1f820489 100644 --- a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 7537c5cfd5b..91ef3e35e71 100644 --- a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/Context.cs index 21ec09e7e9d..30319ddf626 100644 --- a/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Microsoft.AVS.Management.brown/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.VMware.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index a1a6a674d40..5bcfe8a3ecd 100644 --- a/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 39196da4b34..980498c7349 100644 --- a/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Microsoft.DBforMySQL.FlexibleServers.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index ad3e9deed92..bf3baa33181 100644 --- a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 0a441f74f47..6c0ddaa169e 100644 --- a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/Context.cs index 471d476b1cf..8c1d2f38d9e 100644 --- a/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Microsoft.DevOpsInfrastructure.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.DevOpsInfrastructure.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index c1fd04a1979..f55e7251db1 100644 --- a/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index c4ae827506a..509d45f814e 100644 --- a/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Microsoft.RecoveryServices.RecoveryServicesBackup.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 7142b68af20..4f4096f2aed 100644 --- a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index a9a14cc5d61..27462153f7f 100644 --- a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/Context.cs index 8935ee6a221..e20ebe7515f 100644 --- a/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Neon.Postgres.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.NeonPostgres.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index f44c616511c..7c4bf34cb66 100644 --- a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 346132492de..f1957b1e824 100644 --- a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/Context.cs index af0194d9eb5..a46adcf67c4 100644 --- a/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/NetworkAnalytics.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.NetworkAnalytics.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index d392ddc9b6b..64cd0a79c94 100644 --- a/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 58df7e4cea0..b38e14c228f 100644 --- a/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Oracle.Database.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 0528064fb9a..e22fdbe63da 100644 --- a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 98848d094cd..392d097bc48 100644 --- a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/Context.cs index 2c7189e0401..dcb6553720b 100644 --- a/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Pinecone.VectorDb.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.Pinecone.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 7428cabb6e9..8a9beef4e9a 100644 --- a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index a785e0c1529..9b48204de12 100644 --- a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/Context.cs index bc8bbff686f..7ba7085caab 100644 --- a/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Qumulo.Storage.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.Qumulo.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 34b6f9d11ea..661d98be312 100644 --- a/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 7bc24ee52bd..7baa209efcc 100644 --- a/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/RecoveryServices.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index fb11e3d7615..4f425f7cdd8 100644 --- a/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 4333ee0b06c..3eabb627b4f 100644 --- a/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/ServiceFabricManagedClusters.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 9c435a45fc7..fb0f7521d34 100644 --- a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index e18a63be3e4..fae7c94b313 100644 --- a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/Context.cs index 6307b17a66e..e781cce98ba 100644 --- a/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Sphere.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.Sphere.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 381858d327d..f320ce20065 100644 --- a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 34d07afd1d6..ebe3e9c367c 100644 --- a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/Context.cs index d0544a1ad04..464960b7733 100644 --- a/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/StandbyPool.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.StandbyPool.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index 190fc2f2fff..634214ac70b 100644 --- a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index ec08cda6ce5..51211184f7b 100644 --- a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/Context.cs index 572f8a828a2..25e4d8a4530 100644 --- a/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/StorageAction.Management.brown/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.StorageAction.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext { diff --git a/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index bed38bb65b9..529c26b6b97 100644 --- a/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index dcd7f28fdd5..b08e05e0fc0 100644 --- a/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/StorageMover.Management.brown/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs index d7eb35f946d..1b144b6634d 100644 --- a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs +++ b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Cmdlets/ExportProxyCmdlet.cs @@ -139,6 +139,7 @@ protected override void ProcessRecord() } sb.Append($"){Environment.NewLine}{Environment.NewLine}"); + sb.Append(variantGroup.ToDynamicParamOutput()); sb.Append(variantGroup.ToBeginOutput()); sb.Append(variantGroup.ToProcessOutput()); sb.Append(variantGroup.ToEndOutput()); diff --git a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs index 627ca81b0bf..660f9516a32 100644 --- a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs +++ b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/BuildTime/Models/PsProxyOutputs.cs @@ -199,6 +199,59 @@ public string ClearTelemetryContext() } } + internal class DynamicParamOutput : BaseOutput + { + public DynamicParamOutput(VariantGroup variantGroup) : base(variantGroup) + { + } + + // Change Safety: only emit a dynamicparam block when a wrapped (private) cmdlet actually declares + // dynamic parameters via IDynamicParameters. For every other cmdlet this emits nothing (zero diff), + // so it is a no-op that just forwards the private cmdlet's runtime parameters through the proxy. + private bool HasDynamicParameters() => VariantGroup.Variants.Any(v => + { + var implementingType = (v.Info as CmdletInfo)?.ImplementingType; + return implementingType != null && typeof(IDynamicParameters).IsAssignableFrom(implementingType); + }); + + private string GetParameterSetToCmdletMapping() + { + var sb = new StringBuilder(); + sb.AppendLine($"{Indent}$mapping = @{{"); + foreach (var variant in VariantGroup.Variants) + { + sb.AppendLine($@"{Indent}{Indent}{variant.VariantName} = '{variant.PrivateModuleName}\{variant.PrivateCmdletName}';"); + } + sb.Append($"{Indent}}}"); + return sb.ToString(); + } + + public override string ToString() => !HasDynamicParameters() ? String.Empty : $@"dynamicparam {{ +{Indent}$parameterSet = $PSCmdlet.ParameterSetName +{GetParameterSetToCmdletMapping()} +{Indent}if (-not $mapping.ContainsKey($parameterSet)) {{ $parameterSet = @($mapping.Keys)[0] }} +{Indent}try {{ +{Indent}{Indent}$targetCmd = $ExecutionContext.InvokeCommand.GetCommand(($mapping[$parameterSet]), [System.Management.Automation.CommandTypes]::Cmdlet, $PSBoundParameters) +{Indent}{Indent}$dynamicParams = @($targetCmd.Parameters.GetEnumerator() | Microsoft.PowerShell.Core\Where-Object {{ $_.Value.IsDynamic }}) +{Indent}{Indent}if ($dynamicParams.Length -gt 0) {{ +{Indent}{Indent}{Indent}$paramDictionary = [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() +{Indent}{Indent}{Indent}foreach ($param in $dynamicParams) {{ +{Indent}{Indent}{Indent}{Indent}$param = $param.Value +{Indent}{Indent}{Indent}{Indent}if (-not $MyInvocation.MyCommand.Parameters.ContainsKey($param.Name)) {{ +{Indent}{Indent}{Indent}{Indent}{Indent}$dynParam = [System.Management.Automation.RuntimeDefinedParameter]::new($param.Name, $param.ParameterType, $param.Attributes) +{Indent}{Indent}{Indent}{Indent}{Indent}$paramDictionary.Add($param.Name, $dynParam) +{Indent}{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}}} +{Indent}{Indent}{Indent}return $paramDictionary +{Indent}{Indent}}} +{Indent}}} catch {{ +{Indent}{Indent}throw +{Indent}}} +}} + +"; + } + internal class BeginOutput : BaseOutput { public BeginOutput(VariantGroup variantGroup) : base(variantGroup) @@ -640,6 +693,8 @@ public static string ToSyntaxTypeName(this Type type) public static ParameterNameOutput ToParameterNameOutput(this string parameterName, bool isLast) => new ParameterNameOutput(parameterName, isLast); + public static DynamicParamOutput ToDynamicParamOutput(this VariantGroup variantGroup) => new DynamicParamOutput(variantGroup); + public static BeginOutput ToBeginOutput(this VariantGroup variantGroup) => new BeginOutput(variantGroup); public static ProcessOutput ToProcessOutput(this VariantGroup variantGroup) => new ProcessOutput(variantGroup); diff --git a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/Context.cs b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/Context.cs index 70817b9e63a..5d5b1e331f0 100644 --- a/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/Context.cs +++ b/tests-upgrade/tests-emitter/Workloads.SAPVirtualInstance.Management/target/generated/runtime/Context.cs @@ -20,7 +20,7 @@ namespace Microsoft.Azure.PowerShell.Cmdlets.SAPVirtualInstance.Runtime /// The IContext Interface defines the communication mechanism for input customization. /// /// - /// In the context, we will have client, pipeline, PSBoundParamters, default EventListener, Cancellation. + /// In the context, we will have client, pipeline, PSBoundParameters, default EventListener, Cancellation. /// public interface IContext {