Add option to direnv shell.nix

Hello,

New user so this may be a very basic question.

First, my goal and below what I’ve tried and failed to work:

My goal is to use nix-direnv and add shell.nix fiels for my projects, so that the build tools and optionally dev tools can become available when you enter the project. By build tools I mean everything needed to build the project headless on command line. By dev tools I mean IDEs, and anything that I would use interactively.

What I have gotten to work

I have home manager working and nix-direnv active. I’ve created .envrc with use nix, ran direnv allow and created a shell.nix that gets picked up and auto-activates pulling in the build tools (it is a java project so maven and the jdk):

let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.11";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShellNoCC {
  packages = with pkgs; [
    flatbuffers temurin-bin maven
    temurin-bin-23
  ];
}

What I am having trouble with

I see people using lib.mkOption to add options and then if statements to define packages. I tried defining an option but I have trouble importing standard libs.

let
  nixpkgs = fetchTarball "https://github.com/NixOS/nixpkgs/tarball/nixos-24.11";
  pkgs = import nixpkgs { config = {}; overlays = []; };
in
pkgs.mkShellNoCC {
  options = {
    devtools.enable.option = lib.mkOption {
      type = lib.types.bool;
      default = false;
    };
  };
  packages = with pkgs; [
    flatbuffers temurin-bin maven
    temurin-bin-23
  ] ++ (
    if (config.devtools.enable == true) then [
      eclipses.eclipse-java
    ]
    else []
  );
}

Which fails to access lib with:

error: undefined variable 'lib'
       at /var/home/karypid@ad.home.lan/devroot/wc.git/bitbucket.org/varia/java-playground/shell.nix:7:30:
            6|   options = {
            7|     devtools.enable.option = lib.mkOption {
             |                              ^
            8|       type = lib.types.bool;
  1. Is it possible to make the direnv optionally add packages?
  2. How would one go about declaring their intent (as you noticed, by default only build tools would get activated, one should be able to reload shell.nix and specify devtools.enalbe=true)

Looking online I have come up with the following:

{
  description = "A Nix-flake-based Java development environment";

  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/release-24.11";
  };

  outputs = { self, nixpkgs }:
    let
      supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
      forEachSupportedSystem = f: nixpkgs.lib.genAttrs supportedSystems (system: f {
        pkgs = import nixpkgs {
          inherit system;
        };
      });
    in
    {
      devShells = forEachSupportedSystem ({ pkgs }: {
        default = pkgs.mkShell {
          packages = with pkgs; [
            temurin-bin-17
            temurin-bin
            temurin-bin-23
            maven
            gradle
            gradle-completion
          ] ++ (
            if builtins.pathExists ./.devtools then [ pkgs.visualvm ]
            else [ pkgs.jmeter ]
          );
        };
      });
    };
}

Clearly the significant bit is this extra list of packages:

          ] ++ (
            if builtins.pathExists ./.devtools then [ pkgs.visualvm ]
            else [ pkgs.jmeter ]
          );

My intent is to have tools like visualvm / jmeter installed when the user does touch .devtools but even though the file exists when I under the folder, it always seems to pick the else clause (installing jmeter).

Can anyone help with this approach (or suggest an alternative)?