API / CLI Documentation
Tip
A major advantage of make
is that the programmatic interface is the command-line interface, and vice versa, so the documentation here is often relevant for tool mode or library mode.
Note that the autogenerated section of the API (i.e. scaffolded targets created by compose.import
) is not presented here.. see instead the docs for the Make/Compose Bridge.
This is the complete list of public targets available from compose.mk
, along with their documentation. Things are organized into a few namespaces, so hopefully if you're using this stuff programmatically that helps to avoid collisions with your project targets. See the module layout overview for more details. Most documentation is pulled automatically from the latest source.
Some important notes about how these targets work:
- Target names are reserved names after declaration.
- Targets are usable interactively from your shell as
make <target>
or./compose.mk <target>
- Targets are usable as an API, either as prereq-targets or as part of the body in your project automation.
- Most targets are pure shell, and have no exotic dependencies. That means that they generally run fine on host or as dispatched targets inside containers.
API: io
The io.*
namespace has misc helpers for working with input/output, including utilities for working with temp files and showing output to users. User-facing output leverages charmbracelet utilities like gum[2] and glow[3]. Generally we use tools directly if they are available, falling back to utilities in containers.
DOCS:
-
[1]:
Main API -
[2]:
gum documentation -
[3]:
glow documentation
This documentation is pulled automatically from source.
io.awk/arg
Treats the given define-block name as an awk script,
always running it on stdin. Used internally.
Must remain silent, does not support args.
Also available as a macro.
USAGE:
io.awk/<def_name>
io.bash/arg
Treats the given define-block name as a bash script.
Also available as a macro.
USAGE:
io.bash/<def_name>,<optional_args>
io.browser
Tries to open the given URL in a browser.
NB: This requires python on the host and can not run from docker.
USAGE:
url="..." ./compose.mk io.browser
io.browser/arg
Like `io.browser`, but accepts a variable-name as an argument.
Variable will be dereferenced and stored as 'url' before chaining.
NB: This requires python on the host and can not run from docker.
io.draw.banner
Helper for formatting text and banners using `gum style` and `gum format`.
Expects label text under the `label variable, plus supporting optional `width`.
Also available as a macro. See instead `io.print.banner` for something simpler.
REFS:
[1] [gum documentation](https://github.com/charmbracelet/gum)
EXAMPLE:
label="..." ./compose.mk io.draw.banner
width=30 label='...' ./compose.mk io.draw.banner
io.draw.banner/arg
Alias for io.gum.style/
io.echo
Echos data from input stream. Alias for the `stream.stdin` macro.
io.env
Dumps a relevant subset of environment variables for the current context.
No arguments. Pipe-safe since this is just filtered output from 'env'.
USAGE: ./compose.mk io.env
io.env.filter.prefix/arg
Alias for io.env/
io.env.pretty
Pretty version of io.env, this includes some syntax highlighting.
No arguments. See 'io.envp/<arg>' for a version that supports filtering.
USAGE: ./compose.mk io.envp
io.env.pretty/arg
Alias for io.envp/
io.env/arg
Filters environment variables by the given prefix or (comma-delimited) prefixes.
Also available as a macro.
USAGE:
./compose.mk io.env/<prefix1>,<prefix2>
io.envp
Pretty version of io.env, this includes some syntax highlighting.
No arguments. See 'io.envp/<arg>' for a version that supports filtering.
USAGE: ./compose.mk io.envp
io.envp/arg
Pretty version of 'io.env/<arg>', this includes syntax highlighting and also filters the output.
USAGE:
./compose.mk io.envp/<prefix_to_filter_for>
USAGE: (only vars matching 'TUI*')
./compose.mk io.envp/TUI
io.figlet
Pulls `label` from the environment and renders it with `figlet`.
Also available as a macro. NB: This requires the embedded tui is built.
io.figlet/arg
Treats the argument as a label, and renders it with `figlet`.
NB: This requires the embedded tui is built.
io.gum.choice/arg
Interface to `gum choose`.
This uses gum if it is available, falling back to docker if necessary.
USAGE:
./compose.mk io.gum.choose/choice-one,choice-two
io.gum.choose/arg
Alias for io.gum.choice/
io.gum.div
Draw a horizontal divider with gum.
If `label` is not provided, this defaults to using a timestamp.
USAGE:
label=".." ./compose.mk io.gum.div
io.gum.spin
Runs `gum spin` with the given command/label.
EXAMPLE:
cmd="sleep 2" label=title ./compose.mk io.gum.spin
REFS:
[1] [gum documentation](https://github.com/charmbracelet/gum)
io.gum.style
Helper for formatting text and banners using `gum style` and `gum format`.
Expects label text under the `label variable, plus supporting optional `width`.
Also available as a macro. See instead `io.print.banner` for something simpler.
REFS:
[1] [gum documentation](https://github.com/charmbracelet/gum)
EXAMPLE:
label="..." ./compose.mk io.draw.banner
width=30 label='...' ./compose.mk io.draw.banner
io.gum.style/arg
Prints a divider with the given label.
Invocation must be a legal target (Do not use spaces, etc!)
See also `io.draw.banner` and `io.print.banner` for something simpler.
USAGE: ./compose.mk io.draw.banner/<label>
io.help
Lists only the targets available under the 'io' namespace.
io.mkdir/arg
Runs `mkdir -p` for the named directory
io.preview.file/arg
Outputs syntax-highlighting + line-numbers for the given filename to stderr.
USAGE:
./compose.mk io.preview.file/<fname>
io.preview.img/arg
Console-friendly image preview for the given file. See also: `stream.img`
USAGE:
./compose.mk io.preview.img/<path_to_img>
io.preview.markdown/arg
Console-friendly markdown preview for the given file. See also `stream.markdown`
io.preview.pygmentize/arg
Syntax highlighting for the given file.
Lexer will autodetected unless override is provided.
Style defaults to 'trac', which works best with dark backgrounds.
USAGE:
./compose.mk io.preview.pygmentize/<fname>
lexer=.. ./compose.mk io.preview.pygmentize/<fname>
lexer=.. style=.. ./compose.mk io.preview.pygmentize/<fname>
REFS:
[1]: https://pygments.org/
[2]: https://pygments.org/styles/
io.print.banner
Prints a divider on stdout, defaulting to the full
term-width, with optional label. If label is not set,
a timestamp will be used. Also available as a macro.
USAGE:
label=".." filler=".." width="..." ./compose.mk io.print.banner
io.print.banner/arg
Like `io.print.banner` but accepts a label directly.
io.quiet.stderr.sh
Runs the given target, surpressing stderr output, except in case of error.
USAGE:
./compose.mk io.quiet/<target_name>
io.quiet.stderr/arg
Runs the given target, surpressing stderr output, except in case of error.
USAGE:
./compose.mk io.quiet/<target_name>
io.selector/arg
Uses the given targets to generate and then handle choices.
The 1st argument should be a nullary target; the 2nd must be unary.
USAGE:
./compose.mk io.selector/<choice_generator>,<choice_handler>
io.shell
Starts an interactive shell with all the environment variables set
by the parent environment, plus those set by this Makefile context.
io.stack.pop/arg
Pops first item off the given stack file.
Not strict: popping an empty stack is allowed.
USAGE:
./compose.mk io.stack.pop/<fname>
{.. data ..}
io.stack.push/arg
Pushes new JSON data onto the named stack-file
USAGE:
echo '<json>' | ./compose.mk io.stack.push/<fname>
io.stack/arg
Returns all the data in the named stack-file
USAGE:
./compose.mk io.stack/<fname>
[ {.. data ..}, .. ]
io.tail/arg
Tails the named file. Blocking. Creates file first if necessary.
USAGE: ./compose.mk io.tail/<fname>
io.time.wait
Pauses for 1 second.
io.time.wait/arg
Alias for io.wait/
io.user_exit
Wait for user-input, then exit cleanly.
This explicitly uses `mk.supervisor.exit`,
thus honoring `CMK_AT_EXIT_TARGETS`.
io.wait
Pauses for 1 second.
io.wait/arg
Pauses for the given amount of seconds.
USAGE: ./compose.mk io.time.wait/<int>
io.with.color/arg
A context manager that paints the given targets output as the given color.
This outputs to stderr, and only assumes the original target-output was also on stderr.
USAGE: ( colors the banner red )
./compose.mk io.with.color/red,io.figlet/banner
io.with.file/arg
Context manager.
Creates a temp-file for the given define-block, then runs the
given (unary) target using the temp-file for an argument
USAGE:
./compose.mk io.with.file/<def_name>/<downstream_target>
API: compose
Targets for working with docker compose, without using the compose.import
macro.
These targets support basic operations on compose files like 'build' and 'clean', so in some cases scaffolded targets will chain here.
DOCS:
[1]:
Main API
This documentation is pulled automatically from source.
compose.build/arg
Builds all services for the given compose file.
This optionally runs for just the given service, otherwise on all services.
USAGE:
./compose.mk compose.build/<compose_file>
svc=<svc_name> ./compose.mk compose.build/<compose_file>
compose.clean/arg
Runs `docker compose down` for the given compose file,
including reasonable cleanup like --rmi and --remove-orphans, etc.
This optionally runs on a given service, otherwise on all services.
USAGE:
./compose.mk compose.clean/<compose_file>
svc=<svc_name> ./compose.mk compose.clean/<compose_file>
compose.dispatch.sh/arg
Similar interface to the scaffolded '<compose_stem>.dispatch' target,
except that this is a backup plan for when 'compose.import' has not
imported services more directly.
USAGE:
cmd=<shell_cmd> svc=<svc_name> compose.dispatch.sh/<fname>
compose.get.stem/arg
Returns a normalized version of the stem for the given compose-file.
(A "stem" is just the basename without a suffix.)
USAGE:
./compose.mk compose.get.stem/<fname>
compose.images/arg
Returns all images used with the given compose file.
compose.loadf
Loads the given file,
then curries the rest of the CLI arguments to the resulting environment
FIXME: this is linux-only due to usage of MAKE_CLI?
USAGE:
./compose.mk loadf <compose_file> ...
compose.require
Asserts that docker compose is available.
compose.select/arg
Interactively selects a container from the given docker compose file,
then drops into an interactive shell for that container.
The container must already have sh or bash.
USAGE:
./compose.mk compose.select/demos/data/docker-compose.yml
compose.services/arg
Returns space-delimited names for each non-abstract service defined by the given composefile.
Also available as a macro.
USAGE:
./compose.mk compose.services/demos/data/docker-compose.yml
compose.size/arg
Returns image sizes for all services in the given compose file,
i.e. JSON like `{ "repo:tag" : "human friendly size" }`
compose.validate.quiet/arg
Like `compose.validate`, but silent.
compose.validate/arg
Validates the given compose file (i.e. asks docker compose to parse it)
USAGE:
./compose.mk compose.validate/<compose_file>
compose.versions/arg
Attempts to extract version-defaults from the given compose file.
compose.versions_table/arg
Like `.versions` but returns a markdown table of results
API: docker
The docker.*
targets cover a few helpers for working with docker.
This interface is deliberately minimal, focusing on verbs like 'stop' and 'stat' more than verbs like 'build' and 'run'. That's because containers that re managed by docker compose are preferred, but some ability to work with nlined Dockerfiles for simple use-cases is supported. For an example see the implementation of stream.pygmentize
.
DOCS:
[1]:
Main API
This documentation is pulled automatically from source.
docker.build.def/arg
Alias for docker.from.def/
docker.build/arg
Standard noisy docker build for the given filename.
For embedded Dockerfiles see instead `Dockerfile.build/<def_name>`
For remote Dockerfiles, see instead`docker.from.url`
USAGE:
tag=<tag_to_use> ./compose.mk docker.build/<name>
docker.clean
This refers to "local" images. Cleans all images from 'compose.mk' repository,
i.e. affiliated containers that are related to the embedded TUI, and certain things
created by the 'docker.*' targets. No arguments.
docker.commander
TUI layout providing an overview for docker.
This has 3 panes by default, where the main pane is lazydocker,
plus two utility panes. Automation also ensures that lazydocker
always starts with the "statistics" tab open.
docker.context
Returns all of the available docker context.
JSON output, pipe-friendly.
docker.context/arg
Returns docker-context details for the given context-name.
Pipe-friendly; outputs JSON from 'docker context inspect'
USAGE: (shortcut for the current context name)
./compose.mk docker.context/current
USAGE: (using named context)
./compose.mk docker.context/<context_name>
docker.def.is.cached/arg
Answers whether the named define has a cached docker image
This never fails and exits with "yes" if the image has been
built at least once, and "no" otherwise, but it also respects
whether 'force=1' has been set.
docker.def.run/arg
Builds, then runs the docker-container for the given define-block
docker.def.start/arg
Starts a container represented by named define-block.
(This is like docker.run.def but assumes default entrypoint)
docker.dispatch/arg
Runs the named target inside the named docker container.
This works for any image as given; See instead 'mk.docker.run'
for a version that implicitly uses internally generated containers.
Also available as a macro.
USAGE:
img=<img> make docker.dispatch/<target>
EXAMPLE:
img=debian/buildd:bookworm ./compose.mk docker.dispatch/flux.ok
docker.from.def/arg
Builds a container, treating the given 'define' block as a Dockerfile.
This implicitly prefixes the named define with 'Dockerfile.' to enforce
naming conventions, and make for easier cleanup. Container tags are
determined by 'tag' var if provided, falling back to the name used
for the define-block. Tags are implicitly prefixed with 'compose.mk:',
for the same reason as the other prefixes.
USAGE: ( explicit tag )
tag=<my_tag> make docker.from.def/<my_def_name>
USAGE: ( implicit tag, same name as the define-block )
make docker.from.def/<my_def_name>
REFS:
[1]: https://robot-wranglers.github.io/compose.mk/#demos
docker.from.file/arg
Alias for docker.build/
docker.from.github
Helper that constructs an appropriate url, then chains to `docker.from.url`.
Note that the output tag will not be the same as the input tag here! See
`docker.from.url` for more details.
USAGE:
user=alpine-docker repo=git tag="1.0.38" ./compose.mk docker.from.github
docker.from.url
Builds a container, treating the given 'url' as a Dockerfile.
The 'tag' and 'url' env-vars are required. Note that incoming
tags will get the standard repo prefix, i.e. end up as `compose.mk:<tag>`
See also the docs about supported URL syntax:
https://docs.docker.com/build/concepts/context/#git-repositories
FIXME: this currently does not respect 'force'
USAGE:
url="<repo_url>#<branch_or_tag>:<sub_dir>" tag="<my_tag>" make docker.from.url
docker.help
Lists only the targets available under the 'docker' namespace.
docker.host_ip
Attempts to return the address for the docker host.
This is the IP that *containers* can use to contact the host machine from,
if the network bridge is setup as usual. This can be useful for things
like testing kind/k3d cluster services from the outside.
This must run on the host and the details can be *passed* to containers;
it will not run inside containers. This probably does not work outside of linux.
docker.image.dispatch/arg
Similar to `docker.dispatch/<arg>`, but accepts both the image
and the target as arguments instead of using environment variables.
Also available as a macro.
USAGE:
./compose.mk docker.image.dispatch/<img>/<target>
docker.image.entrypoint
Returns the current entrypoint for the given image.
docker.image.run/arg
Runs the named image, using the (optional) named entrypoint.
Also available as a macro.
USAGE:
./compose.mk docker.image.run/<img>,<entrypoint>
docker.image.sizes
Shows disk-size summaries for all images.
Returns JSON like `{ "repo:tag" : "human friendly size" }`
See `docker.size.summary` for similar column-oriented output
docker.image.stop
Stops one or more running instances launched from given image.
docker.images
Returns only affiliated images from 'compose.mk' repository,
i.e. containers that are related to the embedded TUI, and/or
things created by compose.mk inside the 'docker.*' targets, etc.
These are "local" images.
Extensions (like 'k8s.mk') may optionally export a value for
'CMK_EXTRA_REPO', which appends to the default list described above.
docker.images.all
Like plain 'docker images' CLI, but always returns JSON
This target is also available as a function.
docker.init
Checks if docker is available, then displays version/context (no real setup)
docker.init.compose
Ensures compose is available. Note that
build/run/etc cannot happen without a file,
for that, see instead targets like '<compose_file_stem>.build'
docker.lambda/arg
Similar to `docker.def.run`, but eschews usage of tags
and rebuilds implicitly on every single invocation.
Note that technically, this is still caching and
still actually involves tags, but the tags are naked SHAs.
docker.logs.follow/arg
Tails logs for the given container ID.
This is blocking, and never exits.
docker.logs.timeout/arg
Like docker.logs.follow, but times out after the given number of seconds.
USAGE: docker.logs.timeout/<timeout_in_seconds>,<id>
docker.logs/arg
Tails logs for the given container ID.
This is non-blocking.
docker.network.panic
Runs 'docker network prune' for the entire system.
docker.panic
Debugging only! This is good for ensuring a clean environment,
but running this from automation will nix your cache of downloaded
images, and then you will probably quickly hit rate-limiting at dockerhub.
It tears down volumes and networks also, so you do not want to run this in prod.
docker.prune
Debugging only! Runs 'docker system prune' for the entire system.
docker.prune.old
Debugging only! Runs 'docker system prune --all --force --filter "until=168h"'
docker.ps
Like 'docker ps', but always returns JSON.
docker.run.def
Treats the named define-block as a script, then runs it inside the given container.
USAGE:
entrypoint=<entry> def=<def_name> img=<image> ./compose.mk docker.run.def
docker.run.sh
Runs the given command inside the named container.
This automatically detects whether it is used as a pipe & proxies stdin as appropriate.
This always shares the working directory as a volume & uses that as a workspace.
If 'env' is provided, it should be a comma-delimited list of variable names;
those variables will be dereferenced and passed into docker's "-e" arguments.
USAGE:
img=... entrypoint=... cmd=... env=var1,var2 docker_args=.. ./compose.mk docker.run.sh
docker.run/arg
Starts the named docker image with the default entrypoint
USAGE:
./compose.mk docker.start/<img>
docker.size.summary
Shows disk-size summaries for all images.
Returns nl-delimited output like `repo:tag human_friendly_size`
See `docker.image.sizes` for similar JSON output.
docker.socket
Returns the docker socket in use for the current docker context.
No arguments & pipe-friendly.
docker.start
Like 'docker.run', but uses the default entrypoint.
USAGE:
img=.. ./compose.mk docker.start
docker.start.def/arg
Alias for docker.def.start/
docker.start.tty
Like `docker.start`, but sets tty=1
docker.start.tty/arg
Like `docker.start/..`, but sets tty=1
docker.start/arg
Alias for docker.run/
docker.stat
Show information about docker-status. No arguments.
This is pipe-friendly, although it also displays additional
information on stderr for humans, specifically an abbreviated
table for 'docker ps'. Machine-friendly JSON is also output
with the following schema:
{ "version": .., "container_count": ..,
"socket": .., "context_name": .. }
docker.stop
Stops one or more containers, with optional timeout,
filtering by the given id, name, or image.
USAGE:
id=8f350cdf2867 ./compose.mk docker.stop
name=my-container ./compose.mk docker.stop
name=my-container timeout=99 ./compose.mk docker.stop
img=debian:latest ./compose.mk docker.stop
docker.stop.all
Non-graceful stop for all running containers.
USAGE:
./compose.mk docker.stop name=my-container timeout=99
docker.system.prune
Debugging only! Runs 'docker system prune' for the entire system.
docker.tags.by.repo/arg
Filters all docker images by the given repository.
This helps to separate system images from compose.mk images.
Also available as a function.
See 'docker.images' for more details.
docker.volume.prune
Runs 'docker volume prune' for the entire system.
API: Dockerfile
This documentation is pulled automatically from source.
Dockerfile.build/arg
Alias for docker.from.def/
Dockerfile.from.fs/arg
Alias for docker.build/
API: flux
The flux.* targets describe a miniature workflow library. Combining flux with container dispatch is similar in spirit to things like declarative pipelines in Jenkins, but simpler, more portable, and significantly easier to use.
What's a workflow in this context? Shell by itself is fine for what you might call "process algebra", and using operators like &&
, ||
, |
in the grand unix tradition goes a long way. And adding make
to the mix already provides DAGs.
What flux.*
targets add is flow-control constructs and higher-level join/loop/map instructions over other make targets, taking inspiration from functional programming and threading libraries. Alternatively, one may think of flux as a programming language where all primitives are the objects that make understands, like targets, defines, and variables. Since every target in make
is a DAG, you might say that task-DAGs are also primitives. Since compose.import
maps containers onto targets, containers are primitives too. Since tux
targets map targets onto TUI panes, UI elements are also effectively primitives.
In most cases flux targets are used programmatically for scripting, but in stand-alone mode it can sometimes be useful for cleaning up (external) bash scripts, or porting from bash to makefiles, or ad-hoc interactive scripting.
For parts that are more specific to shell code, see flux.*.sh
, and for working with scripts see flux.*.script
.
DOCS:
[1]:
Main API
See especially the Platform Setup Example for a more complete walk-through of motivation, starting from an example use-case.
This documentation is pulled automatically from source.
flux.all/arg
Performs an 'and' operation with the named comma-delimited targets.
This is equivalent to the default behaviour of `make t1 t2 .. tN`.
This is mostly used as a wrapper in case arguments are unary, but
also has different semantics than default `make`, which ignores
duplicate targets as already satisfied.
USAGE:
./compose.mk flux.and/<t1>,<t2>
See also 'flux.or'.
flux.always/arg
Alias for flux.finally/
flux.and/arg
Alias for flux.all/
flux.any/arg
Alias for flux.or/
flux.apply.later.sh/arg
Applies the given command at some point in the future. This is non-blocking.
Not pipe-safe since targets run in the background, this can garble your display!
USAGE:
cmd="..." ./compose.mk flux.apply.later.sh/<seconds>
flux.apply.later/arg
Applies the given (unary) target at some point in the future. This is non-blocking.
Not pipe-safe, because since targets run in the background, this can garble your display!
USAGE:
./compose.mk flux.apply.later/<seconds>/<target>
flux.apply/arg
Applies the given target to the given argument, comma-delimited.
In case no argument is given, we assume target is nullary.
USAGE: ( generic )
./compose.mk flux.apply/<target>,<arg>
USAGE: ( generic )
./compose.mk flux.apply/<target>
USAGE: ( concrete )
./compose.mk make flux.apply/flux.echo,THUNK
flux.column/arg
Exactly flux.pipeline, but splits targets on colons.
flux.context_manager/arg
Alias for flux.with.ctx/
flux.delay/arg
Alias for flux.apply.later/
flux.do.unless/arg
Runs the 1st target iff the 2nd target fails.
This is a version of 'flux.if.then', see those docs for more details.
USAGE: ( generic )
./compose.mk flux.do.unless/<umbrella>,<dry>
USAGE: ( concrete )
./compose.mk flux.do.unless/flux.ok,flux.fail
flux.do.when/arg
Runs the 1st given target iff the 2nd target is successful.
This is a version of 'flux.if.then', see those docs for more details.
This version is nicer when your "then" target has multiple commas.
USAGE: ( generic )
./compose.mk flux.do.when/<umbrella>,<raining>
flux.each/arg
Similar to `flux.for.each`, but accepts input on a pipe.
This maps the newline/space separated input on to the named (unary) target.
This works via xargs, runs sequentially, and fails fast. Also
available as a macro. The named target MUST be parametric so it
can accept the argument that is passed through!
USAGE:
printf 'one\ntwo' | ./compose.mk flux.each/flux.echo
flux.echo/arg
Simply echoes the given argument.
Mostly used in testing, but also provided for completeness..
you can think of this as the "identity function" for flux algebra.
flux.fail
Alias for 'exit 1', which is POSIX failure.
This is mostly for used for testing other pipelines.
See also the `flux.ok` target.
flux.finally/arg
Always run the given target, even if the rest of the pipeline fails.
See also 'flux.try.except.finally'.
NB: For this to work, the `always` target needs to be declared at the
beginning. See the example below where "<target>" always runs, even
though the pipeline fails in the middle.
USAGE:
./compose.mk flux.always/<target_name> flux.ok flux.fail flux.ok
flux.for.each/arg
Alias for flux.map/
flux.help
Lists only the targets available under the 'flux' namespace.
flux.if.then.else/arg
Standard if/then/else control flow, for make targets.
USAGE: ( generic )
./compose.mk flux.if.then.else/<test_target>,<then_target>,<else_target>
flux.if.then/arg
Runs the 2nd given target iff the 1st one is successful.
Failure (non-zero exit) for the "if" check is not distinguished
from a crash, & it will not propagate. Only the 2nd argument may contain
commas. For a reversed version of this construct, see 'flux.do.when'
USAGE: ( generic )
./compose.mk flux.if.then/<name_of_test_target>,<name_of_then_target>
USAGE: ( concrete )
./compose.mk flux.if.then/flux.fail,flux.ok
flux.indent.sh
Similar to flux.indent, but this works with any shell command.
USAGE:
cmd="echo foo; echo bar >/dev/stderr" ./compose.mk flux.indent.sh
flux.indent/arg
Given a target, this runs it and indents both the resulting output for both stdout/stderr.
See also the 'stream.indent' target.
USAGE:
./compose.mk flux.indent/<target>
flux.joinarg
Alias for flux.mux/
flux.loop.until/arg
Loop the given target until it succeeds.
By default to reduce logging noise, this sends stderr to null, but preserves stdout.
This makes debugging hard, so only use this with well tested/understood sub-targets,
or set "verbose=1" to allow stderr. When "quiet=1" is set, even more logging is trimmed.
USAGE:
flux.loop.watch/arg
Loops the given target forever, using `watch` instead of the while-loop default.
This requires `watch` is actually available.
flux.loop/arg
Helper for repeatedly running the named target a given number of times.
This requires the 'pv' tool for progress visualization, which is available
by default in k8s-tools containers. By default, stdout for targets is
supressed because it messes up the progress bar, but stderr is left alone.
USAGE:
./compose.mk flux.loop/<times>/<target_name>
NB: This requires "flat" targets with no '/' !
flux.loopf.quiet.quiet/arg
Like flux.loopf, but even more quiet.
flux.loopf.quiet/arg
Loops the given target forever.
By default to reduce logging noise, this sends stderr to null, but preserves stdout.
This makes debugging hard, so only use this with well tested/understood sub-targets,
or set "verbose=1" to allow stderr. When "quiet=1" is set, even more logging is trimmed.
USAGE:
./compose.mk flux.loopf/
flux.loopf/arg
Loops the given target forever.
flux.map/arg
Like `flux.each`, but accepts input as an argument.
USAGE:
flux.for.each/flux.echo,hello,world
flux.map/flux.echo,hello,world
flux.match/arg
Alias for flux.star/
flux.mux
Similar to `flux.parallel`, but actually uses processes directly.
See instead that implementation for finer-grained control.
Runs the given comma-delimited targets in parallel, then waits for all of them to finish.
For stdout and stderr, this is a many-to-one mashup of whatever writes first, and nothing
about output ordering is guaranteed. This works by creating a small script, displaying it,
and then running it. It is not very sophisticated! The script just tracks pids of
launched processes, then waits on all pids.
If the named targets are all well-behaved, this *might* be pipe-safe, but in
general it is possible for the subprocess output to be out of order. If you do
want *legible, structured output* that *prints* in ways that are concurrency-safe,
here is a hint: emit nothing, or emit minified JSON output with printf and 'jq -c',
and there is a good chance you can consume it. Printf should be atomic on most
platforms with JSON of practical size? And crucially, 'jq .' handles object input,
empty input, and streamed objects with no wrapper (i.e. '{}<newline>{}').
EXAMPLE: (runs 2 commands in parallel)
targets="io.time.wait/1,io.time.wait/3" ./compose.mk flux.mux | jq .
flux.mux/arg
Like `flux.join` but accepts arguments directly.
flux.negate/arg
Negates the status for the given target.
USAGE:
`./compose.mk flux.negate/flux.fail`
flux.noop
NO-OP mostly used for testing.
Similar to 'flux.ok', but this does not include logging.
USAGE:
./compose.mk flux.noop
flux.ok
Alias for 'exit 0', which is success.
This is mostly for used for testing other pipelines.
See also `flux.fail`
flux.or/arg
Performs an 'or' operation with the named comma-delimited targets.
This is equivalent to 'make target1 || .. || make targetN'. See also 'flux.and'.
USAGE: (generic)
./compose.mk flux.or/<t1>,<t2>,..
USAGE: (example)
./compose.mk flux.or/flux.fail,flux.ok
flux.parallel/arg
Runs the named targets in parallel, using builtin support for concurrency.
Similar to `flux.join` but using `make --jobs`, this is fundamentally much more
tricky to handle than `flux.join`, but also in some ways will allow for
finer-grained control. It probably does not work the way you think, because
concurrency may affect *more* than the top level targets that are named as
arguments. See [1] for more documentation about that.
See the `flux.join` docs for some hints about running concurrently but safely
producing structured output. Major caveat: input streams [2] probably cannot be
easily or safely used with `flux.parallel`.
REFS:
[1] https://www.gnu.org/software/make/manual/html_node/Parallel-Disable.html
[2] https://www.gnu.org/software/make/manual/html_node/Parallel-Input.html
flux.pipe.fork
Demultiplex / fan-out operator that sends stdin to each of the named targets in parallel.
This is like `flux.sh.tee` but works with make-target names instead of shell commands.
Also available as a macro.
USAGE: (pipes the same input to target1 and target2)
echo {} | targets="jq,jq" ./compose.mk flux.pipe.fork
flux.pipe.fork/arg
Same as flux.pipe.fork, but accepts arguments directly (no variable)
Stream-usage is required (this blocks waiting on stdin).
USAGE: ( pipes the same input to yq and jq )
echo hello-world | ./compose.mk flux.pipe.fork/stream.echo,stream.echo
flux.pipeline.quiet/arg
flux.pipeline.verbose/arg
flux.pipeline/arg
Runs the given comma-delimited targets in a bash-style command pipeline.
Besides working with targets and allowing for DAG composition, this has
the advantage of giving visibility to the intermediate results.
There are several caveats though: all targets *must* be pipe safe on stdout,
and downstream targets must consume stdin. Note also that this does not use
pure streams, and tmp files are created as part of an attempt to debuffer and
avoid reordering stderr output. Error handling is also probably not great!
USAGE: (example)
./compose.mk flux.pipeline/extract,transform,load
=> roughly equivalent to `make extract | make transform | make load`
flux.post/arg
Dispatch post-hook if one is available
flux.pre/arg
Dispatch pre-hook if one is available
flux.retry/arg
Retries the given target a certain number of times.
USAGE: (using default interval of FLUX_POLL_DELTA)
./compose.mk flux.retry/<times>/<target>
USAGE: (explicit interval in seconds)
interval=3 ./compose.mk flux.retry/<times>/<target>
flux.select.and.dispatch
USAGE:
pattern='*.mk' dir=demos/ ./compose.mk flux.select.and.dispatch
flux.select.file/arg
Opens an interactive file-selector using the given dir,
then treats user-choice as a parameter to be passed into
the given target.
You can use this to build layered interactions, getting new
input at each stage. See example usage below which first
chooses a file from `demos/` folder, then uses `mk.select`
to choose a target
USAGE:
pattern='*.mk' dir=demos/ ./compose.mk flux.select.file/mk.select
flux.sh.tee
Helper for constructing a parallel process pipeline with `tee` and command substitution.
Pipe-friendly, this works directly with stdin. This exists mostly to enable `flux.pipe.fork`
but it can be used directly.
Using this is easier than the alternative pure-shell version for simple commands, but it is
also pretty naive, and splits commands on commas; probably better to avoid loading other
pipelines as individual commands with this approach.
USAGE: ( pipes the same input to 'jq' and 'yq' commands )
echo {} | cmds="jq,yq" ./compose.mk flux.sh.tee
flux.split
Demultiplex / fan-out operator that sends stdin to each of the named targets in parallel.
This is like `flux.sh.tee` but works with make-target names instead of shell commands.
Also available as a macro.
USAGE: (pipes the same input to target1 and target2)
echo {} | targets="jq,jq" ./compose.mk flux.pipe.fork
flux.split/arg
Alias for flux.split, but accepts arguments directly
flux.stage
Returns the name of the current stage. No Arguments.
flux.stage.clean
Cleans all stage-files from all runs, including ones that do not belong to this pid!
No arguments.
USAGE: ( generic )
./compose.mk flux.stage./
flux.stage.clean/arg
Cleans only stage files that belong to the given stage.
USAGE:
./compose.mk flux.stage.clean/<stage_name>
flux.stage.enter/arg
Declares entry for the given stage.
Stage names are generally target names or similar, no spaces allowed.
Calling this target prints a pretty divider that makes output easier
to parse, but stages also add an idea of persistence to our otherwise
pretty stateless workflows, via a file-backed JSON stack object that
cooperating tasks can *push/pop* from.
By default we draw a banner with `io.draw.banner`, but you can override
with e.g. `target_banner=io.figlet`, etc.
USAGE:
./compose.mk flux.stage.enter/<stage_name>
flux.stage.exit/arg
Declares exit for the given stage.
Calling this is optional but if you do not, stack-files will not be deleted!
USAGE: ( generic )
./compose.mk flux.stage.exit/<stage_name>
flux.stage.file/arg
Returns the name of the current stage file.
USAGE: ( generic )
./compose.mk flux.stage.file/<stage_name>
flux.stage.pop/arg
Pops the stack for the named stage.
Caller should handle empty value, this will not throw an error.
USAGE:
./compose.mk flux.stage.pop/<stage_name>
{"key":"val"}
flux.stage.push
Push the JSON data on stdin into the stack for the implied stage
USAGE: ( generic )
./compose.mk flux.stage.push
flux.stage.push/arg
Push the JSON data on stdin into the stack for the named stage.
USAGE:
echo '<json_data>' | ./compose.mk flux.stage.push/<stage_name>
flux.stage.stack
Dumps JSON for all the data on the current stack-file.
USAGE: ( generic )
./compose.mk flux.stage.stack/
flux.stage.stack/arg
Returns the entire stack given a stack name
USAGE: ( generic )
./compose.mk flux.stage./
flux.stage.wrap
Like `flux.stage.wrap/<stage>/<target>`, but taking args from env
flux.stage.wrap/arg
Context-manager that wraps the given target with stage-enter
and stage-exit. It only accepts one stage at a time, but can
easily be combined with `flux.wrap` for multiplem targets.
USAGE: ( generic )
./compose.mk flux.stage.wrap/<stage>/<target>
USAGE: ( concrete )
./compose.mk flux.stage.wrap/MAIN/flux.ok
flux.stage/arg
Alias for flux.stage.enter/
flux.star/arg
Runs all targets in the local namespace matching given pattern
USAGE: (run all the test targets)
make -f project.mk flux.star/test.
flux.starmap/arg
Based on itertools.starmap from python,
this accepts 2 targets called the "function" and the "iterable".
The iterable is nullary, and the function is unary. The "function"
target will be called once for each result of the "iterable" target.
Iterable *must* return newline-separated data, usually one word per line!
USAGE: ( generic )
./compose.mk flux.starmap/<fn>,<iterable>
flux.stream.obliviate/arg
Runs the given target, consigning all output to oblivion
flux.timeout.sh
Runs the given command for the given amount of seconds, then stops it with TERM.
Exit status is ignored
USAGE: (tails docker logs for up to 10s, then stops)
./compose.mk flux.timeout.sh cmd='docker logs -f xxxx' timeout=10
FIXME: use timeout(1) ?
flux.timeout/arg
Runs the given target for the given number of seconds, then stops it with TERM.
USAGE:
./compose.mk flux.timeout/<seconds>/<target>
flux.timer/arg
Emits run time for the given make-target in seconds.
USAGE:
./compose.mk flux.timer/<target_to_run>
flux.try.except.finally/arg
Performs a try/except/finally operation with the named targets.
See also 'flux.finally'.
USAGE: (generic)
./compose.mk flux.try.except.finally/<try_target>,<except_target>,<finally_target>
USAGE: (concrete)
./compose.mk flux.try.except.finally/flux.fail,flux.ok,flux.ok
flux.try.except/arg
Performs a try/except operation with the named targets.
This is just `flux.try.except.finally` where `finally` is `flux.noop`.
USAGE: (generic)
./compose.mk flux.try.except/<try_target>,<except_target>
flux.try.finally/arg
Performs a try/finally operation with the named targets.
This is just `flux.try.except.finally` where `except` is `flux.noop`.
USAGE: (generic)
./compose.mk flux.try.finally/<try_target>,<finally_target>
flux.with.ctx/arg
Runs the given target, using the given namespace as a context-manager
USAGE:
./compose.mk flux.ctx/<target>,<ctx_name>
Roughly equivalent to `compose.mk <ctx_name>.enter <target> <ctx_name>.exit`
flux.wrap/arg
Same as `flux.and` except that it accepts commas or colon-delimited args.
You can use this to disambiguate targets that need to have "," reserved.
This performs an 'and' operation with the named targets, equivalent to the
default behaviour of `make t1 t2 .. tN`. Mostly used as a wrapper in case
targets are unary
API: mk
The 'mk.*' targets are meta-tooling that include various extensions to make
itself, including some support for reflection and runtime changes.
A rough guide to stuff you can find here:
-
mk.supervisor.*
for signals and supervisors -
mk.def.*
for tools related to reading 'define' blocks -
mk.parse.*
for makefile parsing (used as part of generating help) -
mk.help.*
for help-generation
DOCS:
-
[1]:
Main API
This documentation is pulled automatically from source.
mk.__main__
Runs the default goal, whatever it is.
We need this for use with the supervisor because
usage of `mk.supervisor.enter/<pid>` is ALWAYS present,
and that overrides default that would run with an empty CLI.
mk.assert.env/arg
Asserts that the (comma-delimited) environment variables are set and non-empty.
Also available as a macro.
mk.compile
This is a transpiler for the CMK language -> Makefile.
Accepts streaming CMK source on stdin, result on stdout.
Quiet by default, pass quiet=0 to preview results from intermediate stages.
USAGE:
echo "<source_code>" | ./compose.mk mk.compiler
mk.compile/arg
Like `mk.compile`, but accepts file as argument instead of using stdin.
mk.compiler
This is a transpiler for the CMK language -> Makefile.
Accepts streaming CMK source on stdin, result on stdout.
Quiet by default, pass quiet=0 to preview results from intermediate stages.
USAGE:
echo "<source_code>" | ./compose.mk mk.compiler
mk.compiler/arg
Alias for mk.compile/
mk.def.dispatch/arg
Reads the given <def_name>, writes to a tmp-file,
then runs the given interpreter on the tmp file.
This requires that the interpreter is actually available..
for dockerized access to similar functionality, see `docker.run.def`
USAGE:
./compose.mk mk.def.dispatch/<interpreter>,<def_name>
HINT: for testing, use 'make mk.def.dispatch/cat,<def_name>'
mk.def.read/arg
Reads the named define/endef block from this makefile,
emitting it to stdout. This works around normal behaviour
of completely wrecking indention/newlines and requiring
escaped dollar-signs present inside the block.
Also available as a macro.
USAGE:
./compose.mk mk.read_def/<name_of_define>
mk.def.to.file/arg
Reads the given define/endef block from this makefile context,
writing it to the given output file. Also available as a macro.
USAGE: ( explicit filename for output )
./compose.mk mk.def.to.file/<def_name>/<fname>
USAGE: ( use <def_name> as filename )
./compose.mk mk.def.to.file/<def_name>
mk.docker
Like `mk.docker/..` but expects `img` argument is available from environment.
mk.docker.dispatch/arg
Like `docker.run` but insists that image is "local" or internally
managed by compose.mk, i.e. using the "compose.mk:" prefix.
Also available as a macro.
mk.docker.image/arg
Alias for mk.docker/
mk.docker.prune
Like `docker.prune` but only covers "local" images internally
managed by compose.mk, i.e. using the "compose.mk:" prefix.
mk.docker.run.sh
Like docker.run.sh, but implicitly assumes the 'compose.mk:' prefix.
mk.docker/arg
Like `docker.image.run`, but automatically adds the `compose.mk:` prefix.
This is used with "local" images that are managed by compose.mk itself,
e.g. embedded images that are built with `Dockerfile.build/..`, etc.
mk.fork.guest
Like `mk.fork.guest`, but with streaming input.
mk.fork.guest/arg
Forks this source code, returning modified version on stdout.
This rewrites the contents of the current "guest" section.
mk.fork.payload
Like `mk.fork.payload`, but with streaming input.
mk.fork.payload/arg
Forks this source code, returning modified version on stdout.
This rewrites the contents of the current "guest" section.
mk.fork.services
Like `mk.fork.services`, but with streaming input.
mk.fork.services/arg
Forks this source code, returning modified version on stdout.
This rewrites the contents of the default services section.
mk.fork/arg
USAGE: ./compose.mk mk.fork/<Makefile>,<composefile>
Like `mk.fork.guest/1st` followed by `mk.fork.services/2nd`
mk.get/arg
Returns the value of the given make-variable
mk.help
Lists only the targets available under the 'mk' namespace.
mk.help.block/arg
Shows the help-block matching the given pattern.
Similar to module-docs, but this need not match a target namespace.
USAGE: ./compose.mk mk.help.block/<pattern>
mk.help.module/arg
Shows help for the named module.
USAGE: ./compose.mk mk.help.module/<mod_name>
mk.help.search/arg
Shows all targets matching the given prefix.
USAGE:
./compose.mk mk.help.search/<pattern>
mk.help.target/arg
Shows rendered help for the named target.
USAGE: ./compose.mk mk.help.target/<target_name>
mk.ifdef/arg
Answers whether the given variable is defined.
This is silent, and only communicates via the exit code.
mk.ifndef/arg
Flips the assertion for 'mk.ifdef'.
mk.include/arg
Dynamic includes. Experimental stuff for reflection support.
This works by using code-generation and turning over the execution,
so it requires the supervisor/signals hack to short-circuit the
original execution!
USAGE: ( generic )
./compose.mk mk.include/<makefile>
USAGE: ( concrete )
./compose.mk mk.include/demos/no-include.mk foo:flux.ok mk.let/bar:foo bar
mk.interpret
This is similar to `mk.include`, and (simulates) changes to the `make` runtime.
It is mostly intended to be used as shebang, and essentially sets up `compose.mk`
as an alternative to using `make` as an interpreter. By opting in to this,
extensions can inherit not only `compose.mk` code, but also the signals / supervisors.
See `mk.interpret!` for a version of this that does preprocessing.
See https://robot-wranglers.github.io/compose.mk/signals/ for more information.
USAGE:
./compose.mk mk.interpret path/to/Makefile <target> .. <target>
mk.interpret!
Like `mk.interpret`, but runs CMK preprocessing/transpilation step first.
USAGE:
./compose.mk mk.interpret! <fname>
mk.interpret/arg
A version of `mk.interpret` that accepts file-args.
USAGE: ./compose.mk mk.interpret/<fname>
mk.interrupt
The default interrupt. This is shorthand for mk.interrupt/SIGINT
mk.interrupt/arg
Alias for mk.supervisor.interrupt/
mk.kernel
Executes the input data on stdin as a kind of "script" that
runs inside the current make-context. This basically allows
you to treat targets as an instruction-set without any kind
of 'make ... ' preamble.
USAGE: ( concrete )
echo flux.ok | ./compose.mk kernel
echo flux.and/flux.ok,flux.ok | ./compose.mk kernel
mk.let/arg
Dynamic target assignment.
This is experimental stuff for reflection support.
This is basically a hack to work around the dreaded error
that "recipes may not define targets". It should probably
be regarded as black magic that is best avoided!
This works by using code-generation and turning over the execution,
so it requires the supervisor/signals hack to short-circuit the
original execution!
USAGE: ( generic )
./compose.mk mk.let/<newtarget>:<oldtarget>
USAGE: ( concrete )
./compose.mk mk.let/foo:flux.ok mk.let/bar:foo bar
mk.namespace.filter/arg
Lists all targets in the given namespace, filtering them by the given pattern.
Simple, pipe-friendly output.
WARNING: Callers must anticipate parametric targets with percent-signs, i.e. "foo.bar/%"
USAGE: ./compose.mk mk.namespace.filter/<namespace>
mk.namespace.list
Returns only the top-level target namespaces
Pipe-friendly; stdout is newline-delimited target prefixes.
mk.parse.block/arg
Pulls out documentation blocks that match the given pattern.
USAGE:
pattern=.. ./compose.mk mk.parse.block/<makefile>
EXAMPLE:
pattern='*Keybindings*' make mk.parse.block/compose.mk
mk.parse.local
Returns only local targets for the current Makefile, ignoring includes
Output of `mk.parse.shallow/` for the current val of MAKEFILE.
mk.parse.module.docs/arg
Parses the given Makefile, returning module-level documentation.
USAGE:
pattern=.. ./compose.mk mk.parse.module.docs/<makefile>
mk.parse.shallow/arg
Alias for mk.targets/
mk.parse.targets
Returns only local targets for the current Makefile, ignoring includes
Output of `mk.parse.shallow/` for the current val of MAKEFILE.
mk.parse.targets/arg
Parses the given Makefile, returning target-names only. Simple, pipe-friendly output.
Also available as a macro.
WARNING: Callers must anticipate parametric targets with percent-signs, i.e. "foo.bar/%"
USAGE:
./compose.mk mk.parse.targets/<file>
mk.parse/arg
Parses the given Makefile, returning JSON output that describes the targets, docs, etc.
This parsing is "deep", i.e. it returns docs & metadata for *included* targets as well.
This uses a dockerized version of the pynchon[1] tool.
REFS:
* `[1]`: https://github.com/elo-enterprises/pynchon/
mk.pkg
Like `mk.self`, but includes `compose.mk` source also.
mk.pkg.root
Packages the application root, or the given command if provided.
mk.pkg/arg
Packages the given make target as a single-file executable.
This works by using to `makeself` to bundle/freeze/release
a self-extracting archive where we include the current Makefile,
and try to automatically include any related dependencies.
To add other explicit deps to the archive, set `archive`
as a space-separated list of files or directories.
USAGE:
archive="file1 file2 dir1" make -f ... mk.pkg/<target_name>
mk.preprocess
Runs the CMK input preprocessor on stdin.
mk.preprocess.decorators
Runs the decorator-preprocessor on stdin.
NB: This must come before sugar/dialects.
mk.preprocess.dialect
Runs dialect preprocessor on stdin.
Part of the CMK->Makefile transpilation process.
mk.preprocess.minify
Assuming stdin is makefile source, minifies it and outputs to stdout
mk.preprocess.sugar
Runs sugar-preprocessor on stdin.
Part of the CMK->Makefile transpilation process.
mk.preprocess/arg
A version of `mk.preprocess` that accepts a file-arg.
USAGE: ./compose.mk mk.preprocess/<fname>
mk.reconn/arg
Runs makefile in dry-run / reconn mode
mk.require.tool/arg
Asserts that the given tool is available in the environment.
Output is only on stderr, but this shows whereabouts if it is in PATH.
If not found, this exits with an error. Also available as a macro.
mk.run/arg
A target that runs the given makefile.
This uses `make` directly and naively, NOT using the current context.
mk.select
Interactive target selection / runner for the local Makefile
mk.select.local
Interactive target selection / runner for the local Makefile
mk.select/arg
Interactive target-selector for the given Makefile.
This uses `gum choose` for user-input.
mk.self
An interface to a dockerized version of the `makeself` tool.[1]
You can use this to create self-extracting executables.
Required arguments are only accepted as environment variables.
Set `archive` as a space-separated list of files or directories.
Set `script` as the script that will run inside the archive.
Set `bin` as the name of the executable you want to create.
Optionally set `label`. This is displayed at runtime,
after rehydrating the archive but before the script runs.
USAGE:
archive=<dirname> label=<label> bin=<bin_name> script="pwd; ls" ./compose.mk mk.self
[1]: https://makeself.io/
mk.set/arg
Setter for make variables, available as a target.
This is experimental stuff for reflection support.
USAGE: ./compose.mk mk.set/<key>/<val>
mk.src
Returns source-code for this make-context (excluding compose.mk).
This effectively flattens includes, basically concatenating
MAKEFILE_LIST in reverse order, and is used internally as part
of mk.compile. This has a different meaning if called from extensions
mk.stat
Shows version-information for make itself & compose.mk
USAGE: ./compose.mk mk.stat
mk.supervisor.enter/arg
Unconditionally executed by the supervisor program, prior to main pipeline.
Argument is always supervisors PPID. Not to be confused with
the supervisors pid; See instead 'mk.supervisor.pid'
mk.supervisor.exit/arg
Unconditionally executed by the supervisor program after main pipeline,
regardless of whether that pipeline was successful. Argument is always
the exit-status of the main pipeline.
mk.supervisor.interrupt
The default interrupt. This is shorthand for mk.interrupt/SIGINT
mk.supervisor.interrupt/arg
Sends the given signal to the process-tree supervisor, then kills this process with SIGKILL.
This is mostly used to short-circuit default command-line processing
so that targets can be greedy about consuming the *whole* CLI, rather than
having make try to interpret everything as additional targets.
This can be used without a supervisor process wrapping 'make',
but in that case the exit status is *always* failure, and there
is *always* an error that the user has to know they should ignore.
To correct for exit status/error output, you will have to have a supervisor.
See the polyglot-wrapper at the top of this file for more info, and see
the 'mk.supervisor.*' namespace for handlers invoked by that supervisor.
mk.supervisor.pid
Returns the pid for the supervisor process which is responsible for trapping signals.
See 'mk.interrupt' docs for more details.
mk.supervisor.trap/arg
Executed by the supervisor program when the given signal is trapped.
mk.targets
Returns only local targets for the current Makefile, ignoring includes
Output of `mk.parse.shallow/` for the current val of MAKEFILE.
mk.targets.filter.parametric/arg
Filters all parametric targets by the given pattern.
mk.targets.filter/arg
Lists all targets in the given namespace, filtering them by the given pattern.
Simple, pipe-friendly output.
WARNING: Callers must anticipate parametric targets with percent-signs, i.e. "foo.bar/%"
USAGE: ./compose.mk mk.targets.filter/<namespace>
mk.targets.local
Returns only local targets for the current Makefile, ignoring includes
Output of `mk.parse.shallow/` for the current val of MAKEFILE.
mk.targets.parametric
This finds only the parametric targets in the current namespace.
Note that targets like 'foo/%:' are automatically converted to simply 'foo',
which makes this friendly for use with stuff like `flux.starmap`, etc.
mk.targets.simple/arg
Returns only local targets from the given file,
excluding parametric targets, and ignoring included targets.
mk.targets/arg
Returns only local targets from the given file, ignoring includes.
Returns a newline-delimited list of targets inside the given Makefile.
Unlike `mk.parse`, this is "flat" and too naive to parse targets that come
via includes. Targets starting with "." are considered private, and
ommitted from the return value.
mk.validate
Validates whether the input stream is legal Makefile
mk.validate/arg
Validate the given Makefile (using `make -n`)
mk.vars
Lists all the variables known to Make, including local or
inherited env-vars, make-vars, make-defines etc.
This target is also available as a macro.
mk.vars.filter/arg
Filter output of `mk.vars` with the given pattern.
Non-strict; no error in case of no-match.
API: stream
The stream.*
targets support IO streams, including basic stuff with JSON, newline-delimited, and space-delimited formats.
General purpose tools:
-
For conversion, see
stream.nl.to.comma
,stream.comma.to.nl
, etc. -
For JSON ops, see
stream.jb
[2] andstream.json.append.*
, etc -
For formatting and printing, see
stream.dim.*
, etc.
Macro Equivalents:
Most targets here are also available as macros, which can be used
as an optimization since it saves a process.
# For example, from a makefile, these are equivalent commands:
echo "one,two,three" | ${stream.comma.to.nl}
echo "one,two,three" | make stream.comma.to.nl
DOCS:
-
[1]:
Main API -
[2]:
Docs for jb
This documentation is pulled automatically from source.
stream.as.log
A dimmed, indented version of the input stream sent to stderr.
See `stream.indent` for a version that works with stdout.
Note that this consumes the input stream.. see instead
`stream.peek` for a version with pass-through.
stream.chafa
Given an image file on stdin, this shows a preview on the console.
Under the hood, this works using a dockerized version of `chafa`.
USAGE: ( generic )
> cat docs/img/docker.png | ./compose.mk stream.img.preview
stream.code
A version of `io.preview.file` that works with streaming input.
Uses pygments on the backend; pass style=.. lexer=.. to override.
stream.comma.to.json
Converts comma-delimited input into minimized JSON array
USAGE:
> echo 1,2,3 | ./compose.mk stream.comma.to.json
["1","2","3"]
stream.comma.to.nl
Converts comma-delimited input stream to newline-delimited output.
Also available as a macro.
USAGE:
> echo 'foo,bar' | ./compose.mk stream.comma.to.nl
foo
bar
stream.comma.to.space
Converts comma-delimited input stream to space-delimited output
stream.csv.pygmentize
Highlights the input stream as if it were a CSV. Pygments actually
does not have a CSV lexer, so we have to fake it with an awk script.
USAGE: ( concrete )
echo one,two | ./compose.mk stream.csv.pygmentize
stream.dim
Pipe-friendly helper for dimming the input text.
USAGE:
$ echo "logging info" | ./compose.mk stream.dim
stream.dim.indent
Like 'io.print.indent' except it also dims the text.
stream.echo
Just echoes the input stream. Mostly used for testing. See also `flux.echo`.
EXAMPLE:
echo hello-world | ./compose.mk stream.echo
stream.fold
Uses fold(1) to wrap the input stream to the given width,
defaulting to current terminal width if nothing is provided.
Also available as a macro.
stream.glow
Renders markdown from stdin to stdout.
stream.help
Lists only the targets available under the 'stream' namespace.
stream.img
Given an image file on stdin, this shows a preview on the console.
Under the hood, this works using a dockerized version of `chafa`.
USAGE: ( generic )
> cat docs/img/docker.png | ./compose.mk stream.img.preview
stream.img.preview
Given an image file on stdin, this shows a preview on the console.
Under the hood, this works using a dockerized version of `chafa`.
USAGE: ( generic )
> cat docs/img/docker.png | ./compose.mk stream.img.preview
stream.indent
Indents the input stream to stdout. Also available as a macro.
For a version that works with stderr, see `stream.as.log`
stream.indent.to.stderr
Shortcut for ' .. | stream.indent | stream.to.stderr'
stream.ini.pygmentize
Highlights input stream using the 'ini' lexer.
stream.jb
Interface to jb[1]. You can use this to build JSON on the fly.
Also available as macro.
USAGE:
$ echo foo=bar | ./compose.mk stream.jb
{"foo":"bar"}
REFS:
`[1]:` https://github.com/h4l/json.bash
stream.json.append
Appends the given key/val to the input object.
This is usually used to build JSON objects from scratch.
USAGE:
> echo {} | key=foo val=bar ./compose.mk stream.json.object.append
{"foo":"bar"}
stream.json.array.append
Appends <val> to input array
USAGE:
> echo "[]" | val=1 ./compose.mk stream.json.array.append | val=2 make stream.json.array.append
[1,2]
stream.json.object.append
Appends the given key/val to the input object.
This is usually used to build JSON objects from scratch.
USAGE:
> echo {} | key=foo val=bar ./compose.mk stream.json.object.append
{"foo":"bar"}
stream.json.pygmentize
Syntax highlighting for the JSON on stdin.
stream.lstrip
Left-strips the input stream. Also available as a macro.
stream.markdown
Renders markdown from stdin to stdout.
stream.nl.enum
Enumerates the newline-delimited input stream, zipping index with values
USAGE:
> printf "one\ntwo" | ./compose.mk stream.nl.enum
0 one
1 two
stream.nl.to.comma
stream.nl.to.json.array
Converts newline-delimited input stream into a JSON array
stream.nl.to.space
Converts newline-delimited input stream to space-delimited output.
Also available as a macro.
USAGE:
$ echo '\nfoo\nbar' | ./compose.mk stream.nl.to.space
> foo bar
stream.peek
Prints the entire input stream as indented/dimmed text on stderr,
Then passes-through the entire stream to stdout. Note that this uses
a tmpfile because proc-substition seems to disorder output.
USAGE:
echo hello-world | ./compose.mk stream.peek | cat
stream.preview
Sends input stream to stderr.
Unlike 'stream.peek', this does not pass on the input stream.
stream.pygmentize
Syntax highlighting for the input stream.
Lexer will be autodetected unless override is provided.
Style defaults to 'monokai', which works best with dark backgrounds.
Also available as a macro.
USAGE: (using JSON lexer)
> echo {} | lexer=json ./compose.mk stream.pygmentize
REFS:
[1]: https://pygments.org/
[2]: https://pygments.org/styles/
stream.space.enum
Enumerates the space-delimited input list,
zipping indexes with values in newline delimited output.
USAGE:
printf one two | ./compose.mk stream.space.enum
0 one
1 two
stream.space.to.nl
Converts a space-separated stream to a newline-separated one
stream.strip
Pipe-friendly helper for stripping whitespace.
stream.to.docker/arg
This is a work-around because some interpreters require files and can not work with streams.
USAGE: ( generic )
echo ..code.. | ./compose.mk stream.to.docker/<img>,<optional_entrypoint>
USAGE: ( generic, as macro )
${mk.def.read}/<def_name> | ${stream.to.docker}/<img>,<optional_entrypoint>
stream.to.stderr
Sends input stream to stderr.
Unlike 'stream.peek', this does not pass on the input stream.
stream.yaml.to.json
Converts yaml to JSON
The stream.*
targets support IO streams, including basic stuff with JSON, newline-delimited, and space-delimited formats.
General purpose tools:
-
For conversion, see
stream.nl.to.comma
,stream.comma.to.nl
, etc. -
For JSON ops, see
stream.jb
[2] andstream.json.append.*
, etc -
For formatting and printing, see
stream.dim.*
, etc.
Macro Equivalents:
Most targets here are also available as macros, which can be used
as an optimization since it saves a process.
# For example, from a makefile, these are equivalent commands:
echo "one,two,three" | ${stream.comma.to.nl}
echo "one,two,three" | make stream.comma.to.nl
DOCS:
-
[1]:
Main API -
[2]:
Docs for jb