Что означает троеточие `./...` в командах Go?
Что такое `./...` в Go: полное объяснение
Вы всё правильно поняли — `./...` в командах Go действительно означает рекурсивный обход всех подпапок относительно указанного пути. Это не магия, а специальный паттерн, встроенный в инструментарий Go (go toolchain) для работы с пакетами.
Как это работает
Конструкция `...` (три точки) в Go-командах — это wildcard (шаблон), который означает "все подпакеты рекурсивно". Когда вы пишете:
go test ./...
Go ищет все пакеты (директории с файлами `.go`), начиная с текущей директории (`./`) и рекурсивно заходя во все вложенные папки. Для каждого найденного пакета выполняется команда (в данном случае `go test`).
Конкретные примеры
Предположим, у вас такая структура проекта:
myproject/
├── main.go
├── utils/
│ ├── math.go
│ └── math_test.go
├── api/
│ ├── handler.go
│ └── handler_test.go
└── internal/
└── db/
├── database.go
└── database_test.go
Команды и их эффект:
go test ./...— протестирует пакеты:myproject,myproject/utils,myproject/api,myproject/internal/db.go test ./utils/...— протестирует толькоmyproject/utils(и его подпакеты, если бы они были).go test .— протестирует только корневой пакетmyproject(без вложенных).go test ./utils— протестирует толькоmyproject/utils(без рекурсии).
Почему `go run ./...` не работает?
Команда go run предназначена для запуска одного main-пакета (с функцией main()). Она не поддерживает множественные пакеты или рекурсивный обход. Если вам нужно запустить все main-пакеты в проекте, используйте go run ./cmd/... (если структура позволяет) или скрипт оболочки.
Где можно использовать `./...`
Паттерн `...` поддерживается следующими командами:
go buildgo testgo vetgo listgo cleango install
Расширенные возможности
Вы также можете использовать `...` для указания конкретных пакетов внутри модуля:
go test github.com/username/myproject/...
Или для исключения тестов в vendor-папках (если вы используете vendoring):
go test ./... -mod=mod
Практический совет
В современных Go-проектах (с go modules) ./... — это стандартный способ убедиться, что вы не пропустили ни один пакет. Особенно полезно для CI/CD, когда нужно проверить весь проект одной командой.
Альтернативный взгляд: как `...` обрабатывается внутри
Стоит добавить, что `./...` — это не просто "магическая строка", а часть паттерна соответствия пакетов в Go. Технически, когда вы пишете go test ./..., Go делает следующее:
- Определяет корень модуля (файл go.mod).
- Сканирует все директории от указанного пути рекурсивно.
- Фильтрует только те директории, которые содержат хотя бы один файл `.go` (это и есть пакеты).
- Выполняет команду для каждого такого пакета.
Важный нюанс с vendor
Если ваш проект использует go mod vendor, то ./... не будет заходить в папку vendor/ — Go автоматически её исключает. Это сделано, чтобы не тестировать сторонние зависимости случайно.
Комбинация с другими паттернами
Вы можете комбинировать `...` с отрицанием:
go test ./... -run TestIntegration -count=1
Это запустит только тесты, имя которых содержит "TestIntegration", но во всех пакетах рекурсивно.
Также обратите внимание, что ./... работает только в контексте go-команд. В обычной оболочке (bash, zsh) три точки не имеют специального значения — это именно фича инструментария Go.