gomod2nix icon indicating copy to clipboard operation
gomod2nix copied to clipboard

How to use this with go 1.21?

Open Kamillaova opened this issue 1 year ago • 3 comments

Kamillaova avatar Oct 08 '23 02:10 Kamillaova

It won't work until the version of golang.org/x/mod/modfile is bumped to one that supports the new format, and the version of nixpkgs in the flake is updated to one that includes go_1_21.

a-h avatar Oct 16 '23 16:10 a-h

gomod2nix seems to work with go_1_21 if you rebuild the binary manually, either by

  • installing it using go install:
    $ go install https://github.com/nix-community/gomod2nix@latest
    
  • building it using buildGo121Module:
    {
      fetchFromGitHub,
      buildGo121Module,
    }: let
      pname = "gomod2nix";
      version = "1.5.0";
      src = fetchFromGitHub {
        owner = "nix-community";
        repo = "${pname}";
        rev = "v${version}";
        hash = "sha256-v2WMKnkpkz5YLYTBwh0NVgi3Xl4En249LCdrKTA4Nek=";
      };
      vendorHash = "sha256-4XoSRJKxLBYOZi/cEruFISn1KsxQZTDvnMfdS+oNK98=";
      subPackages = ["."];
    in
      buildGo121Module {
        inherit pname version src vendorHash subPackages;
      }
    

You can then use buildGoApplication by setting go = pkgs.go_1_21:

buildGoApplication = {
  # (...)
  go = pkgs.go_1_21;
  # (...)
};

jakzale avatar Oct 27 '23 11:10 jakzale

Here's a full flake.nix example:

flake.nix

{
  inputs = {
    nixpkgs = {
      url = "github:NixOS/nixpkgs/23.11";
    };
    gomod2nix = {
      url = "github:nix-community/gomod2nix";
      inputs.nixpkgs.follows = "nixpkgs";
    };
  };

  outputs = { self, nixpkgs, gomod2nix }:
    let
      allSystems = [
        "x86_64-linux" # 64-bit Intel/AMD Linux
        "aarch64-linux" # 64-bit ARM Linux
        "x86_64-darwin" # 64-bit Intel macOS
        "aarch64-darwin" # 64-bit ARM macOS
      ];
      forAllSystems = f: nixpkgs.lib.genAttrs allSystems (system: f {
        inherit system;
        pkgs = import nixpkgs {
          inherit system;
        };
      });
    in
    {
      packages = forAllSystems ({ system, pkgs, ... }:
        let
          buildGoApplication = gomod2nix.legacyPackages.${system}.buildGoApplication;
        in
        {
          default = buildGoApplication {
            # Required args.
            name = "nix-gomod2nix-example";
            src = ./.;

            # Override default Go with Go 1.21.
            #
            # In the latest versions of Go, the go.mod can contain 1.21.5
            # In that case, if the toolchain doesn't match, the go build operation will
            # try and download the correct toolchain.
            #
            # To prevent this, update the go.mod file to contain `go 1.21` instead of `go 1.21.5`.
            go = pkgs.go_1_21;

            # Must be added due to bug https://github.com/nix-community/gomod2nix/issues/120
            pwd = ./.;

            # Optional flags.
            CGO_ENABLED = 0;
            flags = [ "-trimpath" ];
            ldflags = [ "-s" "-w" "-extldflags -static" ];
          };
        });

      devShells = forAllSystems ({ system, pkgs }: {
        default = pkgs.mkShell {
          packages = with pkgs; [
            go_1_21
            gotools
            gomod2nix.packages.${system}.default # gomod2nix CLI
          ];
        };
      });
    };
}

If you drop this into a Go project, change the name argument value, and run nix develop, you'll get a shell containing gomod2nix.

Once you've ran gomod2nix, you'll have a gomod2nix.toml file in the directory.

You can then run nix build and you'll get a Go binary out.

Full example repo at https://github.com/a-h/nix-gomod2nix-example

a-h avatar Jan 18 '24 15:01 a-h