NuGet/New-BcNuGetPackage.ps1
<#
.Synopsis POC PREVIEW: Create a new Business Central NuGet Package .Description Create a new NuGet package containing one or more Business Central apps .Parameter useRuntimePackages Include this switch to .Parameter appfiles .Parameter dependencyAppFiles .Parameter testAppFiles .Parameter packageId .Parameter packageVersion .Parameter packageTitle .Parameter packageDescription .Parameter packageAuthors .Parameter githubRepository .Parameter includeNuGetDependencies .Parameter dependencyIdTemplate .Example todo #> Function New-BcNuGetPackage { Param( [switch] $useRuntimePackages, [Parameter(Mandatory=$true)] [string[]] $appfiles, [string[]] $dependencyAppFiles = @(), [string[]] $testAppFiles = @(), [string] $packageId = "", [System.Version] $packageVersion = $null, [string] $packageTitle = "", [string] $packageDescription = "", [string] $packageAuthors = "", [string] $githubRepository = "", [switch] $includeNuGetDependencies, [string] $dependencyIdTemplate = '{id}' ) if ($useRuntimePackages) { throw "Runtime packages not yet supported" } $ok = $true $appFiles | Out-Host $dependencyAppFiles | Out-Host $testAppFiles | Out-Host $appFiles,$dependencyAppFiles,$testAppFiles | Where-Object { $_ } | ForEach-Object { if (-not (Test-Path $_)) { Write-Host -foregroundColor Red "Unable to locate file: $_" $ok = $false } } if (!$ok) { throw "Error Creating NuGet Package" } if ($appfiles.Count -eq 0) { throw "You need to specify at least one appfile" } elseif ($appfiles.Count -gt 1) { if ($packageId -eq "" -or $packageVersion -eq $null -or $packageTitle -eq "" -or $packageAuthors -eq "") { throw "When specifying multiple files, you need to specify packageId, packageVersion, packageTitle and packageAuthors" } if ($includeNuGetDependencies) { throw "includeNuGetDependencies is only supported when creating a NuGet package for a single app" } } $appFile = $appfiles | Select-Object -First 1 $tmpFolder = Join-Path $ENV:TEMP ([GUID]::NewGuid().ToString()) Extract-AppFileToFolder -appFilename $appFile -generateAppJson -appFolder $tmpFolder $appJsonFile = Join-Path $tmpFolder 'app.json' $appJson = Get-Content $appJsonFile -Encoding UTF8 | ConvertFrom-Json Remove-Item $tmpFolder -Recurse -Force $testsFolderName = "Tests" $dependenciesFolderName = "Dependencies" $rootFolder = Join-Path $ENV:TEMP ([GUID]::NewGuid().ToString()) New-Item -Path $rootFolder -ItemType Directory | Out-Null try { $testsFolder = Join-Path $rootFolder $testsFolderName New-Item -Path $testsFolder -ItemType Directory | Out-Null $dependenciesFolder = Join-Path $rootFolder $dependenciesFolderName New-Item -Path $dependenciesFolder -ItemType Directory | Out-Null $appfiles | ForEach-Object { Copy-Item -Path $_ -Destination $rootFolder -Force } $testAppfiles | ForEach-Object { Copy-Item -Path $_ -Destination $testsFolder -Force } $dependencyAppfiles | ForEach-Object { Copy-Item -Path $_ -Destination $dependenciesFolder -Force } if ($packageId) { $packageId = $packageId.replace('{id}',$appJson.id).replace('{name}',$appJson.name).replace('{publisher}',$appJson.publisher) } else { $packageId = $appJson.id } if ($packageVersion -eq $null) { $packageVersion = [System.Version]$appJson.version } if (-not $packageTitle) { $packageTitle = $appJson.name } if (-not $packageDescription) { $packageDescription = $appJson.description if (-not $packageDescription) { $packageDescription = $packageTitle } } if (-not $packageAuthors) { $packageAuthors = $appJson.publisher } $nuspecFileName = Join-Path $rootFolder "manifest.nuspec" $xmlObjectsettings = New-Object System.Xml.XmlWriterSettings $xmlObjectsettings.Indent = $true $xmlObjectsettings.IndentChars = " " $xmlObjectsettings.Encoding = [System.Text.Encoding]::UTF8 $XmlObjectWriter = [System.XML.XmlWriter]::Create($nuspecFileName, $xmlObjectsettings) $XmlObjectWriter.WriteStartDocument() $XmlObjectWriter.WriteStartElement("package", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd") $XmlObjectWriter.WriteStartElement("metadata") $XmlObjectWriter.WriteElementString("id", $packageId) $XmlObjectWriter.WriteElementString("version", $packageVersion.ToString()) $XmlObjectWriter.WriteElementString("title", $packageTitle) $XmlObjectWriter.WriteElementString("description", $packageDescription) $XmlObjectWriter.WriteElementString("authors", $packageAuthors) if ($githubRepository) { $XmlObjectWriter.WriteStartElement("repository") $XmlObjectWriter.WriteAttributeString("type", "git"); $XmlObjectWriter.WriteAttributeString("url", $githubRepository); $XmlObjectWriter.WriteEndElement() } if ($includeNuGetDependencies) { $XmlObjectWriter.WriteStartElement("dependencies") $appJson.dependencies | ForEach-Object { $XmlObjectWriter.WriteStartElement("dependency") $XmlObjectWriter.WriteAttributeString("id", $dependencyIdTemplate.replace('{id}',$_.id)) $XmlObjectWriter.WriteAttributeString("version", $_.Version); $XmlObjectWriter.WriteEndElement() } $XmlObjectWriter.WriteEndElement() } $XmlObjectWriter.WriteEndElement() $XmlObjectWriter.WriteStartElement("files") $appFiles | ForEach-Object { $XmlObjectWriter.WriteStartElement("file") $appFileName = [System.IO.Path]::GetFileName($_) $XmlObjectWriter.WriteAttributeString("src", $appFileName ); $XmlObjectWriter.WriteAttributeString("target", $appFileName); $XmlObjectWriter.WriteEndElement() } $testAppFiles | ForEach-Object { $XmlObjectWriter.WriteStartElement("file") $appFileName = [System.IO.Path]::GetFileName($_) $XmlObjectWriter.WriteAttributeString("src", "$testsFolderName\$appFileName" ); $XmlObjectWriter.WriteAttributeString("target", "$testsFolderName\$appFileName" ); $XmlObjectWriter.WriteEndElement() } $dependencyAppFiles | ForEach-Object { $XmlObjectWriter.WriteStartElement("file") $appFileName = [System.IO.Path]::GetFileName($_) $XmlObjectWriter.WriteAttributeString("src", "$dependenciesFolderName\$appFileName" ); $XmlObjectWriter.WriteAttributeString("target", "$dependenciesFolderName\$appFileName" ); $XmlObjectWriter.WriteEndElement() } $XmlObjectWriter.WriteEndElement() $XmlObjectWriter.WriteEndElement() $XmlObjectWriter.WriteEndDocument() $XmlObjectWriter.Flush() $XmlObjectWriter.Close() $nuPkgFileName = "$($packageId)-$($packageVersion).nupkg" $nupkgFile = Join-Path $ENV:TEMP $nuPkgFileName if (Test-Path $nuPkgFile -PathType Leaf) { Remove-Item $nupkgFile -Force } Compress-Archive -Path "$rootFolder\*" -DestinationPath "$nupkgFile.zip" -Force Rename-Item -Path "$nupkgFile.zip" -NewName $nuPkgFileName $size = (Get-Item $nupkgFile).Length if ($size -gt 1MB) { $sizeStr = "$([int]($size/1MB))Mb" } elseif ($size -gt 1KB) { $sizeStr = "$([int]($size/1KB))Kb" } else { $sizeStr = "$size bytes" } Write-Host -ForegroundColor Green "Successfully created NuGet package (Size: $sizeStr)" $nupkgFile } finally { Remove-Item -Path $rootFolder -Recurse -Force -ErrorAction SilentlyContinue } } Export-ModuleMember -Function New-BcNuGetPackage |