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