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