mudlet/CI/update-autocompletion.lua
missionz3r0 b4d625e73d
fix: Lua local variable declaration leaks into global (#7853)
It'll be easier to review this commit by commit instead of as a whole.

It'd also be preferable to squash merge. My commit naming conventions
changed as I went.


### Brief overview of PR changes/additions
A number of functions, methods, and one file on the lua side of things
leaked local variable declarations into the global namespace. This cures
the current leaks.

### Motivation for adding to Mudlet
Leaking local variables into global space can have unforeseen side
affects. If two functions leak the same variable name, calling one might
affect a call to the other. `Geyser.remove` specifically made me wince.

I did not see any cases where this was actively an issue, but thought it
best to remove any chance of it happening.

### Other info (issues closed, discussion etc)

#### Thoughts on future improvements
I'd like to go through to remove *all* global declarations, including at
the file level. Instead, exposing anything global in `LuaGlobal`. I'll
put the gist of why here, but I can make a proper issue if there is
support for it.

Because:
* It'd make any further mistakes like this far more visible
* diagnostics tools will only point at actual issues rather than every
global object.
* Example: here is VS Code complaining about `db` being global, when we
obviously want it to be global. There are thousands of warnings like
this hiding the actual leaks.

![image](https://github.com/user-attachments/assets/5d72d8d6-e768-4314-b219-dc41e1102efd)

* and increase code readability.
* Mudlet devs would need to require modules on this side of things in
order to use them.
* note: this will only affect how Mudlet devs use the functions. Because
`LuaGlobal` will be loaded in for users(which dumps module contents into
the global space), this change should only affect our side of things.
    * Example: calls to `replace` would become `GUIUtils.replace`

---------

Co-authored-by: Zooka <136661366+ZookaOnGit@users.noreply.github.com>
2025-05-25 14:15:09 +02:00

69 lines
1.7 KiB
Lua

local http_request = require "http.request"
local lunajson = require "lunajson"
local function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
local function magiclines(s)
if s:sub(-1)~="\n" then s=s.."\n" end
return s:gmatch("(.-)\n")
end
local function scrapeLuaFunctions(htmlbody)
local funcs = {}
local funcsHash = {}
local count = 0
local state = 0
local line = nil
local match = nil
local name, usage, definition
for line in magiclines(htmlbody) do
if state == 0 then
--print("testing match on " .. line)
name = string.match(line, '<h2><span class="mw%-headline" id="(.-)">.-</span></h2>')
if name then
state = 1
--print("Name: " .. name)
end
elseif state == 1 then
usage = string.match(line, '<dl><dt>(.-)</dt>')
if usage then
state = 0
--print("Usage: " .. usage)
local func = {}
func.name = trim(name)
func.usage = trim(usage)
table.insert(funcs, func)
end
end
end
funcsHash = {}
local count = 0
for i, v in ipairs(funcs) do
count = count + 1
--print(v.name .. " - " .. v.usage)
if not string.match(v.name, "[%:%.]") then
funcsHash[v.name] = v.usage
end
end
local jsonText = lunajson.encode(funcsHash)
print(count .. " functions in the API.")
return jsonText
end
local headers, stream = assert(http_request.new_from_uri("https://wiki.mudlet.org/w/Manual:Lua_Functions"):go())
local body = assert(stream:get_body_as_string())
if headers:get ":status" ~= "200" then
error(body)
end
local data = scrapeLuaFunctions(body)
local f = io.open(arg[1], "w")
io.output(f)
io.write(data)
io.close(f)