Skip to content

Commit 5fa5eb3

Browse files
authored
Merge branch 'master' into master
2 parents 462561b + 9212866 commit 5fa5eb3

File tree

175 files changed

+6114
-3049
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

175 files changed

+6114
-3049
lines changed

apidiff/README.md

Lines changed: 116 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
1-
# Checking Go Package API Compatibility
1+
# Checking Go API Compatibility
22

3-
The `apidiff` tool in this directory determines whether two versions of the same
4-
package are compatible. The goal is to help the developer make an informed
5-
choice of semantic version after they have changed the code of their module.
3+
The `apidiff` tool in this directory determines whether two examples of a
4+
package or module are compatible. The goal is to help the developer make an
5+
informed choice of semantic version after they have changed the code of their
6+
module.
67

78
`apidiff` reports two kinds of changes: incompatible ones, which require
89
incrementing the major part of the semantic version, and compatible ones, which
910
require a minor version increment. If no API changes are reported but there are
1011
code changes that could affect client code, then the patch version should
1112
be incremented.
1213

13-
Because `apidiff` ignores package import paths, it may be used to display API
14-
differences between any two packages, not just different versions of the same
15-
package.
16-
17-
The current version of `apidiff` compares only packages, not modules.
18-
14+
`apidiff` may be used to display API differences between any two packages or
15+
modules, not just different versions of the same thing. It does this by ignoring
16+
the package import paths when directly comparing two packages, and
17+
by ignoring module paths when comparing two modules. That is to say, when
18+
comparing two modules, the package import paths **do** matter, but are compared
19+
_relative_ to their respective module root.
1920

2021
## Compatibility Desiderata
2122

@@ -222,6 +223,111 @@ element types correspond.
222223

223224
We can now present the definition of compatibility used by `apidiff`.
224225

226+
### Module Compatibility
227+
228+
> A new module is compatible with an old one if:
229+
>1. Each package present in the old module also appears in the new module,
230+
> with matching import paths relative to their respective module root, and
231+
>2. Each package present in both modules fulfills Package Compatibility as
232+
> defined below.
233+
>
234+
>Otherwise the modules are incompatible.
235+
236+
If a package is converted into a nested module of the original module then
237+
comparing two versions of the module, before and after nested module creation,
238+
will produce an incompatible package removal message. This removal message does
239+
not necessarily mean that client code will need to change. If the package API
240+
retains Package Compatibility after nested module creation, then only the
241+
`go.mod` of the client code will need to change. Take the following example:
242+
243+
```
244+
./
245+
go.mod
246+
go.sum
247+
foo.go
248+
bar/bar.go
249+
```
250+
251+
Where `go.mod` is:
252+
253+
```
254+
module example.com/foo
255+
256+
go 1.20
257+
```
258+
259+
Where `bar/bar.go` is:
260+
261+
```
262+
package bar
263+
264+
var V int
265+
```
266+
267+
And `foo.go` is:
268+
269+
```
270+
package foo
271+
272+
import "example.com/foo/bar"
273+
274+
_ = bar.V
275+
```
276+
277+
Creating a nested module with the package `bar` while retaining Package
278+
Compatibility is _code_ compatible, because the import path of the package does
279+
not change:
280+
281+
```
282+
./
283+
go.mod
284+
go.sum
285+
foo.go
286+
bar/
287+
bar.go
288+
go.mod
289+
go.sum
290+
```
291+
292+
Where `bar/go.mod` is:
293+
```
294+
module example.com/foo/bar
295+
296+
go 1.20
297+
```
298+
299+
And the top-level `go.mod` becomes:
300+
```
301+
module example.com/foo
302+
303+
go 1.20
304+
305+
// New dependency on nested module.
306+
require example.com/foo/bar v1.0.0
307+
```
308+
309+
If during nested module creation either Package Compatibility is broken, like so
310+
in `bar/bar.go`:
311+
312+
```
313+
package bar
314+
315+
// Changed from V to T.
316+
var T int
317+
```
318+
319+
Or the nested module uses a name other than the original package's import path,
320+
like so in `bar/go.mod`:
321+
322+
```
323+
// Completely different module name
324+
module example.com/qux
325+
326+
go 1.20
327+
```
328+
329+
Then the move is backwards incompatible for client code.
330+
225331
### Package Compatibility
226332

227333
> A new package is compatible with an old one if:

0 commit comments

Comments
 (0)