gomod2nix

repository·master·Indexed 43 days ago

https://github.com/nix-community/gomod2nix

A tool to convert Go applications using Go modules into Nix expressions for reproducible builds. It provides a CLI to generate gomod2nix.toml files and import Go sources into the Nix store. The project includes the buildGoApplication and mkGoEnv functions to manage Go builds and development environments within the Nix ecosystem.

Tokens
2.2K
Snippets
10
Records
12
Agent score
55%

What's inside gomod2nix

  1. Install Gomod2nix using Niv

    master

    To use Gomod2nix with Niv, initialize Niv and add the repository. You will then need to configure a shell.nix for your development environment and a default.nix for building your application, both of which must use the gomod2nix overlay.

    $ niv init --latest
    $ niv add nix-community/gomod2nix
  2. Convert a Go project to Nix using gomod2nix

    master

    To convert a Go application using Go modules into a Nix expression, follow these steps:

    1. Navigate to your Go project directory in your terminal.
    2. Run the gomod2nix command. This generates a gomod2nix.toml file in your current directory.
    3. Use the generated gomod2nix.toml as the modules argument in a Nix expression that calls buildGoApplication.

    Note: buildGoApplication must be provided via a Nix overlay as shown in the example below.

    $ gomod2nix
    let
      pkgs = import <nixpkgs> {
        overlays = [
          (self: super: {
            buildGoApplication = super.callPackage ./builder { };
          })
        ];
      };
    in pkgs.buildGoApplication {
      pname = "gomod2nix-example";
      version = "0.1";
      src = ./.;
      modules = ./gomod2nix.toml;
    }
  3. Configure shell.nix and default.nix for Niv

    master

    When using Niv, ensure your Nix files include the gomod2nix overlay.

    Use this shell.nix for a development environment containing gomod2nix, niv, and a Go environment:

    { pkgs ? ( 
        let
          sources = import ./nix/sources.nix;
        in
        import sources.nixpkgs {
          overlays = [
            (import "${sources.gomod2nix}/overlay.nix")
          ];
        }
      ) :
    }: 
    
    let
      goEnv = pkgs.mkGoEnv { pwd = ./.; };
    in
    pkgs.mkShell {
      packages = [
        goEnv
        pkgs.gomod2nix
        pkgs.niv
      ];
    }

    Use this default.nix to build your Go application using buildGoApplication with the modules argument pointing to your gomod2nix.toml:

    { pkgs ? ( 
        let
          sources = import ./nix/sources.nix;
        in
        import sources.nixpkgs {
          overlays = [
            (import "${sources.gomod2nix}/overlay.nix")
          ];
        }
      ) :
    }: 
    
    pkgs.buildGoApplication {
      pname = "myapp";
      version = "0.1";
      pwd = ./.;
      src = ./.;
      modules = ./gomod2nix.toml;
    }
    # shell.nix example
    { pkgs ? ( 
        let
          sources = import ./nix/sources.nix;
        in
        import sources.nixpkgs {
          overlays = [
            (import "${sources.gomod2nix}/overlay.nix")
          ];
        }
      ) :
    }: 
    
    let
      goEnv = pkgs.mkGoEnv { pwd = ./.; };
    in
    pkgs.mkShell {
      packages = [
        goEnv
        pkgs.gomod2nix
        pkgs.niv
      ];
    }
  4. Install Gomod2nix using Nix Flakes

    master

    If you are using Nix Flakes, you can quickly initialize a project using the provided templates.

    To start a standard application project:

    nix flake init -t github:nix-community/gomod2nix#app

    To start a project configured to build container images:

    nix flake init -t github:nix-community/gomod2nix#container
    $ nix flake init -t github:nix-community/gomod2nix#app
  5. Use buildGoApplication to build a Go application

    master

    The buildGoApplication function is used to create a Nix derivation for building a Go application based on a gomod2nix.toml configuration. It accepts several specific arguments to control the build process, and any additional arguments provided are passed directly to stdenv.mkDerivation.

    buildGoApplication {
      modules = ./gomod2nix.toml;
      src = ./path/to/source;
      go = pkgs.go;
      subPackages = [ "cmd/myapp" ];
      tags = [ "netgo" ];
      ldflags = [ "-s -w" ];
      nativeBuildInputs = [ pkgs.pkg-config ];
    }
  6. Use mkGoEnv to create a Go environment

    master

    The mkGoEnv function creates a Nix derivation that sets up a Go development environment. It uses a gomod2nix.toml file for module configuration and can optionally use a tools.go file to define required tools. Other arguments are passed verbatim to stdenv.mkDerivation.

    mkGoEnv {
      pwd = ./my-project;
      modules = ./gomod2nix.toml;
      toolsGo = ./tools.go;
    }
  7. Reference the mkGoEnv arguments

    master

    The following arguments are available for mkGoEnv:

    ArgumentDescription
    pwdPath to working directory
    modulesPath to gomod2nix.toml (defaults to pwd + "/gomod2nix.toml")
    toolsGoPath to tools.go (defaults to pwd + "/tools.go")

    Note: All other arguments are passed verbatim to stdenv.mkDerivation.

  8. Reference the buildGoApplication arguments

    master

    The following arguments are available for buildGoApplication:

    ArgumentDescription
    modulesPath to gomod2nix.toml (defaults to pwd + "/gomod2nix.toml")
    srcPath to sources (defaults to pwd)
    pwdPath to working directory (defaults to null)
    goThe Go compiler to use (can be omitted)
    subPackagesOnly build these specific sub packages
    allowGoReferenceAllow references to the Go compiler in the output closure (defaults to false)
    tagsA list of tags to pass the Go compiler during the build (defaults to [ ])
    ldflagsA list of ldflags to pass the Go compiler during the build (defaults to [ ])
    nativeBuildInputsA list of packages to include in the build derivation (defaults to [ ])

    Note: All other arguments are passed verbatim to stdenv.mkDerivation.

  9. Generate gomod2nix.toml

    master

    Once inside your development shell, use the generate command to create the gomod2nix.toml file required for building.

    To optimize build performance by pre-compiling dependencies in the build cache, use the --with-deps flag. This generates a list of imported packages to be pre-compiled, which significantly reduces subsequent build times for projects with many dependencies.

    # Basic generation
    $ gomod2nix generate
    
    # Generation with dependency pre-compilation
    $ gomod2nix generate --with-deps
  10. Use the gomod2nix CLI

    master

    The gomod2nix CLI provides two primary modes of operation: generating a gomod2nix.toml file to describe Go dependencies for Nix, and importing Go sources directly into the Nix store.

    Commands

    • gomod2nix generate: Runs the gomod2nix.toml generator. This creates a configuration file that describes how to build your Go project in Nix.
    • gomod2nix import: Imports Go sources into the Nix store. This is used when you want to bring specific Go packages into the Nix environment.

    Global Flags

    All flags are persistent and can be used with the commands above:

    • --dir <string>: The Go project directory. Defaults to ./.
    • --outdir <string>: The directory where the output (e.g., gomod2nix.toml) will be written. Defaults to the project directory.
    • --jobs <int>: The maximum number of concurrent jobs to run. Defaults to 10.
    • --with-deps: A boolean flag. When present, it includes dependencies in gomod2nix.toml to help prime the build cache.
    # Example: Generate a config file for the current directory with dependency caching
    gomod2nix generate --with-deps
    
    # Example: Generate a config file for a specific directory and output it elsewhere
    gomod2nix generate --dir ./my-go-app --outdir ./nix-config
    
    # Example: Import packages from a specific directory
    gomod2nix import --dir ./my-go-app
  11. Import Go sources into the Nix store

    master

    The import command is used to bring Go sources into the Nix store. This is typically used when you want to manage Go dependencies as Nix store paths.

    Flags for import:

    • --dir: The Go project directory containing the sources to import.
    • --jobs: The maximum number of concurrent jobs for the import process.
    # Import sources from a specific directory
    gomod2nix import --dir ./my-go-project