mirror of
https://github.com/tailscale/tailscale.git
synced 2024-12-12 03:04:40 +00:00
66 lines
1.8 KiB
Go
66 lines
1.8 KiB
Go
|
// Copyright (c) Tailscale Inc & AUTHORS
|
||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||
|
|
||
|
package main
|
||
|
|
||
|
import (
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io/fs"
|
||
|
"os"
|
||
|
"path/filepath"
|
||
|
)
|
||
|
|
||
|
// makeGoroot constructs a GOROOT-like file structure in outPath,
|
||
|
// which consists of toolchainRoot except for the `go` binary, which
|
||
|
// points to gocross.
|
||
|
//
|
||
|
// It's useful for integrating with tooling that expects to be handed
|
||
|
// a GOROOT, like the Goland IDE or depaware.
|
||
|
func makeGoroot(toolchainRoot, outPath string) error {
|
||
|
self, err := os.Executable()
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("getting gocross's path: %v", err)
|
||
|
}
|
||
|
|
||
|
os.RemoveAll(outPath)
|
||
|
if err := os.MkdirAll(filepath.Join(outPath, "bin"), 0750); err != nil {
|
||
|
return fmt.Errorf("making %q: %v", outPath, err)
|
||
|
}
|
||
|
if err := os.Symlink(self, filepath.Join(outPath, "bin/go")); err != nil {
|
||
|
return fmt.Errorf("linking gocross into outpath: %v", err)
|
||
|
}
|
||
|
|
||
|
if err := linkFarm(toolchainRoot, outPath); err != nil {
|
||
|
return fmt.Errorf("creating GOROOT link farm: %v", err)
|
||
|
}
|
||
|
if err := linkFarm(filepath.Join(toolchainRoot, "bin"), filepath.Join(outPath, "bin")); err != nil {
|
||
|
return fmt.Errorf("creating GOROOT/bin link farm: %v", err)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// linkFarm symlinks every entry in srcDir into outDir, unless that
|
||
|
// directory entry already exists.
|
||
|
func linkFarm(srcDir, outDir string) error {
|
||
|
ents, err := os.ReadDir(srcDir)
|
||
|
if err != nil {
|
||
|
return fmt.Errorf("reading %q: %v", srcDir, err)
|
||
|
}
|
||
|
|
||
|
for _, ent := range ents {
|
||
|
dst := filepath.Join(outDir, ent.Name())
|
||
|
_, err := os.Lstat(dst)
|
||
|
if errors.Is(err, fs.ErrNotExist) {
|
||
|
if err := os.Symlink(filepath.Join(srcDir, ent.Name()), dst); err != nil {
|
||
|
return fmt.Errorf("symlinking %q to %q: %v", ent.Name(), outDir, err)
|
||
|
}
|
||
|
} else if err != nil {
|
||
|
return fmt.Errorf("stat-ing %q: %v", dst, err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|