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.

Summary
#!/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.