Skip to content

Commit 8f53efa

Browse files
add survey helper for cmdlet base (#262)
* add survey helper for cmdlet base * catch exception when color was not available from console * update schema * add intercepttriggered attribute * update survey message * add write survey method * send survey info to telemetry * set intercepttriggered to 1 when first time prompt * polish code * flush immediately while prompting survey * polish code * move survey to Share * refactor * add constants.cs * refactor pt2 * resolve comments * remove unnecessary changes * Add shared variable * polish code * add volatile * update publish pipeline config to use main as default branch name * polish naming Co-authored-by: dingmeng-xue <[email protected]>
1 parent 07c8a9b commit 8f53efa

11 files changed

+613
-31
lines changed

.azure-pipelines/Azure-PowerShell-Common-Publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# https://aka.ms/yaml
55

66
trigger:
7-
- master
7+
- main
88

99
pool:
1010
name: Hosted VS2017

Azure.PowerShell.Common.sln

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.28307.1231
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.31313.79
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "src\Common\Common.csproj", "{5EE72C53-1720-4309-B54B-5FB79703195F}"
77
EndProject
@@ -43,6 +43,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PolicyInsights", "src\Polic
4343
EndProject
4444
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Authentication.Abstractions.Test", "src\Authentication.Abstractions.Test\Authentication.Abstractions.Test.csproj", "{E4CBF250-E488-4DE1-B6FC-80341A910F15}"
4545
EndProject
46+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Share", "src\Share\Share.csproj", "{29ECE00D-4FD5-4AFC-BEBF-136002E9CB9C}"
47+
EndProject
4648
Global
4749
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4850
Debug|Any CPU = Debug|Any CPU
@@ -121,6 +123,14 @@ Global
121123
{E4CBF250-E488-4DE1-B6FC-80341A910F15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
122124
{E4CBF250-E488-4DE1-B6FC-80341A910F15}.Debug|Any CPU.Build.0 = Debug|Any CPU
123125
{E4CBF250-E488-4DE1-B6FC-80341A910F15}.Release|Any CPU.ActiveCfg = Release|Any CPU
126+
{19D8A2BB-CA57-4EC0-9F5B-66AD3372A0B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
127+
{19D8A2BB-CA57-4EC0-9F5B-66AD3372A0B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
128+
{19D8A2BB-CA57-4EC0-9F5B-66AD3372A0B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
129+
{19D8A2BB-CA57-4EC0-9F5B-66AD3372A0B0}.Release|Any CPU.Build.0 = Release|Any CPU
130+
{29ECE00D-4FD5-4AFC-BEBF-136002E9CB9C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
131+
{29ECE00D-4FD5-4AFC-BEBF-136002E9CB9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
132+
{29ECE00D-4FD5-4AFC-BEBF-136002E9CB9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
133+
{29ECE00D-4FD5-4AFC-BEBF-136002E9CB9C}.Release|Any CPU.Build.0 = Release|Any CPU
124134
EndGlobalSection
125135
GlobalSection(SolutionProperties) = preSolution
126136
HideSolutionNode = FALSE

LICENSE.txt

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -189,30 +189,6 @@ BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS. IF YOU DO NOT ACCEPT THEM, DO NOT
189189

190190
----------------START OF THIRD PARTY NOTICE--------------------------------
191191

192-
193-
The software includes the AutoMapper library ("AutoMapper"). The MIT License set out below is provided for informational purposes only. It is not the license that governs any part of the software.
194-
195-
Provided for Informational Purposes Only
196-
197-
AutoMapper
198-
199-
The MIT License (MIT)
200-
Copyright (c) 2010 Jimmy Bogard
201-
202-
203-
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
204-
205-
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
206-
207-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
208-
209-
210-
211-
212-
213-
214-
***************
215-
216192
The software includes Newtonsoft.Json. The MIT License set out below is provided for informational purposes only. It is not the license that governs any part of the software.
217193

218194
Newtonsoft.Json

src/Common/AzurePSCmdlet.cs

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
using Microsoft.Azure.ServiceManagement.Common.Models;
1919
using Microsoft.WindowsAzure.Commands.Common;
2020
using Microsoft.WindowsAzure.Commands.Common.CustomAttributes;
21+
using Microsoft.Azure.PowerShell.Share.Survey;
2122
using System;
2223
using System.Collections.Concurrent;
2324
using System.Collections.Generic;
2425
using System.Diagnostics;
2526
using System.Globalization;
2627
using System.IO;
2728
using System.Linq;
28-
using System.Linq.Expressions;
2929
using System.Management.Automation;
3030
using System.Net.Http.Headers;
3131
using System.Text;
@@ -265,9 +265,7 @@ public bool IsDataCollectionAllowed()
265265
protected bool CheckIfInteractive()
266266
{
267267
bool interactive = true;
268-
if (this.Host == null ||
269-
this.Host.UI == null ||
270-
this.Host.UI.RawUI == null ||
268+
if (this.Host?.UI?.RawUI == null ||
271269
Environment.GetCommandLineArgs().Any(s =>
272270
s.Equals("-NonInteractive", StringComparison.OrdinalIgnoreCase)))
273271
{
@@ -410,6 +408,14 @@ protected override void BeginProcessing()
410408
/// </summary>
411409
protected override void EndProcessing()
412410
{
411+
if (CheckIfInteractive() && SurveyHelper.GetInstance().ShouldPropmtSurvey(this.MyInvocation.MyCommand.ModuleName, this.MyInvocation.MyCommand.Version))
412+
{
413+
WriteSurvey();
414+
if (_qosEvent != null)
415+
{
416+
_qosEvent.SurveyPrompted = true;
417+
}
418+
}
413419
LogQosEvent();
414420
LogCmdletEndInvocationInfo();
415421
TearDownDebuggingTraces();
@@ -434,6 +440,57 @@ protected bool IsVerbose()
434440
return verbose;
435441
}
436442

443+
protected void WriteSurvey()
444+
{
445+
HostInformationMessage newLine = new HostInformationMessage()
446+
{
447+
Message = "\n"
448+
};
449+
HostInformationMessage howWas = new HostInformationMessage()
450+
{
451+
Message = ": How was your experience using Azure PowerShell?\nRun ",
452+
NoNewLine = true
453+
};
454+
HostInformationMessage survey;
455+
HostInformationMessage link;
456+
try
457+
{
458+
survey = new HostInformationMessage()
459+
{
460+
Message = "Survey",
461+
NoNewLine = true,
462+
ForegroundColor = (ConsoleColor)Host.PrivateData.Properties.Match("ProgressForegroundColor").SingleOrDefault().Value
463+
};
464+
link = new HostInformationMessage()
465+
{
466+
Message = "Open-AzSurveyLink",
467+
NoNewLine = true,
468+
ForegroundColor = (ConsoleColor)Host.PrivateData.Properties.Match("ProgressbackgroundColor").SingleOrDefault().Value
469+
};
470+
}
471+
catch
472+
{
473+
survey = new HostInformationMessage()
474+
{
475+
Message = "Survey",
476+
NoNewLine = true,
477+
};
478+
link = new HostInformationMessage()
479+
{
480+
Message = "Open-AzSurveyLink",
481+
NoNewLine = true,
482+
};
483+
}
484+
HostInformationMessage action = new HostInformationMessage()
485+
{
486+
Message = " to fill out a short Survey"
487+
};
488+
WriteInformation(newLine, new string[] { "PSHOST" });
489+
WriteInformation(survey, new string[] { "PSHOST" });
490+
WriteInformation(howWas, new string[] { "PSHOST" });
491+
WriteInformation(link, new string[] { "PSHOST" });
492+
WriteInformation(action, new string[] { "PSHOST" });
493+
}
437494
protected new void WriteError(ErrorRecord errorRecord)
438495
{
439496
FlushDebugMessages(IsDataCollectionAllowed());

src/Common/Common.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@
5454
</EmbeddedResource>
5555
</ItemGroup>
5656

57+
<ItemGroup>
58+
<ProjectReference Include="..\Share\Share.csproj" />
59+
</ItemGroup>
60+
5761
<ItemGroup>
5862
<ProjectReference Include="..\Authentication.Abstractions\Authentication.Abstractions.csproj" />
5963
</ItemGroup>

src/Common/MetricHelper.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
using Microsoft.ApplicationInsights.Extensibility;
1818
using Microsoft.Azure.Commands.Common;
1919
using Microsoft.Azure.Commands.Common.Authentication.Abstractions;
20+
using Microsoft.Azure.PowerShell.Share;
2021
using Microsoft.Rest.Azure;
2122
using Microsoft.WindowsAzure.Commands.Common.Utilities;
2223
using Microsoft.WindowsAzure.Commands.Utilities.Common;
@@ -285,6 +286,15 @@ private void PopulatePropertiesFromQos(AzurePSQoSEvent qos, IDictionary<string,
285286
eventProperties.Add("start-time", qos.StartTime.ToUniversalTime().ToString("o"));
286287
eventProperties.Add("end-time", qos.EndTime.ToUniversalTime().ToString("o"));
287288
eventProperties.Add("duration", qos.Duration.ToString("c"));
289+
if(!string.IsNullOrWhiteSpace(SharedVariable.PredictorCorrelationId))
290+
{
291+
eventProperties.Add("predictor-correlation-id", SharedVariable.PredictorCorrelationId);
292+
SharedVariable.PredictorCorrelationId = null;
293+
}
294+
if (qos.SurveyPrompted)
295+
{
296+
eventProperties.Add("survey-prompted", qos.SurveyPrompted.ToString());
297+
}
288298
if (qos.Uid != null)
289299
{
290300
eventProperties.Add("UserId", qos.Uid);
@@ -530,6 +540,7 @@ public class AzurePSQoSEvent
530540
public string SessionId { get; set; }
531541
public string SubscriptionId { get; set; }
532542
public string TenantId { get; set; }
543+
public bool SurveyPrompted { get; set; }
533544

534545
public string ParameterSetName { get; set; }
535546
public string InvocationName { get; set; }

src/Share/Share.csproj

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<IncludeHyak>true</IncludeHyak>
5+
<IsCmdletProject>true</IsCmdletProject>
6+
</PropertyGroup>
7+
<Import Project="$(ProjectDir)..\Dependencies.Client.targets" />
8+
9+
<PropertyGroup>
10+
<TargetFramework>netstandard2.0</TargetFramework>
11+
<AssemblyName>Microsoft.Azure.PowerShell.Share</AssemblyName>
12+
<RootNamespace>Microsoft.Azure.PowerShell.Share</RootNamespace>
13+
<OutputPath>$(ProjectDir)..\..\artifacts\$(Configuration)</OutputPath>
14+
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
15+
<WarningsAsErrors />
16+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
17+
</PropertyGroup>
18+
19+
<PropertyGroup>
20+
<Title>Microsoft Azure PowerShell Share</Title>
21+
<Description>Microsoft Azure PowerShell Share library. Only for use with the Azure PowerShell runtime. Not intended for general development use.</Description>
22+
<PackageTags>azure;powershell;share</PackageTags>
23+
<Authors>Microsoft Corporation</Authors>
24+
<Copyright>Copyright © Microsoft Corporation</Copyright>
25+
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
26+
<PackageProjectUrl>https://github.com/Azure/azure-powershell-common</PackageProjectUrl>
27+
<PackageOutputPath>$(ProjectDir)..\..\artifacts\Package\$(Configuration)</PackageOutputPath>
28+
</PropertyGroup>
29+
30+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
31+
<DelaySign>false</DelaySign>
32+
<DefineConstants>TRACE;DEBUG;NETSTANDARD</DefineConstants>
33+
</PropertyGroup>
34+
35+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
36+
<SignAssembly>true</SignAssembly>
37+
<DelaySign>true</DelaySign>
38+
<AssemblyOriginatorKeyFile>..\MSSharedLibKey.snk</AssemblyOriginatorKeyFile>
39+
<DefineConstants>TRACE;RELEASE;NETSTANDARD;SIGN</DefineConstants>
40+
</PropertyGroup>
41+
42+
<ItemGroup>
43+
<None Include="..\..\LICENSE.txt" Link="LICENSE.txt" Pack="true" PackagePath="" />
44+
</ItemGroup>
45+
46+
</Project>

src/Share/SharedVariable.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
namespace Microsoft.Azure.PowerShell.Share
16+
{
17+
/// <summary>
18+
/// Static class containing variables shared across assemblies
19+
/// </summary>
20+
public static class SharedVariable
21+
{
22+
private static volatile string _predictorCorrelationId;
23+
24+
/// <summary>
25+
/// Id should be populated by Az.Tools.Predictor and recorded by AzPS cmdlet telemetry. Once it is recorded, value of id will be cleaned.
26+
/// </summary>
27+
public static string PredictorCorrelationId
28+
{
29+
get
30+
{
31+
return _predictorCorrelationId;
32+
}
33+
set
34+
{
35+
_predictorCorrelationId = value;
36+
}
37+
}
38+
}
39+
}

src/Share/Survey/ModuleInfo.cs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Newtonsoft.Json;
16+
17+
namespace Microsoft.Azure.PowerShell.Share.Survey
18+
{
19+
internal class ModuleInfo
20+
{
21+
[JsonProperty(PropertyName = "name")]
22+
internal string Name { get; set; }
23+
24+
[JsonProperty(PropertyName = "majorVersion")]
25+
internal int MajorVersion { get; set; }
26+
27+
[JsonProperty(PropertyName = "activeDays")]
28+
internal int ActiveDays { get; set; }
29+
30+
[JsonProperty(PropertyName = "firstActiveDate")]
31+
internal string FirstActiveDate { get; set; }
32+
33+
[JsonProperty(PropertyName = "lastActiveDate")]
34+
internal string LastActiveDate { get; set; }
35+
36+
[JsonProperty(PropertyName = "enabled")]
37+
internal bool Enabled { get; set; }
38+
39+
internal ModuleInfo(ModuleInfo info)
40+
{
41+
Name = info.Name;
42+
MajorVersion = info.MajorVersion;
43+
ActiveDays = info.ActiveDays;
44+
FirstActiveDate = info.FirstActiveDate;
45+
LastActiveDate = info.LastActiveDate;
46+
Enabled = info.Enabled;
47+
}
48+
49+
internal ModuleInfo() { }
50+
}
51+
}

src/Share/Survey/ScheduleInfo.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Newtonsoft.Json;
16+
using System.Collections.Generic;
17+
18+
namespace Microsoft.Azure.PowerShell.Share.Survey
19+
{
20+
internal class ScheduleInfo
21+
{
22+
[JsonProperty(PropertyName = "lastPromptDate")]
23+
internal string LastPromptDate { get; set; }
24+
25+
[JsonProperty(PropertyName = "modules")]
26+
internal IList<ModuleInfo> Modules { get; set; }
27+
}
28+
}

0 commit comments

Comments
 (0)