Script Functions
Grog injects several helper shell functions into every target command and output check. These helpers let you reference dependency outputs without hard-coding file paths or worrying about where the target is executed from.
$(bin)
Section titled “$(bin)”$(bin //pkg:target) returns the absolute path to the dependency’s bin_output.
You can also use the shorthand $(bin :target) for dependencies that live in the same package, or $(bin //pkg) when the target label can be shortened.
- name: generate_stubs dependencies: - //tools:protoc command: | # The protoc binary path resolves automatically regardless of cwd $(bin //tools:protoc) --python_out=generated proto/*.proto outputs: - dir::generatedtargets { new { name = "generate_stubs" dependencies { "//tools:protoc" } command = """ # The protoc binary path resolves automatically regardless of cwd $(bin //tools:protoc) --python_out=generated proto/*.proto """ outputs { "dir::generated" } }}$(output)
Section titled “$(output)”$(output <label> <index>) exposes every output produced by a dependency.
Indexes are zero-based and follow the order defined in the dependency’s outputs list (with its bin_output appended last when present).
File and directory outputs resolve to absolute paths on disk, while other output types return their identifier strings—for example, Docker outputs return the image tag you defined.
- name: package_site dependencies: - //frontend:build command: | # Copy the compiled assets from the build target's first output directory cp -R $(output //frontend:build 0) dist/ outputs: - dir::disttargets { new { name = "package_site" dependencies { "//frontend:build" } command = """ # Copy the compiled assets from the build target's first output directory cp -R $(output //frontend:build 0) dist/ """ outputs { "dir::dist" } }}Use the same shorthand label forms as $(bin) (:target for same-package deps and //pkg for shorten-able labels).
If you reference an index that does not exist—or a dependency that produces no outputs—Grog exits with an error so you can fix the command quickly.
To reference Docker images (or any other non-filesystem outputs), use the identifier directly:
- name: smoke_test_image dependencies: - //containers:backend_image command: | docker run --rm $(output //containers:backend_image 0) --health-checktargets { new { name = "smoke_test_image" dependencies { "//containers:backend_image" } command = """ docker run --rm $(output //containers:backend_image 0) """ }}$(transitive_outputs)
Section titled “$(transitive_outputs)”$(transitive_outputs) returns newline-separated output paths from all transitive dependencies—not just direct ones.
This is useful when a target needs to aggregate outputs from its full ancestor graph without knowing the exact dependency tree at authoring time.
When there are no transitive dependencies (or none of them produce outputs), the function silently returns nothing.
- name: bundle_all dependencies: - //libs:core command: | # Collect every output produced by any transitive dependency for artifact in $(transitive_outputs); do cp "$artifact" bundle/ done outputs: - dir::bundletargets { new { name = "bundle_all" dependencies { "//libs:core" } command = """ # Collect every output produced by any transitive dependency for artifact in $(transitive_outputs); do cp "$artifact" bundle/ done """ outputs { "dir::bundle" } }}$(transitive_outputs_by_tag)
Section titled “$(transitive_outputs_by_tag)”$(transitive_outputs_by_tag <tag>) returns newline-separated output paths from transitive dependencies that carry a specific tag.
This lets you select a subset of ancestor outputs based on a convention you define with tags, rather than listing every dependency label by hand.
If no transitive dependency carries the requested tag, the function exits with an error to make the misconfiguration obvious. When there are no transitive tagged outputs at all (the target has no transitive deps with tags), the function silently returns nothing.
# A library target that tags its outputs for downstream discovery- name: my_lib tags: - find-links command: | python -m build --wheel --outdir dist/ outputs: - dir::dist
# A downstream target that collects all find-links directories# from the full transitive dependency graph- name: install dependencies: - //libs:my_lib command: | FIND_LINKS="" for dir in $(transitive_outputs_by_tag find-links); do FIND_LINKS="$FIND_LINKS --find-links $dir" done pip install $FIND_LINKS my-packagetargets { new { name = "my_lib" tags { "find-links" } command = """ python -m build --wheel --outdir dist/ """ outputs { "dir::dist" } } new { name = "install" dependencies { "//libs:my_lib" } command = """ FIND_LINKS="" for dir in $(transitive_outputs_by_tag find-links); do FIND_LINKS="$FIND_LINKS --find-links $dir" done pip install $FIND_LINKS my-package """ }}