1// run 2 3// Copyright 2020 The Go Authors. All rights reserved. 4// Use of this source code is governed by a BSD-style 5// license that can be found in the LICENSE file. 6 7// Check that batch files are maintained as CRLF files (consistent 8// behavior on all operating systems). See golang.org/issue/37791. 9 10package main 11 12import ( 13 "bytes" 14 "fmt" 15 "io/ioutil" 16 "log" 17 "os" 18 "path/filepath" 19 "runtime" 20 "strings" 21) 22 23func main() { 24 // Ensure that the GOROOT/src/all.bat file exists and has strict CRLF line endings. 25 enforceBatchStrictCRLF(filepath.Join(runtime.GOROOT(), "src", "all.bat")) 26 27 // Walk the entire Go repository source tree (without GOROOT/pkg), 28 // skipping directories that start with "." and named "testdata", 29 // and ensure all .bat files found have exact CRLF line endings. 30 err := filepath.WalkDir(runtime.GOROOT(), func(path string, d os.DirEntry, err error) error { 31 if err != nil { 32 return err 33 } 34 if d.IsDir() && (strings.HasPrefix(d.Name(), ".") || d.Name() == "testdata") { 35 return filepath.SkipDir 36 } 37 if path == filepath.Join(runtime.GOROOT(), "pkg") { 38 // GOROOT/pkg is known to contain generated artifacts, not source code. 39 // Skip it to avoid false positives. (Also see golang.org/issue/37929.) 40 return filepath.SkipDir 41 } 42 if filepath.Ext(d.Name()) == ".bat" { 43 enforceBatchStrictCRLF(path) 44 } 45 return nil 46 }) 47 if err != nil { 48 log.Fatalln(err) 49 } 50} 51 52func enforceBatchStrictCRLF(path string) { 53 b, err := ioutil.ReadFile(path) 54 if err != nil { 55 log.Fatalln(err) 56 } 57 cr, lf := bytes.Count(b, []byte{13}), bytes.Count(b, []byte{10}) 58 crlf := bytes.Count(b, []byte{13, 10}) 59 if cr != crlf || lf != crlf { 60 if rel, err := filepath.Rel(runtime.GOROOT(), path); err == nil { 61 // Make the test failure more readable by showing a path relative to GOROOT. 62 path = rel 63 } 64 fmt.Printf("Windows batch file %s does not use strict CRLF line termination.\n", path) 65 fmt.Printf("Please convert it to CRLF before checking it in due to golang.org/issue/37791.\n") 66 os.Exit(1) 67 } 68} 69