nix-env-selector
nix-env-selector copied to clipboard
[Feature] Pick up nix environment in tasks
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"
}
]
}
- Start vs code
- Open the project folder
- Select the environment
- Reload the environment
- Click on Terminal menu
- Click on Run Task ... option
- Select hello
- 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
Hi @bcardiff the extension doesn't affect tasks for now :(
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.
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}",
},
Is there any new workaround for this since the referenced issue has been closed?
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