Skip to content

Commit

Permalink
Nuget (microsoft#3283)
Browse files Browse the repository at this point in the history
Compare normalized version numbers when locating nuget packages (ADO
turns 4.4.3.0 into 4.4.3 when getting version numbers and a normal
compare between 4.4.3 and 4.4.3.0 is not equal)

Runtime packages can contain multiple localized versions of the runtime
package.
When installing or downloading nuget packages - grab the country
subfolder (if it exists), else revert to the original version

---------

Co-authored-by: freddydk <[email protected]>
  • Loading branch information
freddydk and freddydk authored Jan 2, 2024
1 parent e932669 commit 4e8cc51
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 91 deletions.
31 changes: 0 additions & 31 deletions AppHandling/Run-AlValidation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -176,37 +176,6 @@ Write-Host -ForegroundColor Yellow @'
$artifactUrl
}

function GetApplicationDependency( [string] $appFile, [string] $minVersion = "0.0" ) {
$tmpFolder = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString())
try {
Extract-AppFileToFolder -appFilename $appFile -appFolder $tmpFolder -generateAppJson
$appJsonFile = Join-Path $tmpFolder "app.json"
$appJson = [System.IO.File]::ReadAllLines($appJsonFile) | ConvertFrom-Json
}
catch {
Write-Host -ForegroundColor Red "Cannot unpack app $([System.IO.Path]::GetFileName($appFile)), it might be a runtime package, ignoring application dependency check"
return $minVersion
}
finally {
if (Test-Path $tmpFolder) {
Remove-Item $tmpFolder -Recurse -Force
}
}
if ($appJson.PSObject.Properties.Name -eq "Application") {
$version = $appJson.application
}
else {
$version = $appJson.dependencies | Where-Object { $_.Name -eq "Base Application" -and $_.Publisher -eq "Microsoft" } | ForEach-Object { $_.Version }
if (!$version) {
$version = $minVersion
}
}
if ([System.Version]$version -lt [System.Version]$minVersion) {
$version = $minVersion
}
$version
}

function GetFilePath( [string] $path ) {
if ($path -like "http://*" -or $path -like "https://*") {
return $path
Expand Down
13 changes: 2 additions & 11 deletions AppSource/New-AppSourceSubmission.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,8 @@ try {

$appVersionNumber = ""
if ($appFile) {
try {
$tempFolder = Join-Path ([System.IO.Path]::GetTempPath()) ([Guid]::NewGuid().ToString())
Extract-AppFileToFolder -appFilename $appFile -appFolder $tempFolder -generateAppJson
$appJsonFile = Join-Path $tempFolder 'app.json'
$appJson = Get-Content $appJsonFile -Encoding UTF8 | ConvertFrom-Json
Remove-Item $tempFolder -Recurse -Force
$appVersionNumber = [System.Version]$appJson.version
}
catch {
throw "Unable to extract app file and determine version number"
}
$appJson = GetAppJsonFromAppFile -appFile $appFile
$appVersionNumber = [System.Version]$appJson.version
}

$tempFolder = ""
Expand Down
30 changes: 27 additions & 3 deletions HelperFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1332,12 +1332,36 @@ function GetAppJsonFromAppFile {
)
# ALTOOL is at the moment only available in prerelease
$path = DownloadLatestAlLanguageExtension -allowPrerelease
if ($isWindows) {
$alToolExe = Join-Path $path 'extension/bin/win32/altool.exe'
if ($isLinux) {
$alToolExe = Join-Path $path 'extension/bin/linux/altool'
}
else {
$alToolExe = Join-Path $path 'extension/bin/linux/altool'
$alToolExe = Join-Path $path 'extension/bin/win32/altool.exe'
}
$appJson = CmdDo -Command $alToolExe -arguments @('GetPackageManifest', """$appFile""") -returnValue -silent | ConvertFrom-Json
return $appJson
}

function GetApplicationDependency( [string] $appFile, [string] $minVersion = "0.0" ) {
try {
$appJson = GetAppJsonFromAppFile -appFile $appFile
}
catch {
Write-Host -ForegroundColor Red "Unable to read app $([System.IO.Path]::GetFileName($appFile)), ignoring application dependency check"
return $minVersion
}
$version = $minVersion
if ($appJson.PSObject.Properties.Name -eq "Application") {
$version = $appJson.application
}
elseif ($appJson.PSObject.Properties.Name -eq "dependencies") {
$baseAppDependency = $appJson.dependencies | Where-Object { $_.Name -eq "Base Application" -and $_.Publisher -eq "Microsoft" }
if ($baseAppDependency) {
$version = $baseAppDependency.Version
}
}
if ([System.Version]$version -lt [System.Version]$minVersion) {
$version = $minVersion
}
return $version
}
97 changes: 66 additions & 31 deletions NuGet/Download-BcNuGetPackageToFolder.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
.PARAMETER installedPlatform
Version of the installed platform
.PARAMETER installedCountry
Country of the installed application
Country of the installed application. installedCountry is used to determine if the NuGet package is compatible with the installed application localization
.PARAMETER installedApps
List of installed apps
Format is an array of PSCustomObjects with properties Name, Publisher, id and Version
Expand Down Expand Up @@ -67,14 +67,15 @@ Function Download-BcNuGetPackageToFolder {
[Parameter(Mandatory=$false)]
[System.Version] $installedPlatform,
[Parameter(Mandatory=$false)]
[string] $installedCountry,
[string] $installedCountry = '',
[Parameter(Mandatory=$false)]
[PSCustomObject[]] $installedApps = @(),
[ValidateSet('all','own','allButMicrosoft','allButApplication','allButPlatform','none')]
[string] $downloadDependencies = 'allButApplication',
[switch] $allowPrerelease
)

$returnValue = $false
$findSelect = $select
if ($select -eq 'LatestMatching') {
$findSelect = 'Latest'
Expand All @@ -98,8 +99,10 @@ Function Download-BcNuGetPackageToFolder {
foreach($dependency in $manifest.package.metadata.dependencies.GetEnumerator()) {
$dependencyVersion = $dependency.Version
$dependencyId = $dependency.Id
$dependencyCountry = ''
$downloadIt = $false
if ($dependencyId -eq 'Microsoft.Platform') {
$dependencyPublisher = 'Microsoft'
# Dependency is to the platform
if ($installedPlatform) {
if (!([NuGetFeed]::IsVersionIncludedInRange($installedPlatform, $dependencyVersion))) {
Expand All @@ -117,9 +120,10 @@ Function Download-BcNuGetPackageToFolder {
if ($matches.Count -gt 2) {
$dependencyCountry = $matches[2].TrimStart('.')
}
else {
$dependencyCountry = ''
}
if ($installedCountry -and $dependencyCountry -and ($installedCountry -ne $dependencyCountry)) {
# The NuGet package found isn't compatible with the installed application
Write-Host "WARNING: NuGet package $packageId (version $packageVersion) requires $dependencyCountry application. You have $installedCountry application installed"
}
$installedApp = $installedApps | Where-Object { $_ -and $_.Name -eq 'Application' }
if ($installedApp) {
if (!([NuGetFeed]::IsVersionIncludedInRange($installedApp.Version, $dependencyVersion))) {
Expand All @@ -131,6 +135,14 @@ Function Download-BcNuGetPackageToFolder {
}
}
else {
$dependencyPublisher = ''
if ($dependencyId -match '^([^\.]+)\.([^\.]+)\.([^\.]+\.)?([0-9A-Fa-f]{8}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{12})$') {
# Matches publisher.name.[country.].appId format (country section is only for microsoft apps)
$dependencyPublisher = $matches[1]
if ($dependencyPublisher -eq 'microsoft' -and $matches.Count -gt 3) {
$dependencyCountry = $matches[3].TrimEnd('.')
}
}
$installedApp = $installedApps | Where-Object { $_ -and $_.id -and $dependencyId -like "*$($_.id)*" }
if ($installedApp) {
# Dependency is already installed, check version number
Expand All @@ -139,29 +151,15 @@ Function Download-BcNuGetPackageToFolder {
$dependenciesErr = "Dependency $dependencyId is already installed with version $($installedApp.Version), which is not compatible with the version $dependencyVersion required by the NuGet package $packageId (version $packageVersion))"
}
}
elseif ($downloadDependencies -eq 'all' -or $downloadDependencies -eq 'none' -or $downloadDependencies -eq 'allButPlatform' -or $downloadDependencies -eq 'allButMicrosoft' -or $downloadDependencies -eq 'allButApplication') {
$downloadIt = ($downloadDependencies -ne 'none')
elseif ($downloadDependencies -eq 'own') {
$downloadIt = ($dependencyPublisher -eq $manifest.package.authors)
}
elseif ($downloadDependencies -eq 'allButMicrosoft') {
# Download if publisher isn't Microsoft (including if publisher is empty)
$downloadIt = ($dependencyPublisher -ne 'Microsoft')
}
else {
# downloadDependencies is own or allButMicrosoft
# check publisher and name
if ($dependencyId -match '^(.*[^\.])\.(.*[^\.])\.("[0-9A-F]{8}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{4}\-[0-9A-F]{12}")$') {
# Matches publisher.name.appId format
$dependencyPublisher = $matches[1]
$dependencyName = $matches[2]
$dependencyAppId = $matches[3]
if ($downloadDependencies -eq 'allButMicrosoft') {
$downloadIt = ($dependencyPublisher -ne 'Microsoft')
}
else {
$downloadIt = ($dependencyPublisher -eq $manifest.package.authors)
}
}
else {
# Could not match publisher.name.appId format
# All microsoft references should resolve - download it if we want allButMicrosoft
$downloadIt = ($downloadDependencies -eq 'allButMicrosoft')
}
$downloadIt = ($downloadDependencies -ne 'none')
}
}
if ($dependenciesErr) {
Expand All @@ -175,11 +173,36 @@ Function Download-BcNuGetPackageToFolder {
}
}
if ($downloadIt) {
$checkPackageName = ''
if ($dependencyId -match '^.*([0-9A-Fa-f]{8}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{4}\-[0-9A-Fa-f]{12})$') {
# If dependencyId ends in a GUID (AppID) then use the AppId for downloading dependencies
$dependencyId = $matches[1]
if ($dependencyCountry) {
# Dependency is to a specific country version - must find the country version of the dependency
$dependencyId = "$dependencyCountry.$dependencyId"
}
elseif ($installedCountry -and $dependencyPublisher -eq 'Microsoft') {
# Looking for a Microsoft package - check if it exists for the installed country (revert to appId if not)
$checkPackageName = "$installedCountry.$dependencyId"
}
}
elseif (($dependencyId -match '^Microsoft.Application(\.[^\.]+)?$') -and ($matches.Count -eq 1)) {
# If dependency is to the Application without a specific country, then check if a localization version of the application exists for the installed country
$checkPackageName = "Microsoft.Application.$installedCountry"
}
if ($checkPackageName) {
Write-Host -ForegroundColor Yellow $checkPackageName
if (Download-BcNuGetPackageToFolder -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -packageName $checkPackageName -version $dependencyVersion -folder $package -copyInstalledAppsToFolder $copyInstalledAppsToFolder -installedPlatform $installedPlatform -installedCountry $installedCountry -installedApps $installedApps -downloadDependencies $downloadDependencies -verbose:($VerbosePreference -eq 'Continue') -select $select -allowPrerelease:$allowPrerelease) {
$returnValue = $true
$downloadIt = $false
}
}
if ($downloadIt) {
Write-Host -ForegroundColor Yellow $dependencyId
if (Download-BcNuGetPackageToFolder -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -packageName $dependencyId -version $dependencyVersion -folder $package -copyInstalledAppsToFolder $copyInstalledAppsToFolder -installedPlatform $installedPlatform -installedCountry $installedCountry -installedApps $installedApps -downloadDependencies $downloadDependencies -verbose:($VerbosePreference -eq 'Continue') -select $select -allowPrerelease:$allowPrerelease) {
$returnValue = $true
}
}
Download-BcNuGetPackageToFolder -nuGetServerUrl $nuGetServerUrl -nuGetToken $nuGetToken -packageName $dependencyId -version $dependencyVersion -folder $package -installedApps $installedApps -downloadDependencies $downloadDependencies -verbose:($VerbosePreference -eq 'Continue') -select $select
}
}
if ($dependenciesErr) {
Expand All @@ -188,17 +211,29 @@ Function Download-BcNuGetPackageToFolder {
Remove-Item -Path $package -Recurse -Force
continue
}
$appFiles = (Get-Item -Path (Join-Path $package '*.app')).FullName
$appFiles | ForEach-Object {
Copy-Item $_ -Destination $folder -Force
if (Test-Path (Join-Path $package $installedCountry) -PathType Container) {
# NuGet packages of Runtime packages might exist in different versions for different countries
# The runtime package might contain C# invoke calls with different methodis for different countries
# if the installedCountry doesn't have a special version, then the w1 version is used (= empty string)
# If the package contains a country specific folder, then use that
Write-Host "Using country specific folder $installedCountry"
$appFiles = Get-Item -Path (Join-Path $package "$installedCountry/*.app")
}
else {
$appFiles = Get-Item -Path (Join-Path $package "*.app")
}
foreach($appFile in $appFiles) {
$returnValue = $true
Copy-Item $appFile.FullName -Destination $folder -Force
if ($copyInstalledAppsToFolder) {
Copy-Item $_ -Destination $copyInstalledAppsToFolder -Force
Copy-Item $appFile.FullName -Destination $copyInstalledAppsToFolder -Force
}
}
Remove-Item -Path $package -Recurse -Force
break
}
}
return $returnValue
}
Set-Alias -Name Copy-BcNuGetPackageToFolder -Value Download-BcNuGetPackageToFolder
Export-ModuleMember -Function Download-BcNuGetPackageToFolder -Alias Copy-BcNuGetPackageToFolder
2 changes: 1 addition & 1 deletion NuGet/Find-BcNuGetPackage.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Function Find-BcNuGetPackage {
}
elseif ($select -eq 'Exact') {
# We only have a match if the version is exact
if ($packageVersion -eq $version) {
if ([NuGetFeed]::NormalizeVersionStr($packageVersion) -eq [NuGetFeed]::NormalizeVersionStr($version)) {
$bestmatch = [PSCustomObject]@{
"Feed" = $nuGetFeed
"PackageId" = $packageId
Expand Down
Loading

0 comments on commit 4e8cc51

Please sign in to comment.