From 24aaba151d9e537551bb4ae74ce32c0fd07b7588 Mon Sep 17 00:00:00 2001 From: Oleksandr Nikolaiev Date: Mon, 6 Oct 2025 15:29:43 +0300 Subject: [PATCH 1/3] Add new naming --- fscps.tools/fscps.tools.psd1 | 3 +- .../functions/get-fscpsmodelversion.ps1 | 137 ++++++++++++++++++ .../internal/configurations/configuration.ps1 | 4 +- .../functions/invoke-commercecompile.ps1 | 57 +++++++- .../internal/functions/invoke-fsccompile.ps1 | 39 +++++ wiki/settings.md | 13 +- 6 files changed, 248 insertions(+), 5 deletions(-) create mode 100644 fscps.tools/functions/get-fscpsmodelversion.ps1 diff --git a/fscps.tools/fscps.tools.psd1 b/fscps.tools/fscps.tools.psd1 index 8afbd98..7bce6f8 100644 --- a/fscps.tools/fscps.tools.psd1 +++ b/fscps.tools/fscps.tools.psd1 @@ -24,7 +24,7 @@ GUID = '6b3d02bf-e176-4052-9b40-5012339c20b3' Author = 'Oleksandr Nikolaiev (@onikolaiev)' # Company or vendor of this module -CompanyName = 'Ciellos Inc.' +CompanyName = 'Oleksandr Nikolaiev (@onikolaiev)' # Copyright statement for this module Copyright = 'Copyright (c) 2025 Oleksandr Nikolaiev. All rights reserved.' @@ -84,6 +84,7 @@ FunctionsToExport = 'Get-FSCPSSettings', 'Set-FSCPSSettings', 'Invoke-FSCPSChoco 'Register-FSCPSAzureStorageConfig', 'Set-FSCPSActiveAzureStorageConfig', 'Invoke-FSCPSAzureStorageDownload', + 'Get-FSCPSModelVersion', 'Invoke-FSCPSAzureStorageUpload', 'Invoke-FSCPSAzureStorageDelete', 'Update-FSCPSISVSource', 'Update-FSCPSNugetsFromLCS', 'Invoke-FSCPSInstallModule', 'Get-FSCPSADOTestCase', diff --git a/fscps.tools/functions/get-fscpsmodelversion.ps1 b/fscps.tools/functions/get-fscpsmodelversion.ps1 new file mode 100644 index 0000000..29bd6d0 --- /dev/null +++ b/fscps.tools/functions/get-fscpsmodelversion.ps1 @@ -0,0 +1,137 @@ + +<# + .SYNOPSIS + This gets the D365FSC model version + + .DESCRIPTION + This gets the D365FSC model version from the descriptor file by automatically finding the descriptor in the model path + + .PARAMETER ModelPath + Path to the model folder (automatically searches for Descriptor\*.xml inside) + + .EXAMPLE + PS C:\> Get-FSCPSModelVersion -ModelPath "c:\temp\metadata\TestModel" + + This will get the version information of the TestModel by automatically finding the descriptor file + + .EXAMPLE + PS C:\> Get-FSCPSModelVersion -ModelPath "c:\temp\PackagesLocalDirectory\MyCustomModel" + + This will get the version information of MyCustomModel including layer name + + .NOTES + Author: Oleksandr Nikolaiev (@onikolaiev) +#> +function Get-FSCPSModelVersion { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string]$ModelPath + ) + + begin{ + Invoke-TimeSignal -Start + Write-PSFMessage -Level Important -Message "ModelPath: $ModelPath" + + # Validate that the model path exists + if (-not (Test-Path -LiteralPath $ModelPath -PathType Container)) { + throw "Model path '$ModelPath' does not exist or is not a directory" + } + + # Function to convert layer number to layer name + function Get-LayerName { + param([int]$LayerNumber) + + switch ($LayerNumber) { + 0 { return "SYS" } + 1 { return "SYP" } + 2 { return "GLS" } + 3 { return "GLP" } + 4 { return "FPK" } + 5 { return "FPP" } + 6 { return "SLN" } + 7 { return "SLP" } + 8 { return "ISV" } + 9 { return "ISP" } + 10 { return "VAR" } + 11 { return "VAP" } + 12 { return "CUS" } + 13 { return "CUP" } + 14 { return "USR" } + 15 { return "USP" } + default { return "Unknown" } + } + } + } + + process{ + # Look for descriptor file in the model path + $descriptorPath = Join-Path -Path $ModelPath -ChildPath "Descriptor" + $descriptorFiles = @() + + if (Test-Path -Path $descriptorPath -PathType Container) { + $descriptorFiles = Get-ChildItem -Path $descriptorPath -Filter "*.xml" -File + } + + if ($descriptorFiles.Count -eq 0) { + Write-PSFMessage -Level Warning -Message "No descriptor XML files found in '$descriptorPath'" + return $null + } + + if ($descriptorFiles.Count -gt 1) { + Write-PSFMessage -Level Warning -Message "Multiple descriptor files found, using the first one: $($descriptorFiles[0].Name)" + } + + $descriptorFile = $descriptorFiles[0].FullName + Write-PSFMessage -Level Verbose -Message "Found descriptor file: $descriptorFile" + + try { + [xml]$xml = Get-Content $descriptorFile -Encoding UTF8 + + $modelInfo = $xml.SelectNodes("/AxModelInfo") + if ($modelInfo.Count -ne 1) { + throw "File '$descriptorFile' is not a valid model descriptor file" + } + + # Extract model information + $modelName = ($xml.SelectNodes("/AxModelInfo/Name")).InnerText + $layerId = [int]($xml.SelectNodes("/AxModelInfo/Layer")[0].InnerText) + $layerName = Get-LayerName -LayerNumber $layerId + + $versionMajor = ($xml.SelectNodes("/AxModelInfo/VersionMajor")).InnerText + $versionMinor = ($xml.SelectNodes("/AxModelInfo/VersionMinor")).InnerText + $versionBuild = ($xml.SelectNodes("/AxModelInfo/VersionBuild")).InnerText + $versionRevision = ($xml.SelectNodes("/AxModelInfo/VersionRevision")).InnerText + + $fullVersion = "$versionMajor.$versionMinor.$versionBuild.$versionRevision" + + $modelVersion = [PSCustomObject]@{ + ModelName = $modelName + Version = $fullVersion + LayerId = $layerId + LayerName = $layerName + DescriptorPath = $descriptorFile + ModelPath = $ModelPath + VersionMajor = [int]$versionMajor + VersionMinor = [int]$versionMinor + VersionBuild = [int]$versionBuild + VersionRevision = [int]$versionRevision + } + + Write-PSFMessage -Level Important -Message "Found model '$modelName' version $fullVersion in layer $layerName ($layerId)" + return $modelVersion + } + catch { + Write-PSFMessage -Level Host -Message "Something went wrong while reading D365FSC model version from '$descriptorFile'" -Exception $PSItem.Exception + Stop-PSFFunction -Message "Stopping because of errors" -EnableException $true + return + } + } + + end{ + Invoke-TimeSignal -End + } +} + +$curModelVersion = Get-FSCPSModelVersion -ModelPath "D:\Sources\vertex\connector-d365-unified-connector\PackagesLocalDirectory\Vertex" +$curModelVersion.Version \ No newline at end of file diff --git a/fscps.tools/internal/configurations/configuration.ps1 b/fscps.tools/internal/configurations/configuration.ps1 index 12c132b..0f38fd6 100644 --- a/fscps.tools/internal/configurations/configuration.ps1 +++ b/fscps.tools/internal/configurations/configuration.ps1 @@ -91,7 +91,9 @@ Set-PSFConfig -FullName 'fscps.tools.settings.all.artifactsFolderName' -Value 'a Set-PSFConfig -FullName 'fscps.tools.settings.all.generatePackages' -Value $true -Initialize -Description 'Option to enable a packages generation functionality. Default / TRUE' Set-PSFConfig -FullName 'fscps.tools.settings.all.createRegularPackage' -Value $true -Initialize -Description 'Option to generate an LCS Deployable Package after build. The "generatePackages" option should be enabled. Default / TRUE' Set-PSFConfig -FullName 'fscps.tools.settings.all.createCloudPackage' -Value $false -Initialize -Description 'Option to generate a Power Platform Unified Package after build. The "generatePackages" option should be enabled. Default / FALSE' -Set-PSFConfig -FullName 'fscps.tools.settings.all.namingStrategy' -Value 'Default' -Initialize -Description 'The package naming strategy. Custom value means the result package will have the name specified in the packageName variable. Default / Custom' +Set-PSFConfig -FullName 'fscps.tools.settings.all.namingStrategy' -Value 'Default' -Initialize -Description 'The package naming strategy. Custom value means the result package will have the name specified in the packageName variable. Default / Custom / ModelVersion' +Set-PSFConfig -FullName 'fscps.tools.settings.all.versionSourceModelName' -Value '' -Initialize -Description 'The model name to be used for naming the package. This model will be used to receive the metadata number.' + Set-PSFConfig -FullName 'fscps.tools.settings.all.packageNamePattern' -Value 'BRANCHNAME-PACKAGENAME-FNSCMVERSION_DATE.RUNNUMBER' -Initialize -Description '' Set-PSFConfig -FullName 'fscps.tools.settings.all.packageName' -Value '' -Initialize -Description 'Name of the package' diff --git a/fscps.tools/internal/functions/invoke-commercecompile.ps1 b/fscps.tools/internal/functions/invoke-commercecompile.ps1 index 0eb5b95..95388a0 100644 --- a/fscps.tools/internal/functions/invoke-commercecompile.ps1 +++ b/fscps.tools/internal/functions/invoke-commercecompile.ps1 @@ -138,7 +138,7 @@ function Invoke-CommerceCompile { } # Gather version info - #$versionData = Get-FSCPSVersionInfo -Version $Version @CMDOUT + $versionData = Get-FSCPSVersionInfo -Version $Version @CMDOUT $SolutionBuildFolderPath = (Join-Path $BuildFolderPath "$($Version)_build") $responseObject.BUILD_FOLDER_PATH = $SolutionBuildFolderPath @@ -239,6 +239,61 @@ function Invoke-CommerceCompile { break; } + { $settings.namingStrategy -eq "ModelVersion" } + { + # New naming strategy: "Contoso D365 Commerce A10.0.45 PU66 - V2.2.78.1" + try { + $basePackageName = $settings.packageName + $buildVersion = $Version + $platformUpdate = $versionData.data.PlatformUpdate + + # Get commerce version from repo.props file + $commerceVersion = "" + $repoPropsPath = Join-Path $SourcesPath "repo.props" + + if (Test-Path $repoPropsPath) { + try { + [xml]$repoPropsXml = Get-Content $repoPropsPath -Encoding UTF8 + + $majorVersionNode = $repoPropsXml.SelectNodes("//MajorVersion") + $buildNumberNode = $repoPropsXml.SelectNodes("//BuildNumber") + + if ($majorVersionNode -and $buildNumberNode) { + $majorVersion = $majorVersionNode[0].InnerText + $buildNumber = $buildNumberNode[0].InnerText + $commerceVersion = "$majorVersion.$buildNumber" + Write-PSFMessage -Level Important -Message "Found commerce version from repo.props: $commerceVersion" + } + else { + Write-PSFMessage -Level Warning -Message "Could not find MajorVersion or BuildNumber in repo.props" + } + } + catch { + Write-PSFMessage -Level Warning -Message "Error parsing repo.props: $($_.Exception.Message)" + } + } + else { + Write-PSFMessage -Level Warning -Message "repo.props file not found at: $repoPropsPath" + } + + if ([string]::IsNullOrEmpty($commerceVersion)) { + Write-PSFMessage -Level Warning -Message "Commerce version not found, using build version as fallback" + $commerceVersion = $buildVersion + } + + # Construct the package name: "Contoso D365 Commerce A10.0.45 PU66 - V2.2.78.1" + $packageName = "$basePackageName D365 Commerce A$buildVersion PU$platformUpdate - V$commerceVersion" + + Write-PSFMessage -Level Important -Message "Generated package name: $packageName" + } + catch { + Write-PSFMessage -Level Warning -Message "Error generating ModelVersion package name: $($_.Exception.Message). Falling back to settings package name." + $packageName = if($settings.packageName.Contains('.zip')) { $settings.packageName } else { $settings.packageName + ".zip" } + } + + break; + } + Default { $packageName = $settings.packageName break; diff --git a/fscps.tools/internal/functions/invoke-fsccompile.ps1 b/fscps.tools/internal/functions/invoke-fsccompile.ps1 index 7dc661c..c1933f4 100644 --- a/fscps.tools/internal/functions/invoke-fsccompile.ps1 +++ b/fscps.tools/internal/functions/invoke-fsccompile.ps1 @@ -425,6 +425,45 @@ function Invoke-FSCCompile { break; } + { $settings.namingStrategy -eq "ModelVersion" } + { + # New naming strategy: "Contoso D365 FnSCM A10.0.42 PU66 - V2.2.77.1.zip" + try { + $basePackageName = $settings.packageName + $buildVersion = $Version + $platformUpdate = $versionData.data.PlatformUpdate + + # Get model version if versionSourceModelName is specified + $modelVersion = "" + if (-not [string]::IsNullOrEmpty($settings.versionSourceModelName)) { + $modelPath = Join-Path $SourceMetadataPath $settings.versionSourceModelName + if (Test-Path $modelPath) { + $curModelVersion = Get-FSCPSModelVersion -ModelPath $modelPath + if ($curModelVersion) { + $modelVersion = $curModelVersion.Version + } + } + else { + Write-PSFMessage -Level Warning -Message "Model path not found for naming: $modelPath" + } + } + + if ([string]::IsNullOrEmpty($modelVersion)) { + Write-PSFMessage -Level Warning -Message "Model version not found, using build version as fallback" + $modelVersion = $buildVersion + } + + $packageName = "$basePackageName D365 FnSCM A$buildVersion PU$platformUpdate - V$modelVersion.zip" + + Write-PSFMessage -Level Important -Message "Generated package name: $packageName" + } + catch { + Write-PSFMessage -Level Warning -Message "Error generating ModelVersion package name: $($_.Exception.Message). Falling back to settings package name." + $packageName = if($settings.packageName.Contains('.zip')) { $settings.packageName } else { $settings.packageName + ".zip" } + } + + break; + } Default { $packageName = $settings.packageName break; diff --git a/wiki/settings.md b/wiki/settings.md index 82c5729..496aa30 100644 --- a/wiki/settings.md +++ b/wiki/settings.md @@ -58,10 +58,19 @@ The settings file can be everywhere and provided to the fscps.tools through the | FSCServiseUpdatePackageId | The AssetId of the Service Update (GA) package of the FSC. Depends on the FSC Version(version.default.json). | All | GitHub | "" | | ecommerceMicrosoftRepoUrl | The Msdyn365.Commerce.OnlineSDK repo URL what will use to build the ECommerce pacage. | Ecommerce | GitHub | "" | | ecommerceMicrosoftRepoBranch | The Msdyn365.Commerce.OnlineSDK repo branch. | Ecommerce | GitHub | "" | -| namingStrategy | The package naming strategy. Custom value means the result package will have the name specified in the packageName variable. Default / Custom | All | All | Default | +| namingStrategy | The package naming strategy. Custom value means the result package will have the name specified in the packageName variable. Default / Custom / ModelVersion | All | All | Default | | packageName | Name of the package | All | All | "" | +| versionSourceModelName | The model name to be used as version source for package naming when namingStrategy is set to "ModelVersion". This model will be used to retrieve the metadata version number for package name generation. | FSCM | All | "" | | versionStrategy | This value means the version of the NuGet packages that will be taken to build the D365FSC code. GA - the NuGets from the GA version of the FSC will be taken (e.g. 10.0.39). Latest - latest available packages. Values: GA/Latest | FSCM | All | GA | -| cleanupNugets | Cleanup Commerce compiled NuGet packages with microsoft artifacts | Commerce | All | "" | +| cleanupNugets | Cleanup Commerce compiled NuGet packages with microsoft artifacts | Commerce | All | false | +| cleanupAfterBuild | Cleanup build cache after build | All | All | true | +| cleanupCSUPackage | Cleanup CSU (Commerce Scale Unit) package after build | Commerce | All | false | +| solutionName | Name of the solution | All | All | "" | +| artifactsPath | The destination artifacts path | All | All | "" | +| artifactsFolderName | The name of the folder contains the result artifacts | All | All | artifacts | +| signArtifacts | Option to sign generated artifacts | All | All | false | +| repoToken | Repository access token | All | All | "" | +| fscPsVer | Version of the fscps.tools module | All | All | {current module version} | | enableBuildCaching | If true, will "cache" FSC models after build and upload it to the ModelStorage storage account. If next build triggered fscps will check the CRC of each model folder and if its equal with the cached CRC the folder with the model binaries will be extracted to the source folder, and target model will be skipped to the build. | FSCM | All | false | From cab3b2ff01bee871e9e64b7adda9bc0e953faaa5 Mon Sep 17 00:00:00 2001 From: Oleksandr Nikolaiev Date: Mon, 6 Oct 2025 16:02:09 +0300 Subject: [PATCH 2/3] fix --- fscps.tools/fscps.tools.psm1 | 21 ++++++-- .../functions/get-fscpsmodelversion.ps1 | 51 ++++++++++--------- .../functions/test-configstoreagelocation.ps1 | 10 ++-- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/fscps.tools/fscps.tools.psm1 b/fscps.tools/fscps.tools.psm1 index af64bec..18f9e9a 100644 --- a/fscps.tools/fscps.tools.psm1 +++ b/fscps.tools/fscps.tools.psm1 @@ -45,9 +45,24 @@ function Import-ModuleFile $Path ) - $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($Path).ProviderPath - if ($doDotSource) { . $resolvedPath } - else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText($resolvedPath))), $null, $null) } + try { + $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($Path).ProviderPath + if ($script:doDotSource) { + . $resolvedPath + } + else { + $content = [io.file]::ReadAllText($resolvedPath) + if (-not [string]::IsNullOrWhiteSpace($content)) { + $scriptBlock = [scriptblock]::Create($content) + if ($scriptBlock) { + $ExecutionContext.InvokeCommand.InvokeScript($false, $scriptBlock, $null, $null) + } + } + } + } + catch { + Write-Warning "Failed to import module file '$Path': $($_.Exception.Message)" + } } diff --git a/fscps.tools/functions/get-fscpsmodelversion.ps1 b/fscps.tools/functions/get-fscpsmodelversion.ps1 index 29bd6d0..3444b6a 100644 --- a/fscps.tools/functions/get-fscpsmodelversion.ps1 +++ b/fscps.tools/functions/get-fscpsmodelversion.ps1 @@ -22,6 +22,32 @@ .NOTES Author: Oleksandr Nikolaiev (@onikolaiev) #> + +# Helper function to convert layer number to layer name +function Get-LayerName { + param([int]$LayerNumber) + + switch ($LayerNumber) { + 0 { return "SYS" } + 1 { return "SYP" } + 2 { return "GLS" } + 3 { return "GLP" } + 4 { return "FPK" } + 5 { return "FPP" } + 6 { return "SLN" } + 7 { return "SLP" } + 8 { return "ISV" } + 9 { return "ISP" } + 10 { return "VAR" } + 11 { return "VAP" } + 12 { return "CUS" } + 13 { return "CUP" } + 14 { return "USR" } + 15 { return "USP" } + default { return "Unknown" } + } +} + function Get-FSCPSModelVersion { [CmdletBinding()] param( @@ -37,31 +63,6 @@ function Get-FSCPSModelVersion { if (-not (Test-Path -LiteralPath $ModelPath -PathType Container)) { throw "Model path '$ModelPath' does not exist or is not a directory" } - - # Function to convert layer number to layer name - function Get-LayerName { - param([int]$LayerNumber) - - switch ($LayerNumber) { - 0 { return "SYS" } - 1 { return "SYP" } - 2 { return "GLS" } - 3 { return "GLP" } - 4 { return "FPK" } - 5 { return "FPP" } - 6 { return "SLN" } - 7 { return "SLP" } - 8 { return "ISV" } - 9 { return "ISP" } - 10 { return "VAR" } - 11 { return "VAP" } - 12 { return "CUS" } - 13 { return "CUP" } - 14 { return "USR" } - 15 { return "USP" } - default { return "Unknown" } - } - } } process{ diff --git a/fscps.tools/internal/functions/test-configstoreagelocation.ps1 b/fscps.tools/internal/functions/test-configstoreagelocation.ps1 index 8fab65c..d725384 100644 --- a/fscps.tools/internal/functions/test-configstoreagelocation.ps1 +++ b/fscps.tools/internal/functions/test-configstoreagelocation.ps1 @@ -30,24 +30,24 @@ #> function Test-ConfigStorageLocation { [CmdletBinding()] - [OutputType('System.String')] + [OutputType([PSFramework.Configuration.ConfigScope])] param ( [ValidateSet('User', 'System')] [string] $ConfigStorageLocation = "User" ) - $configScope = "UserDefault" + $configScope = [PSFramework.Configuration.ConfigScope]::UserDefault if ($ConfigStorageLocation -eq "System") { if ($Script:IsAdminRuntime) { - $configScope = "SystemDefault" + $configScope = [PSFramework.Configuration.ConfigScope]::SystemDefault } else { Write-PSFMessage -Level Host -Message "Unable to locate save the configuration objects in the system wide configuration store on the machine. Please start an elevated session and run the cmdlet again." Stop-PSFFunction -Message "Elevated permissions needed. Please start an elevated session and run the cmdlet again." -StepsUpward 1 - return + return $null } } - $configScope + return $configScope } \ No newline at end of file From 14b8f1607d4c48afcec3a8a59c7cbb64fd5c5abf Mon Sep 17 00:00:00 2001 From: Oleksandr Nikolaiev Date: Mon, 6 Oct 2025 18:23:45 +0300 Subject: [PATCH 3/3] fix --- docs/Get-FSCPSModelVersion.md | 82 +++++++++++++++++++ .../functions/get-fscpsmodelversion.ps1 | 53 ++++++------ .../functions/Get-FSCPSModelVersion.Tests.ps1 | 49 +++++++++++ 3 files changed, 159 insertions(+), 25 deletions(-) create mode 100644 docs/Get-FSCPSModelVersion.md create mode 100644 fscps.tools/tests/functions/Get-FSCPSModelVersion.Tests.ps1 diff --git a/docs/Get-FSCPSModelVersion.md b/docs/Get-FSCPSModelVersion.md new file mode 100644 index 0000000..110e1fe --- /dev/null +++ b/docs/Get-FSCPSModelVersion.md @@ -0,0 +1,82 @@ +--- +external help file: fscps.tools-help.xml +Module Name: fscps.tools +online version: +schema: 2.0.0 +--- + +# Get-FSCPSModelVersion + +## SYNOPSIS +This gets the D365FSC model version + +## SYNTAX + +``` +Get-FSCPSModelVersion [-ModelPath] [-ProgressAction ] [] +``` + +## DESCRIPTION +This gets the D365FSC model version from the descriptor file by automatically finding the descriptor in the model path + +## EXAMPLES + +### EXAMPLE 1 +``` +Get-FSCPSModelVersion -ModelPath "c:\temp\metadata\TestModel" +``` + +This will get the version information of the TestModel by automatically finding the descriptor file + +### EXAMPLE 2 +``` +Get-FSCPSModelVersion -ModelPath "c:\temp\PackagesLocalDirectory\MyCustomModel" +``` + +This will get the version information of MyCustomModel including layer name + +## PARAMETERS + +### -ModelPath +Path to the model folder (automatically searches for Descriptor\*.xml inside) + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -ProgressAction +{{ Fill ProgressAction Description }} + +```yaml +Type: ActionPreference +Parameter Sets: (All) +Aliases: proga + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +## OUTPUTS + +## NOTES +Tags: D365, FO, Finance, Operations, Model, Version, Descriptor, Metadata + +Author: Oleksandr Nikolaiev (@onikolaiev) + +## RELATED LINKS diff --git a/fscps.tools/functions/get-fscpsmodelversion.ps1 b/fscps.tools/functions/get-fscpsmodelversion.ps1 index 3444b6a..55cbc7d 100644 --- a/fscps.tools/functions/get-fscpsmodelversion.ps1 +++ b/fscps.tools/functions/get-fscpsmodelversion.ps1 @@ -20,34 +20,12 @@ This will get the version information of MyCustomModel including layer name .NOTES + Tags: D365, FO, Finance, Operations, Model, Version, Descriptor, Metadata + Author: Oleksandr Nikolaiev (@onikolaiev) + #> -# Helper function to convert layer number to layer name -function Get-LayerName { - param([int]$LayerNumber) - - switch ($LayerNumber) { - 0 { return "SYS" } - 1 { return "SYP" } - 2 { return "GLS" } - 3 { return "GLP" } - 4 { return "FPK" } - 5 { return "FPP" } - 6 { return "SLN" } - 7 { return "SLP" } - 8 { return "ISV" } - 9 { return "ISP" } - 10 { return "VAR" } - 11 { return "VAP" } - 12 { return "CUS" } - 13 { return "CUP" } - 14 { return "USR" } - 15 { return "USP" } - default { return "Unknown" } - } -} - function Get-FSCPSModelVersion { [CmdletBinding()] param( @@ -63,6 +41,31 @@ function Get-FSCPSModelVersion { if (-not (Test-Path -LiteralPath $ModelPath -PathType Container)) { throw "Model path '$ModelPath' does not exist or is not a directory" } + + # Helper function to convert layer number to layer name + function Get-LayerName { + param([int]$LayerNumber) + + switch ($LayerNumber) { + 0 { return "SYS" } + 1 { return "SYP" } + 2 { return "GLS" } + 3 { return "GLP" } + 4 { return "FPK" } + 5 { return "FPP" } + 6 { return "SLN" } + 7 { return "SLP" } + 8 { return "ISV" } + 9 { return "ISP" } + 10 { return "VAR" } + 11 { return "VAP" } + 12 { return "CUS" } + 13 { return "CUP" } + 14 { return "USR" } + 15 { return "USP" } + default { return "Unknown" } + } + } } process{ diff --git a/fscps.tools/tests/functions/Get-FSCPSModelVersion.Tests.ps1 b/fscps.tools/tests/functions/Get-FSCPSModelVersion.Tests.ps1 new file mode 100644 index 0000000..11f9d04 --- /dev/null +++ b/fscps.tools/tests/functions/Get-FSCPSModelVersion.Tests.ps1 @@ -0,0 +1,49 @@ +Describe "Get-FSCPSModelVersion Unit Tests" -Tag "Unit" { + BeforeAll { + # Place here all things needed to prepare for the tests + } + AfterAll { + # Here is where all the cleanup tasks go + } + + Describe "Ensuring unchanged command signature" { + It "should have the expected parameter sets" { + (Get-Command Get-FSCPSModelVersion).ParameterSets.Name | Should -Be '__AllParameterSets' + } + + It 'Should have the expected parameter ModelPath' { + $parameter = (Get-Command Get-FSCPSModelVersion).Parameters['ModelPath'] + $parameter.Name | Should -Be 'ModelPath' + $parameter.ParameterType.ToString() | Should -Be System.String + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $True + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be 0 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } + It 'Should have the expected parameter ProgressAction' { + $parameter = (Get-Command Get-FSCPSModelVersion).Parameters['ProgressAction'] + $parameter.Name | Should -Be 'ProgressAction' + $parameter.ParameterType.ToString() | Should -Be System.Management.Automation.ActionPreference + $parameter.IsDynamic | Should -Be $False + $parameter.ParameterSets.Keys | Should -Be '__AllParameterSets' + $parameter.ParameterSets.Keys | Should -Contain '__AllParameterSets' + $parameter.ParameterSets['__AllParameterSets'].IsMandatory | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].Position | Should -Be -2147483648 + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipeline | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromPipelineByPropertyName | Should -Be $False + $parameter.ParameterSets['__AllParameterSets'].ValueFromRemainingArguments | Should -Be $False + } + } + + Describe "Testing parameterset __AllParameterSets" { + <# + __AllParameterSets -ModelPath + __AllParameterSets -ModelPath -ProgressAction + #> + } + +} \ No newline at end of file