@@ -7,6 +7,7 @@ Author: Emilio J. Gallego Arias
77import Lean
88import Beam.Broker.Client
99import Beam.Broker.Transport
10+ import RunAt.Lib.NativeLib
1011import RunAt.Protocol
1112import Std.Internal.UV.Signal
1213
@@ -213,10 +214,25 @@ private def readCmdTrim (cmd : String) (args : Array String := #[]) (cwd? : Opti
213214 throw <| IO.userError s! "command failed: { cmd} { String.intercalate " " args.toList} \n { out.stderr} "
214215 pure <| trimLine out.stdout
215216
216- private def commandAvailable (cmd : String) : IO Bool := do
217+ private def commandAvailable (cmd : String) (args : Array String := #[ "--help" ]) : IO Bool := do
217218 try
218- let out ← IO.Process.output { cmd := "sh" , args := #["-c" , s! "command -v { shellQuote cmd} >/dev/null 2>&1" ] }
219- pure (out.exitCode == 0 )
219+ let child ← IO.Process.spawn {
220+ cmd := cmd
221+ args := args
222+ stdin := .null
223+ stdout := .null
224+ stderr := .null
225+ }
226+ if (← child.tryWait).isNone then
227+ try
228+ child.kill
229+ catch _ =>
230+ pure ()
231+ try
232+ discard <| child.wait
233+ catch _ =>
234+ pure ()
235+ pure true
220236 catch _ =>
221237 pure false
222238
@@ -236,10 +252,10 @@ private def runAtHome : IO System.FilePath := do
236252private def defaultBundlePaths (home : System.FilePath) : IO BundlePaths := do
237253 let installedDaemon := home / "libexec" / "beam-daemon"
238254 let installedClient := home / "libexec" / "beam-client"
239- let installedPlugin := home / "libexec" / "librunAt_RunAt.so"
255+ let installedPlugin := RunAt.Lib.pluginSharedLibPath ( home / "libexec" )
240256 let checkoutDaemon := home / ".lake" / "build" / "bin" / "beam-daemon"
241257 let checkoutClient := home / ".lake" / "build" / "bin" / "beam-client"
242- let checkoutPlugin := home / ".lake" / "build" / "lib" / "librunAt_RunAt.so"
258+ let checkoutPlugin := RunAt.Lib.pluginSharedLibPath ( home / ".lake" / "build" / "lib" )
243259 let installedReady :=
244260 (← installedDaemon.pathExists) &&
245261 (← installedClient.pathExists) &&
@@ -371,7 +387,7 @@ private def bundlePathsFor (workspace : System.FilePath) : BundlePaths :=
371387 {
372388 daemon := workspace / ".lake" / "build" / "bin" / "beam-daemon"
373389 client := workspace / ".lake" / "build" / "bin" / "beam-client"
374- plugin := workspace / ".lake" / "build" / "lib" / "librunAt_RunAt.so"
390+ plugin := RunAt.Lib.pluginSharedLibPath ( workspace / ".lake" / "build" / "lib" )
375391 }
376392
377393private def bundleArtifactsReady (workspace : System.FilePath) : IO Bool := do
@@ -407,7 +423,7 @@ private def bundleSourceHashInputLabels : List String :=
407423
408424private def installRuntimePaths : List String :=
409425 ["libexec/beam-cli" , "libexec/beam-daemon" , "libexec/beam-client" ,
410- "libexec/librunAt_RunAt.so " , ".lake/packages" ]
426+ s! "libexec/{ RunAt.Lib.pluginSharedLibName } " , ".lake/packages" ]
411427
412428private def installWrapperPaths : List String :=
413429 ["bin/lean-beam" , "bin/lean-beam-search" ]
@@ -543,11 +559,18 @@ private def fallbackBuildFailureMessage (toolchain : String) (cacheRoot bundleDi
543559 stderr
544560 ]
545561
562+ private def killCommand : IO String := do
563+ let candidates := [System.FilePath.mk "/bin/kill" , System.FilePath.mk "/usr/bin/kill" ]
564+ for candidate in candidates do
565+ if ← candidate.pathExists then
566+ return candidate.toString
567+ if ← commandAvailable "kill" #["-l" ] then
568+ pure "kill"
569+ else
570+ throw <| IO.userError "could not find kill command"
571+
546572private def pidAlive (pid : Nat) : IO Bool := do
547- let out ← IO.Process.output {
548- cmd := "sh"
549- args := #["-c" , s! "kill -0 { pid} >/dev/null 2>&1" ]
550- }
573+ let out ← IO.Process.output { cmd := (← killCommand), args := #["-0" , toString pid] }
551574 pure (out.exitCode == 0 )
552575
553576private partial def acquireLock (lockDir : System.FilePath) : IO Unit := do
@@ -718,19 +741,17 @@ private def leanBin (root : System.FilePath) : IO String := do
718741private def rocqCandidates (root : System.FilePath) : List System.FilePath :=
719742 [root / "_opam" / "bin" / "coq-lsp" , root / "_opam" / "_opam" / "bin" / "coq-lsp" ]
720743
721- private def pathCmd? (cmd : String) : IO (Option String) := do
722- try
723- return some (← readCmdTrim "sh" #["-c" , s! "command -v { shellQuote cmd} " ])
724- catch _ =>
725- return none
726-
727744private def maybeRocqCmd (root : System.FilePath) : IO (Option String) := do
728745 for candidate in rocqCandidates root do
729746 if ← candidate.pathExists then
730747 return some candidate.toString
731748 match ← IO.getEnv "BEAM_ROCQ_CMD" with
732749 | some cmd => pure (some cmd)
733- | none => pathCmd? "coq-lsp"
750+ | none =>
751+ if ← commandAvailable "coq-lsp" then
752+ pure (some "coq-lsp" )
753+ else
754+ pure none
734755
735756private def rocqCmd (root : System.FilePath) : IO String := do
736757 match ← maybeRocqCmd root with
@@ -804,11 +825,11 @@ private def daemonResponds (endpoint : Transport.Endpoint) : IO Bool := do
804825 pure false
805826
806827private def killPid (pid : Nat) : IO Unit := do
807- let _ ← IO.Process.output {
808- cmd := "sh"
809- args := #[ "-c" , s! "kill { pid } >/dev/null 2>&1 || true" ]
810- }
811- pure ()
828+ try
829+ let _ ← IO.Process.output { cmd := (← killCommand), args := #[toString pid] }
830+ pure ()
831+ catch _ =>
832+ pure ()
812833
813834private partial def waitForPidGone (pid : Nat) (tries : Nat := 20 ) : IO Unit := do
814835 if tries == 0 then
@@ -918,16 +939,16 @@ private def startDaemon (desired : DesiredConfig) (endpoint : Transport.Endpoint
918939 IO.FS.createDirAll parent
919940 IO.FS.writeFile logPath ""
920941 let cmd := String.intercalate " " ((desired.daemonBin.toString :: args).map shellQuote)
921- let shell := s! "cd { shellQuote desired.root.toString } && { cmd} >{ shellQuote logPath.toString} 2>&1 < /dev/null & echo $! "
922- let out ← IO.Process.output {
942+ let shell := s! "exec { cmd} >{ shellQuote logPath.toString} 2>&1 < /dev/null"
943+ let child ← IO.Process.spawn {
923944 cmd := "sh"
924945 args := #["-c" , shell]
946+ cwd := some desired.root
947+ stdin := .null
948+ stdout := .null
949+ stderr := .null
925950 }
926- if out.exitCode != 0 then
927- throw <| IO.userError s! "failed to start Beam daemon for { desired.root} \n { out.stderr} "
928- let pidText := trimLine out.stdout
929- let some pid := pidText.toNat?
930- | throw <| IO.userError s! "failed to capture Beam daemon pid for { desired.root} "
951+ let pid := child.pid.toNat
931952 pure pid
932953
933954private partial def waitForDaemon (pid : Nat) (endpoint : Transport.Endpoint) (logPath : System.FilePath)
0 commit comments