1
0
Fork 0
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:
Aguirre Matteo 2025-09-14 00:25:31 +00:00 committed by GitHub
parent 987b114082
commit 768a7042a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 301 additions and 80 deletions

View file

@ -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;
}; };
}) })
] ]
); );
} }

View file

@ -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;
}

View 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

View 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

View file

@ -0,0 +1,5 @@
CXX=g++
GCCGO=gccgo
GOAMD64=v1
GOARCH=amd64
GOAUTH=netrc

View 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}
'';
}

View 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}
'';
}

View 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
'';
}

View 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
'';
}

View 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."
];
}

View file

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("Hello Home-Manager from 'text'!")
}

View file

@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("Hello Home-Manager from 'time'!")
}

View 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}
'';
}