ScoopPlaybook.psm1
#Requires -Version 5.1 using namespace System.Collections.Generic [CmdletBinding()] param ( [ValidateSet("run", "check", "update_scoop")] [string]$Mode = "run" ) Set-StrictMode -Version Latest enum Keywords {name; scoop_install; scoop_uninstall; scoop_install_extras; } enum RunMode {check; run; update_scoop; } # setup $check = "" if ($Mode -eq [RunMode]::check) { Write-Host -ForeGroundColor Yellow "Run with $Mode mode" $check = [RunMode]::check.ToString() } $lineWidth = 83 function Prerequisites { [OutputType([bool])] param () # scoop status $pathExists = ($env:PATH -split ";") | Where-Object {$_ -match "scoop"} | Measure-Object if ($pathExists.Count -gt 0) { return $true } else { Write-Error "scoop not exists in PATH!!" return $false } # status scoop status if (!$?) { return $false } # check potential problem scoop checkup } function RunMain { [OutputType([int])] param( [string]$BaseYaml = "site.yml" ) if (!(Test-Path $BaseYaml)) { return 1 } $basePath = [System.IO.Path]::GetDirectoryName($BaseYaml) $definitions = Get-Content -LiteralPath $BaseYaml -Raw | ConvertFrom-Yaml if ($null -eq $definitions) { Write-Host "Nothing definied in $BaseYaml" return 1 } $playbookName = $definitions["name"] $roles = $definitions["roles"].ToArray() if ($null -eq $roles) { Write-Host "No roles definied in $BaseYaml" return 1 } # BaseYaml's role existstance check $marker = "*" * ($lineWidth - "PLAY [$playbookName]".Length) Write-Host "PLAY [$playbookName] $marker" Write-Output "" foreach ($item in $roles) { Write-Verbose "Checking role definition from [$basePath/roles/$item/tasks/]" $tasks = Get-ChildItem -LiteralPath "$basePath/roles/$item/tasks/" -Include *.yml -File if ($null -eq $tasks) { continue } # role's Task check and run foreach ($task in $tasks.FullName) { Write-Verbose "Read from [$task]" $taskDef = Get-Content -LiteralPath $task -Raw | ConvertFrom-Yaml # role foreach ($def in $taskDef) { $name = $def.name # task contains "scoop_install" check $containsInstall = $def.Contains([Keywords]::scoop_install.ToString()) # task contains "scoop_uninstall" check $containsUninstall = $def.Contains([Keywords]::scoop_uninstall.ToString()) # task contains "scoop_install_extras" check $containsExtraInstall = $def.Contains([Keywords]::scoop_install_extras.ToString()) if ($containsInstall) { $marker = "*" * ($lineWidth - "TASK [$item : $name]".Length) Write-Host "TASK [$item : $($name)] $marker" $tag = [Keywords]::scoop_install.ToString() ScoopInstall -TaskDef $def -Tag $tag } elseif ($containsUninstall) { $marker = "*" * ($lineWidth - "TASK [$item : $name]".Length) Write-Host "TASK [$item : $($name)] $marker" $tag = [Keywords]::scoop_uninstall.ToString() ScoopUninstall -TaskDef $def -Tag $tag } elseif ($containsExtraInstall) { $marker = "*" * ($lineWidth - "TASK [$item : $name]".Length) Write-Host "TASK [$item : $($name)] $marker" scoop bucket add extras $tag = [Keywords]::scoop_install_extras.ToString() ScoopInstall -TaskDef $def -Tag $tag } else { $marker = "*" * ($lineWidth - "skipped: TASK [$item : $name]".Length) Write-Host DarkCyan "skipped: TASK [$item : $($name)] $marker" continue } Write-Output "" } } } } function ScoopInstall { [OutputType([int])] param( [HashTable]$TaskDef, [string]$Tag ) $tools = $TaskDef[$Tag] if ($null -eq $tools) { return } foreach ($tool in $tools) { # blank definition if ([string]::IsNullOrWhiteSpace($tool)) { continue } if ($check -eq [RunMode]::check) { Write-Host "check: [${Tag}: $tool]" $output = scoop info $tool $installedLine = $output -match "Installed" if ($installedLine -match "No") { Write-Host -ForeGroundColor Yellow "$installedLine" } elseif ($installedLine -match "Yes") { Write-Host -ForeGroundColor DarkGray "$installedLine" } else { return 1 } } else { $output = scoop info $tool $installedLine = $output -match "Installed" if ($installedLine -match "No") { Write-Host "changed: [$([Keywords]::scoop_install): $tool]" scoop install $tool } else { Write-Host -ForeGroundColor Green "ok: [$([Keywords]::scoop_install): $tool]" scoop update $tool } } } } function ScoopUninstall { [OutputType([int])] param( [HashTable]$TaskDef, [string]$Tag ) $tools = $TaskDef[$Tag] if ($null -eq $tools) { return } foreach ($tool in $tools) { # blank definition if ([string]::IsNullOrWhiteSpace($tool)) { continue } if ($check -eq [RunMode]::check) { Write-Host "check: [${Tag}: $tool]" $output = scoop info $tool $installedLine = $output -match "Installed" if ($installedLine -match "Yes") { Write-Host -ForeGroundColor Yellow "$installedLine" } elseif ($installedLine -match "No") { Write-Host -ForeGroundColor DarkGray "$installedLine" } else { return 1 } } else { Write-Host -ForegroundColor Yellow "changed: [${Tag}: $tool]" scoop uninstall $tool } } } function Invoke-ScoopPlaybook { [CmdletBinding()] param( [Parameter(Mandatory = $false)] [Alias("FullName", "Path", "PSPath")] $LiteralPath = "./site.yml" ) # prerequisites if ($Mode -eq [RunMode]::update_scoop.ToString()) { scoop update } else { $ok = Prerequisites if (!$?) { return 1 } if (!$ok) { return 1 } # run RunMain -BaseYaml $LiteralPath } } Set-Alias -Name Scoop-Playbook -Value Invoke-ScoopPlaybook Export-ModuleMember -Function Invoke-ScoopPlaybook -Alias Scoop-Playbook |