262 lines
5.7 KiB
Go
262 lines
5.7 KiB
Go
package main
|
|
|
|
import (
|
|
"embed"
|
|
"errors"
|
|
"flag"
|
|
"github.com/go-git/go-git/v5"
|
|
"github.com/go-git/go-git/v5/plumbing"
|
|
"go/format"
|
|
"os"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
//go:embed internal
|
|
var patchFiles embed.FS
|
|
|
|
func main() {
|
|
repositoryUrl := flag.String("url", "https://github.com/golang/go.git", "golang repository url")
|
|
|
|
repositoryRef := flag.String("ref", Version, "git reference")
|
|
|
|
outputDirectory := flag.String("output", ".", "output directory")
|
|
|
|
packagePath := flag.String("pkg", "", "package path")
|
|
|
|
flag.Parse()
|
|
|
|
tmpDir, err := os.MkdirTemp(os.TempDir(), "golang_repo")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
_, err = git.PlainClone(tmpDir, false, &git.CloneOptions{
|
|
URL: *repositoryUrl,
|
|
ReferenceName: plumbing.NewTagReferenceName(*repositoryRef),
|
|
SingleBranch: true,
|
|
Depth: 1,
|
|
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
|
|
ShallowSubmodules: true,
|
|
Progress: os.Stderr,
|
|
})
|
|
if errors.Is(err, git.NoMatchingRefSpecError{}) {
|
|
//retry with branch name instead
|
|
_, err = git.PlainClone(tmpDir, false, &git.CloneOptions{
|
|
URL: *repositoryUrl,
|
|
ReferenceName: plumbing.NewBranchReferenceName(*repositoryRef),
|
|
SingleBranch: true,
|
|
Depth: 1,
|
|
RecurseSubmodules: git.DefaultSubmoduleRecursionDepth,
|
|
ShallowSubmodules: true,
|
|
Progress: os.Stderr,
|
|
})
|
|
}
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
err = os.MkdirAll(*outputDirectory, 0755)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
dirList, err := os.ReadDir(*outputDirectory)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Cleanup directories from source
|
|
for _, d := range dirList {
|
|
if d.IsDir() {
|
|
err = os.RemoveAll(path.Join(*outputDirectory, d.Name()))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
type targets [2]string
|
|
|
|
for _, t := range []targets{
|
|
{"src/cmd/asm/internal/arch", "asm/arch"},
|
|
{"src/cmd/internal/obj", "obj"},
|
|
{"src/cmd/internal/objabi", "objabi"},
|
|
{"src/cmd/internal/goobj", "goobj"},
|
|
{"src/cmd/internal/dwarf", "dwarf"},
|
|
{"src/cmd/internal/src", "src"},
|
|
{"src/cmd/internal/sys", "sys"},
|
|
{"src/internal/abi", "abi"},
|
|
{"src/internal/goarch", "goarch"},
|
|
{"src/internal/buildcfg", "buildcfg"},
|
|
} {
|
|
srcPath := path.Join(tmpDir, t[0])
|
|
outPath := path.Join(*outputDirectory, t[1])
|
|
err = os.MkdirAll(path.Dir(outPath), 0755)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
//todo: os.CopyFS https://github.com/golang/go/issues/62484
|
|
err = os.Rename(srcPath, outPath)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
for _, fileToDelete := range []string{
|
|
// removes dependency on goexperiment
|
|
"buildcfg/exp.go",
|
|
// removes dependency on internal/bisect
|
|
"objabi/flag.go",
|
|
// removes dependency on cmd/internal/bio
|
|
"obj/objfile.go",
|
|
"goobj/objfile.go",
|
|
"goobj/funcinfo.go",
|
|
} {
|
|
err = os.Remove(path.Join(*outputDirectory, fileToDelete))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
var nestPatch func(dir string) error
|
|
nestPatch = func(dir string) error {
|
|
dirList, err := patchFiles.ReadDir(dir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, p := range dirList {
|
|
if p.IsDir() {
|
|
err = nestPatch(path.Join(dir, p.Name()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
fData, err := patchFiles.ReadFile(path.Join(dir, p.Name()))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(path.Join(*outputDirectory, strings.TrimPrefix(dir, "internal/"), p.Name()), fData, 0655)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
err = nestPatch("internal")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Copy license file
|
|
err = os.Rename(path.Join(tmpDir, "LICENSE"), path.Join(*outputDirectory, "LICENSE"))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
type replaceEntry struct {
|
|
Regexp *regexp.Regexp
|
|
Replacement []byte
|
|
}
|
|
|
|
replacer := []replaceEntry{
|
|
// fixup notsha256
|
|
{regexp.MustCompile("(\\s)\"cmd/internal/notsha256\""), []byte("$1\"crypto/sha256\"")},
|
|
{regexp.MustCompile("notsha256\\."), []byte("sha256.")},
|
|
|
|
// fixup lazyregexp
|
|
{regexp.MustCompile("(\\s)\"cmd/internal/lazyregexp\""), []byte("$1\"regexp\"")},
|
|
{regexp.MustCompile("lazyregexp\\.New"), []byte("regexp.MustCompile")},
|
|
|
|
// fixup imports
|
|
{regexp.MustCompile("(\\s)\"cmd/internal"), []byte("$1\"" + *packagePath)},
|
|
{regexp.MustCompile("(\\s)\"internal"), []byte("$1\"" + *packagePath)},
|
|
}
|
|
|
|
var nestDir func(dir string, depth int) error
|
|
nestDir = func(dir string, depth int) error {
|
|
dirList, err := os.ReadDir(dir)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, d := range dirList {
|
|
|
|
fPath := path.Join(dir, d.Name())
|
|
if d.IsDir() {
|
|
// remove tests
|
|
if d.Name() == "testdata" {
|
|
err = os.RemoveAll(fPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
err := nestDir(fPath, depth+1)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
|
|
// do not replace on root
|
|
if depth < 2 {
|
|
continue
|
|
}
|
|
|
|
// remove tests
|
|
if strings.HasSuffix(d.Name(), "_test.go") || strings.HasSuffix(d.Name(), "_test.s") {
|
|
err := os.Remove(fPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
continue
|
|
}
|
|
|
|
if strings.HasSuffix(d.Name(), ".go") {
|
|
err := func() error {
|
|
fData, err := os.ReadFile(fPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, r := range replacer {
|
|
fData = r.Regexp.ReplaceAll(fData, r.Replacement)
|
|
}
|
|
|
|
// gofmt
|
|
fData, err = format.Source(fData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
writer, err := os.Create(fPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer writer.Close()
|
|
_, err = writer.Write(fData)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
return nil
|
|
}
|
|
|
|
err = nestDir(*outputDirectory, 1)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|