moonrepo / moon

A build system and monorepo management tool for the web ecosystem, written in Rust.
https://moonrepo.dev/moon
MIT License
2.82k stars 154 forks source link

[feature] Support Nix #1498

Open rawkode opened 3 months ago

rawkode commented 3 months ago

Is your feature request related to a problem? Please describe.

Nix is the largest software registry in the world, it feels like this could open up a lot more languages quickly vs building out more proto features.

Describe the solution you'd like

Use nixpkgs for platform and language acqusition

Describe alternatives you've considered

I could have a top level Nix flake with all my software for all tasks and use the system platform, but I feel there's a lot of benefits to moon to integrate nix

Additional context

milesj commented 3 months ago

I've never used Nix personally and probably never will, but my understanding of Nix is that it's more like a shell? Do you have an example of how you could use Nix for running one-off tasks? And if that's the case, couldn't you just use it in the task command?

rawkode commented 3 months ago

It's not a shell. Here's an example Flake for one of my services.

You'd run "nix develop" and it would acquire the required tools and add them to your path.

rawkode commented 3 months ago

Maybe this comes back to my previous request for direnv, I'll link when not on mobile.

I'm happy to use shell: true, can I override the shell? I'd need to do some one liner magic to initialize my Nix env

milesj commented 3 months ago

Yah you can use your own shell: https://moonrepo.dev/docs/config/project#shell

This definitely feels like something that could be its own "language" integration once we get the new plugin system up and running.

rawkode commented 3 months ago

OK, I've given the shell approach a try but it would be really painful to implement this across my repo.

Shells are enumerated and only a few are supported and this would require me to configure every single task to run this way.

Here's a working task:

tasks:
  build:
    command: "nix develop --impure -c turso --help"
    options:
      shell: true
      unixShell: bash

and my supporting flake.nix

{
  inputs = {
    devenv.url = "github:cachix/devenv";
    devenv-root = {
      url = "file+file:///dev/null";
      flake = false;
    };
    mk-shell-bin.url = "github:rrbutani/nix-mk-shell-bin";
    nix2container.url = "github:nlewo/nix2container";
    nix2container.inputs.nixpkgs.follows = "nixpkgs";
    nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling";
  };

  nixConfig = {
    extra-trusted-public-keys = "devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw=";
    extra-substituters = "https://devenv.cachix.org";
  };

  outputs =
    inputs@{ flake-parts, devenv-root, ... }:
    flake-parts.lib.mkFlake { inherit inputs; } {
      imports = [ inputs.devenv.flakeModule ];

      systems = [
        "x86_64-linux"
        "i686-linux"
        "x86_64-darwin"
        "aarch64-linux"
        "aarch64-darwin"
      ];

      perSystem =
        {
          config,
          self',
          inputs',
          pkgs,
          system,
          ...
        }:
        {
          devenv.shells.default = {
            devenv.root =
              let
                devenvRootFileContent = builtins.readFile devenv-root.outPath;
              in
              pkgs.lib.mkIf (devenvRootFileContent != "") devenvRootFileContent;

            name = "web.rawkode.academy";

            imports = [ ];

            languages.typescript.enable = true;

            packages = with pkgs; [
              biome
              bun
              nodejs
              turso-cli
            ];

            enterShell = ''
              bun install
            '';

            scripts.dev.exec = ''
              bun x astro dev
            '';
          };
        };

      flake = { };
    };
}

I like the idea of a language plugin that uses my Nix environment, what's the timeline for that?

Is there any way to configure a global shell for all tasks, such as nix develop --impure?

Is there any workaround I'm not familiar with that could get me up and running a bit quicker?

milesj commented 3 months ago

I like the idea of a language plugin that uses my Nix environment, what's the timeline for that?

No timeline, but in progress.

Is there any way to configure a global shell for all tasks, such as nix develop --impure?

You can maybe use task inheritance:

# .moon/tasks.yml
tasks:
  build:
    command: "nix develop --impure"
    options:
      shell: true
      unixShell: bash

# project/moon.yml
tasks:
  build:
    args: "-c turso --help"

Is there any workaround I'm not familiar with that could get me up and running a bit quicker?

I don't know how Nix works so I can't really answer this. moon runs tasks as child processes, so Nix would need to be used based on those constraints.

rawkode commented 1 month ago

@milesj Is it possible for me to add a toolchain plugin to run nix develop instead of using proto?

milesj commented 1 month ago

@rawkode Not right now because the plugin system hasn't been built yet.