numtide/flake-utils

Help standardize around devShell

blaggacao opened this issue · 8 comments

I wonder if this is a good enough abstraction to be encourage by this repo:
https://github.com/nix-community/flake-nimble/blob/22e4e490b5d5ad15e78c9225022d0dc43d65af8a/flake.nix#L55-L64

See also: https://discourse.nixos.org/t/getting-started-nix-repository-template/8024/17?u=blaggacao

# pseudo
{
    devShell = flake-utils.lib.mkShell { buildInputs = [ ". . ." ]; };
}

I want to avoid adding a direct dependency on nixpkgs for this flake because of how flakes works where each flake imports their own instance of nixpkgs.

The shortest version so far, which is far from being trivial, is:

{ self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
  let pkgs = nixpkgs.legacyPackages.${system}; in
  {
    devShell = pkgs.mkShell {
      buildInputs = [ pkgs.hello ];
    };
  }
)

An alternative version is to use the defaultPackage like this:

{ self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
  let pkgs = nixpkgs.legacyPackages.${system}; in
  {
    # create a default derivation that adds all the dependencies on the PATH only.
    defaultPackage = pkgs.buildEnv {
      paths = [ pkgs.hello ];
    };
  }
)

And then load it with nix shell.

That approach has the advantage of keeping the environment clean and only changing the PATH. The disadvantage is that it is messing a shellHook equivalent.

Thank you for providing this context to us. I think you are doing a great job as an educator!

I don't understand why I see the use of "legacyPackages" a lot in my current research on flakes. "Your shared investigation on NixFlakes in understandable terms might be a good place for clarification", my intution alleges.

There are ongoing caveats about building development shells to which I'd like to cross reference. The quid of the issue is that historically, nix dev-shell has conflated two similar but separated use cases. Hence, any implementation of the current devShell in my opinion needs a revision of it's design.

I want to stress the importance of a sound design on this, since devShell use cases will gain traction, as devops team leaders seek to deploy reproducible dev environments to their team. Or normatively put: DevOps teems should be able to leverage nix for their distribution of developmemt environments through a perfectly balanced UX.

I agree that getting this right could make a big difference. Now the question is, what is the right design :-D Nix flakes still has a lot of room to grow in terms of usability, as a whole.

If you have other ideas, I am happy to read about them and tell you if they are practical or not.

I think it boils down to properly scope and name two commands:

  • one, that does provide a dev environment for the application developer.
  • one that provides a debugging environment for the nix packager.

Out of nowhere, devShell sounds like an appropriate name for app development. It's the first association, they have at a point when they are not already sucked knee-deep into the darknix idiosyncracies.

nix develop: since nix is meaningless, the difficulty is to decide which part rules the idiom over the other. Is it develop with nix? Or is it develop nix?

However, let's asume nix to be an imperative tense of a verb "to nix", let's alias for simplicity:
alias do=nix

Then we'd have:

  • do develop github:foo/bar
  • do develop github:foo/bar#web (why not?)
  • do run github:foo/bar#web
  • do flake [stuff]
  • do build github:foo/bar#web
  • do build --shell github:foo/bar (the historic nix-shell)
  • do build -i / --interactive github:foo/bar

So build would be the home command for the traditional nix community (involved builders)

I couldn't help, but to put it this way. 😸

I think we can close this as discussion has evolved around this topic here numtide/devshell#52

Although: there is no dependency on nixpkgs any more... Reopen?