Getting started¶
This walks through detecting a project root with workspace, from install to a working
command.
Install¶
The module needs Go 1.26 or newer.
Detect from the current directory¶
The common case: a tool run from somewhere inside a project wants the project root.
DetectFromCWD starts the walk at the process working directory.
package main
import (
"fmt"
"github.com/spf13/afero"
"gitlab.com/phpboyscout/go/workspace"
)
func main() {
ws, err := workspace.DetectFromCWD(afero.NewOsFs(), workspace.DefaultMarkers)
if err != nil {
fmt.Println("not inside a project:", err)
return
}
fmt.Println("Project root:", ws.Root)
fmt.Println("Detected via:", ws.Marker)
}
Run it from any subdirectory of a Go module and it prints the module root and go.mod.
Detect from an explicit directory¶
When you already have a path — a flag value, an argument — use Detect and pass the
start directory yourself. It takes the same marker set and options.
startDir is resolved to an absolute path before the walk begins, so a relative path
works fine.
Handle "not found"¶
When no marker is seen before the filesystem root (or the depth bound), detection returns
workspace.ErrNotFound. Check for it with errors.Is:
ws, err := workspace.DetectFromCWD(afero.NewOsFs(), workspace.DefaultMarkers)
switch {
case errors.Is(err, workspace.ErrNotFound):
return errors.New("run this inside a project directory")
case err != nil:
return err
default:
// use ws.Root
}
Next steps¶
- Your project isn't a Go module? Detect other project types.
- Writing tests? Test filesystem walks in memory — no temp dirs.
- Curious how precedence and the depth bound work? The marker walk.