Zero Config TUIs
Zero-config TUIs are part of what makes compose.mk
useful in tool mode, especially as a quick option for interacting with third-party projects that you can't control and don't want to edit.
Examples here all involve full-blown TUIs, i.e. multi-pane content with layouts that can be created with no code/config. For something simpler that's still interactive, see also the selector docs.
Basic Examples
For a simple demo that's just exercising containerized tmux
, geometry, and dispatching targets to panes.. try tux.demo:
$ ./compose.mk tux.demo
Embedded TUI capapbilities are usually pulled/built just-in-time and on request, then cached afterwards. So besides doing some basic testing, this has the effect of "priming" the TUI for the other examples below.
For a more involved example of dashboarding, try docker.commander. This demonstrates using other containers as TUI widgets- in this case we combine lazydocker, moncho/dry, and imgrot.
$ ./compose.mk docker.commander
Working with Compose-Files
If your project has a docker-compose file, the selector docs describe how you can select a single container interactively and shell into it. In a similar vein, you can also use the loadf
command to open several container shells at once.
# Opens 3 panes with container shells:
# one for each service mentioned in the file
$ ./compose.mk loadf demos/data/docker-compose.yml
Implicitly loadf
is dynamically creating make-targets corresponding to the compose-services. We can get more explicit by using tux.open
as seen in the Layout Section, and passing in services names or target names:
# Equivalent to above, but more explicit and less magical.
$ layout=spiral ./compose.mk loadf demos/data/docker-compose.yml \
tux.open.service_shells/debian,alpine,ubuntu
# Equivalent to above, but even more explicit
$ layout=spiral ./compose.mk loadf demos/data/docker-compose.yml \
tux.open/debian.shell,alpine.shell,ubuntu.shell
Working with Makefiles
If your project has a Makefile, the selector docs show how you can interactively select/run individual targets. In a similar vein, working with multiple targets and simple "dashboarding" across targets is also possible with no special configuration. This involves the mk.include target, which effectively simulates a include compose.mk
in your project Makefile without actually adding one.
Consider the following vanilla Makefile, which does not include compose.mk
itself, and simply defines fake build
, clean
, and test
targets that do nothing.
#!/usr/bin/env -S make -f
# demos/no-include.mk:
# A very basic demo that *doesnt* include compose.mk.
# This is mostly used for testing parsing & reflection utilities,etc
# Part of the `compose.mk` repo. This file runs as part of the test-suite.
.DEFAULT_GOAL := __main__
__main__: clean build test
clean:
@# Just a fake clean target.
echo cleaning
build:
@# Just a fake build target.
echo building
test:
@# Just a fake test target.
echo testing
Using mk.include
by itself works in the way that you'd probably expect, but does nothing very interesting:
# Roughly equivalent to `make -f demos/no-include.mk`
$ ./compose.mk \
mk.include/demos/no-include.mk
cleaning
building
testing
The interesting part is that using tux.open/<target_list> in the way that we've already seen also works how you'd expect here. Thus you can use the command below to open each target in a separate pane:
$ ./compose.mk \
mk.include/demos/no-include.mk \
tux.open/clean,build,test
This is neat so far.. but it's not that useful to run clean/build/test in parallel.
How about something more practical, like starting a TUI that runs the clean/build targets back-to-back, plus a separate pane that's running test in a loop? This is actually doable. For it to happen, we can leverage the workflow helpers in the flux.*
target namespace. The command line for this starts to get complicated, so let's build it up one piece at a time.
# Running `clean` and `build` in one step:
$ ./compose.mk \
mk.include/demos/no-include.mk \
flux.wrap/clean:build
cleaning
building
# Looping the test-target forever
$ ./compose.mk \
mk.include/demos/no-include.mk \
flux.loopf/test
testing
testing
testing
^C
# Putting it all together
$ layout=horizontal \
./compose.mk \
mk.include/demos/no-include.mk \
tux.open/flux.loopf/test,flux.wrap/clean:build
Next Steps
Expanding on this.. you could add the io.shell target to the comma-separated list of tux.open
arguments for an additional pane featuring an interactive shell. Or you could add the io.env/<var_prefix> target to dump a list of relevant environment variables for this project. You get the idea.
This is pretty useful, but the command-line is unwieldy, and a swiss-army knife CLI will only take you so far. The next section looks at how we can achieve the same thing by editing files and avoiding one-liners.