Modules/businessdev.ALbuild.RuntimePackages/Private/Get-BcRuntimeProjectFolder.ps1

function Get-BcRuntimeProjectFolder {
    <#
    .SYNOPSIS
        Prepares a product's project as a private copy, stamped for one platform version.
 
    .DESCRIPTION
        Both engines need the same thing before they can compile anything: a copy of the project that
        belongs to this worker alone, with the manifest rewritten for the target platform and the released
        version written in. Extracted from Get-BcRuntimeAppFile so the container route and the source
        route cannot drift apart on the one step where a difference would be invisible - a manifest
        stamped one way for the .app and another way for the runtime package would produce two packages
        that disagree without either of them looking wrong.
 
        The copy is not an optimisation. The previous design rewrote app.json in the shared checkout and
        restored it in a 'finally', so two concurrent platform versions fought over one file.
 
        Keyed by platform version AND country: the countries of a version run as concurrent workers, and
        for on-premises the compile resolves against that country's first-party symbols, so the two builds
        are not interchangeable.
 
    .PARAMETER Product
        The planned product entry (Name, AppId, AppVersion, Projects).
 
    .PARAMETER WorkRoot
        The worker's private working folder.
 
    .PARAMETER PlatformVersion
        Target platform version.
 
    .PARAMETER Country
        Localisation of the artifact this build targets.
 
    .OUTPUTS
        System.String - path to the prepared project folder (the one holding app.json).
    #>

    [CmdletBinding()]
    [OutputType([string])]
    param(
        [Parameter(Mandatory)] [ValidateNotNull()] [object] $Product,
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $WorkRoot,
        [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $PlatformVersion,
        [string] $Country = ''
    )

    $projects = @(Get-BcRuntimeProperty -InputObject $Product -Name 'Projects' -Default @())
    if ($projects.Count -eq 0) {
        throw "No project folder is configured for '$($Product.Name)', so it cannot be compiled for platform $PlatformVersion."
    }
    # One catalogue entry = one shipped app. Extra folders in a repo (tests, demo) are excluded by the
    # planner, so the first project is the app itself.
    $source = "$($projects[0])"
    if (-not (Test-Path -LiteralPath $source)) { throw "Project folder '$source' for '$($Product.Name)' does not exist." }

    # Short suffix on purpose: these paths already carry a BC version and an app id, and Windows
    # PowerShell 5.1 enforces MAX_PATH hard.
    $slot = if ($Country) { "$PlatformVersion-$($Country.ToLowerInvariant())" } else { $PlatformVersion }
    $build = Join-Path (Join-Path $WorkRoot 'build') "$slot-$($Product.AppId)"
    if (Test-Path -LiteralPath $build) { Remove-Item -LiteralPath $build -Recurse -Force }
    New-Item -ItemType Directory -Force -Path $build | Out-Null
    Copy-Item -LiteralPath $source -Destination $build -Recurse -Force
    $projectFolder = Join-Path $build (Split-Path -Leaf $source)

    $appJson = Join-Path $projectFolder 'app.json'
    if (-not (Test-Path -LiteralPath $appJson)) { throw "No app.json in '$projectFolder'." }

    # Stamp the RELEASED version, not the source's. The factory compiles from the product's master while
    # the version being shipped comes from the last CD build's artifact, and a runtime package requested
    # from a service tier is requested BY name and version - a mismatch means Get-NAVAppRuntimePackage
    # simply does not find the app that was just installed. The source engine does not ask a server, but
    # the version still has to be the released one: it is what the file is named after and what a customer
    # matches against.
    Set-BcAppVersion -Path $projectFolder -Version "$($Product.AppVersion)" | Out-Null

    $major = ([version](ConvertTo-BcVersion $PlatformVersion)).Major
    Update-BcAppManifest -Path $appJson -BcVersion $PlatformVersion -PreprocessorSymbols @('ONPREM', "BC$major") | Out-Null

    return $projectFolder
}