gofasta impact
Reports the blast radius of a target — every package that depends on it (directly or transitively) and every source file in those packages. Use it before a signature change to know what breaks, when scoping a code review, or when deciding which packages a CI run actually has to re-test.
Loads the whole module with go/packages (full type info), then walks the import graph in reverse from the target. No filesystem scraping, no grep — type-aware so renames and aliases are followed correctly.
Usage
gofasta impact <file-or-package> [--json]The target can be either a file path or an import path:
app/services/order.service.go— a Go file (resolved to its containing package)irodata/app/services— a full import path
Both forms produce the same answer if they resolve to the same package.
Flags
gofasta impact takes no command-specific flags. It honors the global --json flag for machine-parseable output.
Output
Text mode
$ gofasta impact app/services/order.service.go
Target: app/services/order.service.go
Package: irodata/app/services
Direct importers (2):
· irodata/app/di/providers
· irodata/app/rest/controllers
Transitive importers (4):
· irodata/app/di
· irodata/app/di/providers
· irodata/app/rest/controllers
· irodata/cmd
Impacted files (12) — pass to `gofasta verify --since=<ref>` for a scoped check.JSON mode
gofasta impact irodata/app/services --json{
"target": "irodata/app/services",
"package": "irodata/app/services",
"direct_importers": [
"irodata/app/di/providers",
"irodata/app/rest/controllers"
],
"transitive_importers": [
"irodata/app/di",
"irodata/app/di/providers",
"irodata/app/rest/controllers",
"irodata/cmd"
],
"impacted_files": [
"app/di/container.go",
"app/di/wire.go",
"app/di/providers/order.go",
"app/rest/controllers/order.controller.go"
]
}The JSON contract is stable for agent consumption — every field is always present (null when empty).
Examples
Find every package that depends on the order service:
gofasta impact app/services/order.service.goSame answer via import path:
gofasta impact irodata/app/servicesPipe direct importers to another tool:
gofasta impact irodata/app/services --json | jq -r '.direct_importers[]'Confirm a DTO change is isolated (no transitive importers outside dtos/):
gofasta impact app/dtos/order.dtos.go --json | jq '.transitive_importers'How it works
- Load the module.
go/packages.Load("./...", NeedTypes | NeedImports | ...)parses every package with full type info. This is the expensive step (a few seconds on a medium project). - Resolve the target. If the input ends in
.goand matches a file inpkg.GoFilesof some loaded package, the package’s import path is used. Otherwise the input is treated as a direct import path. ReturnsSYMBOL_NOT_FOUNDif neither resolution succeeds. - Build the reverse map. Invert each loaded package’s
Importssorev[imp] = {p : imp ∈ p.Imports}. - BFS from the target. Walk
revto find direct + transitive importers. - Collect files. For each impacted package, list its
GoFiles(cwd-relative).
The reverse walk is O(N) over module size. Loading the module dominates total runtime.
Error codes
| Code | When |
|---|---|
SYMBOL_NOT_FOUND | The target didn’t resolve to a loaded package. Check for typos or whether you’re in the right module root. |
PACKAGE_LOAD_FAILED | go/packages.Load errored (missing go.mod, compile errors that prevent type-checking, or ./... returning zero packages). |
When to use
- Before a signature change. “If I change
OrderService.Create’s return type, what breaks?” →gofasta impact app/services/order.service.go. - PR scoping. Feed
--json | jq '.impacted_files'intogofasta verify --since=…-style tooling to test only the affected packages. - Deletion safety. “Is this helper still used?” → If
direct_importersis empty, the package is dead code. - Code review. Reviewers can see at a glance whether a change in a leaf package is contained or rippling.