Pierre-olivier Gendraud
Pierre-olivier Gendraud

Reputation: 1897

Is there a better way to create an executable of a R project with dependencies with nix

In a file. I have some R files and I have a subdirectory with a "sub application" that calls the R files of the parent directory.

project :

 fileR_n.R

 subapp_directory

     file.R

If file.R were alone this flake.nix would be enough.

{
  description = "virtual environment with Rstudio, R, Shiny";
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let
        pkgs = nixpkgs.legacyPackages.${system};
        rWrapper=pkgs.rWrapper;
        rstudioWrapper=pkgs.rstudioWrapper;
        rstudioServerWrapper=pkgs.rstudioServerWrapper;
        Rpackages=with pkgs.rPackages;
          [
            shiny
            dplyr
            zoo 
            dygraphs
            plotly
            shinydashboard
            shinyjs
            forecast
            DBI
            odbc
            RMySQL
            fasttime
            reshape2
            lme4
            merTools
            Metrics
            rstudioapi
          ];
        RwithPackages=   rWrapper.override{ packages =  Rpackages;};
        RStudio-with-my-packages = rstudioWrapper.override{ packages = Rpackages; };
        myDevTools = [
          RwithPackages
          rstudioServerWrapper
          RStudio-with-my-packages
        ];
        #code_source=".";
        entry_point_name=./my_Exec/app.R;
        exec_name="toBeRenamed";
        Rderivation=with pkgs; stdenv.mkDerivation {
          name = exec_name;  
          src = ./.;
          propagatedBuildInputs  = myDevTools; #todo try with propagatedBuildInputs nativeBuildInputs 
          dontUnpack = true;
          buildPhase =
          "
            mkdir -p $out/bin
            cp ${src} -r  $out/bin
            echo '#!/usr/bin/env Rscript ' > ./temp.txt       
            cat ${entry_point_name} >> ./temp.txt && mv ./temp.txt ${entry_point_name} 
          ";
          installPhase =
          "
            install -Dm755 ${entry_point_name}  $out/bin/${exec_name}
          ";
        };
      in {
        devShells.default = pkgs.mkShell {
          buildInputs = myDevTools;
        };
        packages.default = Rderivation;
        apps.default = flake-utils.lib.mkApp {drv =Rderivation;};

      });
}

Nix build and nix run works. but the built "executable" doesn't work because of this line.

  source("../fileR_n.R ")

this file can' be found

Therefore I ve changed buildPhase like it:

      "
        mkdir -p $out/bin
        cp ${src} -r  $out/bin
        echo '#!/usr/bin/env Rscript ' > ./temp.txt   
        echo 'setwd(\"'$src/subapp_directory'\")' >> ./temp.txt

        cat ${entry_point_name} >> ./temp.txt && mv ./temp.txt ${entry_point_name} 
      ";

you can see t ourself the that the second line of the R file will set the virtual environment somewhere where the source are saved

  head -n 3 result/bin/toBerenamed

Now it works but this is not a beautiful solution And that is very easy to write errors in a string that represent a script that add a line to a script file...

Upvotes: 1

Views: 99

Answers (0)

Related Questions