aboutsummaryrefslogtreecommitdiffstats
path: root/run_tcp.ps1
diff options
context:
space:
mode:
authorMarcos Magueta <maguetamarcos@gmail.com>2026-04-27 23:24:19 -0300
committerGitHub <noreply@github.com>2026-04-27 23:24:19 -0300
commit97960adb8426e5270fe16b027e82a2c61674f821 (patch)
tree03da5611898c06cd3868d4384ef4259005a29b69 /run_tcp.ps1
parent56492ad5f6f09d8c9f337d42803b64d1b9f0668b (diff)
downloadSakura-97960adb8426e5270fe16b027e82a2c61674f821.tar.gz
Sakura-97960adb8426e5270fe16b027e82a2c61674f821.zip
Foreign call PRL (#67)
Diffstat (limited to 'run_tcp.ps1')
-rw-r--r--run_tcp.ps1175
1 files changed, 175 insertions, 0 deletions
diff --git a/run_tcp.ps1 b/run_tcp.ps1
new file mode 100644
index 0000000..175fc26
--- /dev/null
+++ b/run_tcp.ps1
@@ -0,0 +1,175 @@
+param(
+ [string]$ConfigPath = ".\config.sexp",
+ [string]$ServerHost = "127.0.0.1",
+ [int]$Port = 7777,
+ [string[]]$Command,
+ [string]$CommandsPath,
+ [switch]$UseExistingServer,
+ [switch]$UseLocalServer,
+ [switch]$SkipBuild,
+ [switch]$NoInteractive
+)
+
+$ErrorActionPreference = "Stop"
+
+function Invoke-Build {
+ Write-Host "Building Sakura..."
+ dune build
+ if (-not $?) {
+ throw "Build failed."
+ }
+}
+
+function Start-SakuraServer {
+ param(
+ [string]$Config,
+ [string]$WorkingDirectory,
+ [switch]$UseOpam
+ )
+
+ Write-Host "Starting Sakura server with config $Config ..."
+ $filePath = "dune"
+ $serverArgs = @("exec", "sakura-server", "--", $Config)
+ if ($UseOpam) {
+ $filePath = "opam"
+ $serverArgs = @("exec", "--", "sakura-server", $Config)
+ }
+
+ $proc = Start-Process -FilePath $filePath `
+ -ArgumentList $serverArgs `
+ -WorkingDirectory $WorkingDirectory `
+ -PassThru
+
+ return $proc
+}
+
+function Wait-ForTcp {
+ param(
+ [string]$TargetHost,
+ [int]$TargetPort,
+ [int]$TimeoutSeconds = 20
+ )
+
+ $deadline = (Get-Date).AddSeconds($TimeoutSeconds)
+ while ((Get-Date) -lt $deadline) {
+ $client = $null
+ try {
+ $client = [System.Net.Sockets.TcpClient]::new()
+ $async = $client.BeginConnect($TargetHost, $TargetPort, $null, $null)
+ if ($async.AsyncWaitHandle.WaitOne(250)) {
+ $client.EndConnect($async)
+ $client.Close()
+ return
+ }
+ $client.Close()
+ } catch {
+ if ($null -ne $client) {
+ $client.Close()
+ }
+ Start-Sleep -Milliseconds 250
+ }
+ }
+
+ throw "Timed out waiting for TCP server at $TargetHost`:$TargetPort"
+}
+
+function Connect-Tcp {
+ param(
+ [string]$TargetHost,
+ [int]$TargetPort
+ )
+
+ $client = [System.Net.Sockets.TcpClient]::new($TargetHost, $TargetPort)
+ $stream = $client.GetStream()
+ $writer = [System.IO.StreamWriter]::new($stream)
+ $writer.AutoFlush = $true
+ $reader = [System.IO.StreamReader]::new($stream)
+
+ return @{
+ Client = $client
+ Writer = $writer
+ Reader = $reader
+ }
+}
+
+function Send-Command {
+ param(
+ [System.IO.StreamWriter]$Writer,
+ [System.IO.StreamReader]$Reader,
+ [string]$Line
+ )
+
+ $Writer.WriteLine($Line)
+ $response = $Reader.ReadLine()
+ if ($null -eq $response) {
+ throw "Connection closed by server."
+ }
+
+ Write-Host "< $response"
+}
+
+$repoRoot = $PSScriptRoot
+$serverProcess = $null
+
+try {
+ if (-not $SkipBuild) {
+ Invoke-Build
+ }
+
+ if (-not $UseExistingServer) {
+ if ($UseLocalServer) {
+ Write-Host "Server mode: local dune exec sakura-server"
+ } else {
+ Write-Host "Server mode: opam-installed sakura-server"
+ }
+ $serverProcess = Start-SakuraServer -Config $ConfigPath -WorkingDirectory $repoRoot -UseOpam:(-not $UseLocalServer)
+ Wait-ForTcp -TargetHost $ServerHost -TargetPort $Port
+ Write-Host "Server is ready on $ServerHost`:$Port"
+ }
+
+ $conn = Connect-Tcp -TargetHost $ServerHost -TargetPort $Port
+ $writer = $conn.Writer
+ $reader = $conn.Reader
+
+ $commandsToSend = @()
+ if ($null -ne $Command -and $Command.Count -gt 0) {
+ $commandsToSend += $Command
+ }
+ if (-not [string]::IsNullOrWhiteSpace($CommandsPath)) {
+ $fileCommands = Get-Content -Path $CommandsPath |
+ Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
+ $commandsToSend += $fileCommands
+ }
+
+ if ($commandsToSend.Count -gt 0) {
+ foreach ($cmd in $commandsToSend) {
+ Write-Host "> $cmd"
+ Send-Command -Writer $writer -Reader $reader -Line $cmd
+ }
+ }
+
+ if (-not $NoInteractive) {
+ Write-Host "Interactive mode. Type :quit to exit."
+ while ($true) {
+ $line = Read-Host ">"
+ if ($line -eq ":quit") {
+ break
+ }
+ if ([string]::IsNullOrWhiteSpace($line)) {
+ continue
+ }
+
+ Send-Command -Writer $writer -Reader $reader -Line $line
+ }
+ }
+
+ $writer.Dispose()
+ $reader.Dispose()
+ $conn.Client.Close()
+}
+finally {
+ if ($null -ne $serverProcess -and -not $serverProcess.HasExited) {
+ Write-Host "Stopping Sakura server (PID $($serverProcess.Id))"
+ Stop-Process -Id $serverProcess.Id -Force
+ }
+}