Skip to content

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 //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::generated

$(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::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-check

$(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::bundle

$(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-package