Add mkGoEnv
function
This creates an `mkGoEnv` function which takes care of adding the correct Go package to your development environment and installs development dependencies from tools.go in a Nix derivation. The "normal" workflow around Go with tools.go just sticks development dependencies in $GOBIN which isn't ideal since you have no separation between projects.
This commit is contained in:
parent
d7830bd5b2
commit
a4bed25a86
6 changed files with 158 additions and 38 deletions
|
@ -33,6 +33,96 @@ let
|
|||
impureEnvVars = lib.fetchers.proxyImpureEnvVars ++ [ "GOPROXY" ];
|
||||
};
|
||||
|
||||
mkVendorEnv = { go, modulesStruct, localReplaceCommands ? [ ] }: runCommand "vendor-env"
|
||||
{
|
||||
nativeBuildInputs = [ go ];
|
||||
json = builtins.toJSON modulesStruct;
|
||||
|
||||
sources = builtins.toJSON (
|
||||
lib.mapAttrs
|
||||
(goPackagePath: meta: fetchGoModule {
|
||||
goPackagePath = meta.replaced or goPackagePath;
|
||||
inherit (meta) version hash;
|
||||
inherit go;
|
||||
})
|
||||
modulesStruct.mod
|
||||
);
|
||||
|
||||
passAsFile = [ "json" "sources" ];
|
||||
}
|
||||
(
|
||||
''
|
||||
mkdir vendor
|
||||
|
||||
export GOCACHE=$TMPDIR/go-cache
|
||||
export GOPATH="$TMPDIR/go"
|
||||
|
||||
go run ${./symlink.go}
|
||||
${lib.concatStringsSep "\n" localReplaceCommands}
|
||||
|
||||
mv vendor $out
|
||||
''
|
||||
);
|
||||
|
||||
mkGoEnv =
|
||||
{ pwd
|
||||
}@attrs:
|
||||
let
|
||||
goMod = parseGoMod (builtins.readFile "${builtins.toString pwd}/go.mod");
|
||||
modulesStruct = builtins.fromTOML (builtins.readFile "${builtins.toString pwd}/gomod2nix.toml");
|
||||
|
||||
go = attrs.go or (
|
||||
let
|
||||
goVersion = goMod.go;
|
||||
goAttr = "go_" + (lib.replaceStrings [ "." ] [ "_" ] goVersion);
|
||||
in
|
||||
(
|
||||
if builtins.hasAttr goAttr pkgs then pkgs.${goAttr}
|
||||
else builtins.trace "go.mod specified Go version ${goVersion} but doesn't exist. Falling back to ${pkgs.go.version}." pkgs.go
|
||||
)
|
||||
);
|
||||
|
||||
vendorEnv = mkVendorEnv {
|
||||
inherit go modulesStruct;
|
||||
};
|
||||
|
||||
in
|
||||
stdenv.mkDerivation {
|
||||
name = "${builtins.baseNameOf goMod.module}-env";
|
||||
|
||||
dontUnpack = true;
|
||||
dontConfigure = true;
|
||||
dontInstall = true;
|
||||
|
||||
propagatedNativeBuildInputs = [ go ];
|
||||
|
||||
GO_NO_VENDOR_CHECKS = "1";
|
||||
|
||||
GO111MODULE = "on";
|
||||
GOFLAGS = "-mod=vendor";
|
||||
|
||||
preferLocalBuild = true;
|
||||
|
||||
buildPhase = ''
|
||||
mkdir $out
|
||||
|
||||
export GOCACHE=$TMPDIR/go-cache
|
||||
export GOPATH="$out"
|
||||
export GOSUMDB=off
|
||||
export GOPROXY=off
|
||||
|
||||
'' + lib.optionalString (lib.pathExists (pwd + "/tools./.go")) ''
|
||||
mkdir source
|
||||
cp ${pwd + "/go.mod"} source/go.mod
|
||||
cp ${pwd + "/go.sum"} source/go.sum
|
||||
cp ${pwd + "/tools.go"} source/tools.go
|
||||
cd source
|
||||
ln -s ${vendorEnv} vendor
|
||||
|
||||
go run ${./install.go}
|
||||
'';
|
||||
};
|
||||
|
||||
buildGoApplication =
|
||||
{ modules
|
||||
, go ? pkgs.go
|
||||
|
@ -64,39 +154,12 @@ let
|
|||
in
|
||||
if pwd != null then commands else [ ];
|
||||
|
||||
vendorEnv = runCommand "vendor-env"
|
||||
{
|
||||
nativeBuildInputs = [ go ];
|
||||
json = builtins.toJSON modulesStruct;
|
||||
|
||||
sources = builtins.toJSON (
|
||||
lib.mapAttrs
|
||||
(goPackagePath: meta: fetchGoModule {
|
||||
goPackagePath = meta.replaced or goPackagePath;
|
||||
inherit (meta) version hash;
|
||||
inherit go;
|
||||
})
|
||||
modulesStruct.mod
|
||||
);
|
||||
|
||||
passAsFile = [ "json" "sources" ];
|
||||
}
|
||||
(
|
||||
''
|
||||
mkdir vendor
|
||||
|
||||
export GOCACHE=$TMPDIR/go-cache
|
||||
export GOPATH="$TMPDIR/go"
|
||||
|
||||
go run ${./symlink.go}
|
||||
${lib.concatStringsSep "\n" localReplaceCommands}
|
||||
|
||||
mv vendor $out
|
||||
''
|
||||
);
|
||||
|
||||
removeReferences = [ ] ++ lib.optional (!allowGoReference) go;
|
||||
|
||||
vendorEnv = mkVendorEnv {
|
||||
inherit go modulesStruct localReplaceCommands;
|
||||
};
|
||||
|
||||
package = stdenv.mkDerivation (attrs // {
|
||||
nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
|
||||
|
||||
|
@ -230,4 +293,6 @@ let
|
|||
package;
|
||||
|
||||
in
|
||||
buildGoApplication
|
||||
{
|
||||
inherit buildGoApplication mkGoEnv;
|
||||
}
|
||||
|
|
57
builder/install.go
Normal file
57
builder/install.go
Normal file
|
@ -0,0 +1,57 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const filename = "tools.go"
|
||||
|
||||
func main() {
|
||||
fset := token.NewFileSet()
|
||||
|
||||
var src []byte
|
||||
{
|
||||
f, err := os.Open(filename)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
src, err = io.ReadAll(f)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
f, err := parser.ParseFile(fset, filename, src, parser.ImportsOnly)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range f.Imports {
|
||||
path, err := strconv.Unquote(s.Path.Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("go", "install", path)
|
||||
|
||||
fmt.Printf("Executing '%s'\n", cmd)
|
||||
|
||||
err = cmd.Start()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = cmd.Wait()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
2
go.mod
2
go.mod
|
@ -4,7 +4,7 @@ go 1.14
|
|||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.1.0
|
||||
github.com/nix-community/go-nix v0.0.0-20220531154832-fb763dcb3ffc
|
||||
github.com/nix-community/go-nix v0.0.0-20220528121639-b940fb0a12d8
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
golang.org/x/mod v0.5.1
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
||||
|
|
2
go.sum
2
go.sum
|
@ -15,8 +15,6 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/nix-community/go-nix v0.0.0-20220528121639-b940fb0a12d8 h1:IYr+3pldQtTwS55Xm2+3Ry81MpSKNVpMyYMNr7yQpts=
|
||||
github.com/nix-community/go-nix v0.0.0-20220528121639-b940fb0a12d8/go.mod h1:r5pCQAjHNSDWTsy6+UbacPN8EzMVJiCAXDWbRN2qfwU=
|
||||
github.com/nix-community/go-nix v0.0.0-20220531154832-fb763dcb3ffc h1:/uRl4vxjqF0N8m8ha+TouWZxsMRCA98Fft24WNIb0L8=
|
||||
github.com/nix-community/go-nix v0.0.0-20220531154832-fb763dcb3ffc/go.mod h1:r5pCQAjHNSDWTsy6+UbacPN8EzMVJiCAXDWbRN2qfwU=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
|
|
|
@ -29,8 +29,8 @@ schema = 1
|
|||
version = "v0.1.0"
|
||||
hash = "sha256-QT65kTrNypS5GPWGvgnCpGLPlVbQAL4IYvuqAKhepb4="
|
||||
[mod."github.com/nix-community/go-nix"]
|
||||
version = "v0.0.0-20220531154832-fb763dcb3ffc"
|
||||
hash = "sha256-vCoRCe1DcyNXfz6gun9wGBu/o+j6WGcS8mbFmXZfyps="
|
||||
version = "v0.0.0-20220528121639-b940fb0a12d8"
|
||||
hash = "sha256-r6fq1mu0gRFqdI6msuAZp3ZoncAw5L16oBFPUA9vPYk="
|
||||
[mod."github.com/pkg/errors"]
|
||||
version = "v0.9.1"
|
||||
hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
final: prev: {
|
||||
buildGoApplication = final.callPackage ./builder { };
|
||||
inherit (final.callPackage ./builder { }) buildGoApplication mkGoEnv;
|
||||
gomod2nix = final.callPackage ./default.nix { };
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue