Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
- Add `--stdin-filepath` flag to `buf format`, which reads a single `.proto` file from
stdin and writes the formatted result to stdout. The path is not read from disk, and is
only used to report parse errors and diffs.
- Parse v2 `buf.lock` files non-strictly, ignoring unknown fields. A `buf.lock` written by a
newer `buf` that records additional fields no longer fails to parse on an older `buf`.
Comment on lines +11 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe doens't need a changelog as not user facing.


## [v1.73.0] - 2026-09-11

Expand Down
4 changes: 3 additions & 1 deletion private/bufpkg/bufconfig/buf_lock_file.go
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,9 @@ func readBufLockFile(
return newBufLockFile(fileVersion, objectData, depModuleKeys, nil /* remotePluginKeys */, nil /* remotePolicyKeys */, nil /* remotePolicyPluginKeys */)
case FileVersionV2:
var externalBufLockFile externalBufLockFileV2
if err := getUnmarshalStrict(allowJSON)(data, &externalBufLockFile); err != nil {
// Parse non-strict to allow unknown fields possibly written by a newer version of buf.
// Unknown fields are dropped and not written back.
if err := getUnmarshalNonStrict(allowJSON)(data, &externalBufLockFile); err != nil {
return nil, err
}
depModuleKeys := make([]bufmodule.ModuleKey, len(externalBufLockFile.Deps))
Expand Down
71 changes: 71 additions & 0 deletions private/bufpkg/bufconfig/buf_lock_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,77 @@ policies:
)
}

// TestReadBufLockFileIgnoresUnknownFields covers that a buf.lock written by a newer buf
// with fields this version does not know is still readable, and that the unknown fields
// are dropped rather than written back.
func TestReadBufLockFileIgnoresUnknownFields(t *testing.T) {
t.Parallel()

testReadWriteBufLockFileRoundTrip(
t,
// input
`version: v2
future_top_level_field: value
deps:
- name: buf.testing/acme/date
future_dep_field: value
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: b5:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
plugins:
- name: buf.testing/acme/plugin
future_plugin_field: value
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: p1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
policies:
- name: buf.testing/acme/policy
future_policy_field: value
commit: b8488077ea6d4f6d9562a337b98259c8
digest: o1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
plugins:
- name: buf.testing/acme/plugin
future_policy_plugin_field: value
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: p1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
`,
// expected output
`version: v2
deps:
- name: buf.testing/acme/date
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: b5:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
plugins:
- name: buf.testing/acme/plugin
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: p1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
policies:
- name: buf.testing/acme/policy
commit: b8488077ea6d4f6d9562a337b98259c8
digest: o1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
plugins:
- name: buf.testing/acme/plugin
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: p1:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
`,
)

// v1 buf.lock files are still parsed strictly. They are no longer written, so there
// is no newer buf that could add a field to them.
_, err := ReadBufLockFile(
t.Context(),
strings.NewReader(testCleanYAMLData(`version: v1
future_top_level_field: value
deps:
- remote: buf.testing
owner: acme
repository: date
commit: ffded0b4cf6b47cab74da08d291a3c2f
digest: shake256:24ed4f13925cf89ea0ae0127fa28540704c7ae14750af027270221b737a1ce658f8014ca2555f6f7fcd95ea84e071d33f37f86cc36d07fe0d0963329a5ec2462
`)),
DefaultBufLockFileName,
)
require.ErrorContains(t, err, "future_top_level_field")
}

func testReadBufLockFile(
t *testing.T,
inputBufLockFileData string,
Expand Down
Loading