"testing"
)
- // pkgDeps defines the expected dependencies between packages in
+ // depsRules defines the expected dependencies between packages in
// the Go source tree. It is a statement of policy.
- // Changes should not be made to this map without prior discussion.
- //
- // The map contains two kinds of entries:
- // 1) Lower-case keys are standard import paths and list the
- // allowed imports in that package.
- // 2) Upper-case keys define aliases for package sets, which can then
- // be used as dependencies by other rules.
//
// DO NOT CHANGE THIS DATA TO FIX BUILDS.
+ // Existing packages should not have their constraints relaxed
+ // without prior discussion.
+ // Negative assertions should almost never be removed.
//
- var pkgDeps = map[string][]string{
- // L0 is the lowest level, core, nearly unavoidable packages.
- "errors": {"runtime", "internal/reflectlite"},
- "io": {"errors", "sync", "sync/atomic"},
- "runtime": {"unsafe", "runtime/internal/atomic", "runtime/internal/sys", "runtime/internal/math", "internal/cpu", "internal/bytealg"},
- "runtime/internal/sys": {},
- "runtime/internal/atomic": {"unsafe", "internal/cpu"},
- "runtime/internal/math": {"runtime/internal/sys"},
- "internal/race": {"runtime", "unsafe"},
- "sync": {"internal/race", "runtime", "sync/atomic", "unsafe"},
- "sync/atomic": {"unsafe"},
- "unsafe": {},
- "internal/cpu": {},
- "internal/bytealg": {"unsafe", "internal/cpu"},
- "internal/reflectlite": {"runtime", "unsafe", "internal/unsafeheader"},
- "internal/unsafeheader": {"unsafe"},
-
- "L0": {
- "errors",
- "io",
- "runtime",
- "runtime/internal/atomic",
- "sync",
- "sync/atomic",
- "unsafe",
- "internal/cpu",
- "internal/bytealg",
- "internal/reflectlite",
- },
-
- // L1 adds simple functions and strings processing,
- // but not Unicode tables.
- "math": {"internal/cpu", "unsafe", "math/bits"},
- "math/bits": {"unsafe"},
- "math/cmplx": {"math", "math/bits"},
- "math/rand": {"L0", "math"},
- "strconv": {"L0", "unicode/utf8", "math", "math/bits"},
- "unicode/utf16": {},
- "unicode/utf8": {},
-
- "L1": {
- "L0",
- "math",
- "math/bits",
- "math/cmplx",
- "math/rand",
- "sort",
- "strconv",
- "unicode/utf16",
- "unicode/utf8",
- },
-
- // L2 adds Unicode and strings processing.
- "bufio": {"L0", "unicode/utf8", "bytes", "strings"},
- "bytes": {"L0", "unicode", "unicode/utf8"},
- "path": {"L0", "unicode/utf8", "strings"},
- "strings": {"L0", "unicode", "unicode/utf8"},
- "unicode": {},
-
- "L2": {
- "L1",
- "bufio",
- "bytes",
- "path",
- "strings",
- "unicode",
- },
-
- // L3 adds reflection and some basic utility packages
- // and interface definitions, but nothing that makes
- // system calls.
- "crypto": {"L2", "hash"}, // interfaces
- "crypto/cipher": {"L2", "crypto/subtle", "crypto/internal/subtle", "encoding/binary"},
- "crypto/internal/subtle": {"unsafe", "reflect"}, // reflect behind a appengine tag
- "crypto/subtle": {},
- "encoding/base32": {"L2"},
- "encoding/base64": {"L2", "encoding/binary"},
- "encoding/binary": {"L2", "reflect"},
- "hash": {"L2"}, // interfaces
- "hash/adler32": {"L2", "hash"},
- "hash/crc32": {"L2", "hash"},
- "hash/crc64": {"L2", "hash"},
- "hash/fnv": {"L2", "hash"},
- "hash/maphash": {"L2", "hash"},
- "image": {"L2", "image/color"}, // interfaces
- "image/color": {"L2"}, // interfaces
- "image/color/palette": {"L2", "image/color"},
- "internal/fmtsort": {"reflect", "sort"},
- "reflect": {"L2", "internal/unsafeheader"},
- "sort": {"internal/reflectlite"},
-
- "crypto/internal/boring": {"L2", "C", "crypto", "crypto/cipher", "crypto/internal/boring/sig", "crypto/subtle", "encoding/asn1", "hash", "math/big"},
- "crypto/internal/boring/fipstls": {"sync/atomic"},
- "crypto/internal/cipherhw": {"crypto/internal/boring"},
- "crypto/tls/fipsonly": {"crypto/internal/boring/fipstls", "crypto/internal/boring/sig"},
-
- "L3": {
- "L2",
- "crypto",
- "crypto/cipher",
- "crypto/internal/boring",
- "crypto/internal/boring/fipstls",
- "crypto/internal/subtle",
- "crypto/subtle",
- "encoding/base32",
- "encoding/base64",
- "encoding/binary",
- "hash",
- "hash/adler32",
- "hash/crc32",
- "hash/crc64",
- "hash/fnv",
- "image",
- "image/color",
- "image/color/palette",
- "internal/fmtsort",
- "internal/oserror",
- "reflect",
- },
-
- // End of linear dependency definitions.
-
- // Operating system access.
- "syscall": {"L0", "internal/oserror", "internal/race", "internal/syscall/windows/sysdll", "internal/unsafeheader", "syscall/js", "unicode/utf16"},
- "syscall/js": {"L0"},
- "internal/oserror": {"L0"},
- "internal/syscall/unix": {"L0", "syscall"},
- "internal/syscall/windows": {"L0", "syscall", "internal/syscall/windows/sysdll", "internal/unsafeheader", "unicode/utf16"},
- "internal/syscall/windows/registry": {"L0", "syscall", "internal/syscall/windows/sysdll", "unicode/utf16"},
- "internal/syscall/execenv": {"L0", "syscall", "internal/syscall/windows", "unicode/utf16"},
- "time": {
- // "L0" without the "io" package:
- "errors",
- "runtime",
- "runtime/internal/atomic",
- "sync",
- "sync/atomic",
- "unsafe",
- // Other time dependencies:
- "internal/syscall/windows/registry",
- "syscall",
- "syscall/js",
- "time/tzdata",
- },
- "time/tzdata": {"L0", "syscall"},
-
- "internal/cfg": {"L0"},
- "internal/poll": {"L0", "internal/oserror", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8", "internal/syscall/windows", "internal/syscall/unix"},
- "internal/testlog": {"L0"},
- "os": {"L1", "os", "syscall", "time", "internal/oserror", "internal/poll", "internal/syscall/windows", "internal/syscall/unix", "internal/syscall/execenv", "internal/testlog"},
- "path/filepath": {"L2", "os", "syscall", "internal/syscall/windows"},
- "io/ioutil": {"L2", "os", "path/filepath", "time"},
- "os/exec": {"L2", "os", "context", "path/filepath", "syscall", "internal/syscall/execenv"},
- "os/signal": {"L2", "os", "syscall"},
-
- // OS enables basic operating system functionality,
- // but not direct use of package syscall, nor os/signal.
- "OS": {
- "io/ioutil",
- "os",
- "os/exec",
- "path/filepath",
- "time",
- },
-
- // Formatted I/O: few dependencies (L1) but we must add reflect and internal/fmtsort.
- "fmt": {"L1", "os", "reflect", "internal/fmtsort"},
- "log": {"L1", "os", "fmt", "time"},
-
- // Packages used by testing must be low-level (L2+fmt).
- "regexp": {"L2", "regexp/syntax"},
- "regexp/syntax": {"L2"},
- "runtime/debug": {"L2", "fmt", "io/ioutil", "os", "time"},
- "runtime/pprof": {"L2", "compress/gzip", "context", "encoding/binary", "fmt", "io/ioutil", "os", "syscall", "text/tabwriter", "time"},
- "runtime/trace": {"L0", "context", "fmt"},
- "text/tabwriter": {"L2"},
-
- "testing": {"L2", "flag", "fmt", "internal/race", "io/ioutil", "os", "runtime/debug", "runtime/pprof", "runtime/trace", "time"},
- "testing/iotest": {"L2", "log"},
- "testing/quick": {"L2", "flag", "fmt", "reflect", "time"},
- "internal/obscuretestdata": {"L2", "OS", "encoding/base64"},
- "internal/testenv": {"L2", "OS", "flag", "testing", "syscall", "internal/cfg"},
- "internal/lazyregexp": {"L2", "OS", "regexp"},
- "internal/lazytemplate": {"L2", "OS", "text/template"},
-
- // L4 is defined as L3+fmt+log+time, because in general once
- // you're using L3 packages, use of fmt, log, or time is not a big deal.
- "L4": {
- "L3",
- "fmt",
- "log",
- "time",
- },
-
- // Go parser.
- "go/ast": {"L4", "OS", "go/scanner", "go/token"},
- "go/doc": {"L4", "OS", "go/ast", "go/token", "regexp", "internal/lazyregexp", "text/template"},
- "go/parser": {"L4", "OS", "go/ast", "go/scanner", "go/token"},
- "go/printer": {"L4", "OS", "go/ast", "go/scanner", "go/token", "text/tabwriter"},
- "go/scanner": {"L4", "OS", "go/token"},
- "go/token": {"L4"},
-
- "GOPARSER": {
- "go/ast",
- "go/doc",
- "go/parser",
- "go/printer",
- "go/scanner",
- "go/token",
- },
-
- "go/format": {"L4", "GOPARSER", "internal/format"},
- "internal/format": {"L4", "GOPARSER"},
-
- // Go type checking.
- "go/constant": {"L4", "go/token", "math/big"},
- "go/importer": {"L4", "go/build", "go/internal/gccgoimporter", "go/internal/gcimporter", "go/internal/srcimporter", "go/token", "go/types"},
- "go/internal/gcimporter": {"L4", "OS", "go/build", "go/constant", "go/token", "go/types", "text/scanner"},
- "go/internal/gccgoimporter": {"L4", "OS", "debug/elf", "go/constant", "go/token", "go/types", "internal/xcoff", "text/scanner"},
- "go/internal/srcimporter": {"L4", "OS", "fmt", "go/ast", "go/build", "go/parser", "go/token", "go/types", "path/filepath"},
- "go/types": {"L4", "GOPARSER", "container/heap", "go/constant"},
-
- // One of a kind.
- "archive/tar": {"L4", "OS", "syscall", "os/user"},
- "archive/zip": {"L4", "OS", "compress/flate"},
- "container/heap": {"sort"},
- "compress/bzip2": {"L4"},
- "compress/flate": {"L4"},
- "compress/gzip": {"L4", "compress/flate"},
- "compress/lzw": {"L4"},
- "compress/zlib": {"L4", "compress/flate"},
- "context": {"errors", "internal/reflectlite", "sync", "sync/atomic", "time"},
- "database/sql": {"L4", "container/list", "context", "database/sql/driver", "database/sql/internal"},
- "database/sql/driver": {"L4", "context", "time", "database/sql/internal"},
- "debug/dwarf": {"L4"},
- "debug/elf": {"L4", "OS", "debug/dwarf", "compress/zlib"},
- "debug/gosym": {"L4"},
- "debug/macho": {"L4", "OS", "debug/dwarf", "compress/zlib"},
- "debug/pe": {"L4", "OS", "debug/dwarf", "compress/zlib"},
- "debug/plan9obj": {"L4", "OS"},
- "encoding": {"L4"},
- "encoding/ascii85": {"L4"},
- "encoding/asn1": {"L4", "math/big"},
- "encoding/csv": {"L4"},
- "encoding/gob": {"L4", "OS", "encoding"},
- "encoding/hex": {"L4"},
- "encoding/json": {"L4", "encoding"},
- "encoding/pem": {"L4"},
- "encoding/xml": {"L4", "encoding"},
- "flag": {"L4", "OS"},
- "go/build": {"L4", "OS", "GOPARSER", "internal/goroot", "internal/goversion"},
- "html": {"L4"},
- "image/draw": {"L4", "image/internal/imageutil"},
- "image/gif": {"L4", "compress/lzw", "image/color/palette", "image/draw"},
- "image/internal/imageutil": {"L4"},
- "image/jpeg": {"L4", "image/internal/imageutil"},
- "image/png": {"L4", "compress/zlib"},
- "index/suffixarray": {"L4", "regexp"},
- "internal/goroot": {"L4", "OS"},
- "internal/singleflight": {"sync"},
- "internal/trace": {"L4", "OS", "container/heap"},
- "internal/xcoff": {"L4", "OS", "debug/dwarf"},
- "math/big": {"L4"},
- "mime": {"L4", "OS", "syscall", "internal/syscall/windows/registry"},
- "mime/quotedprintable": {"L4"},
- "net/internal/socktest": {"L4", "OS", "syscall", "internal/syscall/windows"},
- "net/url": {"L4"},
- "plugin": {"L0", "OS", "CGO"},
- "internal/profile": {"L4", "OS", "compress/gzip", "regexp"},
- "testing/internal/testdeps": {"L4", "internal/testlog", "runtime/pprof", "regexp"},
- "text/scanner": {"L4", "OS"},
- "text/template/parse": {"L4"},
-
- "html/template": {
- "L4", "OS", "encoding/json", "html", "text/template",
- "text/template/parse",
- },
- "text/template": {
- "L4", "OS", "net/url", "text/template/parse",
- },
-
- // Cgo.
- // If you add a dependency on CGO, you must add the package to
- // cgoPackages in cmd/dist/test.go.
- "runtime/cgo": {"L0", "C"},
- "CGO": {"C", "runtime/cgo"},
-
- // Fake entry to satisfy the pseudo-import "C"
- // that shows up in programs that use cgo.
- "C": {},
-
- // Race detector/MSan uses cgo.
- "runtime/race": {"C"},
- "runtime/msan": {"C"},
-
- // Plan 9 alone needs io/ioutil and os.
- "os/user": {"L4", "CGO", "io/ioutil", "os", "syscall", "internal/syscall/windows", "internal/syscall/windows/registry"},
-
- // Internal package used only for testing.
- "os/signal/internal/pty": {"CGO", "fmt", "os", "syscall"},
-
- // Basic networking.
- // Because net must be used by any package that wants to
- // do networking portably, it must have a small dependency set: just L0+basic os.
- "net": {
- "L0", "CGO",
- "context", "math/rand", "os", "sort", "syscall", "time",
- "internal/nettrace", "internal/poll", "internal/syscall/unix",
- "internal/syscall/windows", "internal/singleflight", "internal/race",
- "golang.org/x/net/dns/dnsmessage", "golang.org/x/net/lif", "golang.org/x/net/route",
- },
-
- // NET enables use of basic network-related packages.
- "NET": {
- "net",
- "mime",
- "net/textproto",
- "net/url",
- },
-
- // Uses of networking.
- "log/syslog": {"L4", "OS", "net"},
- "net/mail": {"L4", "NET", "OS", "mime"},
- "net/textproto": {"L4", "OS", "net"},
-
- // Core crypto.
- "crypto/aes": {"L3"},
- "crypto/des": {"L3"},
- "crypto/hmac": {"L3"},
- "crypto/internal/randutil": {"io", "sync"},
- "crypto/md5": {"L3"},
- "crypto/rc4": {"L3"},
- "crypto/sha1": {"L3"},
- "crypto/sha256": {"L3"},
- "crypto/sha512": {"L3"},
-
- "CRYPTO": {
- "crypto/aes",
- "crypto/des",
- "crypto/hmac",
- "crypto/internal/randutil",
- "crypto/md5",
- "crypto/rc4",
- "crypto/sha1",
- "crypto/sha256",
- "crypto/sha512",
- "golang.org/x/crypto/chacha20poly1305",
- "golang.org/x/crypto/curve25519",
- "golang.org/x/crypto/poly1305",
- },
-
- // Random byte, number generation.
- // This would be part of core crypto except that it imports
- // math/big, which imports fmt.
- "crypto/rand": {"L4", "CRYPTO", "OS", "math/big", "syscall", "syscall/js", "internal/syscall/unix"},
-
- // Not part of CRYPTO because it imports crypto/rand and crypto/sha512.
- "crypto/ed25519": {"L3", "CRYPTO", "crypto/rand", "crypto/ed25519/internal/edwards25519"},
- "crypto/ed25519/internal/edwards25519": {"encoding/binary"},
-
- // Mathematical crypto: dependencies on fmt (L4) and math/big.
- // We could avoid some of the fmt, but math/big imports fmt anyway.
- "crypto/dsa": {"L4", "CRYPTO", "math/big"},
- "crypto/ecdsa": {
- "L4", "CRYPTO", "crypto/elliptic", "math/big",
- "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/cryptobyte/asn1",
- },
- "crypto/elliptic": {"L4", "CRYPTO", "math/big"},
- "crypto/rsa": {"L4", "CRYPTO", "crypto/rand", "math/big"},
-
- "CRYPTO-MATH": {
- "CRYPTO",
- "crypto/dsa",
- "crypto/ecdsa",
- "crypto/elliptic",
- "crypto/rand",
- "crypto/rsa",
- "encoding/asn1",
- "math/big",
- },
-
- // SSL/TLS.
- "crypto/tls": {
- "L4", "CRYPTO-MATH", "OS", "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/hkdf",
- "container/list", "context", "crypto/x509", "encoding/pem", "net", "syscall", "crypto/ed25519",
- },
- "crypto/x509": {
- "L4", "CRYPTO-MATH", "OS", "CGO", "crypto/ed25519",
- "crypto/x509/pkix", "encoding/pem", "encoding/hex", "net", "os/user", "syscall", "net/url",
- "golang.org/x/crypto/cryptobyte", "golang.org/x/crypto/cryptobyte/asn1",
- },
- "crypto/x509/pkix": {"L4", "CRYPTO-MATH", "encoding/hex"},
-
- // Simple net+crypto-aware packages.
- "mime/multipart": {"L4", "OS", "mime", "crypto/rand", "net/textproto", "mime/quotedprintable"},
- "net/smtp": {"L4", "CRYPTO", "NET", "crypto/tls"},
-
- // HTTP, kingpin of dependencies.
- "net/http": {
- "L4", "NET", "OS",
- "compress/gzip",
- "container/list",
- "context",
- "crypto/rand",
- "crypto/tls",
- "golang.org/x/net/http/httpguts",
- "golang.org/x/net/http/httpproxy",
- "golang.org/x/net/http2/hpack",
- "golang.org/x/net/idna",
- "golang.org/x/text/unicode/norm",
- "golang.org/x/text/width",
- "internal/nettrace",
- "mime/multipart",
- "net/http/httptrace",
- "net/http/internal",
- "runtime/debug",
- "syscall/js",
- },
- "net/http/internal": {"L4"},
- "net/http/httptrace": {"context", "crypto/tls", "internal/nettrace", "net", "net/textproto", "reflect", "time"},
-
- // HTTP-using packages.
- "expvar": {"L4", "OS", "encoding/json", "net/http"},
- "net/http/cgi": {"L4", "NET", "OS", "crypto/tls", "net/http", "regexp"},
- "net/http/cookiejar": {"L4", "NET", "net/http"},
- "net/http/fcgi": {"L4", "NET", "OS", "context", "net/http", "net/http/cgi"},
- "net/http/httptest": {
- "L4", "NET", "OS", "crypto/tls", "flag", "net/http", "net/http/internal", "crypto/x509",
- "golang.org/x/net/http/httpguts",
- },
- "net/http/httputil": {"L4", "NET", "OS", "context", "net/http", "net/http/internal", "golang.org/x/net/http/httpguts"},
- "net/http/pprof": {"L4", "OS", "context", "html/template", "net/http", "runtime/pprof", "runtime/trace", "internal/profile"},
- "net/rpc": {"L4", "NET", "encoding/gob", "html/template", "net/http", "go/token"},
- "net/rpc/jsonrpc": {"L4", "NET", "encoding/json", "net/rpc"},
- }
+ // The general syntax of a rule is:
+ //
+ // a, b < c, d;
+ //
+ // which means c and d come after a and b in the partial order
+ // (that is, c and d can import a and b),
+ // but doesn't provide a relative order between a vs b or c vs d.
+ //
+ // The rules can chain together, as in:
+ //
+ // e < f, g < h;
+ //
+ // which is equivalent to
+ //
+ // e < f, g;
+ // f, g < h;
+ //
+ // Except for the special bottom element "NONE", each name
+ // must appear exactly once on the right-hand side of a rule.
+ // That rule serves as the definition of the allowed dependencies
+ // for that name. The definition must appear before any uses
+ // of the name on the left-hand side of a rule. (That is, the
+ // rules themselves must be ordered according to the partial
+ // order, for easier reading by people.)
+ //
+ // Negative assertions double-check the partial order:
+ //
+ // i !< j
+ //
+ // means that it must NOT be the case that i < j.
+ // Negative assertions may appear anywhere in the rules,
+ // even before i and j have been defined.
+ //
+ // Comments begin with #.
+ //
+ // All-caps names are pseudo-names for specific points
+ // in the dependency lattice.
+ //
+ var depsRules = `
+ # No dependencies allowed for any of these packages.
+ NONE
+ < container/list, container/ring,
+ internal/cfg, internal/cpu,
+ internal/goversion, internal/nettrace,
+ unicode/utf8, unicode/utf16, unicode,
+ unsafe;
+
+ # RUNTIME is the core runtime group of packages, all of them very light-weight.
+ internal/cpu, unsafe
+ < internal/bytealg
+ < internal/unsafeheader
+ < runtime/internal/sys
+ < runtime/internal/atomic
+ < runtime/internal/math
+ < runtime
+ < sync/atomic
+ < internal/race
+ < sync
+ < internal/reflectlite
+ < errors
+ < internal/oserror, math/bits
+ < RUNTIME;
+
+ RUNTIME
+ < sort
+ < container/heap;
+
+ RUNTIME
+ < io;
+
+ reflect !< sort;
+
+ # SYSCALL is RUNTIME plus the packages necessary for basic system calls.
+ RUNTIME, unicode/utf8, unicode/utf16, io
+ < internal/syscall/windows/sysdll, syscall/js
+ < syscall
+ < internal/syscall/unix, internal/syscall/windows, internal/syscall/windows/registry
+ < internal/syscall/execenv
+ < SYSCALL;
+
+ # TIME is SYSCALL plus the core packages about time, including context.
+ SYSCALL
+ < time/tzdata
+ < time
+ < context
+ < TIME;
+
+ # MATH is RUNTIME plus the basic math packages.
+ RUNTIME
+ < math
+ < MATH;
+
+ unicode !< math;
+
+ MATH
+ < math/cmplx;
+
+ MATH
+ < math/rand;
+
+ MATH, unicode/utf8
+ < strconv;
+
+ unicode !< strconv;
+
+ # STR is basic string and buffer manipulation.
+ RUNTIME, io, unicode/utf8, unicode/utf16, unicode
+ < bytes, strings
+ < bufio, path;
+
+ bufio, path, strconv
+ < STR;
+
+ # OS is basic OS access, including helpers (path/filepath, os/exec, etc).
+ # OS includes string routines, but those must be layered above package os.
+ # OS does not include reflection.
+ TIME, io, sort
+ < internal/testlog
+ < internal/poll
+ < os
+ < os/signal;
+
+ unicode, fmt !< os, os/signal;
+
+ os/signal, STR
+ < path/filepath
+ < io/ioutil, os/exec
+ < OS;
+
+ reflect !< OS;
+
+ OS
+ < golang.org/x/sys/cpu, internal/goroot;
+
+ # FMT is OS (which includes string routines) plus reflect and fmt.
+ # It does not include package log, which should be avoided in core packages.
+ strconv, unicode
+ < reflect;
+
+ os, reflect
+ < internal/fmtsort
+ < fmt;
+
+ OS, fmt
+ < FMT;
+
+ log !< FMT;
+
+ # Misc packages needing only FMT.
+ FMT
+ < flag,
+ html,
+ mime/quotedprintable,
+ net/internal/socktest,
+ net/url,
+ runtime/debug,
+ runtime/trace,
+ text/scanner,
+ text/tabwriter;
+
+ # encodings
+ # core ones do not use fmt.
+ io, strconv
+ < encoding;
+
+ encoding, reflect
+ < encoding/binary
+ < encoding/base32, encoding/base64;
+
+ fmt !< encoding/base32, encoding/base64;
+
+ FMT, encoding/base32, encoding/base64
+ < encoding/ascii85, encoding/csv, encoding/gob, encoding/hex,
+ encoding/json, encoding/pem, encoding/xml, mime;
+
+ # hashes
+ io
+ < hash
+ < hash/adler32, hash/crc32, hash/crc64, hash/fnv, hash/maphash;
+
+ # math/big
+ FMT, encoding/binary, math/rand
+ < math/big;
+
+ # compression
+ FMT, encoding/binary, hash/adler32, hash/crc32
+ < compress/bzip2, compress/flate, compress/lzw
+ < archive/zip, compress/gzip, compress/zlib;
+
+ # templates
+ FMT
+ < text/template/parse;
+
+ net/url, text/template/parse
+ < text/template
+ < internal/lazytemplate;
+
+ encoding/json, html, text/template
+ < html/template;
+
+ # regexp
+ FMT
+ < regexp/syntax
+ < regexp
+ < internal/lazyregexp;
+
+ # suffix array
+ encoding/binary, regexp
+ < index/suffixarray;
+
+ # executable parsing
+ FMT, encoding/binary, compress/zlib
+ < debug/dwarf
+ < debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff
+ < DEBUG;
+
+ # go parser and friends.
+ FMT
+ < go/token
+ < go/scanner
+ < go/ast
+ < go/parser;
+
+ go/parser, text/tabwriter
+ < go/printer
+ < go/format;
+
+ go/parser, internal/lazyregexp, text/template
+ < go/doc;
+
+ math/big, go/token
+ < go/constant;
+
+ container/heap, go/constant, go/parser
+ < go/types;
+
+ go/doc, go/parser, internal/goroot, internal/goversion
+ < go/build;
+
+ DEBUG, go/build, go/types, text/scanner
+ < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
+ < go/importer;
+
+ # databases
+ FMT
+ < database/sql/internal
+ < database/sql/driver
+ < database/sql;
+
+ # images
+ FMT, compress/lzw, compress/zlib
+ < image/color
+ < image, image/color/palette
+ < image/internal/imageutil
+ < image/draw
+ < image/gif, image/jpeg, image/png;
+
+ # cgo, delayed as long as possible.
+ # If you add a dependency on CGO, you must add the package
+ # to cgoPackages in cmd/dist/test.go as well.
+ RUNTIME
+ < C
+ < runtime/cgo
+ < CGO
+ < runtime/race, runtime/msan;
+
+ # Bulk of the standard library must not use cgo.
+ # The prohibition stops at net and os/user.
- C !< fmt, go/types, CRYPTO-MATH;
++ C !< fmt, go/types;
+
+ CGO, OS
+ < plugin;
+
+ CGO, FMT
+ < os/user
+ < archive/tar;
+
+ sync
+ < internal/singleflight;
+
+ os
+ < golang.org/x/net/dns/dnsmessage,
+ golang.org/x/net/lif,
+ golang.org/x/net/route;
+
+ # net is unavoidable when doing any networking,
+ # so large dependencies must be kept out.
+ # This is a long-looking list but most of these
+ # are small with few dependencies.
+ # math/rand should probably be removed at some point.
+ CGO,
+ golang.org/x/net/dns/dnsmessage,
+ golang.org/x/net/lif,
+ golang.org/x/net/route,
+ internal/nettrace,
+ internal/poll,
+ internal/singleflight,
+ internal/race,
+ math/rand,
+ os
+ < net;
+
+ fmt, unicode !< net;
+
+ # NET is net plus net-helper packages.
+ FMT, net
+ < net/textproto;
+
+ mime, net/textproto, net/url
+ < NET;
+
+ # logging - most packages should not import; http and up is allowed
+ FMT
+ < log;
+
+ log !< crypto/tls, database/sql, go/importer, testing;
+
+ FMT, log, net
+ < log/syslog;
+
+ NET, log
+ < net/mail;
+
- # CRYPTO is core crypto algorithms - no cgo, fmt, net.
- # Unfortunately, stuck with reflect via encoding/binary.
- encoding/binary, golang.org/x/sys/cpu, hash
++ NONE < crypto/internal/boring/sig;
++ sync/atomic < crypto/internal/boring/fipstls;
++
++ encoding/binary, golang.org/x/sys/cpu, hash,
++ FMT, math/big,
++ CGO, crypto/internal/boring/sig, crypto/internal/boring/fipstls
+ < crypto
+ < crypto/subtle
+ < crypto/internal/subtle
+ < crypto/cipher
++ < encoding/asn1
++ < crypto/internal/boring
+ < crypto/aes, crypto/des, crypto/hmac, crypto/md5, crypto/rc4,
+ crypto/sha1, crypto/sha256, crypto/sha512
- < CRYPTO;
-
- CGO, fmt, net !< CRYPTO;
-
- # CRYPTO-MATH is core bignum-based crypto - no cgo, net; fmt now ok.
- CRYPTO, FMT, math/big
+ < crypto/rand
+ < crypto/internal/randutil
+ < crypto/ed25519/internal/edwards25519
+ < crypto/ed25519
- < encoding/asn1
+ < golang.org/x/crypto/cryptobyte/asn1
+ < golang.org/x/crypto/cryptobyte
+ < golang.org/x/crypto/curve25519
+ < crypto/dsa, crypto/elliptic, crypto/rsa
+ < crypto/ecdsa
- < CRYPTO-MATH;
++ < CRYPTO-BORING;
+
- CGO, net !< CRYPTO-MATH;
++ net !< CRYPTO-BORING;
+
+ # TLS, Prince of Dependencies.
- CGO, CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem
++ CGO, CRYPTO-BORING, NET, container/list, encoding/hex, encoding/pem
+ < golang.org/x/crypto/internal/subtle
+ < golang.org/x/crypto/chacha20
+ < golang.org/x/crypto/poly1305
+ < golang.org/x/crypto/chacha20poly1305
+ < golang.org/x/crypto/hkdf
+ < crypto/x509/internal/macOS
+ < crypto/x509/pkix
+ < crypto/x509
+ < crypto/tls;
+
++ crypto/internal/boring/sig, crypto/internal/boring/fipstls
++ < crypto/tls/fipsonly;
++
+ # crypto-aware packages
+
+ NET, crypto/rand, mime/quotedprintable
+ < mime/multipart;
+
+ crypto/tls
+ < net/smtp;
+
+ # HTTP, King of Dependencies.
+
+ FMT
+ < golang.org/x/net/http2/hpack, net/http/internal;
+
+ FMT, NET, container/list, encoding/binary, log
+ < golang.org/x/text/transform
+ < golang.org/x/text/unicode/norm
+ < golang.org/x/text/unicode/bidi
+ < golang.org/x/text/secure/bidirule
+ < golang.org/x/net/idna
+ < golang.org/x/net/http/httpguts, golang.org/x/net/http/httpproxy;
+
+ NET, crypto/tls
+ < net/http/httptrace;
+
+ compress/gzip,
+ golang.org/x/net/http/httpguts,
+ golang.org/x/net/http/httpproxy,
+ golang.org/x/net/http2/hpack,
+ net/http/internal,
+ net/http/httptrace,
+ mime/multipart,
+ log
+ < net/http;
+
+ # HTTP-aware packages
- // isMacro reports whether p is a package dependency macro
- // (uppercase name).
- func isMacro(p string) bool {
- return 'A' <= p[0] && p[0] <= 'Z'
- }
+ encoding/json, net/http
+ < expvar;
- func allowed(pkg string) map[string]bool {
- m := map[string]bool{}
- var allow func(string)
- allow = func(p string) {
- if m[p] {
- return
- }
- m[p] = true // set even for macros, to avoid loop on cycle
+ net/http
+ < net/http/cookiejar, net/http/httputil;
+
+ net/http, flag
+ < net/http/httptest;
+
+ net/http, regexp
+ < net/http/cgi
+ < net/http/fcgi;
+
+ # Profiling
+ FMT, compress/gzip, encoding/binary, text/tabwriter
+ < runtime/pprof;
+
+ OS, compress/gzip, regexp
+ < internal/profile;
+
+ html/template, internal/profile, net/http, runtime/pprof, runtime/trace
+ < net/http/pprof;
+
+ # RPC
+ encoding/gob, encoding/json, go/token, html/template, net/http
+ < net/rpc
+ < net/rpc/jsonrpc;
+
+ # Test-only
+ log
+ < testing/iotest;
+
+ FMT, flag, math/rand
+ < testing/quick;
- // Upper-case names are macro-expanded.
- if isMacro(p) {
- for _, pp := range pkgDeps[p] {
- allow(pp)
- }
- }
- }
- for _, pp := range pkgDeps[pkg] {
- allow(pp)
- }
- return m
- }
+ FMT, flag, runtime/debug, runtime/trace
+ < testing;
+
+ internal/testlog, runtime/pprof, regexp
+ < testing/internal/testdeps;
+
+ OS, flag, testing, internal/cfg
+ < internal/testenv;
+
+ OS, encoding/base64
+ < internal/obscuretestdata;
+
+ CGO, OS, fmt
+ < os/signal/internal/pty;
+
+ NET, testing
+ < golang.org/x/net/nettest;
+
+ FMT, container/heap, math/rand
+ < internal/trace;
+ `
// listStdPkgs returns the same list of packages as "go list std".
func listStdPkgs(goroot string) ([]string, error) {