cachix / devenv

Fast, Declarative, Reproducible, and Composable Developer Environments
https://devenv.sh
Apache License 2.0
3.56k stars 259 forks source link

Is there a way to start devenv-up of something other than the default shell? #1178

Open ElrohirGT opened 2 weeks ago

ElrohirGT commented 2 weeks ago

Hi! For context I'm using devenv with flakes, here's an MRE of my situation:

{
  description = "Basic MRE";

  inputs = {
    nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling";
    systems.url = "github:nix-systems/default";
    devenv.url = "github:cachix/devenv";
    devenv.inputs.nixpkgs.follows = "nixpkgs";
  };

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

  outputs = {
    self,
    nixpkgs,
    devenv,
    systems,
    ...
  } @ inputs: let
    forEachSystem = nixpkgs.lib.genAttrs (import systems);
    postgresHost = "127.0.0.1";
    postgresPort = 5566;
  in {
    packages = forEachSystem (system: {
      devenv-up = self.devShells.${system}.default.config.procfileScript;
      devenv-up-ci = self.devShells.${system}.ci.config.procfileScript;
    });

    devShells =
      forEachSystem
      (system: let
        pkgs = import nixpkgs {inherit system;};
        dbInitFile = "CREATE DATABASE db_test;";
      in {
        ci = devenv.lib.mkShell {
          inherit inputs pkgs;
          modules = [
            {
              packages = with pkgs; [
                oxlint
              ];

              languages.javascript = {
                enable = true;
                yarn.enable = true;
              };

              process = {
                process-compose = pkgs.lib.mkOptionDefault {
                  tui = "false";
                };
              };

              processes = {
                # Start the backend...
                backendApi = {
                  exec = "tail -f /dev/null";
                  process-compose = {
                    depends_on = {
                      postgres = {
                        condition = "process_started";
                      };
                    };
                  };
                };
              };

              services.postgres = {
                enable = true;
                listen_addresses = postgresHost;
                port = postgresPort;
                initialScript = dbInitFile;
              };
            }
          ];
        };

        default = devenv.lib.mkShell {
          inherit inputs pkgs;
          modules = [
            {
              packages = with pkgs; [
                dprint # Javascript formatter
                oxlint # Javascript linter
                act # run github actions locally
              ];

              languages.javascript = {
                enable = true;
                yarn = {
                  enable = true;
                };
              };

              services.postgres = {
                enable = true;
                listen_addresses = postgresHost;
                port = postgresPort;
                initialScript = dbInitFile;
              };
            }
          ];
        };
      });
  };
}

How would I go about starting the services defined in the ci shell? I tried running:

nix develop --impure .#ci --command bash -c "devenv up"

But this still runs only the postgres service thats defined in the default shell.

I also tried running:

nix run .#devenv-up-ci

But this fails with:

error:
       … while evaluating the attribute 'devShells.x86_64-linux.ci.config.procfileScript'

         at /nix/store/2r2766i4xifvn5s2wwysw6k9gz3d6c3i-source/flake.nix:38:9:

           37|       in {
           38|         ci = devenv.lib.mkShell {
             |         ^
           39|           inherit inputs pkgs;

       … in the left operand of the update (//) operator

         at /nix/store/zslv4c6fawyd1bj84a2i4x14gblz3h1w-source/flake.nix:165:24:

          164|           in
          165|           config.shell // {
             |                        ^
          166|             ci = config.ciDerivation;

       (stack trace truncated; use '--show-trace' to show the full trace)

       error: Failed assertions:
       - devenv was not able to determine the current directory.

         See https://devenv.sh/guides/using-with-flakes/ how to use it with flakes.
sandydoo commented 2 weeks ago

Duplicate of #1172. The correct name for the package would be ci-devenv-up, but the devenv up script is currently broken for multiple shells. See https://github.com/cachix/devenv/issues/1172#issuecomment-2082475080.

domenkozar commented 2 weeks ago

What's the motivation to have two shells?

ElrohirGT commented 2 weeks ago

Duplicate of #1172. The correct name for the package would be ci-devenv-up, but the devenv up script is currently broken for multiple shells. See #1172 (comment).

Ohh ok, got it. Thank you!

What's the motivation to have two shells?

My main motivation is trying to run CI tests without degrading the dev experience. For example I found that the TUI of process-compose breaks my CI integration tests workflow because I try to run it in a background process so I would like for my CI environment to run without a TUI but my local development environment to have a TUI.

Since this changes configuration in the process-compose property I thought about defining two shells, one for CI and one for development. They share a lot of configuration but I don't need many packages or processes for the CI environment relative to the dev environment.

By the way, when I tried setting tui = false as a boolean the process-compose command generated failed, I don't have my computer at the moment so I can't share more info but to fix it I had to make it a string instead. Could be great to add it to the docs!

sandydoo commented 1 week ago

when I tried setting tui = false as a boolean the process-compose command generated failed,

Will be fixed as part of https://github.com/cachix/devenv/pull/1161.