Feature
Summary
The buf format command currently accepts only a single <source> positional argument. This makes it incompatible with tools like lint-staged, which pass multiple file paths as positional arguments to formatters. Supporting multiple file paths would greatly improve the developer experience for teams using buf format in pre-commit hooks.
Current Behavior
$ buf format -w file1.proto file2.proto file3.proto
# Error: accepts at most 1 arg(s), received 3
The command fails when given multiple files as positional arguments.
Expected Behavior
$ buf format -w file1.proto file2.proto file3.proto
# Successfully formats all three files
The command should accept multiple file paths and format each of them.
Use Case
Many teams use lint-staged with husky (or similar tools like pre-commit) to run formatters only on staged files during git commits. This is a common pattern for maintaining code quality without formatting the entire codebase on every commit.
lint-staged works by passing the list of staged files as positional arguments to the configured command:
{
"**/*.proto": "buf format -w"
}
When multiple .proto files are staged, lint-staged executes:
buf format -w path/to/file1.proto path/to/file2.proto path/to/file3.proto
This pattern works out-of-the-box with most formatters:
prettier --write ✅
biome check --write ✅
eslint --fix ✅
black (Python) ✅
gofmt -w ✅
buf format -w ❌
Current Workaround
The workaround is to use a bash wrapper that converts positional arguments to --path flags:
{
"**/*.proto": "bash -c 'args=(); for f in \"$@\"; do args+=(--path \"$f\"); done; buf format -w . \"${args[@]}\"' _"
}
While functional, this workaround:
- Is not intuitive or discoverable
- Adds complexity to the configuration
- May not work on all platforms (Windows without bash)
- Requires understanding of bash array manipulation
Proposed Solution
Accept multiple file paths as positional arguments:
# Format multiple specific files
buf format -w file1.proto file2.proto file3.proto
# Equivalent to current behavior with --path
buf format -w . --path file1.proto --path file2.proto --path file3.proto
Alternative: Accept files via stdin
Another option would be to accept file paths from stdin, similar to xargs:
echo "file1.proto file2.proto" | buf format -w --stdin
Additional Context
This is a common pattern request for CLI tools that integrate with the JavaScript/TypeScript ecosystem's pre-commit tooling. The lint-staged project has over 13k GitHub stars and is widely used, so improving compatibility would benefit many developers working with Protocol Buffers.
Related tools that have addressed similar requests:
- Prettier accepts multiple files:
prettier --write file1 file2 file3
- ESLint accepts multiple files:
eslint --fix file1 file2 file3
- Biome accepts multiple files:
biome check --write file1 file2 file3
Feature
Summary
The
buf formatcommand currently accepts only a single<source>positional argument. This makes it incompatible with tools like lint-staged, which pass multiple file paths as positional arguments to formatters. Supporting multiple file paths would greatly improve the developer experience for teams usingbuf formatin pre-commit hooks.Current Behavior
$ buf format -w file1.proto file2.proto file3.proto # Error: accepts at most 1 arg(s), received 3The command fails when given multiple files as positional arguments.
Expected Behavior
$ buf format -w file1.proto file2.proto file3.proto # Successfully formats all three filesThe command should accept multiple file paths and format each of them.
Use Case
Many teams use lint-staged with husky (or similar tools like pre-commit) to run formatters only on staged files during git commits. This is a common pattern for maintaining code quality without formatting the entire codebase on every commit.
lint-staged works by passing the list of staged files as positional arguments to the configured command:
{ "**/*.proto": "buf format -w" }When multiple
.protofiles are staged, lint-staged executes:This pattern works out-of-the-box with most formatters:
prettier --write✅biome check --write✅eslint --fix✅black(Python) ✅gofmt -w✅buf format -w❌Current Workaround
The workaround is to use a bash wrapper that converts positional arguments to
--pathflags:{ "**/*.proto": "bash -c 'args=(); for f in \"$@\"; do args+=(--path \"$f\"); done; buf format -w . \"${args[@]}\"' _" }While functional, this workaround:
Proposed Solution
Accept multiple file paths as positional arguments:
Alternative: Accept files via stdin
Another option would be to accept file paths from stdin, similar to
xargs:Additional Context
This is a common pattern request for CLI tools that integrate with the JavaScript/TypeScript ecosystem's pre-commit tooling. The lint-staged project has over 13k GitHub stars and is widely used, so improving compatibility would benefit many developers working with Protocol Buffers.
Related tools that have addressed similar requests:
prettier --write file1 file2 file3eslint --fix file1 file2 file3biome check --write file1 file2 file3