nix-env-selector icon indicating copy to clipboard operation
nix-env-selector copied to clipboard

[Feature] Pick up nix environment in tasks

Open bcardiff opened this issue 3 years ago • 5 comments

Describe the bug

I attempted a minimalist example to run the hello program provided by nix from a task and the task is not found after loading / hitting the environment. I'm probably doing something wrong here, but if I load the nix environment before opening vscode from the same terminal things work. Thanks in advance.

To Reproduce Steps to reproduce the behavior:

# file: default.nix
{ pkgs ? import <nixpkgs> {}}:

pkgs.mkShell {
  nativeBuildInputs = [ pkgs.hello ];
}
// file: .vscode/tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "hello",
            "type": "shell",
            "command": "hello"
        }
    ]
}
  1. Start vs code
  2. Open the project folder
  3. Select the environment
  4. Reload the environment
  5. Click on Terminal menu
  6. Click on Run Task ... option
  7. Select hello
  8. Select continue without scanning task output

The output in the terminal shows that it can't find hello

> Executing task: hello <

zsh:1: command not found: hello
The terminal process "/bin/zsh '-c', 'hello'" failed to launch (exit code: 127).

Terminal will be reused by tasks, press any key to close it.

Expected behavior

The following is the expected output, but I can only get it if vscode is started from a terminal with the nix environment loaded already. Which is precisely what I am looking to not do with this extension.

> Executing task: hello <

Hello, world!

Terminal will be reused by tasks, press any key to close it.

Environment:

  • OS: macOS 10.15.7 Catalina
  • Version: 1.54.3 (Universal)
  • Commit: 2b9aebd5354a3629c3aba0a5f5df49f43d6689f8
  • Electron: 11.3.0
  • Chrome: 87.0.4280.141
  • Node.js: 12.18.3
  • V8: 8.7.220.31-electron.0
  • OS: Darwin x64 19.6.0

bcardiff avatar Mar 27 '21 03:03 bcardiff

Hi @bcardiff the extension doesn't affect tasks for now :(

arrterian avatar Apr 22 '21 15:04 arrterian

What might be an entry point to solve this is the configuration option terminal.integrated.automationShell.linux. But nix-shell is not a POSIX compliant shell i.e. it does not handle -c well. Furthermore is it not possible to specify additional arguments to vscode to handle this. Obviously one can resort to a wrapper, that filters the -c switch and then set this wrapper as the automation shell.

In the meanwhile, the following tasks.json snippet works without this extension. CAUTION: This snippets assumes, that the nix expression file is called either shell.nix or default.nix:

        {
            "label": "make",
            "type": "shell",
            "linux": {
                "options": {
                    "shell": {
                        "executable": "/run/current-system/sw/bin/nix-shell",
                        "args": [
                            "--run",
                        ],
                    },
                },
            },
            "command": "make",
        },

The VSCode Team seems to focus on terminal profiles. Once these are referencable within tasks, a corresponding task template could be provided by this extension.

leiflm avatar Jun 09 '21 12:06 leiflm

This is a huge pain esp. when dealing with non-type: "shell" tasks. Eg for vscode extension development, the main launch command looks like:

    {
      "name": "Run Extension",
      "type": "extensionHost",
      "request": "launch",
      "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
      "outFiles": ["${workspaceFolder}/out/**/*.js"],
      "preLaunchTask": "${defaultBuildTask}",
    },

samuela avatar Dec 01 '21 00:12 samuela

Is there any new workaround for this since the referenced issue has been closed?

utybo avatar Dec 10 '22 22:12 utybo

Here's an almost transparent workaround:

In .vscode/settings.json:

{
  "terminal.integrated.automationProfile.linux": {
    "path": "${workspaceRoot}/.vscode/nix-shell-or-bash.sh",
    "env": {
      "PROJ_DIR": "${workspaceRoot}"
    }
  }
}

Then, in .vscode/nix-shell-or-bash.sh (don't forget to chmod +x the file!)

#!/bin/sh
echo $PROJ_DIR
shift # ignore the initial -c added by VS Code

# The condition may be wrong because I'm not sure if Nix (!= NixOS) users have this file
if [ -e /run/current-system/sw/bin/nix-shell ]; then
    # A nix-shell is a available
    if [ -e "$PROJ_DIR/.envrc" ]; then
        # Use direnv (usually faster than nix-shell)
        direnv exec $PROJ_DIR $@
    else # TODO you could add an elif for a flake.nix file and launch nix develop instead
        # Use nix-shell
        nix-shell --run "$@"
    fi
else
    # For people not using NixOS
    bash -c "$@"
fi

utybo avatar Dec 10 '22 22:12 utybo