$ go version
go version devel go1.21-f90b4cd655 Fri May 26 03:21:41 2023 +0000 linux/amd64
$ go list -f '{{.Imports}}{{"\n"}}{{.Deps}}' runtime/cgo
[C runtime/internal/sys sync sync/atomic unsafe]
[internal/abi internal/bytealg internal/coverage/rtcov internal/cpu internal/goarch internal/godebugs internal/goexperiment internal/goos internal/race runtime runtime/internal/atomic runtime/internal/math runtime/internal/sys runtime/internal/syscall sync sync/atomic unsafe]
Note how runtime/cgo includes C in its Imports field, but not in its Deps field. 1.20 is the same in this regard:
$ go version
go version go1.20.4 linux/amd64
$ go list -f '{{.Imports}}{{"\n"}}{{.Deps}}' runtime/cgo
[C runtime/internal/sys sync sync/atomic unsafe]
[internal/abi internal/bytealg internal/coverage/rtcov internal/cpu internal/goarch internal/goexperiment internal/goos internal/race runtime runtime/internal/atomic runtime/internal/math runtime/internal/sys runtime/internal/syscall sync sync/atomic unsafe]
The docs say:
Imports []string // import paths used by this package
Deps []string // all (recursively) imported dependencies
So I always naively assumed Imports to be a strict subset of Deps, since one is the set of direct imports, and the other is the set of all direct and indirect package dependencies (transitive imports). However, C breaks this rule.
I think Imports should stop including C, and here are my reasons why:
- Consistency; if
Imports is not the list of direct dependencies, compared to the list of all transitive dependencies in Deps, then how do I get the list of direct dependencies? Right now I'm taking Imports and removing C from it, which feels hacky.
C is not truly a Go package nor a useful import path; see how go list C fails in a funky way (which arguably could be fixed to give a better error, too).
- If a user or tool want to know whether a package uses CGo, they can already consult the
CgoFiles field, which is clearer and more directly useful.
Deps never included it either, so that's some proof that it's not really needed as a package dependency.
The only reason why one could argue that Imports should include C is that there really is an import "C" in the source code. However, Imports is not a direct representation of the import declarations in the source code; they are deduplicated, sorted, and omit any renames like import foo "bar" or import _ "baz".
Note how
runtime/cgoincludesCin itsImportsfield, but not in itsDepsfield. 1.20 is the same in this regard:The docs say:
So I always naively assumed
Importsto be a strict subset ofDeps, since one is the set of direct imports, and the other is the set of all direct and indirect package dependencies (transitive imports). However,Cbreaks this rule.I think
Importsshould stop includingC, and here are my reasons why:Importsis not the list of direct dependencies, compared to the list of all transitive dependencies inDeps, then how do I get the list of direct dependencies? Right now I'm takingImportsand removingCfrom it, which feels hacky.Cis not truly a Go package nor a useful import path; see howgo list Cfails in a funky way (which arguably could be fixed to give a better error, too).CgoFilesfield, which is clearer and more directly useful.Depsnever included it either, so that's some proof that it's not really needed as a package dependency.The only reason why one could argue that
Importsshould includeCis that there really is animport "C"in the source code. However,Importsis not a direct representation of the import declarations in the source code; they are deduplicated, sorted, and omit any renames likeimport foo "bar"orimport _ "baz".