diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9cc7342..e395e7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,17 @@
# Changelog
-## v0.3.0 - 2017-09-29
+## v0.3.0
+- Generate single Verb-Noun cmdlet for OperationIds like Noun_Verb and Noun_VerbBySomething (#358)
+- Move New-HttpClientHandler logic into New-ServiceClient for non-Azure services. (#357)
+- Add few verb mappings for Azure RPs (#356)
+- Add NoVersionFolder switch parameter on New-PSSwaggerModule cmdlet to not create the version folder. (#355)
+- Add all non-complex type properties in output format ps1xml files. (#354)
+- Escape '<#' and '#>', and replace '--' with '==' in Header content (#352)
+- Use separate PSCmdletOutputItemType variable for getting the output item type of pageable swagger operations. (#351)
+- Verb map change: 'Regenerate' to 'New' instead of 'Update' as per the feedback recieved from Azure PowerShell team. (#347)
+- [Azure and AzureStack] Use IClientFactory to create ARM Client in Azure PowerShell way. (#348)
+- New-ServiceClient error on custom host (#350)
+- Add CHANGELOG.md, and minor update for releasing the 0.3.0 version of PSSwagger and PSSwaggerUtility modules. (#345)
- Add support for generating proper output type for the Swagger operations with x-ms-pageable extension (#342)
- Add support for parameter type references to enum definitions (#341)
- Add support for AdditionalProperties Json schema with array type (#339)
@@ -21,7 +32,7 @@
- Update Readme and fix an error related to importing the PSSwaggerUtility module (#300)
- Support custom x-ms-pageable\NextLinkName field name (#294)
-## v0.2.0 - 2017-08-15
+## v0.2.0
* First preview release
diff --git a/PSSwagger/AssemblyGenerationHelpers.Resources.psd1 b/PSSwagger/AssemblyGenerationHelpers.Resources.psd1
index 9b00b0c..4ff8f77 100644
--- a/PSSwagger/AssemblyGenerationHelpers.Resources.psd1
+++ b/PSSwagger/AssemblyGenerationHelpers.Resources.psd1
@@ -1,11 +1,3 @@
-#########################################################################################
-#
-# Copyright (c) Microsoft Corporation. All rights reserved.
-#
-# Licensed under the MIT license.
-#
-#########################################################################################
-
ConvertFrom-StringData @'
###PSLOC
diff --git a/PSSwagger/AssemblyGenerationHelpers.ps1 b/PSSwagger/AssemblyGenerationHelpers.ps1
index 5bbbc01..33dcfb3 100644
--- a/PSSwagger/AssemblyGenerationHelpers.ps1
+++ b/PSSwagger/AssemblyGenerationHelpers.ps1
@@ -1,11 +1,3 @@
-#########################################################################################
-#
-# Copyright (c) Microsoft Corporation. All rights reserved.
-#
-# Licensed under the MIT license.
-#
-#########################################################################################
-
Microsoft.PowerShell.Core\Set-StrictMode -Version Latest
Microsoft.PowerShell.Utility\Import-LocalizedData LocalizedData -FileName AssemblyGenerationHelpers.Resources.psd1
diff --git a/PSSwagger/Definitions.psm1 b/PSSwagger/Definitions.psm1
index 39b7aa7..10ef031 100644
--- a/PSSwagger/Definitions.psm1
+++ b/PSSwagger/Definitions.psm1
@@ -988,26 +988,37 @@ function New-SwaggerDefinitionFormatFile
$ViewTypeName = $ViewName
$TableColumnItemsList = @()
$TableColumnItemCount = 0
- $ParametersCount = Get-HashtableKeyCount -Hashtable $FunctionDetails.ParametersTable
- $SkipParameterList = @('id', 'tags')
$FunctionDetails.ParametersTable.GetEnumerator() | ForEach-Object {
-
$ParameterDetails = $_.Value
-
- # Add all properties when definition has 4 or less properties.
- # Otherwise add the first 4 properties with basic types by skipping the complex types, id and tags.
- if(($ParametersCount -le 4) -or
- (($TableColumnItemCount -le 4) -and
- ($SkipParameterList -notcontains $ParameterDetails.Name) -and
- (-not $ParameterDetails.Type.StartsWith($Namespace, [System.StringComparison]::OrdinalIgnoreCase))))
+ # Add all properties otherthan complex typed properties.
+ # Complex typed properties are not displayed by the PowerShell Format viewer.
+ if(-not $ParameterDetails.Type.StartsWith($Namespace, [System.StringComparison]::OrdinalIgnoreCase))
{
$TableColumnItemsList += $TableColumnItemStr -f ($ParameterDetails.Name)
$TableColumnItemCount += 1
}
}
- $TableColumnHeaders = $null
+ if(-not $TableColumnItemCount) {
+ Write-Verbose -Message ($LocalizedData.FormatFileNotRequired -f $FunctionDetails.Name)
+ return
+ }
+
+ $TableColumnHeadersList = @()
+ $DefaultWindowSizeWidth = 120
+ # Getting the width value for each property column. Default console window width is 120.
+ $TableColumnHeaderWidth = [int]($DefaultWindowSizeWidth/$TableColumnItemCount)
+
+ if ($TableColumnItemCount -ge 2) {
+ 1..($TableColumnItemCount - 1) | ForEach-Object {
+ $TableColumnHeadersList += $TableColumnHeaderStr -f ($TableColumnHeaderWidth)
+ }
+ }
+ # Allowing the last property to get the remaining column width, this is useful when customer increases the default window width.
+ $TableColumnHeadersList += $LastTableColumnHeaderStr
+
+ $TableColumnHeaders = $TableColumnHeadersList -join "`r`n"
$TableColumnItems = $TableColumnItemsList -join "`r`n"
$FormatViewDefinition = $FormatViewDefinitionStr -f ($ViewName, $ViewTypeName, $TableColumnHeaders, $TableColumnItems, $XmlHeaderComment)
diff --git a/PSSwagger/GeneratedHelpers.ps1 b/PSSwagger/GeneratedHelpers.ps1
deleted file mode 100644
index 27cc989..0000000
--- a/PSSwagger/GeneratedHelpers.ps1
+++ /dev/null
@@ -1,96 +0,0 @@
-#########################################################################################
-#
-# Copyright (c) Microsoft Corporation. All rights reserved.
-#
-# Licensed under the MIT license.
-#
-#########################################################################################
-Microsoft.PowerShell.Core\Set-StrictMode -Version Latest
-
-<#
-.DESCRIPTION
- Creates AutoRest ServiceClientCredentials for Microsoft Azure using the logged in AzureRM context.
-#>
-function Get-AzServiceCredential
-{
- [CmdletBinding()]
- param()
-
- $AzureContext = & "Get-AzureRmContext" -ErrorAction Stop
- $authenticationFactory = New-Object -TypeName Microsoft.Azure.Commands.Common.Authentication.Factories.AuthenticationFactory
- if ((Get-Variable -Name PSEdition -ErrorAction Ignore) -and ('Core' -eq $PSEdition)) {
- [Action[string]]$stringAction = {param($s)}
- $serviceCredentials = $authenticationFactory.GetServiceClientCredentials($AzureContext, $stringAction)
- } else {
- $serviceCredentials = $authenticationFactory.GetServiceClientCredentials($AzureContext)
- }
-
- $serviceCredentials
-}
-
-<#
-.DESCRIPTION
- Creates delegating handlers for Microsoft Azure generated modules.
-#>
-function Get-AzDelegatingHandler
-{
- [CmdletBinding()]
- param()
-
- New-Object -TypeName System.Net.Http.DelegatingHandler[] 0
-}
-
-<#
-.DESCRIPTION
- Gets the Azure subscription ID from the logged in AzureRM context.
-#>
-function Get-AzSubscriptionId
-{
- [CmdletBinding()]
- param()
-
- $AzureContext = & "Get-AzureRmContext" -ErrorAction Stop
- if($AzureContext)
- {
- if(Get-Member -InputObject $AzureContext.Subscription -Name SubscriptionId)
- {
- return $AzureContext.Subscription.SubscriptionId
- }
- else
- {
- return $AzureContext.Subscription.Id
- }
- }
-}
-
-<#
-.DESCRIPTION
- Gets the resource manager URL from the logged in AzureRM context.
-#>
-function Get-AzResourceManagerUrl
-{
- [CmdletBinding()]
- param()
-
- $AzureContext = & "Get-AzureRmContext" -ErrorAction Stop
- $AzureContext.Environment.ResourceManagerUrl
-}
-
-<#
-.DESCRIPTION
- Creates a System.Net.Http.HttpClientHandler for the given credentials and sets preauthentication to true.
-#>
-function New-HttpClientHandler {
- [CmdletBinding()]
- param(
- [Parameter(Mandatory=$true)]
- [PSCredential]
- $Credential
- )
-
- Add-Type -AssemblyName System.Net.Http
- $httpClientHandler = New-Object -TypeName System.Net.Http.HttpClientHandler
- $httpClientHandler.PreAuthenticate = $true
- $httpClientHandler.Credentials = $Credential
- $httpClientHandler
-}
\ No newline at end of file
diff --git a/PSSwagger/New-ArmServiceClient.ps1 b/PSSwagger/New-ArmServiceClient.ps1
new file mode 100644
index 0000000..d21496a
--- /dev/null
+++ b/PSSwagger/New-ArmServiceClient.ps1
@@ -0,0 +1,49 @@
+Microsoft.PowerShell.Core\Set-StrictMode -Version Latest
+
+<#
+.DESCRIPTION
+ Creates Service Client object.
+
+.PARAMETER FullClientTypeName
+ Client type full name.
+
+.PARAMETER GlobalParameterHashtable
+ Global parameters to be set on client object.
+#>
+function New-ServiceClient {
+ [CmdletBinding()]
+ param(
+ [Parameter(Mandatory = $true)]
+ [string]
+ $FullClientTypeName,
+
+ [Parameter(Mandatory = $false)]
+ [PSCustomObject]
+ $GlobalParameterHashtable
+ )
+
+ # Azure Powershell way
+ [Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContext]$Context = Get-AzureRmContext
+ if (-not $Context -or -not $Context.Account) {
+ Write-Error -Message 'Run Login-AzureRmAccount to login.' -ErrorId 'AzureRmContextError'
+ return
+ }
+
+ $Factory = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.ClientFactory
+ [System.Type[]]$Types = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.IAzureContext], [string]
+ $CreateArmClientMethod = [Microsoft.Azure.Commands.Common.Authentication.IClientFactory].GetMethod('CreateArmClient', $Types)
+ $ClientType = $FullClientTypeName -as [Type]
+ $ClosedMethod = $CreateArmClientMethod.MakeGenericMethod($ClientType)
+ $Arguments = $Context, [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureEnvironment+Endpoint]::ResourceManager
+ $Client = $closedMethod.Invoke($Factory, $Arguments)
+
+ if ($GlobalParameterHashtable) {
+ $GlobalParameterHashtable.GetEnumerator() | ForEach-Object {
+ if ($_.Value -and (Get-Member -InputObject $Client -Name $_.Key -MemberType Property)) {
+ $Client."$($_.Key)" = $_.Value
+ }
+ }
+ }
+
+ return $Client
+}
\ No newline at end of file
diff --git a/PSSwagger/New-ServiceClient.ps1 b/PSSwagger/New-ServiceClient.ps1
index 1b84c90..0bfad60 100644
--- a/PSSwagger/New-ServiceClient.ps1
+++ b/PSSwagger/New-ServiceClient.ps1
@@ -23,9 +23,6 @@ Microsoft.PowerShell.Core\Set-StrictMode -Version Latest
Command should return a custom hostname string.
Overrides the default host in the specification.
-.PARAMETER SubscriptionIdCommand
- Custom command get SubscriptionId value.
-
.PARAMETER GlobalParameterHashtable
Global parameters to be set on client object.
#>
@@ -56,10 +53,6 @@ function New-ServiceClient {
[string]
$HostOverrideCommand,
- [Parameter(Mandatory = $false)]
- [string]
- $SubscriptionIdCommand,
-
[Parameter(Mandatory = $false)]
[PSCustomObject]
$GlobalParameterHashtable
@@ -75,7 +68,12 @@ function New-ServiceClient {
$ClientArgumentList += Invoke-Command @InvokeCommand_parameters
if ($AddHttpClientHandler) {
- $httpClientHandler = New-HttpClientHandler -Credential $Credential
+ if(-not ('System.Net.Http.HttpClientHandler' -as [Type])) {
+ Add-Type -AssemblyName System.Net.Http
+ }
+ $httpClientHandler = New-Object -TypeName System.Net.Http.HttpClientHandler
+ $httpClientHandler.PreAuthenticate = $true
+ $httpClientHandler.Credentials = $Credential
$ClientArgumentList += $httpClientHandler
}
@@ -85,23 +83,14 @@ function New-ServiceClient {
$Client = New-Object -TypeName $FullClientTypeName -ArgumentList $ClientArgumentList
if ($HostOverrideCommand) {
- $Client.BaseUri = Invoke-Command -ScriptBlock [scriptblock]::Create($HostOverrideCommand)
+ [scriptblock]$HostOverrideCommand = [scriptblock]::Create($HostOverrideCommand)
+ $Client.BaseUri = Invoke-Command -ScriptBlock $HostOverrideCommand
}
if ($GlobalParameterHashtable) {
$GlobalParameterHashtable.GetEnumerator() | ForEach-Object {
- if (Get-Member -InputObject $Client -Name $_.Key -MemberType Property) {
- if ((-not $_.Value) -and ($_.Key -eq 'SubscriptionId')) {
- if($SubscriptionIdCommand) {
- $Client.SubscriptionId = Invoke-Command -ScriptBlock [scriptblock]::Create($SubscriptionIdCommand)
- }
- else {
- $Client.SubscriptionId = Get-AzSubscriptionId
- }
- }
- else {
- $Client."$($_.Key)" = $_.Value
- }
+ if ($_.Value -and (Get-Member -InputObject $Client -Name $_.Key -MemberType Property)) {
+ $Client."$($_.Key)" = $_.Value
}
}
}
diff --git a/PSSwagger/PSCommandVerbMap.ps1 b/PSSwagger/PSCommandVerbMap.ps1
index ad28acc..aa19d9c 100644
--- a/PSSwagger/PSCommandVerbMap.ps1
+++ b/PSSwagger/PSCommandVerbMap.ps1
@@ -19,13 +19,15 @@ $script:PSCommandVerbMap = @{
Acquire = 'Get'
Examine = 'Get'
Suggest = 'Get'
+ Retrieve = 'Get'
Create = 'New'
Generate = 'New'
Allocate = 'New'
Provision = 'New'
Make = 'New'
-
+ Regenerate = 'New' # Alternatives: Redo, Update, Reset
+
CreateOrUpdate = 'New,Set'
Failover = 'Set'
Assign = 'Set'
@@ -53,10 +55,10 @@ $script:PSCommandVerbMap = @{
Patch = 'Update'
Refresh = 'Update'
- Regenerate = 'Update' # Alternatives: Redo, New, Reset
Reprocess = "Update" # Alternatives: Redo
Upgrade = 'Update'
Reimage = 'Update' # Alternatives: Format, Reset
+ Retarget = 'Update'
Validate = 'Test'
Check = 'Test'
@@ -103,12 +105,14 @@ $script:PSCommandVerbMap = @{
Migrate = 'Move' # Alternatives: Export
Transfer = 'Move'
Name = 'Move'
+ Reassociate = 'Move'
Change = 'Rename'
Swap = 'Switch' # Alternatives: Move
Execute = 'Invoke'
+ Perform = 'Invoke'
Discover = 'Find' # Alternatives: Search
Locate = 'Find'
@@ -140,4 +144,8 @@ $script:PSCommandVerbMap = @{
Jump = 'Skip'
Separate = 'Split'
+
+ Notify = 'Send'
+
+ Authorize = 'Grant'
}
\ No newline at end of file
diff --git a/PSSwagger/PSSwagger.Constants.ps1 b/PSSwagger/PSSwagger.Constants.ps1
index 5da4695..fe6be5a 100644
--- a/PSSwagger/PSSwagger.Constants.ps1
+++ b/PSSwagger/PSSwagger.Constants.ps1
@@ -59,7 +59,6 @@ if (Test-Path -Path `$ClrPath -PathType Container) {
}
. (Join-Path -Path `$PSScriptRoot -ChildPath 'New-ServiceClient.ps1')
-. (Join-Path -Path `$PSScriptRoot -ChildPath 'GeneratedHelpers.ps1')
`$allPs1FilesPath = Join-Path -Path `$PSScriptRoot -ChildPath '$GeneratedCommandsName' | Join-Path -ChildPath '*.ps1'
Get-ChildItem -Path `$allPs1FilesPath -Recurse -File | ForEach-Object { . `$_.FullName}
@@ -491,7 +490,8 @@ $FormatViewDefinitionStr = @'
{1}
- {2}
+
+{2}
@@ -518,6 +518,10 @@ $TableColumnHeaderStr = @'
'@
+$LastTableColumnHeaderStr = @'
+
+'@
+
$DefaultGeneratedFileHeader = @'
Code generated by Microsoft (R) PSSwagger {0}
Changes may cause incorrect behavior and will be lost if the code is regenerated.
diff --git a/PSSwagger/PSSwagger.Resources.psd1 b/PSSwagger/PSSwagger.Resources.psd1
index 5b3b8f5..ee0a3cf 100644
--- a/PSSwagger/PSSwagger.Resources.psd1
+++ b/PSSwagger/PSSwagger.Resources.psd1
@@ -43,6 +43,7 @@ ConvertFrom-StringData @'
GeneratedPathCommand=Generated path command '{0}'.
GeneratedDefinitionCommand=Generated command '{0}' for the definition name '{1}'.
GeneratedFormatFile=Generated output format file for the definition name '{0}'.
+ FormatFileNotRequired=It is not required to generated the format file as this definition '{0}' doesn't have non-complex typed properties.
DeleteGeneratedFile=Deleting generated file '{0}'
ExtractingMetadata=Extracting metadata from generated assembly
ExpectedServiceClientTypeNotFound=Unable to find expected service client type: {0}
@@ -87,5 +88,6 @@ ConvertFrom-StringData @'
InvalidPSMetaFlattenParameter=Flatten property is specified as 'true' for an invalid parameter '{0}' with type '{1}'.
InvalidHeaderFileExtension=Header '{0}' file extension should be '.txt'.
InvalidHeaderFilePath=The specified value '{0}' for Header parameter is should be a valid file path.
+ HeaderContentTwoHyphenWarning=The specified Header content has '--', replacing '--' with '=='.
###PSLOC
'@
\ No newline at end of file
diff --git a/PSSwagger/PSSwagger.psm1 b/PSSwagger/PSSwagger.psm1
index d0163e4..0595470 100644
--- a/PSSwagger/PSSwagger.psm1
+++ b/PSSwagger/PSSwagger.psm1
@@ -72,6 +72,9 @@ Microsoft.PowerShell.Utility\Import-LocalizedData LocalizedData -filename PSSwa
.PARAMETER Version
Version of the generated PowerShell module.
+.PARAMETER NoVersionFolder
+ Switch to not create the version folder under the generated module folder.
+
.PARAMETER DefaultCommandPrefix
Prefix value to be prepended to cmdlet noun or to cmdlet name without verb.
@@ -163,6 +166,10 @@ function New-PSSwaggerModule
[Version]
$Version = '0.0.1',
+ [Parameter(Mandatory = $false)]
+ [switch]
+ $NoVersionFolder,
+
[Parameter(Mandatory = $false)]
[string]
$DefaultCommandPrefix,
@@ -449,7 +456,7 @@ function New-PSSwaggerModule
$nameSpace = $swaggerDict['info'].NameSpace
$models = $swaggerDict['info'].Models
- if($PSVersionTable.PSVersion -lt '5.0.0') {
+ if($NoVersionFolder -or $PSVersionTable.PSVersion -lt '5.0.0') {
if (-not $outputDirectory.EndsWith($Name, [System.StringComparison]::OrdinalIgnoreCase)) {
$outputDirectory = Join-Path -Path $outputDirectory -ChildPath $Name
$SymbolPath = Join-Path -Path $SymbolPath -ChildPath $Name
@@ -611,11 +618,14 @@ function New-PSSwaggerModule
-Info $swaggerDict['info'] `
-PSHeaderComment $PSHeaderComment
- $CopyFilesMap = [ordered]@{
- 'GeneratedHelpers.ps1' = 'GeneratedHelpers.ps1'
- 'Test-CoreRequirements.ps1' = 'Test-CoreRequirements.ps1'
- 'Test-FullRequirements.ps1' = 'Test-FullRequirements.ps1'
- 'New-ServiceClient.ps1' = 'New-ServiceClient.ps1'
+ $CopyFilesMap = [ordered]@{}
+ if($UseAzureCsharpGenerator) {
+ $CopyFilesMap['New-ArmServiceClient.ps1'] = 'New-ServiceClient.ps1'
+ $CopyFilesMap['Test-FullRequirements.ps1'] = 'Test-FullRequirements.ps1'
+ $CopyFilesMap['Test-CoreRequirements.ps1'] = 'Test-CoreRequirements.ps1'
+ }
+ else {
+ $CopyFilesMap['New-ServiceClient.ps1'] = 'New-ServiceClient.ps1'
}
if (-not $AssemblyFileName) {
@@ -1108,6 +1118,14 @@ function Get-HeaderContent {
}
}
+ # Escape block comment character sequence, if any, using the PowerShell escape character, grave-accent(`).
+ $HeaderContent = $HeaderContent.Replace('<#', '<`#').Replace('#>', '#`>')
+
+ if ($HeaderContent -match '--') {
+ Write-Warning -Message $LocalizedData.HeaderContentTwoHyphenWarning
+ $HeaderContent = $HeaderContent.Replace('--', '==')
+ }
+
return $HeaderContent
}
diff --git a/PSSwagger/Paths.psm1 b/PSSwagger/Paths.psm1
index a771d0e..435348d 100644
--- a/PSSwagger/Paths.psm1
+++ b/PSSwagger/Paths.psm1
@@ -196,6 +196,25 @@ function Get-SwaggerSpecPathInfo
} else {
$commandNames = Get-PathCommandName -OperationId $operationId
}
+
+ # Priority of a parameterset will be used to determine the default parameterset of a cmdlet.
+ $Priority = 0
+ $ParametersCount = Get-HashtableKeyCount -Hashtable $ParametersTable
+ if($ParametersCount) {
+ # Priority for parameter sets with mandatory parameters starts at 100
+ $Priority = 100
+
+ $ParametersTable.GetEnumerator() | ForEach-Object {
+ if($_.Value.ContainsKey('Mandatory') -and $_.Value.Mandatory -eq '$true') {
+ $Priority++
+ }
+ }
+
+ # If there are no mandatory parameters, use the parameter count as the priority.
+ if($Priority -eq 100) {
+ $Priority = $ParametersCount
+ }
+ }
$ParameterSetDetail = @{
Description = $FunctionDescription
@@ -206,7 +225,7 @@ function Get-SwaggerSpecPathInfo
OperationType = $operationType
EndpointRelativePath = $EndpointRelativePath
PathCommonParameters = $PathCommonParameters
- Priority = 100 # Default
+ Priority = $Priority
'x-ms-pageable' = $x_ms_pageableObject
}
@@ -228,10 +247,6 @@ function Get-SwaggerSpecPathInfo
}
}
- if ($approximateVerb.StartsWith("List")) {
- $ParameterSetDetail.Priority = 0
- }
-
$commandNames | ForEach-Object {
$FunctionDetails = @{}
if ($PathFunctionDetails.ContainsKey($_.name)) {
@@ -445,6 +460,9 @@ function New-SwaggerPath
} elseif (-not $x_ms_pageableObject) {
$x_ms_pageableObject = $parameterSetDetail.'x-ms-pageable'
$x_ms_pageableObject['ReturnType'] = $parameterSetDetail.ReturnType
+ if($parameterSetDetail.ContainsKey('PSCmdletOutputItemType')) {
+ $x_ms_pageableObject['PSCmdletOutputItemType'] = $parameterSetDetail.PSCmdletOutputItemType
+ }
if ($x_ms_pageableObject.Containskey('operationName')) {
# Search for the cmdlet with a parameter set with the given operationName
$pagingFunctionDetails = $PathFunctionDetails.GetEnumerator() | Where-Object { $_.Value.ParameterSetDetails | Where-Object { $_.OperationId -eq $x_ms_pageableObject.operationName }} | Select-Object -First 1
@@ -561,11 +579,15 @@ function New-SwaggerPath
$Cmdlet = ''
$CmdletParameter = ''
$CmdletArgs = ''
- $pageType = ''
+ $pageType = 'Array'
+ $PSCmdletOutputItemType = ''
$resultBlockStr = $resultBlockNoPaging
if ($x_ms_pageableObject) {
if ($x_ms_pageableObject.ReturnType -ne 'NONE') {
$pageType = $x_ms_pageableObject.ReturnType
+ if($x_ms_pageableObject.ContainsKey('PSCmdletOutputItemType')) {
+ $PSCmdletOutputItemType = $x_ms_pageableObject.PSCmdletOutputItemType
+ }
}
if ($x_ms_pageableObject.ContainsKey('Operations')) {
@@ -616,24 +638,25 @@ function New-SwaggerPath
}
# Process security section
- $SubscriptionIdCommand = ""
$AuthenticationCommand = ""
$AuthenticationCommandArgumentName = ''
$hostOverrideCommand = ''
$AddHttpClientHandler = $false
$securityParametersToAdd = @()
$PowerShellCodeGen = $SwaggerMetaDict['PowerShellCodeGen']
- if (($PowerShellCodeGen['ServiceType'] -eq 'azure') -or ($PowerShellCodeGen['ServiceType'] -eq 'azure_stack')) {
- $SubscriptionIdCommand = 'Get-AzSubscriptionId'
- }
- if ($PowerShellCodeGen['CustomAuthCommand']) {
- $AuthenticationCommand = $PowerShellCodeGen['CustomAuthCommand']
- }
- if ($PowerShellCodeGen['HostOverrideCommand']) {
- $hostOverrideCommand = $PowerShellCodeGen['HostOverrideCommand']
+
+ # CustomAuthCommand and HostOverrideCommand are not required for Arm Services
+ if (($PowerShellCodeGen['ServiceType'] -ne 'azure') -and ($PowerShellCodeGen['ServiceType'] -eq 'azure_stack')) {
+ if ($PowerShellCodeGen['CustomAuthCommand']) {
+ $AuthenticationCommand = $PowerShellCodeGen['CustomAuthCommand']
+ }
+ if ($PowerShellCodeGen['HostOverrideCommand']) {
+ $hostOverrideCommand = $PowerShellCodeGen['HostOverrideCommand']
+ }
}
+
# If the auth function hasn't been set by metadata, try to discover it from the security and securityDefinition objects in the spec
- if (-not $AuthenticationCommand) {
+ if (-not $AuthenticationCommand -and -not $UseAzureCsharpGenerator) {
if ($FunctionDetails.ContainsKey('Security')) {
# For now, just take the first security object
if ($FunctionDetails.Security.Count -gt 1) {
@@ -729,7 +752,7 @@ function New-SwaggerPath
}
}
- if (-not $AuthenticationCommand) {
+ if (-not $AuthenticationCommand -and -not $UseAzureCsharpGenerator) {
# At this point, there was no supported security object or overridden auth function, so assume no auth
$AuthenticationCommand = 'Get-AutoRestCredential'
}
@@ -831,7 +854,7 @@ function New-SwaggerPath
if ($nonUniqueParameterSets.Length -gt 1) {
# Pick the highest priority set among $nonUniqueParameterSets, but really it doesn't matter, cause...
# Print warning that this generated cmdlet has ambiguous parameter sets
- $defaultParameterSet = $nonUniqueParameterSets | Sort-Object -Property Priority | Select-Object -First 1
+ $defaultParameterSet = $nonUniqueParameterSets | Sort-Object {$_.Priority} | Select-Object -First 1
$DefaultParameterSetName = $defaultParameterSet.OperationId
$description = $defaultParameterSet.Description
$synopsis = $defaultParameterSet.Synopsis
@@ -973,13 +996,18 @@ function New-SwaggerPath
ParameterGroupsExpressionBlock = $parameterGroupsExpressionBlock
SwaggerDict = $SwaggerDict
SwaggerMetaDict = $SwaggerMetaDict
- AddHttpClientHandler = $AddHttpClientHandler
- HostOverrideCommand = $hostOverrideCommand
- AuthenticationCommand = $AuthenticationCommand
- AuthenticationCommandArgumentName = $AuthenticationCommandArgumentName
- SubscriptionIdCommand = $SubscriptionIdCommand
FlattenedParametersOnPSCmdlet = $flattenedParametersOnPSCmdlet
}
+ if($AuthenticationCommand) {
+ $functionBodyParams['AuthenticationCommand'] = $AuthenticationCommand
+ $functionBodyParams['AuthenticationCommandArgumentName'] = $AuthenticationCommandArgumentName
+ }
+ if($AddHttpClientHandler) {
+ $functionBodyParams['AddHttpClientHandler'] = $AddHttpClientHandler
+ }
+ if($hostOverrideCommand) {
+ $functionBodyParams['hostOverrideCommand'] = $hostOverrideCommand
+ }
if($globalParameters) {
$functionBodyParams['GlobalParameters'] = $globalParameters
}
@@ -988,8 +1016,8 @@ function New-SwaggerPath
$bodyObject = $pathGenerationPhaseResult.BodyObject
$body = $bodyObject.Body
- if($pageType){
- $fullPathDataType = $pageType
+ if($PSCmdletOutputItemType){
+ $fullPathDataType = $PSCmdletOutputItemType
$outputTypeBlock = $executionContext.InvokeCommand.ExpandString($outputTypeStr)
}
else {
@@ -1156,12 +1184,12 @@ function Set-ExtendedCodeMetadata {
$returnType = $returnType.GenericTypeArguments[0]
}
+ # Note: ReturnType and PSCmdletOutputItemType are currently used for Swagger operations which supports x-ms-pageable.
if (($returnType.Name -eq 'IPage`1') -and $returnType.GenericTypeArguments) {
- $returnType = $returnType.GenericTypeArguments[0]
+ $PSCmdletOutputItemTypeString = Convert-GenericTypeToString -Type $returnType.GenericTypeArguments[0]
+ $parameterSetDetail['PSCmdletOutputItemType'] = $PSCmdletOutputItemTypeString.Trim('[]')
}
- # Note: ReturnType is currently used for Swagger operations which supports x-ms-pageable.
- $returnTypeString = Convert-GenericTypeToString -Type $returnType
- $parameterSetDetail['ReturnType'] = $returnTypeString
+ $parameterSetDetail['ReturnType'] = Convert-GenericTypeToString -Type $returnType
$ParamList = @()
$oDataQueryFound = $false
@@ -1282,7 +1310,7 @@ function Convert-GenericTypeToString {
)
if (-not $Type.IsGenericType) {
- return $Type.FullName.Trim('[]')
+ return $Type.FullName
}
$genericTypeStr = ''
diff --git a/PSSwagger/ServiceTypes/azure.PSMeta.json b/PSSwagger/ServiceTypes/azure.PSMeta.json
index c3de351..ffc184b 100644
--- a/PSSwagger/ServiceTypes/azure.PSMeta.json
+++ b/PSSwagger/ServiceTypes/azure.PSMeta.json
@@ -1,7 +1,5 @@
{
"info": {
- "x-ps-code-generation-settings": {
- "customAuthCommand": "Get-AzServiceCredential"
- }
+ "x-ps-code-generation-settings": {}
}
}
\ No newline at end of file
diff --git a/PSSwagger/ServiceTypes/azure_stack.PSMeta.json b/PSSwagger/ServiceTypes/azure_stack.PSMeta.json
index 8bcd7a5..ffc184b 100644
--- a/PSSwagger/ServiceTypes/azure_stack.PSMeta.json
+++ b/PSSwagger/ServiceTypes/azure_stack.PSMeta.json
@@ -1,8 +1,5 @@
{
"info": {
- "x-ps-code-generation-settings": {
- "customAuthCommand": "Get-AzServiceCredential",
- "hostOverrideCommand": "Get-AzResourceManagerUrl"
- }
+ "x-ps-code-generation-settings": {}
}
}
\ No newline at end of file
diff --git a/PSSwagger/SwaggerUtils.psm1 b/PSSwagger/SwaggerUtils.psm1
index 58f7971..8a0f891 100644
--- a/PSSwagger/SwaggerUtils.psm1
+++ b/PSSwagger/SwaggerUtils.psm1
@@ -1402,10 +1402,16 @@ function Get-PathCommandName
# This is still empty when a verb match is found that is the entire string, but it might not be worth checking for that case and skipping the below operation
$cmdNounSuffix = $UnapprovedVerb.Substring($beginningOfSuffix)
# Add command noun suffix only when the current noun doesn't contain it or vice-versa.
- if(-not $cmdNoun -or (($cmdNoun -notmatch $cmdNounSuffix) -and ($cmdNounSuffix -notmatch $cmdNoun))) {
- $cmdNoun = $cmdNoun + (Get-PascalCasedString -Name $UnapprovedVerb.Substring($beginningOfSuffix))
- } elseif($cmdNounSuffix -match $cmdNoun) {
- $cmdNoun = $cmdNounSuffix
+ if(-not $cmdNoun) {
+ $cmdNoun = Get-PascalCasedString -Name $cmdNounSuffix
+ }
+ elseif(-not $cmdNounSuffix.StartsWith('By', [System.StringComparison]::OrdinalIgnoreCase)) {
+ if(($cmdNoun -notmatch $cmdNounSuffix) -and ($cmdNounSuffix -notmatch $cmdNoun)) {
+ $cmdNoun = $cmdNoun + (Get-PascalCasedString -Name $cmdNounSuffix)
+ }
+ elseif($cmdNounSuffix -match $cmdNoun) {
+ $cmdNoun = $cmdNounSuffix
+ }
}
}
}
@@ -1471,7 +1477,7 @@ function Get-PathFunctionBody
[string]
$HostOverrideCommand,
- [Parameter(Mandatory=$true)]
+ [Parameter(Mandatory=$false)]
[string]
$AuthenticationCommand,
@@ -1479,10 +1485,6 @@ function Get-PathFunctionBody
[string]
$AuthenticationCommandArgumentName,
- [Parameter(Mandatory=$false)]
- [string]
- $SubscriptionIdCommand,
-
[Parameter(Mandatory=$true)]
[PSCustomObject]
$FlattenedParametersOnPSCmdlet
diff --git a/Tests/PSSwagger.Unit.Tests.ps1 b/Tests/PSSwagger.Unit.Tests.ps1
index da4aa69..31e272a 100644
--- a/Tests/PSSwagger.Unit.Tests.ps1
+++ b/Tests/PSSwagger.Unit.Tests.ps1
@@ -266,6 +266,24 @@ Describe "PSSwagger Unit Tests" -Tag @('BVT', 'DRT', 'UnitTest', 'P0') {
It "Get-HeaderContent should return MICROSOFT_APACHE_NO_CODEGEN header content with '-Header MICROSOFT_APACHE_NO_CODEGEN'" {
Get-HeaderContent -SwaggerDict @{Info = @{Header = 'MICROSOFT_APACHE_NO_CODEGEN'}} | Should BeExactly $MicrosoftApacheLicenseHeader
}
+
+ It 'Get-HeaderContent should escape <#' {
+ Get-HeaderContent -SwaggerDict @{Info = @{Header = 'Header content with <#'}} | Should BeExactly 'Header content with <`#'
+ }
+
+ It 'Get-HeaderContent should escape #>' {
+ Get-HeaderContent -SwaggerDict @{Info = @{Header = 'Header content with #>'}} | Should BeExactly 'Header content with #`>'
+ }
+
+ It 'Get-HeaderContent should replace -- with ==' {
+ Get-HeaderContent -SwaggerDict @{Info = @{Header = 'Header content with --'}} -WarningVariable wv -WarningAction SilentlyContinue | Should BeExactly 'Header content with =='
+ $wv | Should not BeNullOrEmpty
+ $wv.Message -match '==' | Should Be $true
+ }
+
+ It "Get-HeaderContent should escape '<#' and '#>', and replace '--' with '=='" {
+ Get-HeaderContent -SwaggerDict @{Info = @{Header = 'Header content with <# PS comment #> and --.'}} -WarningAction SilentlyContinue | Should BeExactly 'Header content with <`# PS comment #`> and ==.'
+ }
}
Context "Get-CSharpModelName Unit Tests" {
@@ -287,7 +305,7 @@ Describe "PSSwagger Unit Tests" -Tag @('BVT', 'DRT', 'UnitTest', 'P0') {
Convert-GenericTypeToString -Type ('System.Int32' -as [type]) | Should BeExactly 'System.Int32'
}
It "Convert-GenericTypeToString with 'System.String[]' type" {
- Convert-GenericTypeToString -Type ('System.String[]' -as [type]) | Should BeExactly 'System.String'
+ Convert-GenericTypeToString -Type ('System.String[]' -as [type]) | Should BeExactly 'System.String[]'
}
It "Convert-GenericTypeToString with 'System.Collections.Generic.List[string]' type" {
Convert-GenericTypeToString -Type ('System.Collections.Generic.List[string]' -as [type]) | Should BeExactly 'System.Collections.Generic.List[System.String]'
diff --git a/Tests/PSSwaggerScenario.Tests.ps1 b/Tests/PSSwaggerScenario.Tests.ps1
index 4884a56..2c1d29b 100644
--- a/Tests/PSSwaggerScenario.Tests.ps1
+++ b/Tests/PSSwaggerScenario.Tests.ps1
@@ -223,7 +223,7 @@ Describe "Optional parameter tests" -Tag ScenarioTest {
}
It "Generates cmdlet using optional path parameters" {
- $results = Get-CupcakeByMaker -Flavor "chocolate" -Maker "bob"
+ $results = Get-Cupcake -Flavor "chocolate" -Maker "bob"
$results.Length | should be 1
}
@@ -528,10 +528,10 @@ Describe "AzureExtensions" -Tag @('AzureExtension','ScenarioTest') {
}
It "Test x-ms-paths generated cmdlets" {
- $results = Get-CupcakeById -Id 1
+ $results = Get-Cupcake -Id 1
$results.Count | should be 1
- $results = Get-CupcakeByFlavor -Flavor 'vanilla'
+ $results = Get-Cupcake -Flavor 'vanilla'
$results.Count | should be 1
}
@@ -546,6 +546,22 @@ Describe "AzureExtensions" -Tag @('AzureExtension','ScenarioTest') {
$cmdInfo = Should BeNullOrEmpty
$ev.FullyQualifiedErrorId | Should Be 'CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand'
}
+
+ It "Validate default parameterset name of generated cmdlet" {
+ $CommandInfo = Get-Command -Name Get-Cupcake
+ $DefaultParameterSet = 'Cupcake_List'
+ $ParameterSetNames = @(
+ $DefaultParameterSet,
+ 'Cupcake_GetById',
+ 'Cupcake_GetByFlavor'
+ )
+ $CommandInfo.DefaultParameterSet | Should Be $DefaultParameterSet
+ $CommandInfo.ParameterSets.Count | Should Be $ParameterSetNames.Count
+
+ $ParameterSetNames | ForEach-Object {
+ $CommandInfo.ParameterSets.Name -contains $_ | Should Be $true
+ }
+ }
}
AfterAll {
@@ -1141,4 +1157,32 @@ Describe "Output type scenario tests" -Tag @('OutputType','ScenarioTest') {
$CommandInfo = Get-Command -Name Get-IotHubResourceEventHubConsumerGroup -Module $ModuleName
$CommandInfo.OutputType.Type.ToString() | Should BeExactly 'System.String'
}
-}
\ No newline at end of file
+}
+
+Describe 'New-PSSwaggerModule cmdlet parameter tests' -Tag @('CmdletParameterTest','ScenarioTest') {
+ BeforeAll {
+ $ModuleName = 'Generated.Module.NoVersionFolder'
+ $SwaggerSpecPath = Join-Path -Path $PSScriptRoot -ChildPath 'Data' | Join-Path -ChildPath 'AzureExtensions' | Join-Path -ChildPath 'AzureExtensionsSpec.json'
+ $GeneratedPath = Join-Path -Path $PSScriptRoot -ChildPath 'Generated'
+ $GeneratedModuleBase = Join-Path -Path $GeneratedPath -ChildPath $ModuleName
+ if (Test-Path -Path $GeneratedModuleBase -PathType Container) {
+ Remove-Item -Path $GeneratedModuleBase -Recurse -Force
+ }
+ }
+
+ It 'Test NoVersionFolder switch parameter' {
+ $params = @{
+ SpecificationPath = $SwaggerSpecPath
+ Name = $ModuleName
+ UseAzureCsharpGenerator = $true
+ Path = $GeneratedPath
+ NoVersionFolder = $true
+ ConfirmBootstrap = $true
+ Verbose = $true
+ }
+ Invoke-NewPSSwaggerModuleCommand -NewPSSwaggerModuleParameters $params
+
+ $ModuleInfo = Import-Module $GeneratedModuleBase -Force -PassThru
+ $ModuleInfo.ModuleBase | Should Be $GeneratedModuleBase
+ }
+}
diff --git a/Tests/TestUtilities.psm1 b/Tests/TestUtilities.psm1
index d9d2781..3fdb292 100644
--- a/Tests/TestUtilities.psm1
+++ b/Tests/TestUtilities.psm1
@@ -78,6 +78,9 @@ function Invoke-NewPSSwaggerModuleCommand {
$NewPSSwaggerModuleParameters['NoAssembly'] = $false
$NewPSSwaggerModuleParameters['ConfirmBootstrap'] = $true
}
+ elseif (-not $NewPSSwaggerModuleParameters.ContainsKey('AssemblyFileName')) {
+ $NewPSSwaggerModuleParameters['NoAssembly'] = $true
+ }
if ((Get-Variable -Name PSEdition -ErrorAction Ignore) -and ('Core' -eq $PSEdition)) {
if ($IncludeAssembly) {
diff --git a/docs/commands/New-PSSwaggerModule.md b/docs/commands/New-PSSwaggerModule.md
index a1612f7..87db1f5 100644
--- a/docs/commands/New-PSSwaggerModule.md
+++ b/docs/commands/New-PSSwaggerModule.md
@@ -14,30 +14,30 @@ PowerShell command to generate the PowerShell commands for a given RESTful Web S
### SpecificationPath (Default)
```
New-PSSwaggerModule -SpecificationPath -Path -Name [-Version ]
- [-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator] [-NoAssembly]
- [-PowerShellCorePath ] [-IncludeCoreFxAssembly] [-InstallToolsForAllUsers] [-TestBuild]
+ [-NoVersionFolder] [-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator]
+ [-NoAssembly] [-PowerShellCorePath ] [-IncludeCoreFxAssembly] [-InstallToolsForAllUsers] [-TestBuild]
[-SymbolPath ] [-ConfirmBootstrap]
```
### SdkAssemblyWithSpecificationPath
```
New-PSSwaggerModule -SpecificationPath -Path -AssemblyFileName
- [-ClientTypeName ] [-ModelsName ] -Name [-Version ]
+ [-ClientTypeName ] [-ModelsName ] -Name [-Version ] [-NoVersionFolder]
[-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator]
```
### SdkAssemblyWithSpecificationUri
```
New-PSSwaggerModule -SpecificationUri -Path -AssemblyFileName
- [-ClientTypeName ] [-ModelsName ] -Name [-Version ]
+ [-ClientTypeName ] [-ModelsName ] -Name [-Version ] [-NoVersionFolder]
[-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator]
```
### SpecificationUri
```
New-PSSwaggerModule -SpecificationUri -Path -Name [-Version ]
- [-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator] [-NoAssembly]
- [-PowerShellCorePath ] [-IncludeCoreFxAssembly] [-InstallToolsForAllUsers] [-TestBuild]
+ [-NoVersionFolder] [-DefaultCommandPrefix ] [-Header ] [-UseAzureCsharpGenerator]
+ [-NoAssembly] [-PowerShellCorePath ] [-IncludeCoreFxAssembly] [-InstallToolsForAllUsers] [-TestBuild]
[-SymbolPath ] [-ConfirmBootstrap]
```
@@ -191,6 +191,21 @@ Accept pipeline input: False
Accept wildcard characters: False
```
+### -NoVersionFolder
+Switch to not create the version folder under the generated module folder.
+
+```yaml
+Type: SwitchParameter
+Parameter Sets: (All)
+Aliases:
+
+Required: False
+Position: Named
+Default value: False
+Accept pipeline input: False
+Accept wildcard characters: False
+```
+
### -DefaultCommandPrefix
Prefix value to be prepended to cmdlet noun or to cmdlet name without verb.