nix-community / bundix

Generates a Nix expression for your Bundler-managed application. [maintainer=@manveru]
160 stars 54 forks source link

Using local gems #84

Open b12f opened 3 years ago

b12f commented 3 years ago

Hello,

I'm trying to package openproject for nix, but am relatively new to both nix packaging and the ruby ecosystem. The Gemfile for op contains a couple of gems that are part of the git repository itself. Bundix generates a gemset.nix with e.g. the following gem:

  budgets = {
    groups = ["opf_plugins"];
    platforms = [];
    source = {
      path = modules/budgets;
      type = "path";
    };
    version = "1.0.0";
  };

This of course breaks when trying to get a bundlerEnv going, since the modules/budgets path is not available outside of the openproject repo.

My initial idea was to download the sources, apply the gemset via a patch, and then use the source derivation as the gemdir. However, this breaks dramatically with nix-build running into a segfault.

Any ideas? My current derivation attempt is below.

{ lib, stdenv, fetchurl, bundlerEnv, ruby, makeWrapper }:
let
  version = "11.3.1";
  source = stdenv.mkDerivation rec {
    pname = "openproject-source-${version}";

    src = fetchurl {
      url = "https://github.com/opf/openproject/archive/refs/tags/v${version}.tar.gz";
      sha256 = "sha256-f4A4uiHGywQbTOSivUNsiuwlwDV1E7X6GASWRfZtSb8=";
    };

    patches = [ ./gemset.patch ];

    buildPhase = "";
    installPhase = ''
      mkdir -p $out/share/openproject
      cp -r . $out/share/openproject
    '';
  };

  rubyEnv = bundlerEnv {
    name = "openproject-env-${version}";

    inherit ruby;
    gemdir = "${source}" + ./share/openproject; # just `source` also does not work
    groups = [ "development" "production" "sentry" "ldap" "postgres" "test" ];
  };
in
stdenv.mkDerivation rec {
  pname = "openproject";
  inherit version;

  nativeBuildInputs = [ makeWrapper ];
  buildInputs = [ rubyEnv rubyEnv.wrappedRuby rubyEnv.bundler ];

  buildPhase = ''
    #stuff
  '';

  installPhase = ''
    # stuff
    makeWrapper ${rubyEnv.wrappedRuby}/bin/ruby $out/bin/openproject
  '';
}
b12f commented 3 years ago

I should add that building just the source derivation in the code above works fine and applies the patch without problems. I'm guessing this is a problem with stuff being available while the nix language evaluates vs. when derivations are built; source is built after rubyEnv is evaluated. However, how would you then go about doing this?