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