Skip to content

Instantly share code, notes, and snippets.

@jerrymarino
Created June 3, 2019 18:20
Show Gist options
  • Save jerrymarino/c098cb69d189c64496e079c58f4c8c77 to your computer and use it in GitHub Desktop.
Save jerrymarino/c098cb69d189c64496e079c58f4c8c77 to your computer and use it in GitHub Desktop.
Tips for using the nix package manager on macOS

Nix tips

Few tips from using the nix package manager on macOS.

Tip 0 Learn the fundamentals and benefits

https://www.youtube.com/watch?v=D5Gq2wkRXpU

Tip 1 Nix channel pinning

Reference the latest stable channel (18.09-darwin) here and pin to a specific version so we have reproducible builds. Only update if things appear broken or we need more recent updates from upstream.

let
  _pkgs = import <nixpkgs> {};
in
{ pkgs ?
	import (_pkgs.fetchFromGitHub { owner = "NixOS";
			repo = "nixpkgs-channels";
			rev = "e5eabccb00c5d18470c8eff1dca078f1d2365544";
            sha256 = "0mc7vx7afkd940b9lp9kk23kav7lf1z9wqzq4mmklw83ps09srj9";
	}) {}
}:

Tip 2 Ruby configuration

Build gems based on the bundler env by default, nix uses a pegged bundler version The default bundler loaded with bundlerEnv is basically a pass through, so don't use bundler as an input to nix, unless necessary. Bundler is used only as an installation means with bundix

  ruby_2_3 = pkgs.ruby_2_3;
  gems = pkgs.bundlerEnv {
    name = "my_bunlder_env";
    inherit ruby_2_3;
    gemfile = ./Gemfile;
    lockfile = ./Gemfile.lock;
    gemset = ./gemset.nix;
  };

gemset.nix is generated with Bundix and checked in.

Tip 3 Patching outputs by adding phases

this is a hack for xcode-install

  xcode-install = {
    dependencies = ["claide" "fastlane"];
    groups = ["default"];
    platforms = [];
    source = {
      remotes = ["https://rubygems.org"];
      sha256 = "11mhkhc2f6hlpmx9qzv7nz0sincqjp6fmiz0hm51vhic3v79jlg4";
      type = "gem";
    };
    version = "2.5.0";
    postPhases = [ "patchDownloadedGem" ];
    patchDownloadedGem = ''
    echo "Patching downloaded xcversion"
    source env-vars
    cd $out/lib/ruby/gems/2.5.0/gems/xcode-install-2.5.0
    patch -p0 <<'EOF'
diff --git lib/xcode/install.rb lib/xcode/install.rb
index a1c505b..2a87e85 100644
--- lib/xcode/install.rb
+++ lib/xcode/install.rb
@@ -366,8 +366,9 @@ HELP
         return path if path.exist?
       end
       if ENV.key?('XCODE_INSTALL_CACHE_DIR')
-        cache_path = Pathname.new(ENV['XCODE_INSTALL_CACHE_DIR']) + Pathname.new("xcode-#{version}.dmg")
-        return cache_path if cache_path.exist?
+        Pathname.glob(ENV['XCODE_INSTALL_CACHE_DIR'] + '/*').each do |fpath|
+          return fpath if /^xcode_#{version}\.dmg|xip$/ =~ fpath.basename.to_s
+        end
       end

       download(version, progress, url, progress_block)
EOF
    '';
  };

Tip 4 Basic stdenv usage

pkgs.stdenv.mkDerivation rec {
  name = "my_std_env";
  version = "0.1.0";
  buildInputs = [
    pkgs.ruby_2_3
    gems             # Defined above
    #...
  ];

  shellHook = ''
    # use a Gem directory within nix
    export GEM_HOME=$out/.gems
    export PATH=$out/.gems/bin:$PATH
  '';
}

Tip 5 macOS updates

Nix packages are be based on the current OS and may have OS level dependencies. If the OS is updated without updating/recompiling nix dependencies, packages may be broken.

On macOS updates, erase the entire cache of nix ( and likely Nix )

Reference: NixOS/nix#2444

Tip 6 CI <-> Developer Env consistency

Using Nix on the CI and locally makes it easy to ensure that the CI and the developer environment are always on the same packages transitively.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment