class Packagesz { #: System.Management.Automation.IValidateSetValuesGenerator { static [hashtable]GetPackageDictionary() { $local:packages = @{} Get-ChildItem $global:MyPSScriptRoot | ForEach-Object { Join-Path $_.FullName "_.package.json" } | Where-Object { Test-Path $_ } | Get-Item | ForEach-Object { $local:testPkg = Get-Content $_ -Raw | ConvertFrom-Json | Select-Object -ExpandProperty "package" -ErrorAction SilentlyContinue if( $testPkg ) { $local:k = $_.Directory.FullName.Replace($MyPSScriptRoot,'') -replace '^/','' $packages[$k] = $testPkg } } return $packages; } static [bool] ValidatePackageConditions($Package) { if( -not $Package.Condition ) { return $true } $local:valid = $Package.Condition[0].Logic -notin ([szLogic]::or, [szLogic]::ornot) $local:currentSys = [SystemName]::_GetValidValues('',$true,$true); $local:hostname = $(hostname) $local:username = $env:USER ?? $env:USERNAME foreach( $local:c in $Package.Condition ) { if( $valid -eq ($c.Logic -in ([szLogic]::or, [szLogic]::ornot )) ) { continue } $local:v = $true; if( $v -and $c.System ) { $v = $v -and $($c.System | Where-Object { $currentSys -contains $_ }) } if( $v -and $c.Hostname ) { $v = $v -and $($c.Hostname | Where-Object { $hostname -match $_ }) } if( $v -and $c.Username ) { $v = $v -and $($c.Username | Where-Object { $username -match $_ }) } if( $v -and $c.custom ) { $v = $v -and ([bool]$(Invoke-ScriptBlock ([ScriptBlock]::Create($c.custom)))) } switch( $c.Logic ) { [szLogic]::not { $valid = $valid -and -not $v } [szLogic]::or { $valid = $valid -or $v } [szLogic]::ornot { $valid = $valid -or -not $v } default { $valid = $valid -and $v } } } return $valid } static [string[]] _GetValidValues([string]$wordToComplete,[bool]$CurrentOnly,[bool]$Strict) { $local:pkgz = [Packagesz]::GetPackageDictionary() $local:possibleValues = $pkgz.Keys | Where-Object { -not $CurrentOnly -or $( [Packagesz]::ValidatePackageConditions($pkgz[$_]) ) } return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict ); } [String[]] GetValidValues() { return [Packagesz]::_GetValidValues('',$false,$true) } } enum szLogic { and = 0 not = 1 # nand or = 2 ornot = 3 } class szCondition { [ScriptBlock]$custom = { $true } [string[]]$System = $null [string[]]$Hostname = $null [string[]]$Username = $null [szLogic]$Logic = [szLogic]::and [string] ToString() { return "Logic = $($this.Logic); System = $($this.System); Hostname = $($this.Hostname); Username = $($this.Username); Custom = { $($this.Custom.ToString().Trim()) }" } } class szPackage { [string]$Name [szCondition[]]$Condition static [szPackage]Create($Name) { $local:newPkg = New-Object -Type 'szPackage' $newPkg.Name = $Name $newPkg.Condition = @() return $newPkg } }