Assign a value to VSCode launch.json depending on env value with Makefile

eye-catch Other techs

I wrote the following post before. But this requires manual steps. I wanted to automate it, so I needed to change the host in launch.json file and add debugging code automatically.

The host IP address depends on the developer’s environment and it’s used for automatic deployment and other things. I don’t want to change multiple places for the same info.

The goal is to be able to prepare remote debug preparation with single command execution.

Sponsored links

Create .env file

I created an env file first.

SERVER_HOST=192.168.123.1
Sponsored links

Update launch.json file

The launch.json file looks like this. I placed this file to templates/launch.json but not under .vscode directory to prevent an accidental commit.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "PLACEHOLDER_FOR_SOMETHING",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src",
                    "remoteRoot": "/dev/src"
                }
            ],
            "justMyCode": true
        }
    ]
}

I define Makefile like this below.

ifneq ("$(wildcard .env)","")
    include .env
    export
endif

set-ip:
    @cp ./templates/launch.json .vscode/launch.json
    @sed -i "s/PLACEHOLDER_FOR_SOMETHING/$${SERVER_HOST}/g" .vscode/launch.json

sed command can replace text in the following way.

sed -i "s/OLD_TEXT/NEW_TEXT/g" file_path

Once make set-ip command is executed, the json file will be updated.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Remote Attach",
            "type": "python",
            "request": "attach",
            "connect": {
                "host": "192.168.123.1",
                "port": 5678
            },
            "pathMappings": [
                {
                    "localRoot": "${workspaceFolder}/src",
                    "remoteRoot": "/dev/src"
                }
            ],
            "justMyCode": true
        }
    ]
}

Append python remote debugging code automatically

It’s cumbersome to add debugging code whenever I need it. So, I automated it with Makefile. It adds debugging code and then transfers the file to the server. The $${SERVER_HOST} will be replaced with its environment value.

deploy-debugcode:
    @cp ./src/something.py /tmp
    @echo "\n\n\
import debugpy\n\
debugpy.listen((\"$${SERVER_HOST}\", 5678))\n\
debugpy.wait_for_client()" >> /tmp/something.py
    @scp -r /tmp/something.py $${LOGIN_USER}@$${SERVER_HOST}:/dev/src

The original file is copied to a temporary folder in order to prevent an accidental commit with the debugging code.

If you need to add the code into an arbitrary place, you need to do it in a different way.
# PLACE_HOLDER is a placeholder to replace the debugging code. So you need to add it where you want to add the debugging code. Then, sed command replaces it.

deploy-debugcode:
    @cp ./src/something.py /tmp
    @DEBUG_CODE="\
import debugpy\n\
debugpy.listen((\"$${HDH_HOST}\", 5678))\n\
debugpy.wait_for_client()\n"\
    && sed -i "s/# PLACE_HOLDER/$${DEBUG_CODE}/g" ./tmp/something.py
    @scp -r /tmp/something.py $${LOGIN_USER}@$${SERVER_HOST}:/dev/src

This example is for Python language. if the placeholder is added to a function or class, the code above doesn’t work well due to the lack of indent. You must be careful with it. If it is added to the top of the file or somewhere else without any indent, it works well.

The number of lines for something.py is different between localhost and server because debugging code is added to a temporary file. Therefore, the debugger shows a different line from the actual execution line. You need to choose an unimportant file.

Another way is to add the code to __init__.py because the file is normally not necessary to debug. But I haven’t tried it yet if it works.

Execute both commands at once

To set everything in one command, the two commands above need to be executed by one command.

prepare-debug: set-ip deploy-debugcode

The debug preparation will be done by executing make prepare-debug.

The development will be easier with this automation.

Comments

Copied title and URL