4

I'm writing a .nix expression to be used primarily by nix-shell. I'm not sure how to do that. Note this is not on NixOS, but I don't think that is very relevant.

The particular example I'm looking at is that I want to get this version-dependent name that looks like:

  idea-ultimate = buildIdea rec {
    name = "idea-ultimate-${version}";
    version = "2017.2.2"; /* updated by script */
    description = "Integrated Development Environment (IDE) by Jetbrains, requires paid license";
    license = stdenv.lib.licenses.unfree;
    src = fetchurl {
      url = "https://download.jetbrains.com/idea/ideaIU-${version}-no-jdk.tar.gz";
      sha256 = "b8eb9d612800cc896eb6b6fbefbf9f49d92d2350ae1c3c4598e5e12bf93be401"; /* updated by script */
    };
    wmClass = "jetbrains-idea";
    update-channel = "IDEA_Release";
  };

My nix expression is the following:

let
  pkgs = import <nixpkgs> {};
  stdenv = pkgs.stdenv;
  # idea_name = assert pkgs.jetbrains.idea-ultimate.name != ""; pkgs.jetbrains.idea-ultimate.name;
in rec {
  scalaEnv = stdenv.mkDerivation rec {
    name = "scala-env";
    builder = "./scala-build.sh";
    shellHook = ''
    alias cls=clear
    '';
    CLANG_PATH = pkgs.clang + "/bin/clang";
    CLANGPP_PATH = pkgs.clang + "/bin/clang++";
    # A bug in the nixpkgs openjdk (#29151) makes us resort to Zulu OpenJDK for IDEA:
    # IDEA_JDK = pkgs.openjdk + "/lib/openjdk";
    # PATH = "${pkgs.jetbrains.idea-ultimate}/${idea_name}/bin:$PATH";
    IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;
    # IDEA_JDK = /opt/zulu8.23.0.3-jdk8.0.144-linux_x64;
    # IDEA_JDK = /usr/lib/jvm/java-8-openjdk-amd64;
    buildInputs = with pkgs; [
      ammonite
      boehmgc
      clang
      emacs
      jetbrains.idea-ultimate
      less
      libunwind
      openjdk
      re2
      sbt
      stdenv
      unzip
      zlib
    ];
  };
} 

I have commented out setting PATH as it depends on getting idea_name in the let-clause. As an interesting side note, as is, this does not fail if I leave it uncommented but causes a very bizarre error when executing nix-shell about not being able to execute bash. I've also tried the more simple case of let idea_name = pkgs.jetbrains.idea-ultimate.name; but this fails later on when idea_name is used in setting PATH since idea_name ends up being undefined.

Update:

I began exploring with nix-instantiate, but the derivation of interest seems empty:

[nix-shell:/nix/store]$ nix-instantiate --eval --xml -E "((import <nixpkgs> {}).callPackage ./3hk87pqgl2qdqmskxbhy23cyr24q8g6s-nixpkgs-18.03pre114739.d0d905668c/nixpkgs/pkgs/applications/editors/jetbrains { }).idea-ultimate";  


<?xml version='1.0' encoding='utf-8'?>
<expr>
  <derivation>
    <repeated />
  </derivation>
</expr>
bbarker
  • 7,931
  • 5
  • 30
  • 44
  • 1
    I've also tried using something like `nix-shell --verbose --verbose --verbose --verbose --verbose --verbose --show-trace ` to understand why an assertion fails, but despite the vast quantities of information printed, that information doesn't include the assertion values. – bbarker Sep 12 '17 at 01:41

1 Answers1

4

If your intent is to get idea-ultimate into nix-shell environment, then just include that package to buildInputs. I see it's already included, so it should already be present in your PATH.

BTW, you can extend your shellHook and export PATH and other variables rather from there, where you have full bash. Why would you do it from bash? Less copying. When you specify

IDEA_JDK = /usr/lib/jvm/zulu-8-amd64;

in Nix, the file /usr/lib/jvm/zulu-8-amd64 get's copied to nix store and IDEA_JDK is set to point to file in /nix/store. Was that your intent?

Regarding nix-instantiate:

$ nix-instantiate --eval -E 'with import <nixpkgs>{}; idea.pycharm-community.outPath'                                                                                   
"/nix/store/71jk0spr30rm4wsihjwbb1hcwwvzqr4k-pycharm-community-2017.1"

but you still have to remove doublequotes (https://gist.github.com/danbst/a9fc068ff26e31d88de9709965daa2bd)

Also, nitpick, assert pkgs.jetbrains.idea-ultimate.name != ""; can be dropped as it's impossible to have empty derivation name in Nix.

And another nitpick. You'll soon find very incovenient to launch IDE from shell every time. It seems a good idea to specify, that some package is used for development, but nix-shell doesn't work well for non-cli applications. Not to mention occasional problems with Nix GC and nix-shell. You'd better install IDE globally or per-user, it is better long-term solution.


[ADDENDUM]

You are looking for this (dev-environment.nix):

with import <nixpkgs> { };

buildEnv {
  name = "my-super-dev-env";
  paths = [
      #emacs
      nano
      idea.pycharm-community
  ];
  buildInputs = [ makeWrapper ];
  postBuild = ''
    for f in $(ls -d $out/bin/*); do
      wrapProgram $f \
        --set IDEA_JDK "/path/to/zulu-jdk" \
        --set CLANG_PATH ... \
        --set CLANCPP_PATH ...
    done
  '';
}

which you install using nix-env -if ./dev-environment.nix. It will wrap your programs with those env vars, without polluting your workspace (you can pollute it further using nix-shell with shell hook, if you want).

danbst
  • 2,615
  • 13
  • 34
  • Thanks for all the suggestions! Is it possible to use a nix expression to specify the user environment? By the way, I wanted to get the idea path in order to run `idea.sh` directly as part of a workaround of using a different JDK than the one in nix. – bbarker Sep 12 '17 at 10:34
  • @bbarker it's a tricky question, because, while it is possible in Nix, it has drawbacks. I'll add required steps to my answer then – danbst Sep 12 '17 at 10:36
  • Thanks! I am using this from a container, so In a way I view the whole thing as a transient environment. – bbarker Sep 12 '17 at 10:44