devenv icon indicating copy to clipboard operation
devenv copied to clipboard

Devenv for Rust w/ IntelliJ IDEA (RustRover)

Open otobrglez opened this issue 1 year ago • 4 comments

Hey good people!

I would like to first thank you for all the hard work and effort that you are putting into building this tool and improving the developer lives all around the world. I've been playing with Devenv for a while now, and I love it. I used to use a combination of Nix Shell with direnv to isolate individual environments. However, this elevates everything to one or two levels beyond that.

Now. I want to use devenv for Rust development, and my tooling of choice is Mac with IntelliJ IDEA or RustRover. The challenge that I'm facing is that RustRover "requires" the Rust toolbox to have all dependencies installed in the same folder, and direct does not do that... So when I point my Rover to the path... it obviously can't find everything that it needs. I backported my version of the Nix-Shell-based solution to direct.nix... But it feels hackish, and with this approach, I lose tons of features that Direnv promises out of the box.

image

My fix for this

# direnv.nix
{ pkgs, lib, config, inputs, ... }:

let
  rust-toolchain = pkgs.symlinkJoin {
    name = "rust-toolchain";
    paths = [
      pkgs.rustfmt
      pkgs.rustc
      pkgs.cargo
      pkgs.cargo-watch
      pkgs.rustPlatform.rustcSrc
      pkgs.clippy
    ];
  };
in

{
  env.NIX_ENFORCE_PURITY = 0;
  env.RUST_BACKTRACE = "full";
  env.RUST_SRC_PATH = "${pkgs.rustPlatform.rustLibSrc}";

  packages = [
    pkgs.git
    pkgs.libiconv
    pkgs.openssl
    pkgs.pkg-config
    rust-toolchain # see it here
  ];

  # can't use this :(
  # https://devenv.sh/languages/
  #languages.rust = {
  #  enable = true;
  #  rustflags = "-Z threads=8";
  #  components = [ "rustc" "cargo" "clippy" "rustfmt" "rust-analyzer" ];
  #};

  enterShell = ''
    echo "Rust version: $(rustc --version)"
    echo "Cargo version: $(cargo --version)"
    echo "RUST_SRC_PATH: $RUST_SRC_PATH"
  '';
}

I hope that this PR might help someone somewhere in someway. :)

Regards,

- Oto

otobrglez avatar Aug 09 '24 11:08 otobrglez

cc @shyim do you use some kind of direnv plugin?

domenkozar avatar Aug 09 '24 12:08 domenkozar

Try with rust channel stable instead of nixpkgs (default). The stable channel uses fenix which bundles the complete toolchain into a single package.

szlend avatar Aug 09 '24 21:08 szlend

After talking to @szlend I've changed my direnv.nix to something similar to this:

{ pkgs, lib, config, inputs, ... }:

{
  env.NIX_ENFORCE_PURITY = 0;
  env.RUST_BACKTRACE = "full";

  packages = [
    pkgs.git
    pkgs.libiconv
    pkgs.openssl
    pkgs.pkg-config
  ];

  languages.rust = {
    channel = "stable"; # <-- notice this
    enable = true;
    components = [ "rustc" "cargo" "clippy" "rustfmt" "rust-analyzer" ];
  };

  enterShell = ''
    echo "Rust version: $(rustc --version)"
    echo "Cargo version: $(cargo --version)"
    echo "RUST_SRC_PATH: $RUST_SRC_PATH"
  '';
}

Initially, that failed and the tooling recommended running:

$ devenv inputs add fenix github:nix-community/fenix --follows nixpkgs

Upon running that,... I was able to get more recent rust and tooling "combined" together - i.e.:

# Rust version: rustc 1.80.1 (3f5fd8dd4 2024-08-06)
# Cargo version: cargo 1.80.1 (376290515 2024-07-16)

type rustc && type cargo
rustc is /nix/store/jmlrlcww31afdgn5zfi1vqlmmlx53dnn-rust-mixed/bin/rustc
cargo is /nix/store/jmlrlcww31afdgn5zfi1vqlmmlx53dnn-rust-mixed/bin/cargo

echo $RUST_SRC_PATH
/nix/store/gzjan1ww7wq42pa4m821n6zivw98gpcc-rust-src-stable-2024-08-08/lib/rustlib/src/rust/library

Win! 🎉 Thank you @szlend && @domenkozar

otobrglez avatar Aug 13 '24 13:08 otobrglez

It's possible to configure IDEA to use stable, project-local paths rather than global Nix store paths:

  • Toolchain location: [path to project]/.devenv/profile/bin
  • Standard library: [path to project]/.devenv/profile/lib/rustlib/src/rust/library

l0b0 avatar Sep 07 '24 21:09 l0b0

  • .devenv/profile/lib/rustlib/src/rust/library

I dont have that path on my devenv, my config is:

env.NIX_ENFORCE_PURITY = 0;
env.RUST_BACKTRACE = "full";

languages.rust.enable = true;
languages.rust.channel = rustVersion;

languages.javascript.enable = true;
languages.javascript.pnpm.enable = true;
languages.javascript.directory = "./frontend";

packages = with pkgs; [
  rustfmt
  fenixPkgs.clippy
  nodemon
] ++ nativeBuildInputs ++ buildInputs;

enterShell = ''
  echo "Rust version: $(rustc --version)"
  echo "Cargo version: $(cargo --version)"
  echo "RUST_SRC_PATH: $RUST_SRC_PATH"
'';

lfdominguez avatar Jun 06 '25 03:06 lfdominguez

Just wondering, does this also correctly propagate the nix store paths for the cargo.toml dependencies? I am developing Rust on a similar setup as @otobrglez (RustRover on Mac) but I can't seem to find a foolproof way to correct propagate the Rust dependencies in a way that RustRover expects.

JSLJ23 avatar Jun 25 '25 05:06 JSLJ23