github.com/bir3/gocompiler@v0.9.2202/vfs/vfs.go (about)

     1  // Copyright 2022 Bergur Ragnarsson.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package vfs
     6  
     7  import (
     8  	"embed"
     9  	"fmt"
    10  	"os"
    11  	"path/filepath"
    12  
    13  	"github.com/bir3/gocompiler/extra"
    14  	"github.com/bir3/gocompiler/extra/extract_stdlib"
    15  )
    16  
    17  //go:embed goroot
    18  var content embed.FS
    19  
    20  var GOROOT = "/github.com/bir3/gocompiler/error-missing-init"
    21  
    22  func init() {
    23  	if os.Getenv("BIR3_GOCOMPILER_TOOL") == "" {
    24  		return // not in Go toolchain mode
    25  	}
    26  
    27  	d, err := PrivateGOROOT()
    28  	if err != nil {
    29  		return // compiler will fail due to missing GOROOT
    30  	}
    31  	GOROOT = d
    32  }
    33  
    34  func SetupStdlib() error {
    35  	d, err := PrivateGOROOT()
    36  	if err != nil {
    37  		return err
    38  	}
    39  	err = extractStdlib(d) // no-op if already done
    40  	if err != nil {
    41  		return err
    42  	}
    43  	return nil
    44  }
    45  
    46  func PrivateGOROOT() (string, error) {
    47  	return configDir("bir3-gocompiler/stdlib-go1.22.0-0681") //syncvar:
    48  
    49  }
    50  
    51  func extractStdlib(d string) error {
    52  	f, err := content.Open("goroot/stdlib-go1.22.0-0681.tar.zst") //syncvar:
    53  	if err != nil {
    54  		panic(fmt.Sprintf("gocompiler stdlib init failed - %s", err))
    55  	}
    56  	defer f.Close()
    57  
    58  	err = extract_stdlib.ExtractStdlib(f, d)
    59  	if err != nil {
    60  		return fmt.Errorf("github.com/bir3/gocompiler: extract stdlib to %s failed with %v\n", d, err)
    61  	}
    62  	return nil
    63  }
    64  
    65  func configDir(folder string) (string, error) {
    66  	var err error
    67  	d := os.Getenv("BIR3_GOCOMPILER_GOROOT")
    68  	if d == "" {
    69  		d, err = os.UserConfigDir()
    70  		if err != nil {
    71  			return "", fmt.Errorf("failed to get config folder for stdlib - %w", err)
    72  		}
    73  	}
    74  	d = filepath.Join(d, folder)
    75  	if !filepath.IsAbs(d) {
    76  		return "", fmt.Errorf("config folder %s is not absolute path for stdlib - %w", d, err)
    77  	}
    78  	if err == nil {
    79  		err = extra.MkdirAllRace(d, 0755)
    80  	}
    81  	if err != nil {
    82  		return "", fmt.Errorf("failed to create config folder %s for stdlib - %w", d, err)
    83  	}
    84  	readme := `
    85  created by github.com/bir3/gocompiler
    86  
    87  this folder can be set with env BIR3_GOCOMPILER_GOROOT
    88  `
    89  	os.WriteFile(filepath.Join(d, "README-bir3"), []byte(readme), 0666)
    90  	return d, nil
    91  }