mirror of
https://github.com/tweag/gomod2nix.git
synced 2024-11-09 20:19:08 +00:00
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" ];
|
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 =
|
buildGoApplication =
|
||||||
{ modules
|
{ modules
|
||||||
, go ? pkgs.go
|
, go ? pkgs.go
|
||||||
|
@ -64,39 +154,12 @@ let
|
||||||
in
|
in
|
||||||
if pwd != null then commands else [ ];
|
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;
|
removeReferences = [ ] ++ lib.optional (!allowGoReference) go;
|
||||||
|
|
||||||
|
vendorEnv = mkVendorEnv {
|
||||||
|
inherit go modulesStruct localReplaceCommands;
|
||||||
|
};
|
||||||
|
|
||||||
package = stdenv.mkDerivation (attrs // {
|
package = stdenv.mkDerivation (attrs // {
|
||||||
nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
|
nativeBuildInputs = [ removeReferencesTo go ] ++ nativeBuildInputs;
|
||||||
|
|
||||||
|
@ -230,4 +293,6 @@ let
|
||||||
package;
|
package;
|
||||||
|
|
||||||
in
|
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 (
|
require (
|
||||||
github.com/BurntSushi/toml v1.1.0
|
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
|
github.com/sirupsen/logrus v1.8.1
|
||||||
golang.org/x/mod v0.5.1
|
golang.org/x/mod v0.5.1
|
||||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect
|
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/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 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-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/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 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
|
|
@ -29,8 +29,8 @@ schema = 1
|
||||||
version = "v0.1.0"
|
version = "v0.1.0"
|
||||||
hash = "sha256-QT65kTrNypS5GPWGvgnCpGLPlVbQAL4IYvuqAKhepb4="
|
hash = "sha256-QT65kTrNypS5GPWGvgnCpGLPlVbQAL4IYvuqAKhepb4="
|
||||||
[mod."github.com/nix-community/go-nix"]
|
[mod."github.com/nix-community/go-nix"]
|
||||||
version = "v0.0.0-20220531154832-fb763dcb3ffc"
|
version = "v0.0.0-20220528121639-b940fb0a12d8"
|
||||||
hash = "sha256-vCoRCe1DcyNXfz6gun9wGBu/o+j6WGcS8mbFmXZfyps="
|
hash = "sha256-r6fq1mu0gRFqdI6msuAZp3ZoncAw5L16oBFPUA9vPYk="
|
||||||
[mod."github.com/pkg/errors"]
|
[mod."github.com/pkg/errors"]
|
||||||
version = "v0.9.1"
|
version = "v0.9.1"
|
||||||
hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
|
hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
final: prev: {
|
final: prev: {
|
||||||
buildGoApplication = final.callPackage ./builder { };
|
inherit (final.callPackage ./builder { }) buildGoApplication mkGoEnv;
|
||||||
gomod2nix = final.callPackage ./default.nix { };
|
gomod2nix = final.callPackage ./default.nix { };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue