Skip to content

Commit 48c247f

Browse files
authored
Change the default warning message of CmdletPreviewAttribute and allow setting ETA (#395)
* Change the default warning message of CmdletPreviewAttribute and allow setting ETA * polish * add frequency control * polish * polish * change date format to short date in breaking change attribute * polish
1 parent dfe6dba commit 48c247f

8 files changed

+579
-511
lines changed

src/Common/AzurePSCmdlet.cs

+13-1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public abstract class AzurePSCmdlet : PSCmdlet, IDisposable
4747
IAzureEventListener _azureEventListener;
4848
protected static ConcurrentQueue<string> InitializationWarnings { get; set; } = new ConcurrentQueue<string>();
4949

50+
protected static ConcurrentQueue<string> PromptedPreviewMessageCmdlets { get; set; } = new ConcurrentQueue<string>();
51+
5052
private RecordingTracingInterceptor _httpTracingInterceptor;
5153
private object lockObject = new object();
5254
private AzurePSDataCollectionProfile _cachedProfile = null;
@@ -378,7 +380,17 @@ private void WriteBreakingChangeOrPreviewMessage()
378380
&& configManager.GetConfigValue<bool>(ConfigKeysForCommon.DisplayBreakingChangeWarning))
379381
{
380382
BreakingChangeAttributeHelper.ProcessCustomAttributesAtRuntime(this.GetType(), this.MyInvocation, WriteWarning);
381-
PreviewAttributeHelper.ProcessCustomAttributesAtRuntime(this.GetType(), this.MyInvocation, WriteDebug);
383+
384+
// Write preview message once for each cmdlet in one session
385+
// Preview message may be outputed more than once if a cmdlet is concurrently called
386+
// Considering lock affects performance but warning message is no harm
387+
if (this.MyInvocation?.MyCommand != null
388+
&& !PromptedPreviewMessageCmdlets.Contains(this.MyInvocation?.MyCommand?.Name)
389+
&& PreviewAttributeHelper.ContainsPreviewAttribute(this.GetType(), this.MyInvocation))
390+
{
391+
PreviewAttributeHelper.ProcessCustomAttributesAtRuntime(this.GetType(), this.MyInvocation, WriteWarning);
392+
PromptedPreviewMessageCmdlets.Enqueue(this.MyInvocation.MyCommand.Name);
393+
}
382394
}
383395
}
384396

src/Common/Common.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141

4242
<ItemGroup>
4343
<Compile Update="Properties\Resources.Designer.cs">
44-
<DesignTime>true</DesignTime>
44+
<DesignTime>True</DesignTime>
4545
<AutoGen>true</AutoGen>
4646
<DependentUpon>Resources.resx</DependentUpon>
4747
</Compile>

src/Common/CustomAttributes/CmdletPreviewAttribute.cs

+29-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
using Microsoft.WindowsAzure.Commands.Common.Properties;
1616
using System;
17+
using System.Globalization;
1718
using System.Management.Automation;
1819

1920
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
@@ -25,19 +26,46 @@ public class CmdletPreviewAttribute : System.Attribute
2526
{
2627
public string _message;
2728

29+
/// <summary>
30+
/// EstimatedGaDate assumes value follows "en-US" culture,
31+
/// which means dates are written in the month–day–year order like
32+
/// July 19, 2023, 19 July 2023, 07/19/2023 or 2023-07-19
33+
/// </summary>
34+
public DateTime EstimatedGaDate { get; }
35+
36+
public bool IsEstimatedGaDateSet { get; } = false;
37+
2838
public CmdletPreviewAttribute()
2939
{
3040
this._message = Resources.PreviewCmdletMessage;
3141
}
3242

3343
public CmdletPreviewAttribute(string message)
3444
{
35-
this._message = message;
45+
this._message = string.IsNullOrEmpty(message) ? Resources.PreviewCmdletMessage : message;
46+
}
47+
48+
/// <summary>
49+
/// Constructor with message and estimated GA date
50+
/// </summary>
51+
/// <param name="message">Customized preview message</param>
52+
/// <param name="estimatedGaDate">EstimatedGaDate assumes value follows "en-US" culture, which means dates are written in the month–day–year order</param>
53+
public CmdletPreviewAttribute(string message, string estimatedGaDate) : this(message)
54+
{
55+
if (DateTime.TryParse(estimatedGaDate, new CultureInfo("en-US"), DateTimeStyles.None, out DateTime result))
56+
{
57+
this.EstimatedGaDate = result;
58+
this.IsEstimatedGaDateSet = true;
59+
}
3660
}
3761

3862
public void PrintCustomAttributeInfo(Action<string> writeOutput)
3963
{
4064
writeOutput(this._message);
65+
if (IsEstimatedGaDateSet)
66+
{
67+
writeOutput(string.Format(Resources.PreviewCmdletETAMessage, this.EstimatedGaDate.ToShortDateString()));
68+
}
4169
}
4270

4371
public virtual bool IsApplicableToInvocation(InvocationInfo invocation)

src/Common/CustomAttributes/GenericBreakingChangeAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public string GetBreakingChangeTextFromAttribute(Type type, bool withCmdletName)
104104

105105
if (ChangeInEfectByDateSet)
106106
{
107-
breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEfectByDate));
107+
breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEfectByDate.ToShortDateString()));
108108
}
109109

