tools/internal/robustio/copyfiles.go

118 строки
3.6 KiB
Go
Исходник Обычный вид История

// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build ignore
// +build ignore
// The copyfiles script copies the contents of the internal cmd/go robustio
// package to the current directory, with adjustments to make it build.
//
// NOTE: In retrospect this script got out of hand, as we have to perform
// various operations on the package to get it to build at old Go versions. If
// in the future it proves to be flaky, delete it and just copy code manually.
package main
import (
"bytes"
"go/build/constraint"
"go/scanner"
"go/token"
"log"
"os"
"path/filepath"
"runtime"
"strings"
)
func main() {
dir := filepath.Join(runtime.GOROOT(), "src", "cmd", "go", "internal", "robustio")
entries, err := os.ReadDir(dir)
if err != nil {
log.Fatalf("reading the robustio dir: %v", err)
}
// Collect file content so that we can validate before copying.
fileContent := make(map[string][]byte)
windowsImport := []byte("\t\"internal/syscall/windows\"\n")
foundWindowsImport := false
for _, entry := range entries {
if strings.HasSuffix(entry.Name(), ".go") {
pth := filepath.Join(dir, entry.Name())
content, err := os.ReadFile(pth)
if err != nil {
log.Fatalf("reading %q: %v", entry.Name(), err)
}
// Replace the use of internal/syscall/windows.ERROR_SHARING_VIOLATION
// with a local constant.
if entry.Name() == "robustio_windows.go" && bytes.Contains(content, windowsImport) {
foundWindowsImport = true
content = bytes.Replace(content, windowsImport, nil, 1)
content = bytes.Replace(content, []byte("windows.ERROR_SHARING_VIOLATION"), []byte("ERROR_SHARING_VIOLATION"), -1)
}
tools: replace references to obsolete package ioutils ioutil defines 7 functions. 6 of these are replaced by functions in io or os with the same signature. ReadDir is deprecated, but the suggested replacement has a different signature. These changes were generated by a program, with some manual adjutments. The program replaces ReadDir with a call to a function named ioutilReadDir that has the same signature. The code for this function is added to files if necessary. The program replaces all the others with their new versions. The program removes the 'io/ioutil' import and adds, as necessary, 'os', 'io', and 'io/fs', the latter being needed for the signature of ioutilReadDir. The automatic process fails in a few ways: 1. ReadFile occurs only in a comment but the program adds an unneeded import. 2. ioutilReadDir is added to more than one file in the same package Both of these could be viewed as bugs and fixed by looking harder. After manual adjustment, two tests failed: 1. gopls/internal/lsp/regtesg/mis:TestGenerateProgress. The reason was a use of ioutil in a txtar constant. The calls were changed, but the code is not smart enough to change the import inside the string constant. (Or it's not smart enough not to change the contents of a string.) 2. gopls/internal/lsp/analysis/deprecated, which wants to see a use of ioutil These tests were adjused by hand, and all tests (-short) pass. Change-Id: If9efe40bbb0edda36173d9a88afaf71245db8e79 Reviewed-on: https://go-review.googlesource.com/c/tools/+/527675 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Peter Weinberger <pjw@google.com> Reviewed-by: Heschi Kreinick <heschi@google.com>
2023-09-12 17:11:42 +03:00
// Replace os.ReadFile with os.ReadFile (for 1.15 and older). We
// attempt to match calls (via the '('), to avoid matching mentions of
// os.ReadFile in comments.
//
// TODO(rfindley): once we (shortly!) no longer support 1.15, remove
// this and break the build.
if bytes.Contains(content, []byte("os.ReadFile(")) {
content = bytes.Replace(content, []byte("\"os\""), []byte("\"io/ioutil\"\n\t\"os\""), 1)
tools: replace references to obsolete package ioutils ioutil defines 7 functions. 6 of these are replaced by functions in io or os with the same signature. ReadDir is deprecated, but the suggested replacement has a different signature. These changes were generated by a program, with some manual adjutments. The program replaces ReadDir with a call to a function named ioutilReadDir that has the same signature. The code for this function is added to files if necessary. The program replaces all the others with their new versions. The program removes the 'io/ioutil' import and adds, as necessary, 'os', 'io', and 'io/fs', the latter being needed for the signature of ioutilReadDir. The automatic process fails in a few ways: 1. ReadFile occurs only in a comment but the program adds an unneeded import. 2. ioutilReadDir is added to more than one file in the same package Both of these could be viewed as bugs and fixed by looking harder. After manual adjustment, two tests failed: 1. gopls/internal/lsp/regtesg/mis:TestGenerateProgress. The reason was a use of ioutil in a txtar constant. The calls were changed, but the code is not smart enough to change the import inside the string constant. (Or it's not smart enough not to change the contents of a string.) 2. gopls/internal/lsp/analysis/deprecated, which wants to see a use of ioutil These tests were adjused by hand, and all tests (-short) pass. Change-Id: If9efe40bbb0edda36173d9a88afaf71245db8e79 Reviewed-on: https://go-review.googlesource.com/c/tools/+/527675 TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Peter Weinberger <pjw@google.com> Reviewed-by: Heschi Kreinick <heschi@google.com>
2023-09-12 17:11:42 +03:00
content = bytes.Replace(content, []byte("os.ReadFile("), []byte("os.ReadFile("), -1)
}
// Add +build constraints, for 1.16.
content = addPlusBuildConstraints(content)
fileContent[entry.Name()] = content
}
}
if !foundWindowsImport {
log.Fatal("missing expected import of internal/syscall/windows in robustio_windows.go")
}
for name, content := range fileContent {
if err := os.WriteFile(name, content, 0644); err != nil {
log.Fatalf("writing %q: %v", name, err)
}
}
}
// addPlusBuildConstraints splices in +build constraints for go:build
// constraints encountered in the source.
//
// Gopls still builds at Go 1.16, which requires +build constraints.
func addPlusBuildConstraints(src []byte) []byte {
var s scanner.Scanner
fset := token.NewFileSet()
file := fset.AddFile("", fset.Base(), len(src))
s.Init(file, src, nil /* no error handler */, scanner.ScanComments)
result := make([]byte, 0, len(src))
lastInsertion := 0
for {
pos, tok, lit := s.Scan()
if tok == token.EOF {
break
}
if tok == token.COMMENT {
if c, err := constraint.Parse(lit); err == nil {
plusBuild, err := constraint.PlusBuildLines(c)
if err != nil {
log.Fatalf("computing +build constraint for %q: %v", lit, err)
}
insertAt := file.Offset(pos) + len(lit)
result = append(result, src[lastInsertion:insertAt]...)
result = append(result, []byte("\n"+strings.Join(plusBuild, "\n"))...)
lastInsertion = insertAt
}
}
}
result = append(result, src[lastInsertion:]...)
return result
}