Skip to content

Add Server.start and drop run.sh from the API examples - #143

Open
tony wants to merge 8 commits into
masterfrom
feat/private-server-142
Open

tony wants to merge 8 commits into
masterfrom
feat/private-server-142

Conversation

@tony

@tony tony commented Nov 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add Server.start(ServerLaunch) and Server.start(): a private tmux server with its own directory under ServerLaunch.root (/tmp/libtmux-java-dev by default), an empty config unless one is given, none of the caller's TMUX, TMUX_PANE or LIBTMUX_SOCKET*, and a TMUX_TMPDIR inside the directory. It runs as a foreground child (tmux -D), so its exit is observed on the process.
  • close() on that server stops tmux, waits until it no longer answers, stops any server a program left under the directory, removes the directory, and throws IllegalStateException if a server still answers (the directory stays) or one was left.
  • libtmux-junit5's TmuxExtension starts its fixtures with Server.start; the directory naming, the abandoned-server reaping and the exit wait moved into the library with the reaping tests. NamedServerFixture stays: it authenticates and ends a server another process started, which is not this entry point's job.
  • Kotlin Server.start and withPrivateServer { }, Scala direct Server.start() for Using.resource, and Scala Cats Server.start[F] as a Resource.
  • The Java, Kotlin, Scala Direct and Scala Cats API programs start their own server and create work-one and work-two themselves where they read them. examples/api/run.sh, ApiRunnerSandboxTest, the launcher manifest entries and the README's launcher section are removed.
  • Clojure (Add native Clojure facade #20, merged) gets libtmux.core/start!, which takes an option map like open! and returns the Server for with-open; its thirteen example programs start their own server and take no arguments. The facade has no public macros, so there is no with-server.

Closes #142

Docs site (not changed here): packages/api-model/src/languages/jvm-examples.ts in libtmux/docs requires exactly four setup files including run.sh, labels it as a launcher, says the program opens a client for the launcher's server, and prints sh run.sh build/install/api-example/bin/api-example; site/test/jvm-api-examples.test.ts expects five files per example. All of that needs to drop run.sh once this lands.

Test plan

  • ./gradlew :libtmux:test --tests '*PrivateServerTest' failed to compile before Server.start existed, then passed; breaking the environment scrub and the directory removal makes five of its eleven cases fail
  • :libtmux:check :libtmux-junit5:check :libtmux-kotlin:check :libtmux-scala:check :libtmux-scala-cats:check :examples:check
  • Kotlin, Scala and Cats PrivateServerTest and PrivateServerSuite against the real tmux 3.8a on PATH
  • :integration-tests:clojureIntegrationTest, :libtmux-clojure:check, :libtmux-clojure-core-async:check
  • tmux matrix lanes 3.3a through 3.7c (CI)

tony added 8 commits November 7, 2026 21:36
why: Only test code could start and own a tmux server, so every API
example ran inside a 99-line shell launcher that made the socket
directory, scrubbed TMUX, stopped the server and checked for leaks.
That is the work the library exists to take off a caller. Part of #142.

what:
- Add Server.start and ServerLaunch: a foreground daemon in a directory
  of its own, an empty config unless one is given, none of the caller's
  TMUX, TMUX_PANE or LIBTMUX_SOCKET*, and a TMUX_TMPDIR inside the
  directory
- Make close on such a server stop tmux, wait until it no longer
  answers, stop any server a program left under the directory, remove
  it, and throw when one still answers or was left
- Reap servers whose owning JVM is gone, once per root, moved here from
  the JUnit extension with its tests
- Test start, close, the scrubbed environment, both failures and a
  start that cannot finish; each fails when the code it covers breaks
why: The extension carried its own copy of the directory naming,
reaping, readiness probe and exit wait that Server.start now owns.
Part of #142.

what:
- Start each fixture server through Server.start under the test root
- Drop the extension's reaping, directory naming and exit wait, and the
  test of the exit wait that no longer exists
why: A Kotlin caller should scope a private server the way it scopes
any other, with a block that ends it however the block ends. Part of
#142.

what:
- Add Server.start and withPrivateServer, which closes under
  NonCancellable like withServer
- Test that the server and its directory are gone after a block and
  after a block that throws
why: Scala callers scope with Using in the direct facade and a Resource
in the Cats one. Part of #142.

what:
- Add Server.start to the direct facade, so Using.resource ends the
  server
- Add Server.start[F] to the Cats facade as a Resource with the
  facade's operation bound
- Test that the directory is gone after each
why: A reader who copied an example got a program that could not run
without a shell script beside it. The programs should show the library
doing the work. Part of #142.

what:
- Start every Java, Kotlin, Scala Direct and Scala Cats API program's
  server with Server.start and create work-one and work-two in the
  programs that read them
- Delete api/run.sh and its sandbox test, whose checks now live in the
  library's tests, and drop the launcher from the manifest and README
- Run the programs with the matrix's tmux first on PATH
- Match Capture's markers at the end of a line, since a prompt may come
  before the output
why: The new entry point and the removed launcher change what a reader of
the examples and a caller of the library see. Part of #142.

what:
- Add entries to the libtmux, Kotlin, Scala and Scala Cats changelogs
- Add the examples change to the root changelog
why: The Clojure facade copied the shell launcher to own a server, and
a Clojure caller should get the same entry point as Java's
Server.start, in the facade's own shape. Part of #142.

what:
- Add libtmux.core/start!, which takes an option map like open! and
  returns the Server for with-open; closing it stops tmux and removes
  its directory
- Reject unknown options before anything starts
- Regenerate the API reference and fix the README's launcher sentence
- Test a started server's close and the rejected options against real
  tmux
why: The Clojure programs still ran through examples/api/run.sh, which
this change deletes, and took three arguments from it. Part of #142.

what:
- Start every Clojure program's server with start! and drop its
  arguments; create work-one and work-two in the programs that read
  them
- Drop run.sh from the Clojure manifest and README, and run the
  programs with the matrix's tmux first on PATH
- Make Connect assert the snapshot has a session list rather than a
  session, since a fresh server has none

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

No API starts a private tmux server, so examples need run.sh

1 participant