1
0
Fork 0
mirror of https://github.com/nix-community/home-manager.git synced 2025-12-16 14:01:08 +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 = {
GOPATH = mkOption {
type = with types; either str (listOf str);
apply = x: lib.concatStringsSep ":" (lib.toList x);
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 = '' description = ''
Primary {env}`GOPATH` relative to Controls which modules the 'go' command considers to be private (not
{env}`HOME`. It will be exported first and therefore available publicly) and should therefore not use the proxy or checksum database.
used by default by the Go tooling.
''; '';
}; };
};
extraGoPaths = mkOption { };
type = types.listOf types.str; default = { };
default = [ ]; example = lib.literalExpression ''
example = [ {
"extraGoPath1" GOPATH = [
"extraGoPath2" "''${config.home.homeDirectory}/mygo"
"/another/go"
"/yet/another/go"
]; ];
description = ''
Extra {env}`GOPATH`s relative to {env}`HOME` appended
after [](#opt-programs.go.goPath), if that option is set.
'';
};
goBin = mkOption { GOPRIVATE = [
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" "*.corp.example.com"
"rsc.io/private" "rsc.io/private"
]; ];
CXX = "g++";
GCCGO = "gccgo";
GOAMD64 = "v1";
GOARCH = "amd64";
GOAUTH = "netrc";
};
'';
description = '' description = ''
The {env}`GOPRIVATE` environment variable controls Environment variables for Go. All the available options
which modules the go command considers to be private (not can be found running 'go env'.
available publicly) and should therefore not use the proxy
or checksum database.
''; '';
}; };
@ -117,33 +138,43 @@ in
}; };
}; };
config = mkIf cfg.enable ( config =
let
firstGoPath = lib.elemAt (lib.splitString ":" cfg.env.GOPATH) 0;
finalEnv = lib.filterAttrs (_: v: v != "") cfg.env;
in
mkIf cfg.enable (
lib.mkMerge [ lib.mkMerge [
{ {
home.packages = [ cfg.package ]; 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; };
mkSrc = n: v: { "${mainGoPath}/src/${n}".source = v; };
in in
lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages); lib.foldl' (a: b: a // b) { } (lib.mapAttrsToList mkSrc cfg.packages)
);
} }
(mkIf (cfg.goPath != null) { (mkIf (cfg.env != { }) {
home.sessionVariables.GOPATH = lib.concatStringsSep ":" ( xdg.configFile."go/env" = {
map builtins.toPath ( enable = !pkgs.stdenv.hostPlatform.isDarwin;
map (path: "${config.home.homeDirectory}/${path}") ([ cfg.goPath ] ++ cfg.extraGoPaths) source = keyValueFormat.generate "go-env" finalEnv;
) };
);
})
(mkIf (cfg.goBin != null) { home.file."Library/Application Support/go/env" = {
home.sessionVariables.GOBIN = builtins.toPath "${config.home.homeDirectory}/${cfg.goBin}"; enable = pkgs.stdenv.hostPlatform.isDarwin;
}) source = keyValueFormat.generate "go-env" finalEnv;
};
(mkIf (cfg.goPrivate != [ ]) {
home.sessionVariables.GOPRIVATE = lib.concatStringsSep "," cfg.goPrivate;
}) })
(mkIf (cfg.telemetry.mode != null) { (mkIf (cfg.telemetry.mode != null) {

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