Create in-sandbox builder for env

This commit is contained in:
adisbladis 2020-07-23 11:11:31 +02:00
parent 869ea9a6b2
commit 2034c858bd
No known key found for this signature in database
GPG key ID: 110BFAD44C6249B7
3 changed files with 125 additions and 21 deletions

View file

@ -14,6 +14,7 @@ let
buildGoApplication =
{
modules
, src
, CGO_ENABLED ? "0"
, nativeBuildInputs ? []
, allowGoReference ? false
@ -23,34 +24,29 @@ let
}@attrs: let
modulesStruct = builtins.fromTOML (builtins.readFile modules);
# TODO: This is a giant inefficient hack
# Replace this with something that's _like_ buildEnv but doesn't need a
# runCommand per input
vendorEnv = buildEnv {
# Better method for this?
ignoreCollisions = true;
vendorEnv = runCommand "vendor-env" {
nativeBuildInputs = [ pkgs.go ];
json = builtins.toJSON modulesStruct;
# nativeBuildInputs = [ go ];
name = "vendor-env";
paths = lib.mapAttrsToList (goPackagePath: meta: let
sources = builtins.toJSON (lib.mapAttrs (goPackagePath: meta: let
src = fetchgit {
inherit (meta.fetch) url sha256 rev;
fetchSubmodules = true;
};
path = goPackagePath;
srcPath = "${src}/${meta.relPath or ""}";
mkCommand = outpath: ''
mkdir -p $out/$(dirname ${outpath})
ln -s ${srcPath} $out/${outpath}
'';
in srcPath) modulesStruct);
in runCommand "${src.name}-env" {} ''
${mkCommand goPackagePath}
${if lib.hasAttr "vendorPath" meta then (mkCommand meta.vendorPath) else ""}
'') modulesStruct;
passAsFile = [ "json" "sources" ];
} (''
mkdir vendor
};
export GOCACHE=$TMPDIR/go-cache
export GOPATH="$TMPDIR/go"
go run ${./symlink.go}
mv vendor $out
'');
removeReferences = [ ] ++ lib.optional (!allowGoReference) go;
@ -58,7 +54,6 @@ let
nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
inherit (go) GOOS GOARCH;
inherit CGO_ENABLED;
GO_NO_VENDOR_CHECKS = "1";
@ -187,6 +182,8 @@ in buildGoApplication {
pname = "dummyapp";
version = "0.1";
CGO_ENABLED = "1";
src = ./testdata/vuls;
modules = ./testdata/vuls/gomod2nix.toml;

13
go_no_vendor_checks.patch Normal file
View file

@ -0,0 +1,13 @@
diff --git a/src/cmd/go/internal/modload/vendor.go b/src/cmd/go/internal/modload/vendor.go
index 71f68efbcc..3c566d04dd 100644
--- a/src/cmd/go/internal/modload/vendor.go
+++ b/src/cmd/go/internal/modload/vendor.go
@@ -133,7 +133,7 @@ func checkVendorConsistency() {
readVendorList()
pre114 := false
- if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 {
+ if modFile.Go == nil || semver.Compare("v"+modFile.Go.Version, "v1.14") < 0 || (os.Getenv("GO_NO_VENDOR_CHECKS") == "1" && len(vendorMeta) == 0) {
// Go versions before 1.14 did not include enough information in
// vendor/modules.txt to check for consistency.
// If we know that we're on an earlier version, relax the consistency check.

94
symlink.go Normal file
View file

@ -0,0 +1,94 @@
package main
import (
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"sort"
)
type fetchInfo struct {
Type string `toml:"type"`
URL string `toml:"url"`
Rev string `toml:"rev"`
Sha256 string `toml:"sha256"`
}
type packageT struct {
SumVersion string `toml:"sumVersion"`
RelPath string `toml:"relPath,omitempty"`
VendorPath string `toml:"vendorPath,omitempty"`
Fetch *fetchInfo `toml:"fetch"`
}
func main() {
pkgs := make(map[string]*packageT)
sources := make(map[string]string)
b, err := ioutil.ReadFile(os.Getenv("sourcesPath"))
if err != nil {
panic(err)
}
err = json.Unmarshal(b, &sources)
if err != nil {
panic(err)
}
b, err = ioutil.ReadFile(os.Getenv("jsonPath"))
if err != nil {
panic(err)
}
err = json.Unmarshal(b, &pkgs)
if err != nil {
panic(err)
}
keys := make([]string, 0, len(pkgs))
for key := range pkgs {
keys = append(keys, key)
}
sort.Strings(keys)
// Iterate, in reverse order
for i := len(keys) - 1; i >= 0; i-- {
key := keys[i]
src := sources[key]
pkg := pkgs[key]
paths := []string{key}
if pkg.VendorPath != "" {
paths = append(paths, pkg.VendorPath)
}
for _, path := range paths {
vendorDir := filepath.Join("vendor", filepath.Dir(path))
os.MkdirAll(vendorDir, 0755)
if _, err := os.Stat(filepath.Join("vendor", path)); err == nil {
files, err := ioutil.ReadDir(src)
if err != nil {
panic(err)
}
for _, f := range files {
os.Symlink(filepath.Join(src, f.Name()), filepath.Join("vendor", path, f.Name()))
}
continue
}
// If the file doesn't already exist, just create a simple symlink
err := os.Symlink(src, filepath.Join("vendor", path))
if err != nil {
panic(err)
}
}
}
}