You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-- @license MIT, see https://raw.githubusercontent.com/demonnic/MDK/main/src/scripts/LICENSE.lua
10
+
localrevisionator= {
11
+
name="Revisionator",
12
+
patches= {},
13
+
}
14
+
revisionator.__index=revisionator
15
+
localdataDir=getMudletHomeDir() .."/revisionator"
16
+
revisionator.dataDir=dataDir
17
+
ifnotio.exists(dataDir) then
18
+
localok,err=lfs.mkdir(dataDir)
19
+
ifnotokthen
20
+
printDebug(f"Error creating the directory for storing applied revisions: {err}", true)
21
+
end
22
+
end
23
+
24
+
--- Creates a new revisionator
25
+
-- @tparam table options the options to create the revisionator with.
26
+
-- <table class="tg">
27
+
-- <thead>
28
+
-- <tr>
29
+
-- <th>option name</th>
30
+
-- <th>description</th>
31
+
-- <th>default</th>
32
+
-- </tr>
33
+
-- </thead>
34
+
-- <tbody>
35
+
-- <tr>
36
+
-- <td class="tg-1">name</td>
37
+
-- <td class="tg-1">The name of the revisionator. This is absolutely required, as the name is used for tracking the currently applied patch level</td>
38
+
-- <td class="tg-1">raises an error if not provided</td>
39
+
-- </tr>
40
+
-- <tr>
41
+
-- <td class="tg-2">patches</td>
42
+
-- <td class="tg-2">A table of patch functions. It is traversed using ipairs, so must be in the form of {function1, function2, function3} etc. If you do not provide it, you can add the patches by calling :addPatch for each patch in order.</td>
43
+
-- <td class="tg-2">{}</td>
44
+
-- </tr>
45
+
--</tbody>
46
+
--</table>
47
+
functionrevisionator:new(options)
48
+
options=optionsor {}
49
+
localoptionsType=type(options)
50
+
ifoptionsType~="table" then
51
+
printError(f"revisionator:new bad argument #1 type, options as table expected, got {optionsType}", true, true)
52
+
end
53
+
ifnotoptions.namethen
54
+
printError("revisionator:new(options) options must include a 'name' key as this is used as part of tracking the applied patch level.", true, true)
55
+
end
56
+
localme=table.deepcopy(options)
57
+
setmetatable(me, self)
58
+
returnme
59
+
end
60
+
61
+
--- Get the currently applied revision from file
62
+
--- @treturn[1] number the revision number currently applied, or 0 if it can't read a current version
63
+
--- @treturn[2] nil nil
64
+
--- @treturn[2] string error message
65
+
functionrevisionator:getAppliedPatch()
66
+
localfileName=f"{self.dataDir}/{self.name}.txt"
67
+
debugc(fileName)
68
+
localrevision=0
69
+
ifio.exists(fileName) then
70
+
localfile=io.open(fileName, "r")
71
+
localfileContents=file:read("*a")
72
+
file:close()
73
+
localrevNumber=tonumber(fileContents)
74
+
ifrevNumberthen
75
+
revision=revNumber
76
+
else
77
+
returnnil, f"Error while attempting to read current patch version from file: {fileName}\nThe contents of the file are {fileContents} and it was unable to be converted to a revision number"
78
+
end
79
+
end
80
+
returnrevision
81
+
end
82
+
83
+
--- go through all the patches in order and apply any which are still necessary
84
+
--- @treturn boolean true if it successfully applied patches, false if it was already at the latest patch level
85
+
--- @error error message
86
+
functionrevisionator:migrate()
87
+
localapplied,err=self:getAppliedPatch()
88
+
ifnotappliedthen
89
+
printError(err, true, true)
90
+
end
91
+
localpatches=self.patches
92
+
ifapplied>=#patchesthen
93
+
returnfalse
94
+
end
95
+
forrevision, patchinipairs(patches) do
96
+
ifapplied<revisionthen
97
+
localok, err=pcall(patch)
98
+
ifnotokthen
99
+
self:setAppliedPatch(revision-1)
100
+
returnnil, f"Error while running patch #{revision}: {err}"
101
+
end
102
+
end
103
+
end
104
+
self:setAppliedPatch(#patches)
105
+
returntrue
106
+
end
107
+
108
+
--- add a patch to the table of patches
109
+
--- @tparam function func the function to run as the patch
110
+
--- @number[opt] position which patch to insert it as? If not supplied, inserts it as the last patch. Which is usually what you want.
111
+
functionrevisionator:addPatch(func, position)
112
+
ifpositionthen
113
+
table.insert(self.patches, position, func)
114
+
else
115
+
table.insert(self.patches, func)
116
+
end
117
+
end
118
+
119
+
--- Remove a patch from the table of patches
120
+
--- this is primarily used for testing
121
+
--- @local
122
+
--- @number[opt] patchNumber the patch number to remove. Will remove the last item if not provided.
123
+
functionrevisionator:removePatch(patchNumber)
124
+
table.remove(self.patches, patchNumber)
125
+
end
126
+
127
+
--- set the currently applied patch number
128
+
-- only directly called for testing
129
+
--- @local
130
+
--- @number patchNumber the patch number to set as the currently applied patch
-[Mudlet][mudlet-url] MUD Client application must obviously be installed on your operating system (Windows, MacOS, and Linux)
135
-
-[MDK](https://github.com/demonnic/MDK) provides EMCO and SUG support. The required code is already included in the PRS release package, requiring no additional download/install by the user.
136
+
-[MDK](https://github.com/demonnic/MDK) provides EMCO, Revisionator, and SUG support. The required code is already included in the PRS release package, requiring no additional download/install by the user.
0 commit comments