Source file src/cmd/distpack/test.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file contains tests applied to the archives before they are written.
     6  
     7  package main
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"log"
    13  	"os"
    14  	"path"
    15  	"path/filepath"
    16  	"strings"
    17  )
    18  
    19  type testRule struct {
    20  	name    string
    21  	goos    string
    22  	exclude bool
    23  }
    24  
    25  var srcRules = []testRule{
    26  	{name: "go/VERSION"},
    27  	{name: "go/src/cmd/go/main.go"},
    28  	{name: "go/src/bytes/bytes.go"},
    29  	{name: "**/.DS_Store", exclude: true},
    30  	{name: "go/.git", exclude: true},
    31  	{name: "go/.gitattributes", exclude: true},
    32  	{name: "go/.github", exclude: true},
    33  	{name: "go/VERSION.cache", exclude: true},
    34  	{name: "go/bin/**", exclude: true},
    35  	{name: "go/pkg/**", exclude: true},
    36  	{name: "go/src/cmd/dist/dist", exclude: true},
    37  	{name: "go/src/cmd/dist/dist.exe", exclude: true},
    38  	{name: "go/src/internal/runtime/sys/zversion.go", exclude: true},
    39  	{name: "go/src/time/tzdata/zzipdata.go", exclude: true},
    40  }
    41  
    42  var zipRules = []testRule{
    43  	{name: "go/VERSION"},
    44  	{name: "go/src/cmd/go/main.go"},
    45  	{name: "go/src/bytes/bytes.go"},
    46  
    47  	{name: "**/.DS_Store", exclude: true},
    48  	{name: "go/.git", exclude: true},
    49  	{name: "go/.gitattributes", exclude: true},
    50  	{name: "go/.github", exclude: true},
    51  	{name: "go/VERSION.cache", exclude: true},
    52  	{name: "go/bin", exclude: true},
    53  	{name: "go/pkg", exclude: true},
    54  	{name: "go/src/cmd/dist/dist", exclude: true},
    55  	{name: "go/src/cmd/dist/dist.exe", exclude: true},
    56  
    57  	{name: "go/bin/go", goos: "linux"},
    58  	{name: "go/bin/go", goos: "darwin"},
    59  	{name: "go/bin/go", goos: "windows", exclude: true},
    60  	{name: "go/bin/go.exe", goos: "windows"},
    61  	{name: "go/bin/gofmt", goos: "linux"},
    62  	{name: "go/bin/gofmt", goos: "darwin"},
    63  	{name: "go/bin/gofmt", goos: "windows", exclude: true},
    64  	{name: "go/bin/gofmt.exe", goos: "windows"},
    65  	{name: "go/pkg/tool/*/compile", goos: "linux"},
    66  	{name: "go/pkg/tool/*/compile", goos: "darwin"},
    67  	{name: "go/pkg/tool/*/compile", goos: "windows", exclude: true},
    68  	{name: "go/pkg/tool/*/compile.exe", goos: "windows"},
    69  	{name: "go/pkg/tool/*/pack", exclude: true},
    70  	{name: "go/pkg/tool/*/pack.exe", exclude: true},
    71  }
    72  
    73  var modRules = []testRule{
    74  	{name: "golang.org/toolchain@*/VERSION"},
    75  	{name: "golang.org/toolchain@*/src/cmd/go/main.go"},
    76  	{name: "golang.org/toolchain@*/src/bytes/bytes.go"},
    77  
    78  	{name: "golang.org/toolchain@*/lib/wasm/go_js_wasm_exec"},
    79  	{name: "golang.org/toolchain@*/lib/wasm/go_wasip1_wasm_exec"},
    80  	{name: "golang.org/toolchain@*/lib/wasm/wasm_exec.js"},
    81  	{name: "golang.org/toolchain@*/lib/wasm/wasm_exec_node.js"},
    82  
    83  	{name: "**/.DS_Store", exclude: true},
    84  	{name: "golang.org/toolchain@*/.git", exclude: true},
    85  	{name: "golang.org/toolchain@*/.gitattributes", exclude: true},
    86  	{name: "golang.org/toolchain@*/.github", exclude: true},
    87  	{name: "golang.org/toolchain@*/VERSION.cache", exclude: true},
    88  	{name: "golang.org/toolchain@*/bin", exclude: true},
    89  	{name: "golang.org/toolchain@*/pkg", exclude: true},
    90  	{name: "golang.org/toolchain@*/src/cmd/dist/dist", exclude: true},
    91  	{name: "golang.org/toolchain@*/src/cmd/dist/dist.exe", exclude: true},
    92  
    93  	{name: "golang.org/toolchain@*/bin/go", goos: "linux"},
    94  	{name: "golang.org/toolchain@*/bin/go", goos: "darwin"},
    95  	{name: "golang.org/toolchain@*/bin/go", goos: "windows", exclude: true},
    96  	{name: "golang.org/toolchain@*/bin/go.exe", goos: "windows"},
    97  	{name: "golang.org/toolchain@*/bin/gofmt", goos: "linux"},
    98  	{name: "golang.org/toolchain@*/bin/gofmt", goos: "darwin"},
    99  	{name: "golang.org/toolchain@*/bin/gofmt", goos: "windows", exclude: true},
   100  	{name: "golang.org/toolchain@*/bin/gofmt.exe", goos: "windows"},
   101  	{name: "golang.org/toolchain@*/pkg/tool/*/compile", goos: "linux"},
   102  	{name: "golang.org/toolchain@*/pkg/tool/*/compile", goos: "darwin"},
   103  	{name: "golang.org/toolchain@*/pkg/tool/*/compile", goos: "windows", exclude: true},
   104  	{name: "golang.org/toolchain@*/pkg/tool/*/compile.exe", goos: "windows"},
   105  	{name: "golang.org/toolchain@*/pkg/tool/*/pack", exclude: true},
   106  	{name: "golang.org/toolchain@*/pkg/tool/*/pack.exe", exclude: true},
   107  
   108  	// go.mod are renamed to _go.mod.
   109  	{name: "**/go.mod", exclude: true},
   110  	{name: "**/_go.mod"},
   111  }
   112  
   113  func testSrc(a *Archive) {
   114  	test("source", a, srcRules)
   115  
   116  	// Check that no generated files slip in, even if new ones are added.
   117  	for _, f := range a.Files {
   118  		if strings.HasPrefix(path.Base(f.Name), "z") {
   119  			data, err := os.ReadFile(filepath.Join(goroot, strings.TrimPrefix(f.Name, "go/")))
   120  			if err != nil {
   121  				log.Fatalf("checking source archive: %v", err)
   122  			}
   123  			if strings.Contains(string(data), "generated by go tool dist; DO NOT EDIT") {
   124  				log.Fatalf("unexpected source archive file: %s (generated by dist)", f.Name)
   125  			}
   126  		}
   127  	}
   128  }
   129  
   130  func testZip(a *Archive) { test("binary", a, zipRules) }
   131  func testMod(a *Archive) { test("module", a, modRules) }
   132  
   133  func test(kind string, a *Archive, rules []testRule) {
   134  	ok := true
   135  	have := make([]bool, len(rules))
   136  	for _, f := range a.Files {
   137  		for i, r := range rules {
   138  			if r.goos != "" && r.goos != goos {
   139  				continue
   140  			}
   141  			match, err := amatch(r.name, f.Name)
   142  			if err != nil {
   143  				log.Fatal(err)
   144  			}
   145  			if match {
   146  				if r.exclude {
   147  					ok = false
   148  					if !have[i] {
   149  						log.Printf("unexpected %s archive file: %s", kind, f.Name)
   150  						have[i] = true // silence future prints for excluded directory
   151  					}
   152  				} else {
   153  					have[i] = true
   154  				}
   155  			}
   156  		}
   157  	}
   158  	missing := false
   159  	for i, r := range rules {
   160  		if r.goos != "" && r.goos != goos {
   161  			continue
   162  		}
   163  		if !r.exclude && !have[i] {
   164  			missing = true
   165  			log.Printf("missing %s archive file: %s", kind, r.name)
   166  		}
   167  	}
   168  	if missing {
   169  		ok = false
   170  		var buf bytes.Buffer
   171  		for _, f := range a.Files {
   172  			fmt.Fprintf(&buf, "\n\t%s", f.Name)
   173  		}
   174  		log.Printf("archive contents: %d files%s", len(a.Files), buf.Bytes())
   175  	}
   176  	if !ok {
   177  		log.Fatalf("bad archive file")
   178  	}
   179  }
   180  

View as plain text