cachix / devenv

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

`devenv up` no longer works with a flake-based devenv that is not in the current directory #1357

Open reivilibre opened 1 month ago

reivilibre commented 1 month ago

Describe the bug In earlier versions (e.g. v0.6.7 I believe), devenv up would be happy to launch the processes no matter whether you were in the directory with the flake.nix or not.

Since then (currently v1.0.8) this is no longer the case

To reproduce

/pgrepo/flake.nix:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/master";
    systems.url = "github:nix-systems/default";
    devenv.url = "github:cachix/devenv/v1.0.8";
  };

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

      devShells = forEachSystem (system:
        let
          pkgs = import nixpkgs {
            inherit system;
          };
        in {
          default = devenv.lib.mkShell {
            inherit inputs pkgs;
            modules = [
              {
                services.postgres.enable = true;
                services.mailpit.enable = true;
              }
            ];
          };
        });
    };
}
/test$ nix develop --impure ../pgrepo
/test$ devenv up
path '/test' does not contain a 'flake.nix', searching up
error: could not find a flake.nix file
/test$ which devenv
/nix/store/q0z1yxhd4lsv7c12y0yyy3kz90kn6c32-devenv/bin/devenv
/test$ cat /nix/store/q0z1yxhd4lsv7c12y0yyy3kz90kn6c32-devenv/bin/devenv
#!/usr/bin/env bash

# we want subshells to fail the program
set -e

NIX_FLAGS="--show-trace --extra-experimental-features nix-command --extra-experimental-features flakes"

command=$1
if [[ ! -z $command ]]; then
  shift
fi

case $command in
  up)
    procfilescript=$(nix build '.#devenv-up' --no-link --print-out-paths --impure)
    if [ "$(cat $procfilescript|tail -n +2)" = "" ]; then
      echo "No 'processes' option defined: https://devenv.sh/processes/"
      exit 1
    else
      exec $procfilescript "$@"
    fi
    ;;
  version)
    echo "devenv: 1.0.7"
    ;;
  *)
    echo "https://devenv.sh (version 1.0.7): Fast, Declarative, Reproducible, and Composable Developer Environments"
    echo 
    echo "This is a flake integration wrapper that comes with a subset of functionality from the flakeless devenv CLI."
    echo
    echo "Usage: devenv command"
    echo
    echo "Commands:"
    echo
    echo "up              Starts processes in foreground. See http://devenv.sh/processes"
    echo "version         Display devenv version"
    echo
    exit 1
esac

I guess the problem is procfilescript=$(nix build '.#devenv-up' --no-link --print-out-paths --impure), due to . in nix build.

Since the flake is invoked with --impure anyway, I wonder if we could template the path in to this script directly when building the env, or otherwise feed it in as a env var (DEVENV_DIR or something sounds like it would be pretty sensible)?

Prior versions of devenv handled this without issue, but I think that was before a big refactoring or something so I have no idea if the old solution would apply. :)

Version

Related:

nickkadutskyi commented 1 month ago

I guess the problem is procfilescript=$(nix build '.#devenv-up' --no-link --print-out-paths --impure), due to . in nix build.

Yes the problem is because this scripts has the path hardcoded nix build '.#devenv-up' means nix build git+file:.#devenv-up which will only refer to a flake in the same directory and will include all the files tracked by git.

I have a similar issue with this script https://github.com/cachix/devenv/issues/1164 so I just run my custom script.

Here is my custom devenv-devShell.nix script that allows me to add a specific path to devenv up so I run it like this: devenv-custom up path:nix, or in your case it would be devenv-custom up path:../pgrepo or just devenv-custom up ../pgrepo depending on what files you want to include into the store.

{ config, pkgs }:
let
  lib = pkgs.lib;
  shellPrefix = shellName: if shellName == "default" then "" else "${shellName}-";
in
pkgs.writeScriptBin "devenv-custom" ''
  #!/usr/bin/env bash

  # we want subshells to fail the program
  set -e

  NIX_FLAGS="--show-trace --extra-experimental-features nix-command --extra-experimental-features flakes"

  command=$1
  if [[ ! -z $command ]]; then
    shift
  fi

  flakePath=$1
  if [[ $flakePath == "path:"* ]]; then
    shift
  else
    flakePath="."
  fi

  case $command in
    up)
      procfilescript=$(nix build $flakePath#'${shellPrefix (config._module.args.name or "default")}devenv-up' --no-link --print-out-paths --impure)
      if [ "$(cat $procfilescript|tail -n +2)" = "" ]; then
        echo "No 'processes' option defined: https://devenv.sh/processes/"
        exit 1
      else
        echo "Executing procfilescript: $procfilescript"
        exec $procfilescript "$@"
      fi
      ;;
    *)
      echo "This is a flake integration wrapper that comes with a subset of functionality from the flakeless devenv CLI."
      echo
      echo "Usage: devenv-custom command"
      echo
      echo "Commands:"
      echo
      echo "up              Starts processes in foreground. See http://devenv.sh/processes"
      echo
      exit 1
  esac
''
saucoide commented 4 weeks ago

running into the same thing here, for [reasons] i need to keep flakes outside of my projects, so i keep flakes for all my projects in something like~/flakes/my-project/flake.nix and from the project direnv activates it with use flake --impure ~/flakes/my-project

on 1.0.7 devenv up will complain saying the current dir is not part of a flake :/