2021-02-10 23:26:48 +00:00
|
|
|
[CmdletBinding(SupportsShouldProcess)]param(
|
2021-03-23 05:06:49 +00:00
|
|
|
[ArgumentCompleter({Invoke-Command -ScriptBlock $_DockerComposeDirsCompleter -ArgumentList $args})]
|
2021-02-22 19:58:49 +00:00
|
|
|
[string[]]$ProjectPath,
|
2021-01-13 06:02:37 +00:00
|
|
|
[switch]$Recurse,
|
|
|
|
[int]$Depth=1,
|
|
|
|
[switch]$Force,
|
|
|
|
[switch]$OneLine,
|
2021-03-23 05:06:49 +00:00
|
|
|
[Parameter(Position = 0, mandatory, ValueFromRemainingArguments = $true)]
|
|
|
|
[ArgumentCompleter({Invoke-Command -ScriptBlock $_DockerComposeCompleter -ArgumentList $args})]
|
2021-01-13 06:02:37 +00:00
|
|
|
[array]$CliParams
|
|
|
|
)
|
|
|
|
|
2021-02-22 19:58:49 +00:00
|
|
|
if( -not $ProjectPath ) { $ProjectPath=@($PWD) }
|
|
|
|
|
2021-01-13 06:02:37 +00:00
|
|
|
$script:JobQueue = @()
|
|
|
|
$script:CleanupJobQueue = @()
|
2021-02-10 23:26:48 +00:00
|
|
|
function CompleteJobs {
|
2021-01-13 06:02:37 +00:00
|
|
|
if( -not $JobQueue ) { return }
|
|
|
|
$local:currentJobQueue = $JobQueue
|
|
|
|
$JobQueue = @()
|
2021-02-10 23:26:48 +00:00
|
|
|
$CleanupJobQueue += $currentJobQueue.Job
|
2021-01-13 06:02:37 +00:00
|
|
|
|
2021-02-10 23:26:48 +00:00
|
|
|
$local:sw = [System.Diagnostics.StopWatch]::StartNew()
|
|
|
|
$local:progress = [ordered]@{
|
|
|
|
Activity = "Waiting for docker-compose..."
|
|
|
|
ItemCount = $currentJobQueue.Count
|
|
|
|
}
|
|
|
|
|
|
|
|
while( $true ) {
|
|
|
|
$local:activeJobs = $($currentJobQueue | Where-Object Done -eq $false)
|
|
|
|
$progress.CurrentOperation = "Processing: $($activeJobs.Name -join ', ')..."
|
|
|
|
$progress.ItemProgress = $currentJobQueue.Count - $activeJobs.Count
|
|
|
|
$progress.Elapsed = $sw.Elapsed
|
|
|
|
Show-Progress @progress
|
|
|
|
$local:doneJobs = $activeJobs |
|
|
|
|
Select-Object -ExpandProperty Job |
|
|
|
|
Wait-Job -Any -Timeout 3
|
|
|
|
if( $doneJobs ) {
|
|
|
|
$doneJobs | ForEach-Object {
|
|
|
|
$_ | Receive-Job | ForEach-Object {
|
|
|
|
Write-Host "---: $($_.Path) | $($_.Params)" -ForegroundColor Cyan
|
|
|
|
$_.Results
|
|
|
|
foreach( $local:j in $currentJobQueue ) {
|
|
|
|
if( $j.Path -eq $_.Path ) {
|
|
|
|
$j.Done = $true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
2021-02-10 23:26:48 +00:00
|
|
|
if( -not $($currentJobQueue.Done -contains $false) ) { break }
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
|
|
|
Write-Host '--- Background jobs completed' -ForegroundColor Green
|
2021-02-10 23:26:48 +00:00
|
|
|
|
|
|
|
Show-Progress -Activity $progress.Activity -Completed
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if( $CliParams[0] -is [string] ) {
|
|
|
|
$CliParams = @($CliParams,@($null))
|
|
|
|
}
|
|
|
|
|
2021-02-20 18:09:38 +00:00
|
|
|
$local:ext = ".yml"
|
|
|
|
$local:dcPathList = @()
|
|
|
|
$ProjectPath | ForEach-Object {
|
|
|
|
while( $true ) {
|
|
|
|
if( (Test-Path (Join-Path $_ "docker-compose$ext")) -and -not $Recurse ) {
|
|
|
|
$dcPathList += Resolve-Path $_
|
|
|
|
} elseif( $Recurse ) {
|
|
|
|
$local:gciParams = [ordered]@{
|
|
|
|
Recurse = $true
|
|
|
|
}
|
|
|
|
if( $Depth ) {
|
|
|
|
$gciParams.Depth = $Depth
|
|
|
|
}
|
|
|
|
$dcPathList += Get-ChildItem -Path $_ -Include "docker-compose$ext" @gciParams |
|
|
|
|
Select-Object -ExpandProperty Directory |
|
|
|
|
Where-Object { $Force -or -not (Test-Path $(Join-Path $_ .noauto.all)) }
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
2021-02-20 18:09:38 +00:00
|
|
|
if( ($dcPathList -and -not $Recure) -or $ext -eq '.yaml' ) {
|
|
|
|
break
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
2021-02-20 18:09:38 +00:00
|
|
|
$ext = '.yaml'
|
2021-01-13 06:02:37 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if( -not $dcPathList ) { return }
|
2021-01-21 03:30:57 +00:00
|
|
|
|
|
|
|
$local:SingleProject = $dcPathList.Length -eq 1
|
2021-01-13 06:02:37 +00:00
|
|
|
|
|
|
|
foreach( $local:p in $CliParams ) {
|
|
|
|
if( -not $p ) { continue }
|
|
|
|
|
|
|
|
$local:AsJob = $false;
|
|
|
|
$local:Wait = $false;
|
|
|
|
|
2021-01-15 06:56:10 +00:00
|
|
|
if( $p -isnot [String] -or $p.Length -eq 1 ) {
|
2021-01-13 06:02:37 +00:00
|
|
|
$local:skipFirst = $true
|
|
|
|
switch( $p[0] ) {
|
2021-01-21 03:30:57 +00:00
|
|
|
'&' { $AsJob = -not $SingleProject }
|
|
|
|
'!' { $Wait = -not $SingleProject }
|
2021-01-13 06:02:37 +00:00
|
|
|
default { $skipFirst = $false }
|
|
|
|
}
|
|
|
|
if( $skipFirst ) { $p = $p | Select-Object -Skip 1 }
|
|
|
|
}
|
|
|
|
|
2021-01-15 06:56:10 +00:00
|
|
|
$local:dcParams=@()
|
2021-03-23 05:06:49 +00:00
|
|
|
$local:dcParams += $p | Where-Object { $_ } | ForEach-Object {
|
2021-01-13 06:02:37 +00:00
|
|
|
if( $_ -match "(?:^'[^']+'$)|(?:^`"[^`"]+`"$)|(?:^[^\s]+$)" ) { $_ }
|
|
|
|
else { "'$($_.Replace( "'", "''" ))'" }
|
|
|
|
}
|
|
|
|
|
|
|
|
$dcPathList | ForEach-Object {
|
2021-02-20 18:09:38 +00:00
|
|
|
$local:dcPath = Join-Path $_ 'docker-compose.yaml'
|
|
|
|
if( -not (Test-Path $dcPath) ) {
|
|
|
|
$dcPath = Join-Path $_ 'docker-compose.yml'
|
|
|
|
}
|
2021-02-10 23:26:48 +00:00
|
|
|
if( -not (Test-Path $dcPath) ) {
|
|
|
|
if( $Recurse ) { return }
|
|
|
|
else { throw "ERROR: dcPath ($dcPath) does not exists" }
|
|
|
|
}
|
2021-01-13 06:02:37 +00:00
|
|
|
|
2021-01-15 06:56:10 +00:00
|
|
|
if( $Wait ) {
|
|
|
|
if( $WhatIfPreference ) {
|
|
|
|
Write-Host -ForegroundColor DarkCyan "Wait for bg jobs to complete !"
|
|
|
|
} else {
|
2021-01-13 06:02:37 +00:00
|
|
|
CompleteJobs
|
2021-01-15 06:56:10 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-13 06:02:37 +00:00
|
|
|
|
2021-01-15 06:56:10 +00:00
|
|
|
if( -not $dcParams ) { continue }
|
2021-01-13 06:02:37 +00:00
|
|
|
|
2021-01-21 03:30:57 +00:00
|
|
|
$local:nextActionDescription = "In $dcPath Run $(if($AsJob){"(bg) "})with: $dcParams"
|
2021-01-15 06:56:10 +00:00
|
|
|
if( $WhatIfPreference ) {
|
2021-01-21 03:30:57 +00:00
|
|
|
Write-Host -ForegroundColor DarkYellow $nextActionDescription
|
2021-01-15 06:56:10 +00:00
|
|
|
} else {
|
2021-01-21 03:30:57 +00:00
|
|
|
Write-Verbose $nextActionDescription
|
2021-01-15 06:56:10 +00:00
|
|
|
|
|
|
|
if( $AsJob ) {
|
2021-02-10 23:26:48 +00:00
|
|
|
$JobQueue += ([PSCustomObject]([ordered]@{
|
|
|
|
Path = $dcPath
|
|
|
|
Name = Split-Path -Leaf $(Split-Path -Parent $dcPath)
|
|
|
|
Job = Start-Job -ArgumentList @($dcPath,$dcParams) -ScriptBlock {
|
|
|
|
param($dcPath,$dcParams)
|
|
|
|
[PSCustomObject] $([ordered]@{
|
|
|
|
Path = $dcPath
|
|
|
|
Params = $dcParams
|
|
|
|
Results = $(& docker-compose --file $dcPath $dcParams)
|
|
|
|
})}
|
|
|
|
Done = $false
|
|
|
|
}))
|
2021-01-13 06:02:37 +00:00
|
|
|
} else {
|
|
|
|
& docker-compose --file $dcPath $dcParams
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-01-15 06:56:10 +00:00
|
|
|
}
|
2021-01-13 06:02:37 +00:00
|
|
|
|
2021-01-15 06:15:54 +00:00
|
|
|
# if( $WhatIfPreference ) { return }
|
2021-01-13 06:02:37 +00:00
|
|
|
|
|
|
|
CompleteJobs
|
|
|
|
if( $CleanupJobQueue ) {
|
|
|
|
$CleanupJobQueue | Remove-Job
|
|
|
|
}
|