110110
if (DeprecateByVersionSet)
@@ -147,7 +147,7 @@ public void PrintCustomAttributeInfo(Type type, bool withCmdletName, Action<stri
147147

148148
if (ChangeInEfectByDateSet)
149149
{
150-
writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEfectByDate));
150+
writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEfectByDate.ToShortDateString()));
151151
}
152152

153153
if (DeprecateByVersionSet)

src/Common/CustomAttributes/GenericBreakingChangeWithVersionAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public string GetBreakingChangeTextFromAttribute(Type type, bool withCmdletName)
9999

100100
if (ChangeInEffectByDateSet)
101101
{
102-
breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate));
102+
breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate.ToShortDateString()));
103103
}
104104

105105
if (!string.IsNullOrWhiteSpace(DeprecateByVersion))
@@ -144,7 +144,7 @@ public void PrintCustomAttributeInfo(Type type, bool withCmdletName, Action<stri
144144

145145
if (ChangeInEffectByDateSet)
146146
{
147-
writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate));
147+
writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate.ToShortDateString()));
148148
}
149149

150150
writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByAzVersion, this.DeprecateByAzVersion));

src/Common/CustomAttributes/PreviewAttributeHelper.cs

+17-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using System.Linq;
1818
using System.Management.Automation;
1919
using System.Reflection;
20+
using System.Text;
2021

2122
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
2223
{
@@ -33,16 +34,31 @@ internal class PreviewAttributeHelper
3334
public static void ProcessCustomAttributesAtRuntime(Type type, InvocationInfo invocationInfo, Action<string> writeOutput)
3435
{
3536
List<CmdletPreviewAttribute> attributes = new List<CmdletPreviewAttribute>(GetAllAttributesInType(type, invocationInfo));
37+
StringBuilder sb = new StringBuilder().Clear();
38+
Action<string> appendPreviewMessage = (string s) => sb.Append(s);
3639

3740
if (attributes != null && attributes.Count > 0)
3841
{
3942
foreach (CmdletPreviewAttribute attribute in attributes)
4043
{
41-
attribute.PrintCustomAttributeInfo(writeOutput);
44+
attribute.PrintCustomAttributeInfo(appendPreviewMessage);
4245
}
46+
writeOutput(sb.ToString());
47+
4348
}
4449
}
4550

51+
/// <summary>
52+
/// Process CmdletExperimentation attribute in runtime
53+
/// </summary>
54+
/// <param name="type"></param>
55+
/// <param name="invocationInfo"></param>
56+
/// <param name="writeOutput"></param>
57+
public static bool ContainsPreviewAttribute(Type type, InvocationInfo invocationInfo)
58+
{
59+
return GetAllAttributesInType(type, invocationInfo).Count() > 0;
60+
}
61+
4662
private static IEnumerable<CmdletPreviewAttribute> GetAllAttributesInType(Type type, InvocationInfo invocationInfo)
4763
{
4864
List<CmdletPreviewAttribute> attributeList = new List<CmdletPreviewAttribute>();

0 commit comments

Comments
 (0)