diff --git a/src/Common/CustomAttributes/CmdletDeprecationAttribute.cs b/src/Common/CustomAttributes/CmdletDeprecationAttribute.cs
index 87b4f9cac0..922d9921ca 100644
--- a/src/Common/CustomAttributes/CmdletDeprecationAttribute.cs
+++ b/src/Common/CustomAttributes/CmdletDeprecationAttribute.cs
@@ -21,6 +21,7 @@
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
+ [Obsolete("CmdletDeprecationAttribute is deprecated. Please use CmdletDeprecationWithVersionAttribute instead to ensure that version information is included in the deprecation message.", false)]
[AttributeUsage(
AttributeTargets.Class,
AllowMultiple = true)]
diff --git a/src/Common/CustomAttributes/CmdletDeprecationWithVersionAttribute.cs b/src/Common/CustomAttributes/CmdletDeprecationWithVersionAttribute.cs
new file mode 100644
index 0000000000..53c35b3046
--- /dev/null
+++ b/src/Common/CustomAttributes/CmdletDeprecationWithVersionAttribute.cs
@@ -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 : GenericBreakingChangeAttribute
+ {
+ public string ReplacementCmdletName { get; set; }
+
+ public CmdletDeprecationWithVersionAttribute(string deprecateByVersion) :
+ base(string.Empty, deprecateByVersion)
+ {
+ }
+
+ public CmdletDeprecationWithVersionAttribute(string deprecateByVersion, string changeInEffectByDate) :
+ base(string.Empty, deprecateByVersion, changeInEffectByDate)
+ {
+ }
+
+ protected override string GetAttributeSpecificMessage()
+ {
+ if (string.IsNullOrWhiteSpace(ReplacementCmdletName))
+ {
+ return Resources.BreakingChangesAttributesCmdLetDeprecationMessageNoReplacement;
+ }
+ else
+ {
+ return string.Format(Resources.BreakingChangesAttributesCmdLetDeprecationMessageWithReplacement, ReplacementCmdletName);
+ }
+ }
+ }
+}
diff --git a/src/Common/CustomAttributes/CmdletOutputBreakingChangeAttribute.cs b/src/Common/CustomAttributes/CmdletOutputBreakingChangeAttribute.cs
index 84798ef267..f31c71bd05 100644
--- a/src/Common/CustomAttributes/CmdletOutputBreakingChangeAttribute.cs
+++ b/src/Common/CustomAttributes/CmdletOutputBreakingChangeAttribute.cs
@@ -21,6 +21,7 @@
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
+ [Obsolete("CmdletOutputBreakingChangeAttribute is deprecated. Please use CmdletOutputBreakingChangeWithVersionAttribute instead to ensure that version information is included in the breaking change message.", false)]
[AttributeUsage(
AttributeTargets.Class,
AllowMultiple = true)]
diff --git a/src/Common/CustomAttributes/CmdletOutputBreakingChangeWithVersionAttribute.cs b/src/Common/CustomAttributes/CmdletOutputBreakingChangeWithVersionAttribute.cs
new file mode 100644
index 0000000000..694048c882
--- /dev/null
+++ b/src/Common/CustomAttributes/CmdletOutputBreakingChangeWithVersionAttribute.cs
@@ -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 deprecateByVersion) :
+ base(string.Empty, deprecateByVersion)
+ {
+ this.DeprecatedCmdLetOutputType = deprecatedCmdletOutputTypeName;
+ }
+
+ public CmdletOutputBreakingChangeWithVersionAttribute(Type deprecatedCmdletOutputTypeName, string deprecateByVersion, string changeInEfectByDate) :
+ base(string.Empty, 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();
+ }
+ }
+}
diff --git a/src/Common/CustomAttributes/CmdletParameterBreakingChangeAttribute.cs b/src/Common/CustomAttributes/CmdletParameterBreakingChangeAttribute.cs
index 7db08eff30..f9bb7101e6 100644
--- a/src/Common/CustomAttributes/CmdletParameterBreakingChangeAttribute.cs
+++ b/src/Common/CustomAttributes/CmdletParameterBreakingChangeAttribute.cs
@@ -22,6 +22,7 @@
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
+ [Obsolete("CmdletParameterBreakingChangeAttribute is deprecated. Please use CmdletParameterBreakingChangeWithVersionAttribute instead to ensure that version information is included in the breaking change message.", false)]
[AttributeUsage(
AttributeTargets.Property |
AttributeTargets.Field,
@@ -80,7 +81,7 @@ protected override string GetAttributeSpecificMessage()
}
}
- //See if the type of the param is changing
+ //See if the type of the param is changing
if (OldParamaterType != null && !string.IsNullOrWhiteSpace(NewParameterTypeName))
{
message.Append(string.Format(Resources.BreakingChangeAttributeParameterTypeChange, OldParamaterType.FullName, NewParameterTypeName));
@@ -90,7 +91,7 @@ protected override string GetAttributeSpecificMessage()
///
/// See if the bound parameters contain the current parameter, if they do
- /// then the attribbute is applicable
+ /// then the attribute is applicable
/// If the invocationInfo is null we return true
///
///
diff --git a/src/Common/CustomAttributes/CmdletParameterBreakingChangeWithVersionAttribute.cs b/src/Common/CustomAttributes/CmdletParameterBreakingChangeWithVersionAttribute.cs
new file mode 100644
index 0000000000..03776bed97
--- /dev/null
+++ b/src/Common/CustomAttributes/CmdletParameterBreakingChangeWithVersionAttribute.cs
@@ -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 deprecateByVersion) :
+ base(string.Empty, deprecateByVersion)
+ {
+ this.NameOfParameterChanging = nameOfParameterChanging;
+ }
+
+ public CmdletParameterBreakingChangeWithVersionAttribute(string nameOfParameterChanging, string deprecateByVersion, string changeInEffectByDate) :
+ base(string.Empty, 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();
+ }
+
+ ///
+ /// 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
+ ///
+ ///
+ /// bool
+ public override bool IsApplicableToInvocation(InvocationInfo invocationInfo)
+ {
+ bool? applicable = invocationInfo == null ? true : invocationInfo.BoundParameters?.Keys?.Contains(this.NameOfParameterChanging);
+ return applicable.HasValue ? applicable.Value : false;
+ }
+ }
+}
diff --git a/src/Common/CustomAttributes/GenericBreakingChangeAttribute.cs b/src/Common/CustomAttributes/GenericBreakingChangeAttribute.cs
index 396a49ec9c..8e1602358d 100644
--- a/src/Common/CustomAttributes/GenericBreakingChangeAttribute.cs
+++ b/src/Common/CustomAttributes/GenericBreakingChangeAttribute.cs
@@ -23,6 +23,7 @@
namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
{
+ [Obsolete("GenericBreakingChangeAttribute is deprecated. Please use GenericBreakingChangeWithVersionAttribute instead to ensure that version information is included in the breaking change message.", false)]
[AttributeUsage(
AttributeTargets.Class |
AttributeTargets.Field |
@@ -35,7 +36,7 @@ namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
public class GenericBreakingChangeAttribute : System.Attribute
{
private string _message;
- //A dexcription of what the change is about, non mandatory
+ //A description of what the change is about, non mandatory
public string ChangeDescription { get; set; } = null;
//The version the change is effective from, non mandatory
@@ -83,9 +84,9 @@ public DateTime getInEffectByDate()
/**
* This function returns the breaking change text for the attribute
- * If the withCmdletName is true we return the message with the cmdlet name in it otherwse not
+ * If the withCmdletName is true we return the message with the cmdlet name in it otherwise not
*
- * We get the cmdlet name from the passed in Type (it is expected to have the CMdlet attribute decorated on the class)
+ * We get the cmdlet name from the passed in Type (it is expected to have the Cmdlet attribute decorated on the class)
*/
public string GetBreakingChangeTextFromAttribute(Type type, bool withCmdletName)
{
@@ -128,7 +129,7 @@ public string GetBreakingChangeTextFromAttribute(Type type, bool withCmdletName)
* If the "withCmdletName" is specified, the message is printed out with the cmdlet name in it
* otherwise not
*
- * We get the cmdlet name from the passed in Type (it is expected to have the CMdlet attribute decorated on the class)
+ * We get the cmdlet name from the passed in Type (it is expected to have the Cmdlet attribute decorated on the class)
* */
public void PrintCustomAttributeInfo(Type type, bool withCmdletName, Action writeOutput)
{
diff --git a/src/Common/CustomAttributes/GenericBreakingChangeWithVersionAttribute.cs b/src/Common/CustomAttributes/GenericBreakingChangeWithVersionAttribute.cs
new file mode 100644
index 0000000000..545b06a480
--- /dev/null
+++ b/src/Common/CustomAttributes/GenericBreakingChangeWithVersionAttribute.cs
@@ -0,0 +1,176 @@
+// ----------------------------------------------------------------------------------
+//
+// 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.Globalization;
+using System.Management.Automation;
+using System.Text;
+
+namespace Microsoft.WindowsAzure.Commands.Common.CustomAttributes
+{
+ [AttributeUsage(
+ AttributeTargets.Class |
+ AttributeTargets.Field |
+ AttributeTargets.Property,
+ AllowMultiple = true)]
+
+ /*
+ * This class acts as the base
+ */
+ public class GenericBreakingChangeWithVersionAttribute : System.Attribute
+ {
+ private string _message;
+ //A description of what the change is about, non mandatory
+ public string ChangeDescription { get; set; } = null;
+
+ //The version the change is effective from, non mandatory
+ public string DeprecateByVersion { get; }
+ public bool DeprecateByVersionSet { get; } = false;
+
+ //The date on which the change comes in effect
+ public DateTime ChangeInEffectByDate { get; }
+ public bool ChangeInEffectByDateSet { get; } = false;
+
+ //Old way of calling the cmdlet
+ public string OldWay { get; set; }
+ //New way fo calling the cmdlet
+ public string NewWay { get; set; }
+
+ public GenericBreakingChangeWithVersionAttribute(string message, string deprecateByVersion)
+ {
+ _message = message;
+ this.DeprecateByVersion = deprecateByVersion;
+ this.DeprecateByVersionSet = true;
+ }
+
+ public GenericBreakingChangeWithVersionAttribute(string message, string deprecateByVersion, string changeInEffectByDate)
+ {
+ _message = message;
+ this.DeprecateByVersion = deprecateByVersion;
+ this.DeprecateByVersionSet = true;
+
+ if (DateTime.TryParse(changeInEffectByDate, new CultureInfo("en-US"), DateTimeStyles.None, out DateTime result))
+ {
+ this.ChangeInEffectByDate = result;
+ this.ChangeInEffectByDateSet = true;
+ }
+ }
+
+ public DateTime getInEffectByDate()
+ {
+ return this.ChangeInEffectByDate.Date;
+ }
+
+ /**
+ * This function returns the breaking change text for the attribute
+ * If the withCmdletName is true we return the message with the cmdlet name in it otherwise not
+ *
+ * We get the cmdlet name from the passed in Type (it is expected to have the Cmdlet attribute decorated on the class)
+ */
+ public string GetBreakingChangeTextFromAttribute(Type type, bool withCmdletName)
+ {
+ StringBuilder breakingChangeMessage = new StringBuilder();
+
+ if (!withCmdletName)
+ {
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesDeclarationMessage, GetAttributeSpecificMessage()));
+ }
+ else
+ {
+
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesDeclarationMessageWithCmdletName, Utilities.GetNameFromCmdletType(type), GetAttributeSpecificMessage()));
+ }
+
+ if (!string.IsNullOrWhiteSpace(ChangeDescription))
+ {
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesChangeDescriptionMessage, this.ChangeDescription));
+ }
+
+ if (ChangeInEffectByDateSet)
+ {
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate));
+ }
+
+ if (DeprecateByVersionSet)
+ {
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesInEffectByVersion, this.DeprecateByVersion));
+ }
+
+ if (!string.IsNullOrWhiteSpace(OldWay) && !string.IsNullOrWhiteSpace(NewWay))
+ {
+ breakingChangeMessage.Append(string.Format(Resources.BreakingChangesAttributesUsageChangeMessage, OldWay, NewWay));
+ }
+
+ return breakingChangeMessage.ToString();
+ }
+
+ /**
+ * This function prints out the breaking change message for the attribute on the cmdline
+ * If the "withCmdletName" is specified, the message is printed out with the cmdlet name in it
+ * otherwise not
+ *
+ * We get the cmdlet name from the passed in Type (it is expected to have the Cmdlet attribute decorated on the class)
+ * */
+ public void PrintCustomAttributeInfo(Type type, bool withCmdletName, Action writeOutput)
+ {
+ if (!withCmdletName)
+ {
+ if (!GetAttributeSpecificMessage().StartsWith(Environment.NewLine))
+ {
+ writeOutput(Environment.NewLine);
+ }
+ writeOutput(string.Format(Resources.BreakingChangesAttributesDeclarationMessage, GetAttributeSpecificMessage()));
+ }
+ else
+ {
+ writeOutput(string.Format(Resources.BreakingChangesAttributesDeclarationMessageWithCmdletName, Utilities.GetNameFromCmdletType(type), GetAttributeSpecificMessage()));
+ }
+
+ if (!string.IsNullOrWhiteSpace(ChangeDescription))
+ {
+ writeOutput(string.Format(Resources.BreakingChangesAttributesChangeDescriptionMessage, this.ChangeDescription));
+ }
+
+ if (ChangeInEffectByDateSet)
+ {
+ writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByDateMessage, this.ChangeInEffectByDate));
+ }
+
+ if (DeprecateByVersionSet)
+ {
+ writeOutput(string.Format(Resources.BreakingChangesAttributesInEffectByVersion, this.DeprecateByVersion));
+ }
+
+ if (OldWay != null && NewWay != null)
+ {
+ writeOutput(string.Format(Resources.BreakingChangesAttributesUsageChangeMessageConsole, OldWay, NewWay));
+ }
+ }
+
+ public virtual bool IsApplicableToInvocation(InvocationInfo invocation)
+ {
+ return true;
+ }
+
+ protected virtual string GetAttributeSpecificMessage()
+ {
+ return _message;
+ }
+ protected virtual string GetAttributeSpecificVersion()
+ {
+ return DeprecateByVersion;
+ }
+ }
+}