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