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

View as plain text