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