cachix / devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
https://devenv.sh
Apache License 2.0
4.38k stars 329 forks source link

Devenv for Rust w/ IntelliJ IDEA (RustRover) #1369

Open otobrglez opened 2 months ago

otobrglez commented 2 months ago

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

domenkozar commented 2 months ago

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

szlend commented 2 months ago

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

otobrglez commented 2 months ago

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

l0b0 commented 1 month ago

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