Skip to content

Hongtu/attribute0518 #387

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 18, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
create new attributes with version instead of modifying existing attr…
…ibutes
  • Loading branch information
Hongtu Zhang (FA Talent) committed May 18, 2023
commit b930002b3f9cd64244e722a4aad40944ac637330
18 changes: 9 additions & 9 deletions src/Common/CustomAttributes/BreakingChangeAttributeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ Please leave this section at the top of the breaking change documentation.
* */
public static void ProcessCustomAttributesAtRuntime(Type type, InvocationInfo invocationInfo, Action<string> writeOutput)
{
List<GenericBreakingChangeAttribute> attributes = new List<GenericBreakingChangeAttribute>(GetAllBreakingChangeAttributesInType(type, invocationInfo));
List<GenericBreakingChangeWithVersionAttribute> attributes = new List<GenericBreakingChangeWithVersionAttribute>(GetAllBreakingChangeAttributesInType(type, invocationInfo));
StringBuilder sb = new StringBuilder();
Action<string> appendBreakingChangeInfo = (string s) => sb.Append(s);

if (attributes != null && attributes.Count > 0)
{
appendBreakingChangeInfo(string.Format(Resources.BreakingChangesAttributesHeaderMessage, Utilities.GetNameFromCmdletType(type)));

foreach (GenericBreakingChangeAttribute attribute in attributes)
foreach (GenericBreakingChangeWithVersionAttribute attribute in attributes)
{
attribute.PrintCustomAttributeInfo(type, false, appendBreakingChangeInfo);
}
Expand All @@ -109,7 +109,7 @@ public static List<string> GetBreakingChangeMessagesForType(Type type)

//This is used as a migration guide, we need to process all properties/fields, moreover at this point of time we do not have a list of all the
//bound params anyways
foreach (GenericBreakingChangeAttribute attribute in GetAllBreakingChangeAttributesInType(type, null))
foreach (GenericBreakingChangeWithVersionAttribute attribute in GetAllBreakingChangeAttributesInType(type, null))
{
messages.Add(attribute.GetBreakingChangeTextFromAttribute(type, true));
}
Expand All @@ -124,25 +124,25 @@ public static List<string> GetBreakingChangeMessagesForType(Type type)
* 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 IEnumerable<GenericBreakingChangeAttribute> GetAllBreakingChangeAttributesInType(Type type, InvocationInfo invocationInfo)
public static IEnumerable<GenericBreakingChangeWithVersionAttribute> GetAllBreakingChangeAttributesInType(Type type, InvocationInfo invocationInfo)
{
List<GenericBreakingChangeAttribute> attributeList = new List<GenericBreakingChangeAttribute>();
List<GenericBreakingChangeWithVersionAttribute> attributeList = new List<GenericBreakingChangeWithVersionAttribute>();

attributeList.AddRange(type.GetCustomAttributes(typeof(GenericBreakingChangeAttribute), false).Cast<GenericBreakingChangeAttribute>());
attributeList.AddRange(type.GetCustomAttributes(typeof(GenericBreakingChangeWithVersionAttribute), false).Cast<GenericBreakingChangeWithVersionAttribute>());

foreach (MethodInfo m in type.GetRuntimeMethods())
{
attributeList.AddRange((m.GetCustomAttributes(typeof(GenericBreakingChangeAttribute), false).Cast<GenericBreakingChangeAttribute>()));
attributeList.AddRange((m.GetCustomAttributes(typeof(GenericBreakingChangeWithVersionAttribute), false).Cast<GenericBreakingChangeWithVersionAttribute>()));
}

foreach (FieldInfo f in type.GetRuntimeFields())
{
attributeList.AddRange(f.GetCustomAttributes(typeof(GenericBreakingChangeAttribute), false).Cast<GenericBreakingChangeAttribute>());
attributeList.AddRange(f.GetCustomAttributes(typeof(GenericBreakingChangeWithVersionAttribute), false).Cast<GenericBreakingChangeWithVersionAttribute>());
}

foreach (PropertyInfo p in type.GetRuntimeProperties())
{
attributeList.AddRange(p.GetCustomAttributes(typeof(GenericBreakingChangeAttribute), false).Cast<GenericBreakingChangeAttribute>());
attributeList.AddRange(p.GetCustomAttributes(typeof(GenericBreakingChangeWithVersionAttribute), false).Cast<GenericBreakingChangeWithVersionAttribute>());
}

return invocationInfo == null ? attributeList : attributeList.Where(e => e.IsApplicableToInvocation(invocationInfo));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.WindowsAzure.Commands.Common.Properties;
using System;

namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
[AttributeUsage(
AttributeTargets.Class,
AllowMultiple = true)]
public class CmdletDeprecationWithVersionAttribute : GenericBreakingChangeWithVersionAttribute
{
public string ReplacementCmdletName { get; set; }

public CmdletDeprecationWithVersionAttribute(string deprecateByAzVersion, string deprecateByVersion) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion)
{
}

public CmdletDeprecationWithVersionAttribute(string deprecateByAzVersion, string deprecateByVersion, string changeInEffectByDate) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion, changeInEffectByDate)
{
}

protected override string GetAttributeSpecificMessage()
{
if (string.IsNullOrWhiteSpace(ReplacementCmdletName))
{
return Resources.BreakingChangesAttributesCmdLetDeprecationMessageNoReplacement;
}
else
{
return string.Format(Resources.BreakingChangesAttributesCmdLetDeprecationMessageWithReplacement, ReplacementCmdletName);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.WindowsAzure.Commands.Common.Properties;
using System;
using System.Text;

namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
[AttributeUsage(
AttributeTargets.Class,
AllowMultiple = true)]
public class CmdletOutputBreakingChangeWithVersionAttribute : GenericBreakingChangeWithVersionAttribute
{
public Type DeprecatedCmdLetOutputType { get; }

//This is still a String instead of a Type as this
//might be undefined at the time of adding the attribute
public string ReplacementCmdletOutputTypeName { get; set; }

public string[] DeprecatedOutputProperties { get; set; }

public string[] NewOutputProperties { get; set; }


public CmdletOutputBreakingChangeWithVersionAttribute(Type deprecatedCmdletOutputTypeName, string deprecateByAzVersion, string deprecateByVersion) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion)
{
this.DeprecatedCmdLetOutputType = deprecatedCmdletOutputTypeName;
}

public CmdletOutputBreakingChangeWithVersionAttribute(Type deprecatedCmdletOutputTypeName, string deprecateByAzVersion, string deprecateByVersion, string changeInEfectByDate) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion, changeInEfectByDate)
{
this.DeprecatedCmdLetOutputType = deprecatedCmdletOutputTypeName;
}

protected override string GetAttributeSpecificMessage()
{
StringBuilder message = new StringBuilder();

//check for the deprecation scenario
if (string.IsNullOrWhiteSpace(ReplacementCmdletOutputTypeName) && NewOutputProperties == null && DeprecatedOutputProperties == null && string.IsNullOrWhiteSpace(ChangeDescription))
{
message.Append(string.Format(Resources.BreakingChangesAttributesCmdLetOutputTypeDeprecated, DeprecatedCmdLetOutputType.FullName));
}
else
{
if (!string.IsNullOrWhiteSpace(ReplacementCmdletOutputTypeName))
{
message.Append(string.Format(Resources.BreakingChangesAttributesCmdLetOutputChange1, DeprecatedCmdLetOutputType.FullName, ReplacementCmdletOutputTypeName));
}
else
{
message.Append(string.Format(Resources.BreakingChangesAttributesCmdLetOutputChange2, DeprecatedCmdLetOutputType.FullName));
}

if (DeprecatedOutputProperties != null && DeprecatedOutputProperties.Length > 0)
{
message.Append(Resources.BreakingChangesAttributesCmdLetOutputPropertiesRemoved);
foreach (string property in DeprecatedOutputProperties)
{
message.Append(" '" + property + "'");
}
}

if (NewOutputProperties != null && NewOutputProperties.Length > 0)
{
message.Append(Resources.BreakingChangesAttributesCmdLetOutputPropertiesAdded);
foreach (string property in NewOutputProperties)
{
message.Append(" '" + property + "'");
}
}
}
return message.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// ----------------------------------------------------------------------------------
//
// Copyright Microsoft Corporation
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------------------------------------------------------------

using Microsoft.WindowsAzure.Commands.Common.Properties;
using System;
using System.Linq;
using System.Text;
using System.Management.Automation;
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
[AttributeUsage(
AttributeTargets.Property |
AttributeTargets.Field,
AllowMultiple = true)]
public class CmdletParameterBreakingChangeWithVersionAttribute : GenericBreakingChangeWithVersionAttribute
{
public string NameOfParameterChanging { get; }

public string ReplaceMentCmdletParameterName { get; set; } = null;

public bool IsBecomingMandatory { get; set; } = false;

public Type OldParamaterType { get; set; }

public String NewParameterTypeName { get; set; }


public CmdletParameterBreakingChangeWithVersionAttribute(string nameOfParameterChanging, string deprecateByAzVersion, string deprecateByVersion) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion)
{
this.NameOfParameterChanging = nameOfParameterChanging;
}

public CmdletParameterBreakingChangeWithVersionAttribute(string nameOfParameterChanging, string deprecateByAzVersion, string deprecateByVersion, string changeInEffectByDate) :
base(string.Empty, deprecateByAzVersion, deprecateByVersion, changeInEffectByDate)
{
this.NameOfParameterChanging = nameOfParameterChanging;
}

protected override string GetAttributeSpecificMessage()
{
StringBuilder message = new StringBuilder();
if (!string.IsNullOrWhiteSpace(ReplaceMentCmdletParameterName))
{
if (IsBecomingMandatory)
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterReplacedMandatory, NameOfParameterChanging, ReplaceMentCmdletParameterName));
}
else
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterReplaced, NameOfParameterChanging, ReplaceMentCmdletParameterName));
}
}
else
{
if (IsBecomingMandatory)
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterMandatoryNow, NameOfParameterChanging));
}
else
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterChanging, NameOfParameterChanging));
}
}

//See if the type of the param is changing
if (OldParamaterType != null && !string.IsNullOrWhiteSpace(NewParameterTypeName))
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterTypeChange, OldParamaterType.FullName, NewParameterTypeName));
}
return message.ToString();
}

/// <summary>
/// See if the bound parameters contain the current parameter, if they do
/// then the attribute is applicable
/// If the invocationInfo is null we return true
/// </summary>
/// <param name="invocationInfo"></param>
/// <returns>bool</returns>
public override bool IsApplicableToInvocation(InvocationInfo invocationInfo)
{
bool? applicable = invocationInfo == null ? true : invocationInfo.BoundParameters?.Keys?.Contains(this.NameOfParameterChanging);
return applicable.HasValue ? applicable.Value : false;
}
}
}
Loading