< Summary - Kestrun — Combined Coverage

Information
Class: Public.Service.New-KrServiceDescriptor
Assembly: Kestrun.PowerShell.Public
File(s): /home/runner/work/Kestrun/Kestrun/src/PowerShell/Kestrun/Public/Service/New-KrServiceDescriptor.ps1
Tag: Kestrun/Kestrun@09cad9a8fdafda7aca15f5f5e888b4bbcc8f0674
Line coverage
90%
Covered lines: 40
Uncovered lines: 4
Coverable lines: 44
Total lines: 139
Line coverage: 90.9%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 03/26/2026 - 03:54:59 Line coverage: 90.9% (40/44) Total lines: 139 Tag: Kestrun/Kestrun@844b5179fb0492dc6b1182bae3ff65fa7365521d

Metrics

File(s)

/home/runner/work/Kestrun/Kestrun/src/PowerShell/Kestrun/Public/Service/New-KrServiceDescriptor.ps1

#LineLine coverage
 1<#
 2.SYNOPSIS
 3    Creates a Service.psd1 descriptor file.
 4.DESCRIPTION
 5    Creates a Service.psd1 descriptor file used by Kestrun.Tool content-root service install flow.
 6    Required keys are FormatVersion, Name, Description, Version, and EntryPoint.
 7    Optional keys are ServiceLogPath and PreservePaths.
 8.PARAMETER Path
 9    Target descriptor path. Accepts either a descriptor file path or a directory path.
 10    When a directory path is provided, Service.psd1 is appended automatically.
 11.PARAMETER Name
 12    Immutable service name value written to the descriptor.
 13.PARAMETER Description
 14    Service description value.
 15.PARAMETER Version
 16    Service version. Must be compatible with System.Version.
 17.PARAMETER EntryPoint
 18    Optional entry point path relative to the content root. Defaults to Service.ps1.
 19.PARAMETER ServiceLogPath
 20    Optional default service log path.
 21.PARAMETER PreservePaths
 22    Optional list of relative file/folder paths that must be preserved during service update.
 23.PARAMETER Force
 24    Overwrite an existing descriptor file.
 25.PARAMETER WhatIf
 26    Shows what would happen if the cmdlet runs. The cmdlet is not executed.
 27.PARAMETER Confirm
 28    Prompts for confirmation before running the cmdlet.
 29.EXAMPLE
 30    New-KrServiceDescriptor -Name demo -Description 'Demo service' -Version 1.2.0
 31#>
 32function New-KrServiceDescriptor {
 33    [KestrunRuntimeApi('Everywhere')]
 34    [CmdletBinding(SupportsShouldProcess)]
 35    [OutputType([pscustomobject])]
 36    param(
 37        [Parameter()]
 38        [ValidateNotNullOrEmpty()]
 39        [string]$Path = 'Service.psd1',
 40
 41        [Parameter(Mandatory)]
 42        [ValidateNotNullOrEmpty()]
 43        [string]$Name,
 44
 45        [Parameter(Mandatory)]
 46        [ValidateNotNullOrEmpty()]
 47        [string]$Description,
 48
 49        [Parameter(Mandatory)]
 50        [ValidateNotNullOrEmpty()]
 51        [version]$Version,
 52
 53        [Parameter()]
 54        [string]$EntryPoint,
 55
 56        [Parameter()]
 57        [string]$ServiceLogPath,
 58
 59        [Parameter()]
 60        [string[]]$PreservePaths,
 61
 62        [Parameter()]
 63        [switch]$Force
 64    )
 65
 166    $fullPath = [System.IO.Path]::GetFullPath($Path)
 167    if (Test-Path -LiteralPath $fullPath -PathType Container) {
 168        $fullPath = Join-Path -Path $fullPath -ChildPath 'Service.psd1'
 69    }
 70
 171    if ([System.IO.Path]::GetExtension($fullPath) -ne '.psd1') {
 072        throw "Path must target a .psd1 descriptor file or an existing directory: $fullPath"
 73    }
 74
 275    if ((Test-Path -LiteralPath $fullPath) -and -not $Force) {
 076        throw "Descriptor file already exists: $fullPath. Use -Force to overwrite."
 77    }
 78
 179    $directory = [System.IO.Path]::GetDirectoryName($fullPath)
 280    if (-not [string]::IsNullOrWhiteSpace($directory) -and -not (Test-Path -LiteralPath $directory)) {
 081        $null = New-Item -ItemType Directory -Path $directory -Force
 82    }
 83
 184    $escapedName = $Name.Replace("'", "''")
 185    $escapedDescription = $Description.Replace("'", "''")
 186    $escapedVersion = $Version.ToString().Replace("'", "''")
 387    $resolvedEntryPoint = if ([string]::IsNullOrWhiteSpace($EntryPoint)) { 'Service.ps1' } else { $EntryPoint }
 88
 189    if ([System.IO.Path]::IsPathRooted($resolvedEntryPoint)) {
 090        throw "EntryPoint must be a relative path under the descriptor directory: $resolvedEntryPoint"
 91    }
 92
 293    $entryPointPath = [System.IO.Path]::GetFullPath((Join-Path -Path $directory -ChildPath $resolvedEntryPoint))
 294    $descriptorRootWithSeparator = if ($directory.EndsWith([System.IO.Path]::DirectorySeparatorChar)) { $directory } els
 195    if (-not $entryPointPath.StartsWith($descriptorRootWithSeparator, [System.StringComparison]::OrdinalIgnoreCase)) {
 196        throw "EntryPoint must resolve to a file under descriptor path: $resolvedEntryPoint"
 97    }
 98
 299    if (-not (Test-Path -LiteralPath $entryPointPath -PathType Leaf)) {
 1100        throw "EntryPoint file not found under descriptor path: $resolvedEntryPoint"
 101    }
 102
 1103    $escapedEntryPoint = $resolvedEntryPoint.Replace("'", "''")
 104
 1105    $contentLines = [System.Collections.Generic.List[string]]::new()
 1106    $contentLines.Add('@{')
 1107    $contentLines.Add("    FormatVersion = '1.0'")
 1108    $contentLines.Add("    Name = '$escapedName'")
 1109    $contentLines.Add("    Description = '$escapedDescription'")
 1110    $contentLines.Add("    Version = '$escapedVersion'")
 1111    $contentLines.Add("    EntryPoint = '$escapedEntryPoint'")
 112
 1113    if (-not [string]::IsNullOrWhiteSpace($ServiceLogPath)) {
 1114        $escapedServiceLogPath = $ServiceLogPath.Replace("'", "''")
 1115        $contentLines.Add("    ServiceLogPath = '$escapedServiceLogPath'")
 116    }
 117
 1118    if ($null -ne $PreservePaths -and $PreservePaths.Count -gt 0) {
 1119        $contentLines.Add('    PreservePaths = @(')
 1120        foreach ($preservePath in $PreservePaths) {
 1121            if ([string]::IsNullOrWhiteSpace($preservePath)) {
 122                continue
 123            }
 124
 1125            $escapedPreservePath = $preservePath.Replace("'", "''")
 1126            $contentLines.Add("        '$escapedPreservePath'")
 127        }
 128
 1129        $contentLines.Add('    )')
 130    }
 131
 1132    $contentLines.Add('}')
 133
 1134    if ($PSCmdlet.ShouldProcess($fullPath, 'Create Service.psd1 descriptor')) {
 2135        Set-Content -LiteralPath $fullPath -Value ($contentLines -join [Environment]::NewLine) -Encoding utf8NoBOM
 136    }
 137
 1138    Get-KrServiceDescriptor -Path $fullPath
 139}

Methods/Properties

New-KrServiceDescriptor()