I've got a workspace in VS Code and want a pre-configured environment when working on it. For this purpose, I've created a script, shown below, to be sourced before launching VS Code.
#!/bin/bash
if [ -n "${SCRIPT_HELPERS_LOADED}" ]; then
logDebug "Script helpers already loaded!"
return 0
fi
# Some functions and variables...
for func in $(declare -F | awk '{print $3}'); do
if [[ "${func}" != _* ]]; then
logDebug "Exporting function: '${func?}'"
export -f "${func?}"
fi
done
export SCRIPT_HELPERS_LOADED=1
logInfo "Environment set up."
This is how I source this script.
projectFolder$ source scripts/script-helpers.sh
[L70][INFO] Environment set up.
projectFolder$ logInfo "Just a message."
[L2][INFO] Just a message.
projectFolder$ code .
As you can see, I'm able to use one of the exported functions in the same terminal. When VS Code is launched, the exported functions are not accessible through its integrated terminal. Somehow, the exported variables are accessible.
projectFolder$ echo $SCRIPT_HELPERS_LOADED
1
projectFolder$ logInfo "Another message"
logInfo: command not found
How can I solve this problem?
tasks.json
I might have found a solution thanks to a colleague. Appending the below to the .vscode/settings.json
does exactly what I ask without modifying the existing files.
{
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash",
"args": [
"-c",
"source ${workspaceFolder}/scripts/script-helpers.sh; bash"
]
},
},
"terminal.integrated.defaultProfile.linux": "bash",
}
Somehow, the above approach corrupts shell
typed tasks. For instance, the below task doesn't generate any output and it never ends. .vscode/tasks.json
{
"version": "2.0.0",
"tasks":
[
{
"label": "Do Something",
"type": "shell",
"group": "build",
"command": [
"echo 'Doing something...';"
]
}
]
}
Using bash -c "source ${workspaceFolder}/scripts/script-helpers.sh; bash"
isn't suitable for tasks as VS Code spawns any task as below
/usr/bin/bash <arguments from .settings.json> '-c' <task body>
. Hence, if we use -c
in argument list, there will be multiple -c
arguments. Instead of -c
, we need to use --init-file
which by default equals to ${HOME}/.bashrc
.
Another problem is that providing your custom script as --init-file
prevents sourcing the ${HOME}/.bashrc
and you will not get your default terminal environment, e.g. custom prompt, custom commands, aliases, etc.
Therefore, we need to create a wrapper script that sources both the custom environment script and the default environment script. Then, providing it as the --init-file
will solve the problem. In my case, the wrapper script placed at .vscode/environment.sh
looks as below.
#!/bin/bash
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
TOPDIR="$(realpath ${SCRIPT_DIR}/..)"
source "${HOME}/.bashrc"
if [ $? -ne 0 ]; then
>&2 echo "Couldn't source '.bashrc'!";
return 1;
fi
source "${TOPDIR}/scripts/script-helpers.sh"
if [ $? -ne 0 ]; then
>&2 echo "Couldn't source 'script-helpers.sh'!";
return 1;
fi
And the .vscode/settings.json
will include the below.
{
"terminal.integrated.profiles.linux": {
"bash": {
"path": "bash",
"icon": "terminal-bash",
"args": [
"--init-file",
"${workspaceFolder}/.vscode/environment.sh"
]
},
},
"terminal.integrated.defaultProfile.linux": "bash",
}