Nix ruby

From wikinotes

Documentation

official nixpkgs ruby docs https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/ruby.section.md
official ruby docs https://nixos.org/manual/nixpkgs/stable/#sec-language-ruby
wiki docs https://nixos.wiki/wiki/Packaging/Ruby
bundix github https://github.com/nix-community/bundix
bundlerEnv src https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/ruby-modules/bundler-env/default.nix

Tutorials

compiling native extensions in bundix https://stackoverflow.com/questions/37933375/how-to-build-a-ruby-gem-using-nix-that-has-native-extensions
nix rails performance https://www.tweag.io/blog/2020-06-25-eval-cache/

Package Providers

ad-hoc

# install ruby version with target gems
nix-shell -p "ruby_2_7.withPackages (ps: with ps; [ nokogiri pry ])"

bundix (builtin)

${package}/Gemfile

Just a regular Gemfile

source 'https://rubygems.org'
gem 'graphql'
gem 'pry'

${package}/default.nix


# ${package}/default.nix
#
# first run:
#    nix-shell -p bundler --run 'bundle lock'
#    nix-shell -p bundix --run 'bundix -m'
#    nix-shell
#      bundle install
#      bundle exec pry

{ pkgs ? import <nixpkgs> {} }:
  pkgs.stdenv.mkDerivation {
    pname = "ruby-graphql-intro";
    version = "0.0.1";
    env = pkgs.bundlerEnv {
      name = "ruby-graphql-intro";
      ruby = pkgs.ruby;
      gemdir = ./.;
    };
    buildInputs = [
      pkgs.ruby
      pkgs.bundler
    ];
  }


  • bundix creates gemset.nix from your Gemfile
  • bundler-env configures your environment using the Gemfile, gemset.nix, etc.
  • gem-config allows you to override mkDerivation for each gem

To interactively add additional dev packages, you can simply gem install them.

nix-shell
gem install solargraph
irb
require 'solargraph'

So far, I've been managing the initial setup with a Makefile.
See ruby rails: project section on nix for a more complex build involving build overrides.

overridable bundix (builtin)

Keep the same default.nix,
we'll just inject some gems and packages specific to your dev environment.

${package}/shell.nix

# ${package}/shell.nix

{ pkgs ? import <nixpkgs> {} }:

let
  pkg = import ./default.nix {};

in
  pkg.overrideAttrs(
    old: {
      shellHook = 
        (if builtins.hasAttr "shellHook" pkg
          then builtins.getAttr "shellHook" pkg
          else "")
          + "\n" 
          + ''
          gem install pry
        '';
      buildInputs =
        (if builtins.hasAttr "buildInputs" pkg
          then builtins.getAttr "buildInputs" pkg
          else [])
          ++ [
            pkgs.ripgrep
            pkgs.vim
          ];
    }
  )

rails and other setups

See ruby rails: project