mirror of
https://github.com/nix-community/home-manager.git
synced 2025-11-08 19:46:05 +01:00
go: use env file instead of home.sessionVariables (#7751)
This commit is contained in:
parent
987b114082
commit
768a7042a6
13 changed files with 301 additions and 80 deletions
|
|
@ -9,22 +9,41 @@ let
|
||||||
literalExpression
|
literalExpression
|
||||||
mkIf
|
mkIf
|
||||||
mkOption
|
mkOption
|
||||||
|
mkChangedOptionModule
|
||||||
|
mkRenamedOptionModule
|
||||||
types
|
types
|
||||||
;
|
;
|
||||||
|
|
||||||
cfg = config.programs.go;
|
cfg = config.programs.go;
|
||||||
|
keyValueFormat = pkgs.formats.keyValue { };
|
||||||
|
|
||||||
modeFileContent = "${cfg.telemetry.mode} ${cfg.telemetry.date}";
|
modeFileContent = "${cfg.telemetry.mode} ${cfg.telemetry.date}";
|
||||||
|
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
meta.maintainers = [ lib.maintainers.rvolosatovs ];
|
meta.maintainers = [ lib.maintainers.rvolosatovs ];
|
||||||
|
|
||||||
|
imports = [
|
||||||
|
(mkChangedOptionModule [ "programs" "go" "goPath" ] [ "programs" "go" "env" "GOPATH" ] (config: [
|
||||||
|
"${config.home.homeDirectory}/${config.programs.go.goPath}"
|
||||||
|
]))
|
||||||
|
|
||||||
|
(mkChangedOptionModule [ "programs" "go" "extraGoPaths" ] [ "programs" "go" "env" "GOPATH" ] (
|
||||||
|
config:
|
||||||
|
lib.mkOrder 1500 (map (x: "${config.home.homeDirectory}/${x}") config.programs.go.extraGoPaths)
|
||||||
|
))
|
||||||
|
|
||||||
|
(mkChangedOptionModule [ "programs" "go" "goBin" ] [ "programs" "go" "env" "GOBIN" ] (
|
||||||
|
config: "${config.home.homeDirectory}/${config.programs.go.goBin}"
|
||||||
|
))
|
||||||
|
|
||||||
|
(mkRenamedOptionModule [ "programs" "go" "goPrivate" ] [ "programs" "go" "env" "GOPRIVATE" ])
|
||||||
|
];
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
programs.go = {
|
programs.go = {
|
||||||
enable = lib.mkEnableOption "Go";
|
enable = lib.mkEnableOption "Go";
|
||||||
|
|
||||||
package = lib.mkPackageOption pkgs "go" { };
|
package = lib.mkPackageOption pkgs "go" { nullable = true; };
|
||||||
|
|
||||||
packages = mkOption {
|
packages = mkOption {
|
||||||
type = with types; attrsOf path;
|
type = with types; attrsOf path;
|
||||||
|
|
@ -38,49 +57,51 @@ in
|
||||||
description = "Packages to add to GOPATH.";
|
description = "Packages to add to GOPATH.";
|
||||||
};
|
};
|
||||||
|
|
||||||
goPath = mkOption {
|
env = mkOption {
|
||||||
type = with types; nullOr str;
|
type = types.submodule {
|
||||||
default = null;
|
freeformType = with types; attrsOf str;
|
||||||
example = "go";
|
options = {
|
||||||
description = ''
|
GOPATH = mkOption {
|
||||||
Primary {env}`GOPATH` relative to
|
type = with types; either str (listOf str);
|
||||||
{env}`HOME`. It will be exported first and therefore
|
apply = x: lib.concatStringsSep ":" (lib.toList x);
|
||||||
used by default by the Go tooling.
|
default = "";
|
||||||
|
description = "List of directories that should be used by the Go tooling.";
|
||||||
|
};
|
||||||
|
GOPRIVATE = mkOption {
|
||||||
|
type = with types; either str (listOf str);
|
||||||
|
apply = x: lib.concatStringsSep "," (lib.toList x);
|
||||||
|
default = "";
|
||||||
|
description = ''
|
||||||
|
Controls which modules the 'go' command considers to be private (not
|
||||||
|
available publicly) and should therefore not use the proxy or checksum database.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
default = { };
|
||||||
|
example = lib.literalExpression ''
|
||||||
|
{
|
||||||
|
GOPATH = [
|
||||||
|
"''${config.home.homeDirectory}/mygo"
|
||||||
|
"/another/go"
|
||||||
|
"/yet/another/go"
|
||||||
|
];
|
||||||
|
|
||||||
|
GOPRIVATE = [
|
||||||
|
"*.corp.example.com"
|
||||||
|
"rsc.io/private"
|
||||||
|
];
|
||||||
|
|
||||||
|
CXX = "g++";
|
||||||
|
GCCGO = "gccgo";
|
||||||
|
GOAMD64 = "v1";
|
||||||
|
GOARCH = "amd64";
|
||||||
|
GOAUTH = "netrc";
|
||||||
|
};
|
||||||
'';
|
'';
|
||||||
};
|
|
||||||
|
|
||||||
extraGoPaths = mkOption {
|
|
||||||
type = types.listOf types.str;
|
|
||||||
default = [ ];
|
|
||||||
example = [
|
|
||||||
"extraGoPath1"
|
|
||||||
"extraGoPath2"
|
|
||||||
];
|
|
||||||
description = ''
|
description = ''
|
||||||
Extra {env}`GOPATH`s relative to {env}`HOME` appended
|
Environment variables for Go. All the available options
|
||||||
after [](#opt-programs.go.goPath), if that option is set.
|
can be found running 'go env'.
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
goBin = mkOption {
|
|
||||||
type = with types; nullOr str;
|
|
||||||
default = null;
|
|
||||||
example = ".local/bin.go";
|
|
||||||
description = "GOBIN relative to HOME";
|
|
||||||
};
|
|
||||||
|
|
||||||
goPrivate = mkOption {
|
|
||||||
type = with types; listOf str;
|
|
||||||
default = [ ];
|
|
||||||
example = [
|
|
||||||
"*.corp.example.com"
|
|
||||||
"rsc.io/private"
|
|
||||||
];
|
|
||||||
description = ''
|
|
||||||
The {env}`GOPRIVATE` environment variable controls
|
|
||||||
which modules the go command considers to be private (not
|
|
||||||
available publicly) and should therefore not use the proxy
|
|
||||||
or checksum database.
|
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -117,46 +138,56 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable (
|
config =
|
||||||
lib.mkMerge [
|
let
|
||||||
{
|
firstGoPath = lib.elemAt (lib.splitString ":" cfg.env.GOPATH) 0;
|
||||||
home.packages = [ cfg.package ];
|
finalEnv = lib.filterAttrs (_: v: v != "") cfg.env;
|
||||||
|
in
|
||||||
|
mkIf cfg.enable (
|
||||||
|
lib.mkMerge [
|
||||||
|
{
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion =
|
||||||
|
cfg.packages != { } -> cfg.env.GOPATH != "" -> lib.hasPrefix config.home.homeDirectory firstGoPath;
|
||||||
|
message = "The first element of `programs.go.env.GOPATH must be an absolute path that points to a directory inside ${config.home.homeDirectory} if `programs.go.packages` is set.";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
home.packages = mkIf (cfg.package != null) [ cfg.package ];
|
||||||
|
|
||||||
home.file =
|
home.file = mkIf (cfg.packages != { }) (
|
||||||
let
|
let
|
||||||
goPath = if cfg.goPath != null then cfg.goPath else "go";
|
mainGoPath = if (cfg.env.GOPATH != "") then firstGoPath else "go";
|
||||||
mkSrc = n: v: { "${goPath}/src/${n}".source = v; };
|
|
||||||
in
|
|
||||||
lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages);
|
|
||||||
}
|
|
||||||
|
|
||||||
(mkIf (cfg.goPath != null) {
|
mkSrc = n: v: { "${mainGoPath}/src/${n}".source = v; };
|
||||||
home.sessionVariables.GOPATH = lib.concatStringsSep ":" (
|
in
|
||||||
map builtins.toPath (
|
lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages)
|
||||||
map (path: "${config.home.homeDirectory}/${path}") ([ cfg.goPath ] ++ cfg.extraGoPaths)
|
);
|
||||||
)
|
}
|
||||||
);
|
|
||||||
})
|
|
||||||
|
|
||||||
(mkIf (cfg.goBin != null) {
|
(mkIf (cfg.env != { }) {
|
||||||
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}";
|
xdg.configFile."go/env" = {
|
||||||
})
|
enable = !pkgs.stdenv.hostPlatform.isDarwin;
|
||||||
|
source = keyValueFormat.generate "go-env" finalEnv;
|
||||||
|
};
|
||||||
|
|
||||||
(mkIf (cfg.goPrivate != [ ]) {
|
home.file."Library/Application Support/go/env" = {
|
||||||
home.sessionVariables.GOPRIVATE = lib.concatStringsSep "," cfg.goPrivate;
|
enable = pkgs.stdenv.hostPlatform.isDarwin;
|
||||||
})
|
source = keyValueFormat.generate "go-env" finalEnv;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
|
||||||
(mkIf (cfg.telemetry.mode != null) {
|
(mkIf (cfg.telemetry.mode != null) {
|
||||||
home.file."Library/Application Support/go/telemetry/mode" = {
|
home.file."Library/Application Support/go/telemetry/mode" = {
|
||||||
enable = pkgs.stdenv.hostPlatform.isDarwin;
|
enable = pkgs.stdenv.hostPlatform.isDarwin;
|
||||||
text = modeFileContent;
|
text = modeFileContent;
|
||||||
};
|
};
|
||||||
|
|
||||||
xdg.configFile."go/telemetry/mode" = {
|
xdg.configFile."go/telemetry/mode" = {
|
||||||
enable = !pkgs.stdenv.hostPlatform.isDarwin;
|
enable = !pkgs.stdenv.hostPlatform.isDarwin;
|
||||||
text = modeFileContent;
|
text = modeFileContent;
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,9 @@
|
||||||
{ go-telemetry = ./go-telemetry.nix; }
|
{
|
||||||
|
go-telemetry = ./go-telemetry.nix;
|
||||||
|
go-example-config = ./example-config.nix;
|
||||||
|
go-suboptions-unset = ./suboptions-unset.nix;
|
||||||
|
go-packages-default-gopath = ./packages-default-gopath.nix;
|
||||||
|
go-packages-custom-gopath = ./packages-custom-gopath.nix;
|
||||||
|
go-packages-invalid-main-gopath = ./packages-invalid-main-gopath.nix;
|
||||||
|
go-old-options = ./old-options.nix;
|
||||||
|
}
|
||||||
|
|
|
||||||
7
tests/modules/programs/go/env
Normal file
7
tests/modules/programs/go/env
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
CXX=g++
|
||||||
|
GCCGO=gccgo
|
||||||
|
GOAMD64=v1
|
||||||
|
GOARCH=amd64
|
||||||
|
GOAUTH=netrc
|
||||||
|
GOPATH=/home/hm-user/mygo:/another/go:/yet/another/go
|
||||||
|
GOPRIVATE=*.corp.example.com,rsc.io/private
|
||||||
3
tests/modules/programs/go/env-old-options
Normal file
3
tests/modules/programs/go/env-old-options
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
GOBIN=/home/hm-user/.local/bin.go
|
||||||
|
GOPATH=/home/hm-user/mygo:/home/hm-user/another/go:/home/hm-user/yet/another/go
|
||||||
|
GOPRIVATE=*.corp.example.com,rsc.io/private
|
||||||
5
tests/modules/programs/go/env-suboptions-unset
Normal file
5
tests/modules/programs/go/env-suboptions-unset
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
CXX=g++
|
||||||
|
GCCGO=gccgo
|
||||||
|
GOAMD64=v1
|
||||||
|
GOARCH=amd64
|
||||||
|
GOAUTH=netrc
|
||||||
33
tests/modules/programs/go/example-config.nix
Normal file
33
tests/modules/programs/go/example-config.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
env = {
|
||||||
|
GOPATH = [
|
||||||
|
"${config.home.homeDirectory}/mygo"
|
||||||
|
"/another/go"
|
||||||
|
"/yet/another/go"
|
||||||
|
];
|
||||||
|
GOPRIVATE = [
|
||||||
|
"*.corp.example.com"
|
||||||
|
"rsc.io/private"
|
||||||
|
];
|
||||||
|
CXX = "g++";
|
||||||
|
GCCGO = "gccgo";
|
||||||
|
GOAMD64 = "v1";
|
||||||
|
GOARCH = "amd64";
|
||||||
|
GOAUTH = "netrc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script =
|
||||||
|
let
|
||||||
|
goCfgDir = if !pkgs.stdenv.isDarwin then ".config/go" else "Library/Application Support/go";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
assertFileExists "home-files/${goCfgDir}/env"
|
||||||
|
assertFileContent "home-files/${goCfgDir}/env" \
|
||||||
|
${./env}
|
||||||
|
'';
|
||||||
|
}
|
||||||
40
tests/modules/programs/go/old-options.nix
Normal file
40
tests/modules/programs/go/old-options.nix
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
options,
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
goPath = "mygo";
|
||||||
|
extraGoPaths = [
|
||||||
|
"another/go"
|
||||||
|
"yet/another/go"
|
||||||
|
];
|
||||||
|
goBin = ".local/bin.go";
|
||||||
|
goPrivate = [
|
||||||
|
"*.corp.example.com"
|
||||||
|
"rsc.io/private"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
test.asserts.warnings.expected = [
|
||||||
|
"The option `programs.go.goPrivate' defined in ${lib.showFiles options.programs.go.goPrivate.files} has been renamed to `programs.go.env.GOPRIVATE'."
|
||||||
|
"The option `programs.go.goBin' defined in ${lib.showFiles options.programs.go.goBin.files} has been changed to `programs.go.env.GOBIN' that has a different type. Please read `programs.go.env.GOBIN' documentation and update your configuration accordingly."
|
||||||
|
"The option `programs.go.extraGoPaths' defined in ${lib.showFiles options.programs.go.extraGoPaths.files} has been changed to `programs.go.env.GOPATH' that has a different type. Please read `programs.go.env.GOPATH' documentation and update your configuration accordingly."
|
||||||
|
"The option `programs.go.goPath' defined in ${lib.showFiles options.programs.go.goPath.files} has been changed to `programs.go.env.GOPATH' that has a different type. Please read `programs.go.env.GOPATH' documentation and update your configuration accordingly."
|
||||||
|
];
|
||||||
|
|
||||||
|
nmt.script =
|
||||||
|
let
|
||||||
|
goCfgDir = if !pkgs.stdenv.isDarwin then ".config/go" else "Library/Application\ Support/go";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
assertFileExists "home-files/${goCfgDir}/env"
|
||||||
|
assertFileContent "home-files/${goCfgDir}/env" \
|
||||||
|
${./env-old-options}
|
||||||
|
'';
|
||||||
|
}
|
||||||
22
tests/modules/programs/go/packages-custom-gopath.nix
Normal file
22
tests/modules/programs/go/packages-custom-gopath.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
env.GOPATH = [
|
||||||
|
"${config.home.homeDirectory}/mygo"
|
||||||
|
"/another/go"
|
||||||
|
"/yet/another/go"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = {
|
||||||
|
"golang.org/x/text" = ./packages/text;
|
||||||
|
"golang.org/x/time" = ./packages/time;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists home-files/mygo/src/golang.org/x/text/main.go
|
||||||
|
assertFileExists home-files/mygo/src/golang.org/x/time/main.go
|
||||||
|
'';
|
||||||
|
}
|
||||||
14
tests/modules/programs/go/packages-default-gopath.nix
Normal file
14
tests/modules/programs/go/packages-default-gopath.nix
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
packages = {
|
||||||
|
"golang.org/x/text" = ./packages/text;
|
||||||
|
"golang.org/x/time" = ./packages/time;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script = ''
|
||||||
|
assertFileExists home-files/go/src/golang.org/x/text/main.go
|
||||||
|
assertFileExists home-files/go/src/golang.org/x/time/main.go
|
||||||
|
'';
|
||||||
|
}
|
||||||
20
tests/modules/programs/go/packages-invalid-main-gopath.nix
Normal file
20
tests/modules/programs/go/packages-invalid-main-gopath.nix
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
{ config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
env.GOPATH = [
|
||||||
|
"/not/my/home/mygo"
|
||||||
|
"/another/go"
|
||||||
|
"/yet/another/go"
|
||||||
|
];
|
||||||
|
|
||||||
|
packages = {
|
||||||
|
"golang.org/x/text" = ./packages/text;
|
||||||
|
"golang.org/x/time" = ./packages/time;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
test.asserts.assertions.expected = [
|
||||||
|
"The first element of `programs.go.env.GOPATH must be an absolute path that points to a directory inside ${config.home.homeDirectory} if `programs.go.packages` is set."
|
||||||
|
];
|
||||||
|
}
|
||||||
7
tests/modules/programs/go/packages/text/main.go
Normal file
7
tests/modules/programs/go/packages/text/main.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello Home-Manager from 'text'!")
|
||||||
|
}
|
||||||
7
tests/modules/programs/go/packages/time/main.go
Normal file
7
tests/modules/programs/go/packages/time/main.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("Hello Home-Manager from 'time'!")
|
||||||
|
}
|
||||||
24
tests/modules/programs/go/suboptions-unset.nix
Normal file
24
tests/modules/programs/go/suboptions-unset.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{ pkgs, config, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
programs.go = {
|
||||||
|
enable = true;
|
||||||
|
env = {
|
||||||
|
CXX = "g++";
|
||||||
|
GCCGO = "gccgo";
|
||||||
|
GOAMD64 = "v1";
|
||||||
|
GOARCH = "amd64";
|
||||||
|
GOAUTH = "netrc";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
nmt.script =
|
||||||
|
let
|
||||||
|
goCfgDir = if !pkgs.stdenv.isDarwin then ".config/go" else "Library/Application\ Support/go";
|
||||||
|
in
|
||||||
|
''
|
||||||
|
assertFileExists "home-files/${goCfgDir}/env"
|
||||||
|
assertFileContent "home-files/${goCfgDir}/env" \
|
||||||
|
${./env-suboptions-unset}
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue