Get-ALAppOrder.ps1
<#
.SYNOPSIS Sort apps into order in which must be compiled/installed to fullfill their dependencies .DESCRIPTION Sort apps into order in which must be compiled/installed to fullfill their dependencies .EXAMPLE PS C:\> Get-ALAppOrder -Path .\ Read all app.json from the subfolders and sort the app objects .Parameter ContainerName Name of the container to use to get info from .App file .Parameter Path Folder in which the app.json will be searched. If no app.json is found, all *.app packages will be used. .Parameter Recurse Will search for files recursively .Parameter AppCollection Array of app.json files you want to compile. .OUTPUTS Array of App objects having these members: name publisher version AppPath dependencies name publisher version #> function Get-ALAppOrder { [CMDLetBinding(DefaultParameterSetName="Path")] Param( [Parameter(ValueFromPipelineByPropertyName=$True)] $ContainerName, #Path to the repository [Parameter(ParameterSetName="Path")] $Path='.\', [switch]$Recurse, #Array of Files you want to use [Parameter(ValueFromPipelineByPropertyName=$True,ParameterSetName="Collection")] [Hashtable]$AppCollection ) function ConvertTo-ALAppsInfo { Param( $Files ) $result = @{}; foreach ($F in $Files) { $AppJson = Get-Content -Path $F.FullName | ConvertFrom-Json $AppJson | Add-Member -MemberType NoteProperty -Name "AppPath" -Value $F.FullName if (-not $result.ContainsKey($AppJson.name)) { $result.Add($AppJson.name,$AppJson) } } return $result } function Get-ALBuildOrder { Param( $Apps ) $AppsOrdered = @() $AppsToAdd = @{} $AppsCompiled = @{} do { foreach($App in $Apps.GetEnumerator()) { if (-not $AppsCompiled.ContainsKey($App.Value.name)) { #test if all dependencies are compiled $DependencyOk = $true foreach ($Dependency in $App.Value.dependencies) { if (-not $Apps.Contains($Dependency.name)) { $NewApp=New-Object -TypeName PSObject $NewApp | Add-Member -MemberType NoteProperty -Name 'name' -Value $Dependency.name $NewApp | Add-Member -MemberType NoteProperty -Name 'version' -Value $Dependency.version $NewApp | Add-Member -MemberType NoteProperty -Name 'publisher' -Value $Dependency.publisher $NewApp | Add-Member -MemberType NoteProperty -Name 'AppPath' -Value "" if (-not $AppsCompiled.ContainsKey($Dependency.name)) { $AppsCompiled.Add($Dependency.name,$NewApp) $AppsToAdd.Add($Dependency.name,$NewApp) $AppsOrdered += $NewApp } } if (-not $AppsCompiled.ContainsKey($Dependency.name)) { $DependencyOk = $false } } if ($DependencyOk) { $AppsOrdered += $App.Value if (-not $AppsCompiled.ContainsKey($App.Value.name)) { $AppsCompiled.Add($App.Value.name,$App.Value) } } } } foreach ($App in $AppsToAdd.GetEnumerator()) { if (-not $Apps.ContainsKey($App.Value.name)) { $Apps.Add($App.Value.name,$App.Value) } } $AppsToAdd =@{} } while ($Apps.Count -ne $AppsCompiled.Count) return $AppsOrdered } function Get-AppJsonFromApp { Param( $AppFile, $ContainerName ) $AppDeps = @() $AppInfo = Get-NavContainerAppInfoFile -AppPath $AppFile -ContainerName $ContainerName $AppJson = New-Object -TypeName PSObject $AppJson | Add-Member -MemberType NoteProperty -Name "name" -Value $AppInfo.Name $AppJson | Add-Member -MemberType NoteProperty -Name "publisher" -Value $AppInfo.Publisher $AppJson | Add-Member -MemberType NoteProperty -Name "version" -Value $AppInfo.Version foreach ($AppDep in $AppInfo.Dependencies) { $AppDepJson = New-Object -TypeName PSObject $AppDepJson | Add-Member -MemberType NoteProperty -Name "name" -Value $AppDep.Name $AppDepJson | Add-Member -MemberType NoteProperty -Name "publisher" -Value $AppDep.Publisher $AppDepJson | Add-Member -MemberType NoteProperty -Name "version" -Value $AppDep.MinVersion $AppDeps += $AppDepJson } $AppJson | Add-Member -MemberType NoteProperty -Name "dependencies" -Value $AppDeps $AppJson | Add-Member -MemberType NoteProperty -Name "AppPath" -Value $AppFile return $AppJson } if($AppCollection) { $Apps = $AppCollection } else { $AppConfigs = Get-ChildItem -Path $Path -Filter App.json -Recurse if ($AppConfigs) { $Apps = ConvertTo-ALAppsInfo -Files $AppConfigs } } if(-not $Apps) { $Apps = @{} $AppFiles = Get-ChildItem -Path $Path -Filter *.app -Recurse:$Recurse foreach ($AppFile in $AppFiles) { #$App = Get-NAVAppInfo -Path $AppFile.FullName $App = Get-AppJsonFromApp -AppFile $AppFile.FullName -ContainerName $ContainerName if ($App.publisher -ne 'Microsoft') { if (-not $Apps.ContainsKey($App.name)) { $Apps.Add($App.name,$App) } } } } $AppsOrdered = Get-ALBuildOrder -Apps $Apps Write-Output $AppsOrdered } |