devshell icon indicating copy to clipboard operation
devshell copied to clipboard

Document how to build a devshell using nix or a mix of nix and toml

Open nova-nowiz opened this issue 3 years ago • 8 comments

Is your feature request related to a problem? Please describe. The problem I'm facing is that I cannot add a custom package with the toml file. I would like to add more precisely a python with packages.

Another thing is that in the documentation, it is mentionned that 80% can be achieved with the toml but there is no mention (or did I miss it?) of a way to get that 20% in case it is necessary.

Describe the solution you'd like I would like to know how the mkShell works and what options it has so that I am able to use nix as a backup solution when the toml file is not enough.

Describe alternatives you've considered An alternative would be to use a bare nix devShell so not using this repository.

nova-nowiz avatar Jul 06 '21 13:07 nova-nowiz

Perhaps what I do over here, at the bottom of the file, would be helpful?

yusdacra avatar Jul 06 '21 16:07 yusdacra

woops, I left this issue hanging. Actually, it is totally possible to use it like this:

{
  description = "virtual environments";

  inputs.devshell.url = "github:numtide/devshell";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, flake-utils, devshell, nixpkgs }:
    flake-utils.lib.eachDefaultSystem (system: {
      devShell =
        let pkgs = import nixpkgs {
          inherit system;

          overlays = [ devshell.overlay ];
        };
        in
        pkgs.devshell.mkShell {
          imports = [ (pkgs.devshell.importTOML ./devshell.toml) ];
          devshell.packages = with pkgs; [
            (python39Full.withPackages(p: with p; [ pygments ]))
            elmPackages.elm
            elmPackages.elm-test
            elmPackages.elm-language-server
            elmPackages.elm-format
            elmPackages.elm-analyse
            elmPackages.elm-coverage
            elmPackages.elm-json
            elmPackages.elm-review
          ];
        };
    });
}

I got devshell.packages from the documentation here: https://numtide.github.io/devshell/modules_schema.html on a toml, you would do this iirc:

[[devshell]]
packages = [
python39Full
]

using devshell.packages in nix is the strict equivalent.

nova-nowiz avatar Jul 20 '21 15:07 nova-nowiz

this should be however still be documented on the website.

nova-nowiz avatar Jul 20 '21 15:07 nova-nowiz

@zimbatm how can you import the extra modules from nix?

nova-nowiz avatar Aug 03 '21 17:08 nova-nowiz

That's what the extraModulesPath is for: https://www.github.com/numtide/devshell/tree/master/modules%2Fdefault.nix

blaggacao avatar Aug 03 '21 18:08 blaggacao

ok I followed the trail once more. In our personal flake.nix that we create, we add devshell.overlay to the overlays of pkgs. So we should know what this overlay is. If we look at the flake.nix of this repo, we find the following: https://github.com/numtide/devshell/blob/4b5ac7cf7d9a1cc60b965bb51b59922f2210cbc7/flake.nix#L35-L43 the overlay is thus this file: https://github.com/numtide/devshell/blob/4b5ac7cf7d9a1cc60b965bb51b59922f2210cbc7/overlay.nix#L1-L5 these lines mean that we add devshell to whatever we apply the overlay to, meaning that we have in our personal flake.nix pkgs.devshell. in this pkgs.devshell attribute, we have everything that is in default.nix of this repository and so we have the following: https://github.com/numtide/devshell/blob/4b5ac7cf7d9a1cc60b965bb51b59922f2210cbc7/default.nix#L24-L27

here is the flake.nix I have as a result:

{
  description = "Developement environment for Nix users";

  inputs.devshell.url = "github:numtide/devshell";
  inputs.flake-utils.url = "github:numtide/flake-utils";

  outputs = { self, flake-utils, devshell, nixpkgs }:
    flake-utils.lib.eachDefaultSystem (system: {
      devShell =
        let pkgs = import nixpkgs {
          inherit system;

          overlays = [ devshell.overlay ];
        };
        in
        pkgs.devshell.mkShell {
          imports = [ "${pkgs.devshell.extraModulesDir}/language/c.nix" ];
          commands = [
            {
              package = pkgs.devshell.cli;
              help = "Per project developer environments";
            }
            {
              package = pkgs.gitflow;
            }
            {
              package = pkgs.elmPackages.elm;
            }
            {
              package = pkgs.nodejs;
            }
            {
              package = pkgs.nim;
              name = "nim";
            }
          ];
          devshell.packages = with pkgs; [
            (python39Full.withPackages(p: with p; [ pygments ]))
            elmPackages.elm-test
            elmPackages.elm-language-server
            elmPackages.elm-format
            elmPackages.elm-analyse
            elmPackages.elm-coverage
            elmPackages.elm-json
            elmPackages.elm-review
            nimlsp
          ];
          language.c.libraries = with pkgs; [
            libzip
          ];
        };
    });
}

This flake.nix could be of use in the documentation of the project so that everyone has an idea of how to achieve everything in pure nix ;) I hope that this comment will be of use to anyone having the same issue and wanting to know how this flake works internally. I tried my best to teach how to navigate the codebase and understanding it rather than just giving out the solution I found.

give a man a fish and he’ll eat for a day, teach him how to fish and he’ll eat forever

also thank you @blaggacao for your comment! I solved my issue and began the writing of this comment before you posted but thank you anyway for the help!

nova-nowiz avatar Aug 03 '21 19:08 nova-nowiz

Nixpkgs modules can be passed either an attrset or a function. In which case the extraModulesDir becomes an available parameter. Something like that should also work:

pkgs.devshell.mkShell { extraModulesDir, ... }: {
  imports = [ "${extraModulesDir}/language/c.nix" ];
  //...

zimbatm avatar Aug 04 '21 08:08 zimbatm

oh! I didn't know that, that's quite cool and a really good piece of information to keep in mind, thanks! I however don't understand why extraModulesDir is an available parameter in this case, is it because we are calling the pkgs.devshell.mkShell module which is directly under pkgs.devshell? Sorry for the newbie question in advance x) I've been on NixOS for a while but the language is still a tough nut to crack for me :joy: Where have you been able to learn these tricks? Is there a specification somewhere that I could read or is nix pills the way to gain such knowlegde?

nova-nowiz avatar Aug 06 '21 22:08 nova-nowiz