Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document how to share devshell modules #52

Closed
blaggacao opened this issue Dec 24, 2020 · 14 comments
Closed

Document how to share devshell modules #52

blaggacao opened this issue Dec 24, 2020 · 14 comments
Labels
documentation Improvements or additions to documentation

Comments

@blaggacao
Copy link
Contributor

blaggacao commented Dec 24, 2020

I think flakes are an excellent code / knowledge sharing platform infrastructure.

I would like to seek structural guidance (later on: eg. examples / templates) on how to combine those ideas in a proper way.

I'm also wondering, how user provided devshells would / could / should interact with project provided devshells.

@colemickens
Copy link

note, I don't expose mine in my flake yet - I've recently been thinking about this too. I have lots of lofty ideas with fuzzy handwaving around devshells and it intersects with a lot of the questions you prompt here @blaggacao. I don't have much to contribute right now, I have too many other things I really need to finish first.

@blaggacao
Copy link
Contributor Author

I'd love to hear of those lofty handwaving thoughts. 😉 If only for the pure joy of waving back at them, or — in fact — trying to broker the hearsay through the graph.

@zimbatm
Copy link
Member

zimbatm commented Dec 26, 2020

Since devshell uses the nix module system, I think we should take advantage of that more. There is already one project that uses it successfully.

Potentially flakes could export a devshellModules attribute that is a list of modules to load. This would then allow composing the module definitions into the current shell.

@blaggacao
Copy link
Contributor Author

Thank you! Sounds like a good idea, I'll adapt my exploratory draft PR over at nixflk accordingly.

@nrdxp
Copy link
Contributor

nrdxp commented Dec 29, 2020

Since devshell uses the nix module system, I think we should take advantage of that more. There is already one project that uses it successfully.

@zimbatm, could you expand on this more. What do mean by nix modules? Surely you don't mean NixOS modules 😜

@blaggacao
Copy link
Contributor Author

blaggacao commented Dec 29, 2020

I think this refers to the way a numtide/devshell is configured and read. I understand that those devshell configurations can be made composable modules.

@nrdxp
Copy link
Contributor

nrdxp commented Dec 29, 2020

Thanks, makes perfect sense.

@zimbatm
Copy link
Member

zimbatm commented Dec 29, 2020

There are actually two levels to share shells.

nix develop <flake-id>#<shell-name>. Hypothetical example: nix develop github:nix-community/nix-environments#arduino. In this case we provide a fixed shell environment that is dedicated for a purpose. The nix-community/nix-environments repo really exists and could be converted into flakes. The nice thing about this approach is that the invocation is direct, and the downside is that it's not tunable without forking the repo.

The other way, that would work with the devshell project is to export some nix modules. Since devshell is extensible using the same module system as NixOS, extensions could be written and exported out of a flake attribute. In that scenario, the setup is a bit more complicated. First, there is a flake that exports the modules.

{
  outputs = inputs: {
    # A module that generates per-project TLS certificates.
    devshellModules.certificates = { config, lib, ... }: {
       options.certificates = {
         enable = lib.mkEnableOption "certificates";
         # TODO: add real config here
       };
       config = lib.optionalAttrs config.certificiates.enable {
         # TODO: set some devshell config here, like add a new command
       };
    };
  };
}

Then on the consumer side:

{
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.devshell.url = "github:numtide/devshell";
  inputs.devshell-modules.uri = "github:numtide/devshell-modules"; # does not exist

  outputs = { self, flake-utils, devshell, devshell-modules, nixpkgs }:
    flake-utils.lib.simpleFlake {
      inherit nixpkgs;
      name = "my-project";
      preOverlays = [ (import devshell.overlay) ];
      shell = { pkgs }:
        pkgs.mkDevShell {
          imports  = [ (import devshell-modules.devshellModules.certificates) ];
          # Now the certificates options are available
          certificates.enable = true;
        };
    };
}

Something like that. As you can see it's much more complicated to use. But it allows changing the behavior of devshell.

@blaggacao
Copy link
Contributor Author

I would be opposite to opposed to github:numtide/devshell-modules. Would you give birth to it? I take the cert example as a hint.

@blaggacao
Copy link
Contributor Author

blaggacao commented Dec 29, 2020

Playing around with this idea: https://github.com/nrdxp/nixflk/pull/39/files done so in nixflk to encourage sharing by default, but any community curated devshells should probably live in github:nix-community/nix-environments @colemickens I hope its helpful to see how this could play out. I have skill deficits from here on.

EDIT: also divnix/digga#55 for a more useful attempt.

@blaggacao
Copy link
Contributor Author

blaggacao commented Dec 29, 2020

After some thought, for the first sharing use case mentioned, I think nix should be amended to provide for devshells and defaultDevshell analogous to templates & defaultTemplate, etc.

A simple project-proper use case:

  • A project provides two or three devshells:
    • backend
    • frontend
    • combined
  • Quid: when the frontend team evolves, they don't force a shell rebuild on the backend team each time.
  • The use case can be projected onto a different division of project shells managed (and evolved!) by different teams within the project (at different speeds!)

How should this be proposed / approached for most chances of success and effectiveness?

@zimbatm zimbatm added this to the Stable release milestone Jan 22, 2021
@zimbatm zimbatm added the documentation Improvements or additions to documentation label Jan 22, 2021
@zimbatm zimbatm changed the title Provide a thought model for sharing devshells Document how to share devshell modules Jan 22, 2021
@blaggacao
Copy link
Contributor Author

blaggacao commented May 21, 2021

One possible implementation / blueprint for docs: divnix/digga#24

(Exported as self.devshellModules)

@blaggacao
Copy link
Contributor Author

we just use self.devshellModules in digga. Closing.

@teutat3s
Copy link

Sorry for necroposting here, but in case anyone stumbles upon this and tries to use the module method described in #52 (comment) (notably lib.optionalAttrs caused a confusing "infinite recursion" error here)

These are working snippets (atm) that should get you going:

flake.nix that exports the module:

{
  outputs = inputs: {
    # A module that generates per-project TLS certificates.
    devshellModules.certificates = { config, lib, ... }: {
       options.certificates = {
         enable = lib.mkEnableOption "Great certificates option description";
         # TODO: add real config here
       };
       config = lib.mkIf config.certificiates.enable {
         # TODO: set some devshell config here, like add a new command
       };
    };
  };
}

flake.nix consumer side:

{
  inputs.flake-utils.url = "github:numtide/flake-utils";
  inputs.devshell.url = "github:numtide/devshell";
  inputs.devshell-modules.url = "github:numtide/devshell-modules"; # does not exist

  outputs = { self, flake-utils, devshell, devshell-modules, nixpkgs }:
    flake-utils.lib.simpleFlake {
      inherit self nixpkgs;
      name = "my-project";
      preOverlays = [ devshell.overlay ];
      shell = { pkgs }:
        pkgs.devshell.mkShell {
          imports  = [ devshell-modules.devshellModules.certificates ];
          # Now the certificates options are available
          certificates.enable = true;
        };
    };
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants