How to perform operations on VSCode macros? - visual-studio-code

My launch.json specifies a list of arguments for a given debug session (For airflow debugging in this case):
{
"version": "0.2.0",
"configurations": [
{
"name": "airflow_debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/airflow",
"preLaunchTask": "activate-python-venv",
"console": "integratedTerminal",
"env": {
"AIRFLOW_HOME": "${workspaceFolder}",
"AIRFLOW__CORE__LOAD_EXAMPLES": "False",
"AIRFLOW__CORE__DAGS_FOLDER": "${workspaceFolder}/dags",
"AIRFLOW__CORE__EXECUTOR": "SequentialExecutor",
"PYTHONPATH": "${workspaceFolder}/plugins:${workspaceFolder}/dags:${env:PYTHONPATH}"
},
"args": [
"dags",
"test",
"migrate_dtm",
"2022-11-24"
]
}
]
}
In order to be able to debug my dags, I must specify the dag name in the args, here it is migrate_dtm. A more sophisticated way, would be to deduce the name of the dag from the name of the file My file's name is migrate_dtm_dag.py.
The goal here is not to change the launch.json and manually specify the dag name within every different debug launch; but only set a nomenclature rule for the devs to follow.
Something like this would help
"args":[
...
"${file.split('/')[-1].split('_dag')'}", // First split to get only the file name without the path, second split to extract the dag name.
...
]
Is there a way to achieve something like this in a VSCode macro? Or to perform operations on macros at all?

you can use the extension Command Variable
{
"version": "0.2.0",
"configurations": [
{
"name": "airflow_debug",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/.venv/bin/airflow",
"preLaunchTask": "activate-python-venv",
"console": "integratedTerminal",
"env": {
"AIRFLOW_HOME": "${workspaceFolder}",
"AIRFLOW__CORE__LOAD_EXAMPLES": "False",
"AIRFLOW__CORE__DAGS_FOLDER": "${workspaceFolder}/dags",
"AIRFLOW__CORE__EXECUTOR": "SequentialExecutor",
"PYTHONPATH": "${workspaceFolder}/plugins:${workspaceFolder}/dags:${env:PYTHONPATH}"
},
"args": [
"dags",
"test",
"${input:getdag}",
"2022-11-24"
]
}
],
"inputs": [
{
"id": "getdag",
"type": "command",
"command": "extension.commandvariable.transform",
"args": {
"text": "${fileBasenameNoExtension}",
"find": "_dag"
}
}
]
}
The default replace is "", so it removed the text _dag.
With the command extension.commandvariable.dateTime you can create a date string for today.

Related

Nesting/joining a workspace input variable inside multi folder workspaceFolder variable?

Is there a way to nest an input variable inside other variables, particularly ${workspaceFolder}? As an example .code-workspace file:
{
"folders": [
{
"name": "Client",
"path": "path/to/client/code"
},
{
"name": "Server",
"path": "path/to/server/code"
},
{
"name": "Shared",
"path": "path/to/shared/code"
}
],
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${workspaceFolder}",
"program": "apphere"
}
],
"inputs": [
{
"id": "pickProject",
"type": "pickString",
"description": "Select a project:",
"options": [
"Client",
"Server"
]
}
]
}
}
All projects (Client and Server in this example) would share the same launch configurations, the only thing that would need to change is the cwd value. Unfortunately you cannot use ${workspaceFolder} directly in a multi folder workspace as you receive this error:
Variable ${workspaceFolder} can not be resolved in a multi folder workspace. Scope this variable using ':' and a workspace folder name.
What would be perfect is being able to do something like this:
"cwd": "${workspaceFolder:${input:pickProject}}"
Unfortunately this does not work. Is there another way to provide a dynamic scope for the workspaceFolder variable?
I did figure out one rather hacky way to handle this although it feels like there should be a better way: If you change the pickString input options to the folder paths and then change the debug cwd to "cwd": "${workspaceFolder:Shared}/../../../${input:pickProject}" you can arbitrarily pick one of the folders, traverse back out to the root workspace directory, and then append the ${input:pickProject} variable onto the end. In addition to the directory traversals, the debug choices you see will be "path/to/client/code" and "path/to/server/code" instead of the more clean "Client" and "Server". But at least it does seem to work, albeit not overly ideal.
With the extension Command Variable you have possible solutions
extension.commandvariable.file.fileAsKey
When you have a file open and current for Client or Server the F5 will select the correct cwd based on the path of the current file.
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${input:getCWD}",
"program": "apphere"
}
],
"inputs": [
{
"id": "getCWD",
"type": "command",
"command": "extension.commandvariable.file.fileAsKey",
"args": {
"/client/": "/path/to/client/code",
"/server/": "/path/to/server/code"
}
}
]
}
extension.commandvariable.pickStringRemember
If you want a pick list that shows Client and Server but returns the corresponding paths use:
"launch": {
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"cwd": "${input:pickPath}",
"program": "apphere"
}
],
"inputs": [
{
"id": "pickPath",
"type": "command",
"command": "extension.commandvariable.pickStringRemember",
"args": {
"description": "Select a project:",
"options": [
["Client", "/path/to/client/code"],
["Server", "/path/to/server/code"]
]
}
}
]
}

Prevent vscode-jest-tests from opening new terminal

I am using vscode-jest and the "debug" code lens to run individual tests. However, when running a test like this it spawns a new terminal every time. How can I prevent this by modifying the launch configuration in the launch.json file?
For reference, here is my launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"name": "vscode-jest-tests",
"request": "launch",
"args": [
"--runInBand"
],
"cwd": "${workspaceFolder}/data-utils/",
"console": "integratedTerminal",
"internalConsoleOptions": "neverOpen",
"disableOptimisticBPs": true,
"program": "${workspaceFolder}/data-utils/node_modules/jest/bin/jest"
}
]
}

Why cant I take user input in VS code?

How can I take a user-input in VS code?
Here's my launch.json file:
{
"version": "0.2.0",
"configurations": [
{
"name": "Python",
"type": "python",
"request": "launch",
"stopOnEntry": true,
"pythonPath": "${config:python.interpreterPath}",
"program": "${file}",
"debugOptions": [
"WaitOnAbnormalExit",
"WaitOnNormalExit",
"RedirectOutput"
],
"console": "integratedTerminal"
}
]}
What else i need to do?
set this.
{
"code-runner.runInTerminal": true
}
This question is almost certainly a dupe of this

Pass arguments to command in visual studio code

Is it possible to run a command in a variable and pass parameters? Given that this command requires input arguments.
Example:
// in launch.json
{
"program": "${command:somecommand(foo=${someargument})}"
}
Create an input in your launch.json which calls your command, there you can pass your argument. You can then reference the input in your attach/launch config.
// launch.json
{
"version": "0.2.0",
"inputs": [
{
"id": "commandInput",
"type": "command",
"command": "somecommand",
"args": {
"foo": "${someargument}"
}
}
],
"configurations": [
{
"name": "Launch",
"type": "node",
"request": "launch",
"program": "${input:commandInput}"
}
]
}

How to launch specific task from input variable in VS Code?

I'm trying to create a launch configuration where an environment variable is dynamically determined by a shell script. Even though a command variable can start a task via workbench.action.tasks.runTask, it doesn't seem to be possible to specify which task to run. Input variables seem to be a little more flexible in that regard, but I can't seem to get it to work. Here is what I got:
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"XXX": "${input:foo}"
},
"args": []
}
],
"inputs": [
{
"type": "command",
"id": "foo",
"command": "workbench.action.tasks.runTask",
"args": {
"args": "bar",
}
}
]
}
tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "bar",
"type": "shell",
"command": "find /dev -name 'myspecialdevice*' -maxdepth 1"
}
]
}
The issue is that the user is still queried for which task to run. I'm most insecure about the inputs.args section of the launch.json. I don't really know what the key value should be. Perhaps the implementation helps to figure this out?
This answer not really relates to make use of a vscode task, but your introducting sentence offers the motivation/what is intended to be solved.
I was faced to the same question and was wondering about vscode's input type:command. It offers a way to embed a (custom) vscode command -- which looks like a powerfull mechanism to embed a (custom) extension here. But I didn't found a builtin command that simply executes a shell script and returns it stdout. Thus an extension to capture the output of a shell command is imho required todo the trick.
E.g. https://marketplace.visualstudio.com/items?itemName=augustocdias.tasks-shell-input
provides a command shellCommand.execute doing exactly this.
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"XXX": "${input:foo}"
},
"args": []
}
],
"inputs": [
{
"id": "foo",
"type": "command",
"command": "shellCommand.execute",
"args": {
"command": "find /dev -name 'myspecialdevice*' -maxdepth 1",
"cwd": "${workspaceFolder}",
/* To prevent user from selecting output (if there is just
one line printed by command), un-comment next line */
//"useSingleResult": true
}
}
]
}
(Inspired by https://stackoverflow.com/a/58930746/1903441)
In your launch.json, try replacing
"args": {
"args": "bar",
}
with
"args": "bar"
It seems that in vscode, you cannot pass a return or even an environment variable from task.json to launch.json. But you can use a file as a intermediate.
For example, in task.json:
{
"version": "2.0.0",
"tasks": [
{
"label": "bar",
"type": "shell",
"command": "find /dev -name 'myspecialdevice*' -maxdepth 1 > ${workspaceFolder}/.vscode/temp"
}
]
}
In launch.json you set bar as preLaunchTask, and later access the file using inputs, like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch",
"type": "go",
"request": "launch",
"mode": "auto",
"program": "${workspaceFolder}/main.go",
"env": {
"XXX": "${input:foo}"
},
"args": [],
"preLaunchTask": "bar",
}
],
"inputs": [
{
"id": "foo",
"type": "command",
"command": "extension.commandvariable.file.content",
"args": {
"fileName": "${workspaceFolder}/.vscode/temp",
}
}
]
}
To get the comment working, just install this extension: https://marketplace.visualstudio.com/items?itemName=rioj7.command-variable