Auto-update scripts from file (helper-script)

Share your scripts and packages with other Mudlet users.
Post Reply
chrio
Posts: 73
Joined: Mon Aug 22, 2016 11:34 am

Auto-update scripts from file (helper-script)

Post by chrio »

I made a small script that lets you auto-update your mudlet scripts from disk when the file content changes.
It's pretty straightforward, but keep in mind that it will not care if you have multiple scripts with the same name, so keep the script names unique if you decide to use this.

Also, a general disclaimer: This script will not ask any questions, so it will gladly overwrite any changes you made in the local editor if it detects that the corresponding file was updated.

To use it, add the script and update the scriptwatcher.scripts table to fit your needs.

Adjust scriptwatcher.infolevel to 0-2, the default (1) will show you what scripts are being loaded, 2 will probably show you show you more than you want, but is good to get an idea of how it works. Errors will always be shown, even at 0.

Sample output:
Updating script [scriptwatcher] from file
No script with name [some test] found
Here is the code, let me know if you discover any problems with it (besides the unique name requirement).
Code: [show] | [select all] lua
--[[
scriptwatcher.lua

Update scripts in mudlet when they change on disk

scriptwatcher.infolevel
    0=errors only
    1=info
    2=debug

scriptwatcher.addNewScripts
    Set to true to have the scriptwatcher create scripts from file if they do not exist yet.
    Can be useful when starting a new profile (or annoying if you make a typo in the scripts table)
]]

scriptwatcher = scriptwatcher or {}
scriptwatcher.version = '0.3.0'
scriptwatcher.infolevel = 1
scriptwatcher.addNewScripts = false

-- Make sure to only set unique script names
-- we do not watch for instance if we have multiple script with same name
scriptwatcher.scripts = scriptwatcher.scripts or {
    scriptwatcher = 'C:/repos/MudletScripts/scriptwatcher.lua',
}


scriptwatcher.onchange = function()
    if scriptwatcher.infolevel >= 2 then
        print("Scriptwatcher detected a file change")
    end
    for script, path in pairs(scriptwatcher.scripts) do
        local code = getScript(script)
        if code == -1 and scriptwatcher.addNewScripts ~= true then
            print(string.format('No script with name [%s] found', script))
        else
            if code == -1 and scriptwatcher.addNewScripts == true then
                print(string.format('Adding new script with name [%s]', script))
                permScript(script, '', '-- script stub, added from scriptwatcher')
                enableScript(script)
            end
            filecontent = scriptwatcher.read(path)
            if filecontent and filecontent ~= "" then
                if filecontent == code then
                    if scriptwatcher.infolevel >= 2 then
                        print(string.format('Skipping unchanged script [%s]', script))
                    end
                else
                    if pcall(setScript, script, filecontent) then
                        if scriptwatcher.infolevel >= 1 then
                            print(string.format('Updating script [%s]', script))
                        end
                    else
                        print(string.format('Failed updating script [%s]! '..
                        'Check code for errors and try again', script))
                    end
                end
            else
                print(string.format('Unexpected content in [%s], keeping current script [%s] as-is!', path, script))
            end
        end
    end
end

scriptwatcher.read = function(path)
    local file = io.open(path, "r") -- r read mode
    if not file then
        print(string.format('Could not open file [%s]', path))
        return false
    end
    local filecontent = nil
    filecontent = file:read("*all")
    file:close()
    return filecontent
end

scriptwatcher.scriptChangeHandler = function(_, path)
    -- Delay updates for 1 second to give time for mudliple updates
    if scriptwatcher.timer then killTimer(scriptwatcher.timer) end
    scriptwatcher.timer = tempTimer(0.2, scriptwatcher.onchange)
end

for _, value in pairs(scriptwatcher.scripts) do
    removeFileWatch(value)
    addFileWatch(value)
end

scriptwatcher.events = scriptwatcher.events or {
    registerAnonymousEventHandler("sysPathChanged",
                                  "scriptwatcher.scriptChangeHandler")
}
if scriptwatcher.infolevel >= 2 then
    print(string.format('Loaded %s v%s', 'scriptwatcher', scriptwatcher.version))
end

if scriptwatcher.addNewScripts then scriptwatcher.scriptChangeHandler() end
Last edited by chrio on Wed Aug 04, 2021 10:31 am, edited 1 time in total.

chrio
Posts: 73
Joined: Mon Aug 22, 2016 11:34 am

Re: Auto-update scripts from file (helper-script)

Post by chrio »

I noticed that if you have a syntax error in the script file, then setScript() can not update the code. When that happens you either have to debug your file and save again, or do the old copy-paste to get better indications on where your script syntax fails.

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Auto-update scripts from file (helper-script)

Post by Vadi »

'luacheck' is a nice package that can help with this, both Sublime Text and Visual Studio Code have extensions for it.

chrio
Posts: 73
Joined: Mon Aug 22, 2016 11:34 am

Re: Auto-update scripts from file (helper-script)

Post by chrio »

I updated the script to give a warning if it tries to update a file that causes an error.
Failed updating script [somescript]! Check code for errors and try again
I added the script to a github repo, so further updates can be found on https://github.com/chrio/MudletScripts

Post Reply