Support add estimated-ga-date for preview cmdlet (#1200)

* CmdetPreview Message with ETA and frequency control

* fix rush lint issues

* Update powershell/resources/psruntime/BuildTime/Models/PsProxyOutputs.cs
This commit is contained in:
Beisi Zhou 2023-09-06 14:08:53 +08:00 коммит произвёл GitHub
Родитель 630a4631b9
Коммит 9c79a57828
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 103 добавлений и 28 удалений

Просмотреть файл

@ -214,9 +214,12 @@ export function addParameterBreakingChange(targetProperty: Property, parameter:
}
}
export function addPreviewMessage(targetProperty: Property, parameter: any) {
if (parameter.previewMessage) {
targetProperty.add(new Attribute(ClientRuntime.PreviewMessageAttribute, { parameters: [`"${parameter.previewMessage}"`] }));
export function addParameterPreviewMessage(targetProperty: Property, parameter: any) {
if (parameter.previewAnnouncement) {
const parameters = [];
parameters.push(`"${parameter.previewAnnouncement.previewMessage}"`);
if (parameter.previewAnnouncement.estimatedGaDate) parameters.push(`"${parameter.previewAnnouncement.estimatedGaDate}"`);
targetProperty.add(new Attribute(ClientRuntime.PreviewMessageAttribute, { parameters: parameters }));
}
}
@ -1730,7 +1733,7 @@ export class CmdletClass extends Class {
NewAddInfoAttribute(cmdletParameter, propertyType, !!vParam.required, false, desc, (<NewVirtualProperty>vParam.origin).property.serializedName);
NewAddCompleterInfo(cmdletParameter, vParam);
addParameterBreakingChange(cmdletParameter, vParam);
addPreviewMessage(cmdletParameter, vParam);
addParameterPreviewMessage(cmdletParameter, vParam);
addDefaultInfo(cmdletParameter, vParam);
this.addDoNotExport(cmdletParameter, vParam);
}
@ -1867,7 +1870,7 @@ export class CmdletClass extends Class {
}
NewAddCompleterInfo(regularCmdletParameter, vParam);
addParameterBreakingChange(regularCmdletParameter, vParam);
addPreviewMessage(regularCmdletParameter, vParam);
addParameterPreviewMessage(regularCmdletParameter, vParam);
addDefaultInfo(regularCmdletParameter, vParam);
this.addDoNotExport(regularCmdletParameter, vParam);
@ -2087,9 +2090,13 @@ export class CmdletClass extends Class {
}
//add preview message attribute for cmdlet
if (operation.details.csharp.previewMessage) {
this.add(new Attribute(ClientRuntime.PreviewMessageAttribute, { parameters: [`"${operation.details.csharp.previewMessage}"`] }));
if (operation.details.csharp.previewAnnouncement) {
const parameters = [];
parameters.push(`"${operation.details.csharp.previewAnnouncement.previewMessage}"`);
if (operation.details.csharp.previewAnnouncement.estimatedGaDate) parameters.push(`"${operation.details.csharp.previewAnnouncement.estimatedGaDate}"`);
this.add(new Attribute(ClientRuntime.PreviewMessageAttribute, { parameters: parameters }));
}
this.add(new Attribute(OutputTypeAttribute, { parameters: [...outputTypes] }));
if (shouldAddPassThru) {
const passThru = this.add(new Property('PassThru', SwitchParameter, { description: 'When specified, forces the cmdlet return a \'bool\' given that there isn\'t a return type by default.' }));
@ -2103,7 +2110,7 @@ export class CmdletClass extends Class {
if (operation.details.default.externalDocs) {
this.add(new Attribute(ExternalDocsAttribute, {
parameters: [`${new StringExpression(this.operation.details.default.externalDocs?.url ?? '')}`,
`${new StringExpression(this.operation.details.default.externalDocs?.description ?? '')}`]
`${new StringExpression(this.operation.details.default.externalDocs?.description ?? '')}`]
}));
}

Просмотреть файл

@ -87,7 +87,10 @@ interface WhereCommandDirective {
'deprecated-by-azversion': string;
'change-effective-date'?: string;
};
'preview-message'?: string;
'preview-announcement'?: {
'preview-message'?: string;
'estimated-ga-date'?: string;
};
'default'?: {
name: string;
description: string;
@ -385,7 +388,7 @@ async function tweakModel(state: State): Promise<PwshModel> {
: undefined
: undefined;
const breakingChange = (directive.set !== undefined) ? directive.set['breaking-change'] : undefined;
const previewMessage = (directive.set !== undefined) ? directive.set['preview-message'] : undefined;
const previewAnnouncement = (directive.set !== undefined) ? directive.set['preview-announcement'] : undefined;
const subjectReplacer = (directive.set !== undefined) ? directive.set['subject'] : undefined;
const subjectPrefixReplacer = (directive.set !== undefined) ? directive.set['subject-prefix'] : undefined;
const verbReplacer = (directive.set !== undefined) ? directive.set.verb : undefined;
@ -468,7 +471,11 @@ async function tweakModel(state: State): Promise<PwshModel> {
parameter.breakingChange.changeDescription = (breakingChange && breakingChange['change-description']) ? breakingChange['change-description'] : undefined;
}
// handle preview message for parameter
parameter.previewMessage = previewMessage ? previewMessage : undefined;
if (previewAnnouncement) {
parameter.previewAnnouncement = <any>{};
parameter.previewAnnouncement.previewMessage = previewAnnouncement['preview-message'] ?? '';
parameter.previewAnnouncement.estimatedGaDate = previewAnnouncement['estimated-ga-date'] ?? undefined;
}
if (clearAlias) {
parameter.alias = [];
state.message({
@ -589,7 +596,11 @@ See https://github.com/Azure/autorest.powershell/blob/main/docs/directives.md#de
}
// handle preview message for cmdlet
operation.details.csharp.previewMessage = previewMessage ? previewMessage : undefined;
if (previewAnnouncement) {
operation.details.csharp.previewAnnouncement = <any>{};
operation.details.csharp.previewAnnouncement.previewMessage = previewAnnouncement['preview-message'] ?? '';
operation.details.csharp.previewAnnouncement.estimatedGaDate = previewAnnouncement['estimated-ga-date'] ?? undefined;
}
// just the subject prefix can be an empty string
if (subjectPrefixReplacer !== undefined || subjectReplacer || verbReplacer || variantReplacer) {
@ -965,5 +976,5 @@ export async function applyModifiersV2(service: Host) {
const state = await new ModelState<PwshModel>(service).init();
const result = await tweakModel(state);
await service.writeFile({ filename: 'code-model-v4-modifiers-v2.yaml', content: serialize(result), sourceMap: undefined, artifactType: 'code-model-v4'});
await service.writeFile({ filename: 'code-model-v4-modifiers-v2.yaml', content: serialize(result), sourceMap: undefined, artifactType: 'code-model-v4' });
}

Просмотреть файл

@ -121,7 +121,7 @@ namespace Microsoft.Rest.ClientRuntime.PowerShell
: String.Empty;
}
internal class PSArgumentCompleterOutput: ArgumentCompleterOutput
internal class PSArgumentCompleterOutput : ArgumentCompleterOutput
{
public PSArgumentCompleterInfo PSArgumentCompleterInfo { get; }
@ -206,8 +206,14 @@ namespace Microsoft.Rest.ClientRuntime.PowerShell
public string GetProcessCustomAttributesAtRuntime()
{
return VariantGroup.IsInternal ? "" : $@"{Indent}{Indent}$cmdInfo = Get-Command -Name $mapping[$parameterSet]{Environment.NewLine}{Indent}{Indent}[Microsoft.Message.ClientRuntime.MessageAttributeHelper]::ProcessCustomAttributesAtRuntime($cmdInfo, $MyInvocation, $parameterSet, $PSCmdlet)";
return VariantGroup.IsInternal ? "" : $@"{Indent}{Indent}$cmdInfo = Get-Command -Name $mapping[$parameterSet]
{Indent}{Indent}[Microsoft.Message.ClientRuntime.MessageAttributeHelper]::ProcessCustomAttributesAtRuntime($cmdInfo, $MyInvocation, $parameterSet, $PSCmdlet)
{Indent}{Indent}if ($null -ne $MyInvocation.MyCommand -and [Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet]::PromptedPreviewMessageCmdlets -notcontains $MyInvocation.MyCommand.Name -and [Microsoft.Message.ClientRuntime.MessageAttributeHelper]::ContainsPreviewAttribute($cmdInfo, $MyInvocation)){{
{Indent}{Indent}{Indent}[Microsoft.Message.ClientRuntime.MessageAttributeHelper]::ProcessPreviewMessageAttributesAtRuntime($cmdInfo, $MyInvocation, $parameterSet, $PSCmdlet)
{Indent}{Indent}{Indent}[Microsoft.WindowsAzure.Commands.Utilities.Common.AzurePSCmdlet]::PromptedPreviewMessageCmdlets.Enqueue($MyInvocation.MyCommand.Name)
{Indent}{Indent}}}";
}
private string GetTelemetry()
{
if (!VariantGroup.IsInternal && IsAzure)
@ -278,7 +284,8 @@ namespace Microsoft.Rest.ClientRuntime.PowerShell
var parameterName = defaultInfo.ParameterGroup.ParameterName;
sb.AppendLine();
var setCondition = " ";
if (!String.IsNullOrEmpty(defaultInfo.SetCondition)) {
if (!String.IsNullOrEmpty(defaultInfo.SetCondition))
{
setCondition = $" -and {defaultInfo.SetCondition}";
}
sb.AppendLine($"{Indent}{Indent}if (({variantListString}) -contains $parameterSet -and -not $PSBoundParameters.ContainsKey('{parameterName}'){setCondition}) {{");

Просмотреть файл

@ -168,6 +168,11 @@ namespace Microsoft.Message.ClientRuntime
{
public string _message;
public DateTime EstimatedGaDate { get; }
public bool IsEstimatedGaDateSet { get; } = false;
public PreviewMessageAttribute()
{
this._message = Resources.PreviewCmdletMessage;
@ -175,12 +180,26 @@ namespace Microsoft.Message.ClientRuntime
public PreviewMessageAttribute(string message)
{
this._message = message;
this._message = string.IsNullOrEmpty(message) ? Resources.PreviewCmdletMessage : message;
}
public void PrintCustomAttributeInfo(System.Management.Automation.PSCmdlet psCmdlet)
public PreviewMessageAttribute(string message, string estimatedDateOfGa) : this(message)
{
psCmdlet.WriteWarning(this._message);
if (DateTime.TryParse(estimatedDateOfGa, new CultureInfo("en-US"), DateTimeStyles.None, out DateTime result))
{
this.EstimatedGaDate = result;
this.IsEstimatedGaDateSet = true;
}
}
public void PrintCustomAttributeInfo(Action<string> writeOutput)
{
writeOutput(this._message);
if (IsEstimatedGaDateSet)
{
writeOutput(string.Format(Resources.PreviewCmdletETAMessage, this.EstimatedGaDate.ToShortDateString()));
}
}
public virtual bool IsApplicableToInvocation(InvocationInfo invocation)

Просмотреть файл

@ -35,7 +35,7 @@ namespace Microsoft.Message.ClientRuntime
* the boundParameterNames is a list of parameters bound to the cmdlet at runtime,
* We only process the Parameter beaking change attributes attached only params listed in this list (if present)
* */
public static void ProcessCustomAttributesAtRuntime(CommandInfo commandInfo, InvocationInfo invocationInfo, String parameterSet, System.Management.Automation.PSCmdlet psCmdlet)
public static void ProcessCustomAttributesAtRuntime(CommandInfo commandInfo, InvocationInfo invocationInfo, String parameterSet, System.Management.Automation.PSCmdlet psCmdlet, bool showPreviewMessage = true)
{
bool supressWarningOrError = false;
@ -57,36 +57,49 @@ namespace Microsoft.Message.ClientRuntime
{
psCmdlet.WriteWarning("The DefaultProfile parameter is not functional. Use the SubscriptionId parameter when available if executing the cmdlet against a different subscription.");
}
ProcessBreakingChangeAttributesAtRuntime(commandInfo, invocationInfo, parameterSet, psCmdlet);
}
private static void ProcessBreakingChangeAttributesAtRuntime(CommandInfo commandInfo, InvocationInfo invocationInfo, String parameterSet, System.Management.Automation.PSCmdlet psCmdlet)
{
List<GenericBreakingChangeAttribute> attributes = new List<GenericBreakingChangeAttribute>(GetAllBreakingChangeAttributesInType(commandInfo, invocationInfo, parameterSet));
StringBuilder sb = new StringBuilder();
Action<string> appendBreakingChangeInfo = (string s) => sb.Append(s);
Action<string> appendAttributeMessage = (string s) => sb.Append(s);
if (attributes != null && attributes.Count > 0)
{
appendBreakingChangeInfo(string.Format(Resources.BreakingChangesAttributesHeaderMessage, commandInfo.Name.Split('_')[0]));
appendAttributeMessage(string.Format(Resources.BreakingChangesAttributesHeaderMessage, commandInfo.Name.Split('_')[0]));
foreach (GenericBreakingChangeAttribute attribute in attributes)
{
attribute.PrintCustomAttributeInfo(appendBreakingChangeInfo);
attribute.PrintCustomAttributeInfo(appendAttributeMessage);
}
appendBreakingChangeInfo(string.Format(Resources.BreakingChangesAttributesFooterMessage, BREAKING_CHANGE_ATTRIBUTE_INFORMATION_LINK));
appendAttributeMessage(string.Format(Resources.BreakingChangesAttributesFooterMessage, BREAKING_CHANGE_ATTRIBUTE_INFORMATION_LINK));
psCmdlet.WriteWarning(sb.ToString());
}
}
public static void ProcessPreviewMessageAttributesAtRuntime(CommandInfo commandInfo, InvocationInfo invocationInfo, String parameterSet, System.Management.Automation.PSCmdlet psCmdlet)
{
List<PreviewMessageAttribute> previewAttributes = new List<PreviewMessageAttribute>(GetAllPreviewAttributesInType(commandInfo, invocationInfo));
StringBuilder sb = new StringBuilder();
Action<string> appendAttributeMessage = (string s) => sb.Append(s);
if (previewAttributes != null && previewAttributes.Count > 0)
{
foreach (PreviewMessageAttribute attribute in previewAttributes)
{
attribute.PrintCustomAttributeInfo(psCmdlet);
attribute.PrintCustomAttributeInfo(appendAttributeMessage);
}
psCmdlet.WriteWarning(sb.ToString());
}
}
/**
* This function takes in a CommandInfo (CmdletInfo or FunctionInfo)
* And returns all the deprecation attributes attached to it
@ -128,6 +141,12 @@ namespace Microsoft.Message.ClientRuntime
}
return invocationInfo == null ? attributeList : attributeList.Where(e => e.GetType() == typeof(ParameterSetBreakingChangeAttribute) ? ((ParameterSetBreakingChangeAttribute)e).IsApplicableToInvocation(invocationInfo, parameterSet) : e.IsApplicableToInvocation(invocationInfo));
}
public static bool ContainsPreviewAttribute(CommandInfo commandInfo, InvocationInfo invocationInfo)
{
return GetAllPreviewAttributesInType(commandInfo, invocationInfo)?.Count() > 0;
}
private static IEnumerable<PreviewMessageAttribute> GetAllPreviewAttributesInType(CommandInfo commandInfo, InvocationInfo invocationInfo)
{
List<PreviewMessageAttribute> attributeList = new List<PreviewMessageAttribute>();

Просмотреть файл

@ -3135,7 +3135,16 @@ namespace Microsoft.generated.runtime.Properties
}
/// <summary>
/// Looks up a localized string similar to This cmdlet is in preview. The functionality may not be available in the selected subscription.
/// Looks up a localized string similar to The estimated generally available date is &apos;{0}&apos;..
/// </summary>
public static string PreviewCmdletETAMessage {
get {
return ResourceManager.GetString("PreviewCmdletETAMessage", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This cmdlet is in preview. Its behavior is subject to change based on customer feedback..
/// </summary>
public static string PreviewCmdletMessage
{

Просмотреть файл

@ -1736,7 +1736,10 @@ The type of the parameter is changing from '{0}' to '{1}'.</value>
Note : Go to {0} for steps to suppress this breaking change warning, and other information on breaking changes in Azure PowerShell.</value>
</data>
<data name="PreviewCmdletMessage" xml:space="preserve">
<value>This cmdlet is in preview. The functionality may not be available in the selected subscription.</value>
<value>This cmdlet is in preview. Its behavior is subject to change based on customer feedback.</value>
</data>
<data name="PreviewCmdletETAMessage" xml:space="preserve">
<value> The estimated generally available date is '{0}'.</value>
</data>
<data name="BreakingChangesAttributesInEffectByAzVersion" xml:space="preserve">
<value>- The change is expected to take effect from Az version : '{0}'</value>