1

I have this profile settings.json:

{
    "terminal.integrated.profiles.osx": {
        "python-venv": {
            "path": "/opt/homebrew/bin/bash",
            "args": [
                "-l",
                "-c",
                "\"/path/to/my/enforce-venv-script.sh\""
            ],
            "icon": "terminal-bash"
        }
    }
}

And enforce-venv-script.sh:

#!/bin/bash

# Exit on errors
set -e

# Enforce the existence and usage of a Python venv
if [ ! -d ".venv" ]; then
    echo "This is a Python project, but no venv was found. Creating one..."
    python3 -m venv .venv > /dev/null
    echo "Activating venv..."
    source .venv/bin/activate

    # Hand off execution to a new login shell, or else the terminal
    # will simply quit. Don't forget to activate the venv within it!
    # What goes here???
fi

I've tried multiple variations of exec bash, with or without -l, -c and source ... commands, but nothing seems to work.

This is all to facilitate the automatic creation of virtual environments for any Python project that I create.

I use this VS Code profile for all new Python projects, and the idea then is to enforce the usage of a virtual environment within that project. So any time a terminal is opened, the script will run and the venv will be created and activated if not already there.

VS Code already activates venvs automatically when I open a terminal and one exists, so the last missing piece of the puzzle is to create one if there isn't one.

EDIT: In response to @Philippe's answer and comments below, here are some more attempts to get this working:

kenny@MACBOOK-PRO:~/Dev/Hobby_Programming/Python/test$ bash -l --rcfile ~/Library/Application\ Support/Code/User/profiles/73486c58/enforce-venv.sh
bash -l --rcfile ~/Library/Application\ Support/Code/User/profiles/73486c58/enforce-venv.sh
bash: --: invalid option
Usage:  bash [GNU long option] [option] ...
...more usage info removed for brevity
kenny@MACBOOK-PRO:~/Dev/Hobby_Programming/Python/test$ /opt/homebrew/bin/bash -l -rcfile /Users/kenny/Library/Application\ Support/Code/User/profiles/73486c58/en
force-venv.sh
bash: /Users/kenny/Library/Application: restricted: cannot specify `/' in command names
kenny@MACBOOK-PRO:~/Dev/Hobby_Programming/Python/test$ cd ~/Library/Application\ Support/Code/User/profiles/73486c58/
kenny@MACBOOK-PRO:~/Library/Application Support/Code/User/profiles/73486c58$ /opt/homebrew/bin/bash -l -rcfile enforce-venv.sh
bash: enforce-venv.sh: command not found
kenny@MACBOOK-PRO:~/Library/Application Support/Code/User/profiles/73486c58$ /opt/homebrew/bin/bash -l -rcfile ./enforce-venv.sh
bash: ./enforce-venv.sh: restricted: cannot specify `/' in command names

I have no freaking clue what the heck is different enough about our computers that this is happening to me, since it apparently works for Philippe, yet here I am.

4
  • 1
    script runs code in new process and source .venv/bin/activate activates venv only for this proces, but not for others. After ending script it goes back to original process which doesn't have active venv. Some "workaround" is to use .venv/bin/python instead of python to run your python scripts in your project - and they should run like with active venv. Commented Oct 1 at 19:42
  • @furas Yeah I know it's a matter of different processes being created all over the place that don't share environments, but I was hoping there's a way around that. Commented Oct 1 at 20:56
  • I updated my answer, by moving -l at the end of args. Commented Oct 3 at 22:13
  • @Philippe Thank you for continually trying to help me, but I really don't understand why/how you keep giving me instructions that work for you but not for me :-/ Moving the -l arg. to the end stops it from crashing at least, but it seems that's because the enforce-venv-script.sh doesn't run at all (no venv is created) for me. Perhaps if you have the time and patience to deal with a noob like me, we could share screens and I could watch you do this on my PC...? Commented Oct 4 at 3:07

2 Answers 2

1

I think it's impossible to do it with bash. Bash creates another environment, something like another one terminal and executes commands there. And source only activates virtual environment in this new environment.

Sign up to request clarification or add additional context in comments.

1 Comment

Perhaps I've misunderstood you, but what you're saying sounds like what I want, and it doesn't work that way. Anyway I think you're right in saying that it's just simply not possible :-(
1

You can use --rcfile :
.vscode/settings.json

{
    "terminal.integrated.profiles.osx": {
        "python-venv": {
            "path": "/opt/homebrew/bin/bash",
            "args": [
                "--rcfile",
                "./enforce-venv-script.sh",
                "-l"
            ],
            "icon": "terminal-bash"
        }
    }
}

And enforce-venv-script.sh:

#!/bin/bash

# Exit on errors
set -ex

# Enforce the existence and usage of a Python venv
if [ ! -d ".venv" ]; then
    echo "This is a Python project, but no venv was found. Creating one..."
    python3 -m venv .venv > /dev/null

    # Hand off execution to a new login shell, or else the terminal
    # will simply quit. Don't forget to activate the venv within it!
    # What goes here???
fi
echo "Activating venv..."
source .venv/bin/activate

I updated enforce-venv-script.sh with set -ex

Test following commands in a Terminal and post output:


cd your-vscode-project-root-directory
/opt/homebrew/bin/bash --rcfile /path/to/enforce-venv.sh -l

8 Comments

Did you actually try this? I did, and it threw this at me: The terminal process "/opt/homebrew/bin/bash '-l', '--rcfile', '"/path/to/enforce-venv.sh"'" failed to launch (exit code: 2).
Yes I tested. Try to run the command in Terminal. I see double quotes around your script path, they should not be there.
It spits out bash: --: invalid option followed by the help docs if run in the terminal, and still crashes if run through the profile setting. I'm guessing you're on Linux, right? This is probably another one of those nuances of macOS being Unix-based, but not fully equivalent to a Unix/Linux machine. And yes, I removed the extra quotes - made no difference.
I tested on macOS. Try this : /opt/homebrew/bin/bash -l —rcfile /path/to/enforce-venv.sh
That wouldn't source .bashrc though. Perhaps something like set -a; source .venv/bin/activate; exec bash would work
Or you can source.bashrc from .sh file
Edited the question to add some more context. But even if I can get it working in the terminal, I have a sneaking suspicion that it won't work from the profile settings (unless you tested that too @Philippe).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.