Ícone do site Luaverse

Lua: Como debugar projetos Lua no VSCode

Tudo bem pessoal?
Hoje uma dica rápida para resolver um problema um tanto chato quando programamos em lua no VSCode.

Debugar projetos usando o print é ok, mas não é muito produtivo nem muito eficiente e esse é o motivo da minha preferência em usar o debugger.

Problema

Quando utilizamos LuaRocks para instalar dependências no projeto, a localização padrão desses arquivos é a pasta lua_modules.

Ao iniciar o modo debug no VSCode, ele não consegue encontrar as dependências do projeto e mostra um erro com a seguinte mensagem:

Exception has occurred.
src/app.lua:1: module ‘milua’ not found:
no field package.preload[‘milua’]
no file ‘/usr/local/share/lua/5.4/milua.lua’
no file ‘/usr/local/share/lua/5.4/milua/init.lua’
no file ‘/usr/local/lib/lua/5.4/milua.lua’
no file ‘/usr/local/lib/lua/5.4/milua/init.lua’
no file ‘./milua.lua’
no file ‘./milua/init.lua’

Solução

Criar um arquivo com o seguinte código:

local function prepareLuaRocksPath()
    local cpath = ''
    local path = ''
    local luarocks_path = io.popen("luarocks path")

    if not luarocks_path then
        print("Could not get the luarocks path")
        os.exit()
    end

    for line in luarocks_path:lines() do
        if string.match(line, "LUA_CPATH") then
            cpath = string.gsub(line, "export LUA_CPATH%s*=%s*", "")
        elseif string.match(line, "LUA_PATH") then
            path = string.gsub(line, "export LUA_PATH%s*=%s*", "")
        end
    end

    package.path = package.path .. ';' .. path.gsub(path, "'", "")
    package.cpath = package.cpath .. ';' .. cpath.gsub(cpath, "'", "")
end

O objetivo desta função é fazer com que LUA_PATH e LUA_CPATH sejam adicionados respectivamente ao package.path e package.cpath de forma dinâmica, permitindo assim que o debugger encontre esses pacotes e inicialize corretamente.

Para facilitar, eu mantenho um arquivo chamado debug.lua na raiz do meu projeto e utilizo este arquivo como entrypoint do meu debugger.

Leia também: Lua: Como interagir com o Sistema Operacional?

O código inteiro do arquivo debug.lua fica assim:

local function prepareLuaRocksPath()
    local cpath = ''
    local path = ''
    local luarocks_path = io.popen("luarocks path")

    if not luarocks_path then
        print("Could not get the luarocks path")
        os.exit()
    end

    for line in luarocks_path:lines() do
        if string.match(line, "LUA_CPATH") then
            cpath = string.gsub(line, "export LUA_CPATH%s*=%s*", "")
        elseif string.match(line, "LUA_PATH") then
            path = string.gsub(line, "export LUA_PATH%s*=%s*", "")
        end
    end

    package.path = package.path .. ';' .. path.gsub(path, "'", "")
    package.cpath = package.cpath .. ';' .. cpath.gsub(cpath, "'", "")
end

prepareLuaRocksPath()
require "src.main" ()

Essa é a configuração do arquivo de debug do VSCode

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Debug",
            "type": "lua-local",
            "request": "launch",
            "program": {
                "lua": "lua",
                "file": "${workspaceFolder}/debug.lua"
            }
        }
    ]
}

Eu espero que este post tenha te ajudado.
Caso tenha qualquer dúvida, sinta-se à vontade para deixar um comentário abaixo!

Até a próxima!

Sair da versão mobile