Source file
src/go/build/deps_test.go
1
2
3
4
5
6
7
8 package build
9
10 import (
11 "bytes"
12 "fmt"
13 "go/token"
14 "internal/dag"
15 "internal/testenv"
16 "io/fs"
17 "os"
18 "path/filepath"
19 "slices"
20 "strings"
21 "testing"
22 )
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 var depsRules = `
39 # No dependencies allowed for any of these packages.
40 NONE
41 < unsafe
42 < cmp,
43 container/list,
44 container/ring,
45 internal/byteorder,
46 internal/cfg,
47 internal/coverage,
48 internal/coverage/rtcov,
49 internal/coverage/uleb128,
50 internal/coverage/calloc,
51 internal/cpu,
52 internal/goarch,
53 internal/godebugs,
54 internal/goexperiment,
55 internal/goos,
56 internal/goversion,
57 internal/nettrace,
58 internal/platform,
59 internal/profilerecord,
60 internal/runtime/pprof/label,
61 internal/syslist,
62 internal/trace/tracev2,
63 internal/trace/traceviewer/format,
64 log/internal,
65 math/bits,
66 structs,
67 unicode,
68 unicode/utf8,
69 unicode/utf16;
70
71 internal/goarch < internal/abi;
72 internal/byteorder, internal/cpu, internal/goarch < internal/chacha8rand;
73 internal/goarch, math/bits < internal/strconv;
74
75 internal/cpu, internal/strconv < simd/archsimd;
76
77 # RUNTIME is the core runtime group of packages, all of them very light-weight.
78 internal/abi,
79 internal/chacha8rand,
80 internal/coverage/rtcov,
81 internal/cpu,
82 internal/goarch,
83 internal/godebugs,
84 internal/goexperiment,
85 internal/goos,
86 internal/profilerecord,
87 internal/runtime/pprof/label,
88 internal/strconv,
89 internal/trace/tracev2,
90 math/bits,
91 structs,
92 simd/archsimd
93 < internal/bytealg
94 < internal/stringslite
95 < internal/unsafeheader
96 < internal/race
97 < internal/msan
98 < internal/asan
99 < internal/runtime/sys
100 < internal/runtime/syscall/linux
101 < internal/runtime/syscall/windows
102 < internal/runtime/atomic
103 < internal/runtime/exithook
104 < internal/runtime/gc
105 < internal/runtime/math
106 < internal/runtime/maps
107 < internal/runtime/cgroup
108 < internal/runtime/gc/scan
109 < runtime
110 < runtime/secret
111 < sync/atomic
112 < internal/sync
113 < weak
114 < internal/synctest
115 < sync
116 < internal/bisect
117 < internal/godebug
118 < internal/reflectlite
119 < errors
120 < internal/oserror;
121
122 cmp, runtime, math/bits
123 < iter
124 < maps, slices;
125
126 internal/oserror, maps, slices
127 < RUNTIME;
128
129 RUNTIME
130 < sort
131 < container/heap
132 < unique;
133
134 RUNTIME
135 < io;
136
137 RUNTIME
138 < arena;
139
140 syscall !< io;
141 reflect !< sort;
142
143 RUNTIME, unicode/utf8
144 < path;
145
146 unicode !< path;
147
148 # SYSCALL is RUNTIME plus the packages necessary for basic system calls.
149 RUNTIME, unicode/utf8, unicode/utf16, internal/synctest
150 < internal/syscall/windows/sysdll, syscall/js
151 < syscall
152 < internal/syscall/unix, internal/syscall/windows, internal/syscall/windows/registry
153 < internal/syscall/execenv
154 < SYSCALL;
155
156 # TIME is SYSCALL plus the core packages about time, including context.
157 SYSCALL
158 < time/tzdata
159 < time
160 < context
161 < TIME;
162
163 TIME, io, path, slices
164 < io/fs;
165
166 # MATH is RUNTIME plus the basic math packages.
167 RUNTIME
168 < math
169 < MATH;
170
171 unicode !< math;
172
173 MATH
174 < math/cmplx;
175
176 MATH
177 < math/rand, math/rand/v2;
178
179 MATH
180 < runtime/metrics;
181
182 MATH
183 < simd/internal/spec;
184
185 MATH, unicode/utf8
186 < strconv;
187
188 unicode !< strconv;
189
190 # STR is basic string and buffer manipulation.
191 RUNTIME, io, unicode/utf8, unicode/utf16, unicode
192 < bytes, strings
193 < bufio;
194
195 bufio, path, strconv
196 < STR;
197
198 # OS is basic OS access, including helpers (path/filepath, os/exec, etc).
199 # OS includes string routines, but those must be layered above package os.
200 # OS does not include reflection.
201 io/fs
202 < internal/testlog
203 < internal/poll
204 < internal/filepathlite
205 < os
206 < os/signal;
207
208 io/fs
209 < embed;
210
211 unicode, fmt !< net, os, os/signal;
212
213 os/signal, internal/filepathlite, STR
214 < path/filepath
215 < io/ioutil;
216
217 path/filepath, internal/godebug < os/exec;
218
219 io/ioutil, os/exec, os/signal
220 < OS;
221
222 reflect !< OS;
223
224 OS
225 < golang.org/x/sys/cpu;
226
227 # FMT is OS (which includes string routines) plus reflect and fmt.
228 # It does not include package log, which should be avoided in core packages.
229 arena, strconv, unicode
230 < reflect;
231
232 os, reflect
233 < internal/fmtsort
234 < fmt;
235
236 OS, fmt
237 < FMT;
238
239 log !< FMT;
240
241 # Misc packages needing only FMT.
242 FMT
243 < html,
244 internal/dag,
245 internal/goroot,
246 internal/types/errors,
247 mime/quotedprintable,
248 net/internal/socktest,
249 runtime/trace,
250 text/scanner,
251 text/tabwriter;
252
253 io, reflect
254 < internal/saferio;
255
256 # encodings
257 # core ones do not use fmt.
258 io, strconv, slices
259 < encoding, encoding/base32, encoding/base64;
260
261 encoding, reflect
262 < encoding/binary;
263
264 FMT, encoding < flag;
265
266 FMT, simd/archsimd < simd/internal/bridge;
267
268 simd/internal/bridge < simd;
269
270 fmt !< encoding/base32, encoding/base64;
271
272 FMT, encoding, encoding/base32, encoding/base64, encoding/binary,
273 internal/saferio
274 < encoding/ascii85, encoding/csv, encoding/gob, encoding/hex,
275 encoding/pem, encoding/xml, mime;
276
277 STR, errors
278 < encoding/json/internal
279 < encoding/json/internal/jsonflags
280 < encoding/json/internal/jsonopts
281 < encoding/json/internal/jsonwire
282 < encoding/json/jsontext;
283
284 FMT,
285 encoding/hex,
286 encoding/base32,
287 encoding/base64,
288 encoding/binary,
289 encoding/json/jsontext,
290 encoding/json/internal,
291 encoding/json/internal/jsonflags,
292 encoding/json/internal/jsonopts,
293 encoding/json/internal/jsonwire
294 < encoding/json/v2
295 < encoding/json;
296
297 # hashes
298 io
299 < hash
300 < hash/adler32, hash/crc32, hash/crc64, hash/fnv, hash/maphash;
301
302 # math/big
303 FMT, math/rand
304 < math/big;
305
306 # compression
307 FMT, encoding/binary, hash/adler32, hash/crc32, sort
308 < compress/bzip2, compress/flate, compress/lzw, internal/zstd
309 < archive/zip, compress/gzip, compress/zlib;
310
311 # templates
312 FMT
313 < text/template/parse;
314
315 internal/bytealg, math/bits, slices, strconv, unique
316 < net/netip;
317
318 FMT, net/netip
319 < net/url;
320
321 net/url, text/template/parse
322 < text/template
323 < internal/lazytemplate;
324
325 # regexp
326 FMT, sort
327 < regexp/syntax
328 < regexp
329 < internal/lazyregexp;
330
331 encoding/json, html, text/template, regexp
332 < html/template;
333
334 # suffix array
335 encoding/binary, regexp
336 < index/suffixarray;
337
338 # executable parsing
339 FMT, encoding/binary, compress/zlib, internal/saferio, internal/zstd, sort
340 < runtime/debug
341 < debug/dwarf
342 < debug/elf, debug/gosym, debug/macho, debug/pe, debug/plan9obj, internal/xcoff
343 < debug/buildinfo
344 < DEBUG;
345
346 # go parser and friends.
347 FMT, sort
348 < internal/gover
349 < go/version
350 < go/token
351 < go/scanner
352 < go/ast
353 < go/internal/typeparams;
354
355 FMT
356 < go/build/constraint;
357
358 FMT, sort
359 < go/doc/comment;
360
361 go/internal/typeparams, go/build/constraint
362 < go/parser;
363
364 go/doc/comment, go/parser, text/tabwriter
365 < go/printer
366 < go/format;
367
368 math/big, go/token
369 < go/constant;
370
371 FMT, internal/goexperiment
372 < internal/buildcfg;
373
374 # The vast majority of standard library packages should not be resorting to regexp.
375 # go/types is a good chokepoint. It shouldn't use regexp, nor should anything
376 # that is low-enough level to be used by go/types.
377 regexp !< go/types;
378
379 go/doc/comment, go/parser, internal/lazyregexp, text/template
380 < go/doc;
381
382 go/build/constraint, go/doc, go/parser, internal/buildcfg, internal/goroot, internal/goversion, internal/platform, internal/syslist
383 < go/build;
384
385 # images
386 FMT, compress/lzw, compress/zlib
387 < image/color
388 < image, image/color/palette
389 < image/internal/imageutil
390 < image/draw
391 < image/gif, image/jpeg, image/png;
392
393 # cgo, delayed as long as possible.
394 # If you add a dependency on CGO, you must add the package
395 # to cgoPackages in cmd/dist/test.go as well.
396 RUNTIME
397 < C
398 < runtime/cgo
399 < CGO
400 < runtime/msan, runtime/asan;
401
402 # runtime/race
403 NONE < runtime/race/internal/amd64v1;
404 NONE < runtime/race/internal/amd64v3;
405 CGO, runtime/race/internal/amd64v1, runtime/race/internal/amd64v3 < runtime/race;
406
407 # Bulk of the standard library must not use cgo.
408 # The prohibition stops at net and os/user.
409 C !< fmt, go/types, CRYPTO-MATH, log/slog;
410
411 CGO, OS
412 < plugin;
413
414 CGO, FMT
415 < os/user
416 < archive/tar;
417
418 sync
419 < internal/singleflight;
420
421 os
422 < golang.org/x/net/dns/dnsmessage,
423 golang.org/x/net/lif;
424
425 os, net/netip
426 < internal/routebsd;
427
428 # net is unavoidable when doing any networking,
429 # so large dependencies must be kept out.
430 # This is a long-looking list but most of these
431 # are small with few dependencies.
432 CGO,
433 golang.org/x/net/dns/dnsmessage,
434 golang.org/x/net/lif,
435 internal/godebug,
436 internal/goversion,
437 internal/nettrace,
438 internal/poll,
439 internal/routebsd,
440 internal/singleflight,
441 net/netip,
442 os,
443 sort
444 < net;
445
446 fmt, unicode !< net;
447 math/rand !< net; # net uses runtime instead
448
449 # NET is net plus net-helper packages.
450 FMT, net
451 < net/textproto;
452
453 mime, net/textproto, net/url
454 < NET;
455
456 # logging - most packages should not import; http and up is allowed
457 FMT, log/internal
458 < log;
459
460 log, log/slog !< crypto/tls, database/sql, go/importer, testing;
461
462 FMT, log, net
463 < log/syslog;
464
465 RUNTIME
466 < log/slog/internal, log/slog/internal/buffer;
467
468 FMT,
469 encoding, encoding/json,
470 log, log/internal,
471 log/slog/internal, log/slog/internal/buffer,
472 slices
473 < log/slog
474 < log/slog/internal/slogtest, log/slog/internal/benchmarks;
475
476 NET, log
477 < net/mail;
478
479 # FIPS is the FIPS 140 module.
480 # It must not depend on external crypto packages.
481 # Package hash is ok as it's only the interface.
482 # See also fips140deps.AllowedInternalPackages.
483
484 io, math/rand/v2 < crypto/internal/randutil;
485
486 NONE < crypto/internal/constanttime;
487
488 STR < crypto/internal/impl;
489
490 OS < crypto/internal/sysrand
491 < crypto/internal/entropy;
492
493 internal/byteorder < crypto/internal/fips140deps/byteorder;
494 internal/cpu, internal/goarch < crypto/internal/fips140deps/cpu;
495 internal/godebug < crypto/internal/fips140deps/godebug;
496 time, internal/syscall/windows < crypto/internal/fips140deps/time;
497
498 crypto/internal/fips140deps/time, errors, math/bits, sync/atomic, unsafe
499 < crypto/internal/entropy/v1.0.0;
500
501 STR, hash,
502 crypto/internal/impl,
503 crypto/internal/entropy,
504 crypto/internal/randutil,
505 crypto/internal/constanttime,
506 crypto/internal/entropy/v1.0.0,
507 crypto/internal/fips140deps/byteorder,
508 crypto/internal/fips140deps/cpu,
509 crypto/internal/fips140deps/godebug
510 < crypto/internal/fips140
511 < crypto/internal/fips140/alias
512 < crypto/internal/fips140/subtle
513 < crypto/internal/fips140/sha256
514 < crypto/internal/fips140/sha512
515 < crypto/internal/fips140/sha3
516 < crypto/internal/fips140/hmac
517 < crypto/internal/fips140/check
518 < crypto/internal/fips140/pbkdf2
519 < crypto/internal/fips140/aes
520 < crypto/internal/fips140/drbg
521 < crypto/internal/fips140/aes/gcm
522 < crypto/internal/fips140/hkdf
523 < crypto/internal/fips140/mlkem
524 < crypto/internal/fips140/mldsa
525 < crypto/internal/fips140/ssh
526 < crypto/internal/fips140/tls12
527 < crypto/internal/fips140/tls13
528 < crypto/internal/fips140/bigmod
529 < crypto/internal/fips140/nistec/fiat
530 < crypto/internal/fips140/nistec
531 < crypto/internal/fips140/ecdh
532 < crypto/internal/fips140/ecdsa
533 < crypto/internal/fips140/edwards25519/field
534 < crypto/internal/fips140/edwards25519
535 < crypto/internal/fips140/ed25519
536 < crypto/internal/fips140/rsa
537 < crypto/fips140 < FIPS;
538
539 crypto !< FIPS;
540
541 # CRYPTO is core crypto algorithms - no cgo, fmt, net.
542 # Mostly wrappers around the FIPS module.
543
544 NONE < crypto/internal/boring/sig, crypto/internal/boring/syso;
545 sync/atomic < crypto/internal/boring/bcache;
546
547 FIPS, internal/godebug, embed,
548 crypto/internal/boring/sig,
549 crypto/internal/boring/syso,
550 crypto/internal/boring/bcache
551 < crypto/internal/fips140only
552 < crypto
553 < crypto/subtle
554 < crypto/sha3
555 < crypto/internal/fips140hash
556 < crypto/cipher
557 < crypto/internal/boring
558 < crypto/boring
559 < crypto/internal/rand
560 < crypto/aes,
561 crypto/des,
562 crypto/rc4,
563 crypto/md5,
564 crypto/sha1,
565 crypto/sha256,
566 crypto/sha512,
567 crypto/hmac,
568 crypto/hkdf,
569 crypto/pbkdf2,
570 crypto/ecdh,
571 crypto/mlkem,
572 crypto/mldsa
573 < CRYPTO;
574
575 CRYPTO
576 < golang.org/x/crypto/hkdf;
577
578 CGO, fmt, net !< CRYPTO;
579
580 # CRYPTO-MATH is crypto that exposes math/big APIs - no cgo, net; fmt now ok.
581
582 CRYPTO, FMT, math/big, internal/saferio
583 < crypto/internal/boring/bbig
584 < crypto/internal/fips140cache
585 < crypto/rand
586 < crypto/ed25519 # depends on crypto/rand.Reader
587 < encoding/asn1
588 < golang.org/x/crypto/cryptobyte/asn1
589 < golang.org/x/crypto/cryptobyte
590 < crypto/dsa, crypto/elliptic, crypto/rsa
591 < crypto/ecdsa
592 < CRYPTO-MATH;
593
594 CGO, net !< CRYPTO-MATH;
595
596 # uuids
597 crypto/rand, errors, encoding/binary, encoding/hex
598 < uuid;
599
600 # databases
601 FMT, uuid
602 < database/sql/internal
603 < database/sql/driver;
604
605 database/sql/driver, math/rand/v2 < database/sql;
606
607 # TLS, Prince of Dependencies.
608
609 crypto/fips140, sync/atomic < crypto/tls/internal/fips140tls;
610
611 crypto/internal/boring/sig, crypto/tls/internal/fips140tls < crypto/tls/fipsonly;
612
613 CRYPTO, golang.org/x/sys/cpu, encoding/binary, reflect
614 < golang.org/x/crypto/internal/alias
615 < golang.org/x/crypto/internal/subtle
616 < golang.org/x/crypto/chacha20
617 < golang.org/x/crypto/internal/poly1305
618 < golang.org/x/crypto/chacha20poly1305;
619
620 CRYPTO-MATH, golang.org/x/crypto/chacha20poly1305
621 < crypto/hpke;
622
623 CRYPTO-MATH, NET, container/list, encoding/hex, encoding/pem, crypto/hpke,
624 golang.org/x/crypto/chacha20poly1305, crypto/tls/internal/fips140tls
625 < crypto/x509/internal/macos
626 < crypto/x509/pkix
627 < crypto/x509
628 < crypto/tls;
629
630 # crypto-aware packages
631
632 FMT, hash/maphash
633 < container/hash;
634
635 hash/maphash, container/heap, go/constant, go/parser, internal/buildcfg, internal/goversion, internal/types/errors
636 < go/types;
637
638 DEBUG, go/build, go/types, text/scanner, crypto/sha256
639 < internal/pkgbits, internal/exportdata
640 < go/internal/gcimporter, go/internal/gccgoimporter, go/internal/srcimporter
641 < go/importer;
642
643 NET, crypto/rand, mime/quotedprintable
644 < mime/multipart;
645
646 crypto/tls
647 < net/smtp;
648
649 # HTTP, King of Dependencies.
650
651 context
652 < internal/gate;
653
654 FMT, encoding/binary
655 < golang.org/x/net/http2/hpack
656 < net/http/internal, net/http/internal/ascii, net/http/internal/testcert;
657
658 FMT, NET, container/list, encoding/binary, log
659 < golang.org/x/text/transform
660 < golang.org/x/text/unicode/norm
661 < golang.org/x/text/unicode/bidi
662 < golang.org/x/text/secure/bidirule
663 < golang.org/x/net/idna
664 < golang.org/x/net/http/httpguts, golang.org/x/net/http/httpproxy;
665
666 NET, crypto/tls
667 < net/http/httptrace;
668
669 compress/gzip,
670 golang.org/x/net/http/httpguts,
671 golang.org/x/net/http/httpproxy,
672 golang.org/x/net/http2/hpack,
673 net/http/internal,
674 net/http/internal/ascii,
675 net/http/internal/testcert,
676 net/http/httptrace,
677 mime/multipart,
678 log
679 < net/http/internal/httpcommon, net/http/internal/httpsfv
680 < net/http/internal/http2
681 < net/http;
682
683 net/http, golang.org/x/crypto/hkdf, log/slog
684 < golang.org/x/net/internal/quic/quicwire
685 < golang.org/x/net/quic, golang.org/x/net/internal/httpcommon
686 < golang.org/x/net/internal/http3
687 < golang.org/x/net/http3;
688
689 # HTTP-aware packages
690
691 encoding/json, net/http
692 < expvar;
693
694 net/http, net/http/internal/ascii
695 < net/http/cookiejar, net/http/httputil;
696
697 net/http, regexp
698 < net/http/cgi
699 < net/http/fcgi;
700
701 # Profiling
702 internal/runtime/pprof/label, runtime, context < internal/runtime/pprof;
703 FMT, compress/gzip, encoding/binary, sort, text/tabwriter, internal/runtime/pprof, internal/runtime/pprof/label
704 < runtime/pprof;
705
706 OS, compress/gzip, internal/lazyregexp
707 < internal/profile;
708
709 html, internal/profile, net/http, runtime/pprof, runtime/trace
710 < net/http/pprof;
711
712 # RPC
713 encoding/gob, encoding/json, go/token, html/template, net/http
714 < net/rpc
715 < net/rpc/jsonrpc;
716
717 # System Information
718 bufio, bytes, internal/cpu, io, os, strings, sync
719 < internal/sysinfo;
720
721 # Test-only
722 log
723 < testing/iotest
724 < testing/fstest;
725
726 FMT, flag, math/rand
727 < testing/quick;
728
729 FMT, DEBUG, flag, runtime/trace, internal/sysinfo, math/rand
730 < testing;
731
732 testing, math
733 < simd/archsimd/internal/test_helpers;
734
735 log/slog, testing
736 < testing/slogtest;
737
738 testing, crypto/rand
739 < testing/cryptotest;
740
741 NET, internal/gate
742 < internal/nettest;
743
744 net/http, flag, internal/nettest, testing
745 < net/http/httptest;
746
747 FMT, crypto/sha256, encoding/binary, encoding/json,
748 go/ast, go/parser, go/token,
749 internal/godebug, math/rand, encoding/hex
750 < internal/fuzz;
751
752 OS, flag, testing, internal/cfg, internal/platform, internal/goroot
753 < internal/testenv;
754
755 OS, encoding/base64
756 < internal/obscuretestdata;
757
758 CGO, OS, fmt
759 < internal/testpty;
760
761 NET, testing, math/rand
762 < golang.org/x/net/nettest;
763
764 syscall
765 < os/exec/internal/fdtest;
766
767 FMT, sort
768 < internal/diff;
769
770 FMT
771 < internal/txtar;
772
773 internal/synctest, testing
774 < testing/synctest;
775
776 testing
777 < internal/testhash;
778
779 CRYPTO-MATH
780 < crypto/mlkem/mlkemtest;
781
782 CRYPTO-MATH, testing, internal/testenv, internal/testhash, encoding/json, regexp
783 < crypto/internal/cryptotest;
784
785 crypto/internal/cryptotest, encoding/hex
786 < crypto/internal/cryptotest/wycheproof;
787
788 FMT, encoding/json, time, regexp
789 < crypto/internal/cryptotest/x509limbo;
790
791 CGO, FMT
792 < crypto/internal/sysrand/internal/seccomp;
793
794 FIPS
795 < crypto/internal/fips140/check/checktest;
796
797 # v2 execution trace parser.
798 FMT, io, internal/trace/tracev2
799 < internal/trace/version;
800
801 FMT, encoding/binary, internal/trace/version
802 < internal/trace/raw;
803
804 FMT, internal/trace/version, io, sort, encoding/binary
805 < internal/trace/internal/tracev1;
806
807 FMT, encoding/binary, internal/trace/version, internal/trace/internal/tracev1, container/heap, math/rand, regexp
808 < internal/trace;
809
810 # cmd/trace dependencies.
811 FMT,
812 embed,
813 encoding/json,
814 html/template,
815 internal/profile,
816 internal/trace,
817 internal/trace/traceviewer/format,
818 net/http
819 < internal/trace/traceviewer;
820
821 # Coverage.
822 FMT, hash/fnv, encoding/binary, regexp, sort, text/tabwriter,
823 internal/coverage, internal/coverage/uleb128
824 < internal/coverage/cmerge,
825 internal/coverage/pods,
826 internal/coverage/slicereader,
827 internal/coverage/slicewriter;
828
829 internal/coverage/slicereader, internal/coverage/slicewriter
830 < internal/coverage/stringtab
831 < internal/coverage/decodecounter, internal/coverage/decodemeta,
832 internal/coverage/encodecounter, internal/coverage/encodemeta;
833
834 internal/coverage/cmerge
835 < internal/coverage/cformat;
836
837 internal/coverage, crypto/sha256, FMT
838 < cmd/internal/cov/covcmd;
839
840 encoding/json,
841 runtime/debug,
842 internal/coverage/calloc,
843 internal/coverage/cformat,
844 internal/coverage/decodecounter, internal/coverage/decodemeta,
845 internal/coverage/encodecounter, internal/coverage/encodemeta,
846 internal/coverage/pods
847 < internal/coverage/cfile
848 < runtime/coverage;
849
850 internal/coverage/cfile, internal/fuzz, internal/testlog, runtime/pprof, regexp
851 < testing/internal/testdeps;
852
853 # Test-only packages can have anything they want
854
855 FMT, compress/gzip, embed, encoding/binary
856 < encoding/json/internal/jsontest;
857
858 CGO, internal/syscall/unix
859 < net/internal/cgotest;
860
861 FMT, testing
862 < internal/cgrouptest;
863
864 regexp, internal/testenv, internal/trace, internal/trace/raw, internal/txtar, testing
865 < internal/trace/testtrace;
866
867 C, CGO
868 < internal/runtime/cgobench;
869
870 # Generate-only packages can have anything they want.
871
872 container/heap,
873 encoding/binary,
874 fmt,
875 hash/maphash,
876 io,
877 log,
878 math/bits,
879 os,
880 reflect,
881 strings,
882 sync
883 < internal/runtime/gc/internal/gen;
884
885 regexp, internal/txtar, internal/trace, internal/trace/raw
886 < internal/trace/internal/testgen;
887
888 FMT
889 < math/big/internal/asmgen;
890 `
891
892
893 func listStdPkgs(goroot string) ([]string, error) {
894
895 var pkgs []string
896
897 src := filepath.Join(goroot, "src") + string(filepath.Separator)
898 walkFn := func(path string, d fs.DirEntry, err error) error {
899 if err != nil || !d.IsDir() || path == src {
900 return nil
901 }
902
903 base := filepath.Base(path)
904 if strings.HasPrefix(base, ".") || strings.HasPrefix(base, "_") || base == "testdata" {
905 return filepath.SkipDir
906 }
907
908 name := filepath.ToSlash(path[len(src):])
909 if name == "builtin" || name == "cmd" {
910 return filepath.SkipDir
911 }
912
913 pkgs = append(pkgs, strings.TrimPrefix(name, "vendor/"))
914 return nil
915 }
916 if err := filepath.WalkDir(src, walkFn); err != nil {
917 return nil, err
918 }
919 return pkgs, nil
920 }
921
922 func TestDependencies(t *testing.T) {
923 testenv.MustHaveSource(t)
924
925 ctxt := Default
926 all, err := listStdPkgs(ctxt.GOROOT)
927 if err != nil {
928 t.Fatal(err)
929 }
930 slices.Sort(all)
931
932 sawImport := map[string]map[string]bool{}
933 policy := depsPolicy(t)
934
935 for _, pkg := range all {
936 imports, err := findImports(pkg)
937 if err != nil {
938 t.Error(err)
939 continue
940 }
941 if sawImport[pkg] == nil {
942 sawImport[pkg] = map[string]bool{}
943 }
944 var bad []string
945 for _, imp := range imports {
946 sawImport[pkg][imp] = true
947 if !policy.HasEdge(pkg, imp) {
948 bad = append(bad, imp)
949 }
950 }
951 if bad != nil {
952 t.Errorf("unexpected dependency: %s imports %v", pkg, bad)
953 }
954 }
955 }
956
957 var buildIgnore = []byte("\n//go:build ignore")
958
959 func findImports(pkg string) ([]string, error) {
960 vpkg := pkg
961 if strings.HasPrefix(pkg, "golang.org") {
962 vpkg = "vendor/" + pkg
963 }
964 dir := filepath.Join(Default.GOROOT, "src", vpkg)
965 files, err := os.ReadDir(dir)
966 if err != nil {
967 return nil, err
968 }
969 var imports []string
970 var haveImport = map[string]bool{}
971 if pkg == "crypto/internal/boring" {
972 haveImport["C"] = true
973 }
974 fset := token.NewFileSet()
975 for _, file := range files {
976 name := file.Name()
977 if name == "slice_go14.go" || name == "slice_go18.go" {
978
979 continue
980 }
981 if !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
982 continue
983 }
984 info := fileInfo{
985 name: filepath.Join(dir, name),
986 fset: fset,
987 }
988 f, err := os.Open(info.name)
989 if err != nil {
990 return nil, err
991 }
992 err = readGoInfo(f, &info)
993 f.Close()
994 if err != nil {
995 return nil, fmt.Errorf("reading %v: %v", name, err)
996 }
997 if info.parsed.Name.Name == "main" {
998 continue
999 }
1000 if bytes.Contains(info.header, buildIgnore) {
1001 continue
1002 }
1003 for _, imp := range info.imports {
1004 path := imp.path
1005 if !haveImport[path] {
1006 haveImport[path] = true
1007 imports = append(imports, path)
1008 }
1009 }
1010 }
1011 slices.Sort(imports)
1012 return imports, nil
1013 }
1014
1015
1016 func depsPolicy(t *testing.T) *dag.Graph {
1017 g, err := dag.Parse(depsRules)
1018 if err != nil {
1019 t.Fatal(err)
1020 }
1021 return g
1022 }
1023
1024
1025
1026 func TestStdlibLowercase(t *testing.T) {
1027 testenv.MustHaveSource(t)
1028
1029 ctxt := Default
1030 all, err := listStdPkgs(ctxt.GOROOT)
1031 if err != nil {
1032 t.Fatal(err)
1033 }
1034
1035 for _, pkgname := range all {
1036 if strings.ToLower(pkgname) != pkgname {
1037 t.Errorf("package %q should not use upper-case path", pkgname)
1038 }
1039 }
1040 }
1041
1042
1043 func TestFindImports(t *testing.T) {
1044 imports, err := findImports("go/build")
1045 if err != nil {
1046 t.Fatal(err)
1047 }
1048 t.Logf("go/build imports %q", imports)
1049 want := []string{"bytes", "os", "path/filepath", "strings"}
1050 wantLoop:
1051 for _, w := range want {
1052 for _, imp := range imports {
1053 if imp == w {
1054 continue wantLoop
1055 }
1056 }
1057 t.Errorf("expected to find %q in import list", w)
1058 }
1059 }
1060
View as plain text