Querying Targets
Why Query Your Build Graph?
Understanding the relationships between your build targets is essential for optimizing your build process. Grog provides powerful querying capabilities that help you:
- Run only the targets affected by changes in CI, saving build time
- Understand dependencies between targets for better project organization
- Debug build issues by tracing dependency chains
- Create targeted build commands for specific workflows
Available Query Commands
Grog offers several commands that can be used individually or chained together with tools like jq
to extract precisely the information you need:
grog list
: List all targets matching a patterngrog deps
: Get a target’s dependencies (direct or transitive)grog rdeps
: Get a target’s dependents (“reverse dependencies”)grog owners
: Find targets that include specific files as inputsgrog changes
: Identify targets affected by changes since a specific commit
Target Selection Basics
Before diving into specific commands, it’s important to understand how to select targets in Grog. Most query commands accept target patterns that let you specify individual targets or groups of targets.
Target Patterns
# Reference a single targetgrog build //package:target_name
# Reference all targets in a packagegrog build //package:all
# Reference all targets in a package and its sub-packagesgrog build //package/...
# Reference a target in the current packagegrog build :target_name
Filtering by Tags
You can add tags to your targets in their definitions and then filter by those tags:
# Build all targets in the model_training package# that have either the "ci-only" OR "python" taggrog build --tag=ci-only --tag=python //model_training/...
grog list
grog list [target-pattern]
Lists all targets that match the given target pattern. If no pattern is provided, it lists all targets in the repository.
Examples:
# List all targets in the repositorygrog list
# List all targets in a specific package and its sub-packagesgrog list //services/...
# List all targets in a specific package (not including sub-packages)grog list //services:all
Output format:
//package:target1//package:target2//package/subpackage:target3...
grog deps
grog deps <target-label> [--transitive]
Lists the dependencies of a specific target. By default, it shows only direct dependencies, but with the --transitive
flag, it shows the complete dependency tree.
Examples:
# Show direct dependencies of a targetgrog deps //services/api:server
# Show all transitive dependencies (the complete dependency tree)grog deps --transitive //services/api:server
This command is particularly useful for understanding what needs to be built before a specific target can be built.
grog rdeps
grog rdeps <target-pattern> [--transitive]
Lists all targets that depend on the specified target(s) - essentially the reverse of deps
. The --transitive
flag includes indirect dependents.
Examples:
# Find all targets that directly depend on a librarygrog rdeps //libs/common:utils
# Find all targets that directly or indirectly depend on a librarygrog rdeps --transitive //libs/common:utils
This command helps you understand the impact of changes to a target - which other targets will need to be rebuilt if this target changes.
grog owners
grog owners <file-path-or-glob>
Finds all targets that include the specified file(s) in their inputs. This is useful for determining which targets need to be rebuilt when specific files change.
Examples:
# Find targets that use a specific filegrog owners src/libs/auth/login.go
# Find targets that use any Go file in a directorygrog owners src/libs/auth/**/*.go
This command is particularly helpful when you want to understand which parts of your build are affected by changes to specific files.
grog changes
grog changes [target-pattern] [--since=<commit>] [--dependents=none|direct|transitive]
Identifies targets whose inputs have changed since a specific commit. This is extremely useful for CI pipelines where you only want to build what’s changed.
Parameters:
--since
: The git commit to compare against (defaults to HEAD~1)--dependents
: Controls whether to include targets that depend on changed targetsnone
: Only include directly changed targets (default)direct
: Include changed targets and their direct dependentstransitive
: Include changed targets and all their dependents (direct and indirect)
Examples:
# Find all targets that changed in the current commitgrog changes
# Find all targets that changed since a specific commitgrog changes --since=origin/main
# Find all targets that changed in a specific package since a specific commitgrog changes //services/api/... --since=origin/main
# Find all targets affected by changes (including dependents)grog changes --since=origin/main --dependents=transitive
CI Pipeline Example
This command is particularly valuable in CI pipelines. Here’s an example of how you might use it in a GitHub Actions workflow:
jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: fetch-depth: 0 # Needed to access commit history
- name: Build changed targets run: | # Get all targets affected by changes since the merge base with main CHANGED_TARGETS=$(grog changes --since=origin/main --dependents=transitive)
# If there are changed targets, build them if [ -n "$CHANGED_TARGETS" ]; then echo "Building changed targets: $CHANGED_TARGETS" grog build $CHANGED_TARGETS else echo "No targets changed, skipping build" fi
Combining Query Commands
You can combine Grog’s query commands with standard Unix tools to create powerful workflows:
# Find all test targets affected by changesgrog changes --since=origin/main --dependents=transitive | grep "test$" | xargs grog test
# Find all Docker targets that depend on a specific librarygrog rdeps --transitive //libs/common:utils | grep "docker" | xargs grog build
By mastering Grog’s query commands, you can significantly optimize your build process and gain deeper insights into your project’s structure.