Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ Shows all installed scripts.
Shows all available configurations.
- `<name>`: Shows the value of a specific configuration.
- `<name> <value>`: Updates the value of a specific configuration.
## refresh
Downloads the names of all programs and libraries of the official repository.
Refreshes autocomplete.
## help
Shows all available commands and their description.
- `<name>`: Shows the description of a command by name.
Expand Down
221 changes: 217 additions & 4 deletions scm.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ scm.config = {
["programSuffix"] = "-prog",
["librarySuffix"] = "-lib",
["infoFile"] = "files.txt", -- provides the structure of a git repo (paths to all files)
["apiGithubGetRepos"] = "https://api.github.com/orgs/mc-cc-scripts/repos?type=all&per_page=100&page=1",
-- Local Settings
["installScript"] = "1kKZ8zTS",
["rootDirectory"] = "",
Expand All @@ -24,7 +25,10 @@ scm.config = {
["printPrefix"] = "[scm] ",
["logDate"] = false,
["writeLogFile"] = false,
["logFilePath"] = "logs/scm-log.txt"
["logFilePath"] = "logs/scm-log.txt",
["repoScriptsFile"] = "scm-repo-scripts.txt", -- will be saved in configDirectory as well
["allowCLIPrefix"] = true,
["cliPrefix"] = false
}
----------------

Expand Down Expand Up @@ -130,6 +134,16 @@ $ config <name> <value>
Updates the configuration
]]
},
["refresh"] = {
func = function (args)
scm:refreshAutocomplete()
end,
description = [[
$ refresh
Downloads the names of all programs and libraries of the official repository.
Refreshes autocomplete.
]]
},
["help"] = {
---@param args table
func = function (args)
Expand All @@ -152,6 +166,142 @@ $ help <name>
}
}

function scm:refreshRepoScripts ()
self:log("Downloading program and library names from GitHub...")
local repoScripts = {}

local programs = {}
local libraries = {}

local request = http.get(self.config["apiGithubGetRepos"])
if request then
local response = request.readAll()
request.close()

local responseTable = textutils.unserializeJSON(response)

local programSuffix = self.config["programSuffix"]
local librarySuffix = self.config["librarySuffix"]

for i = 1, #responseTable, 1 do
local scriptName = responseTable[i]["name"]
if string.sub(scriptName, -string.len(programSuffix)) == programSuffix then
programs[
string.sub(scriptName, 0, string.len(scriptName)-string.len(programSuffix))
] = {}
elseif string.sub(scriptName, -string.len(librarySuffix)) == librarySuffix then
libraries[
string.sub(scriptName, 0, string.len(scriptName)-string.len(librarySuffix))
] = {}
end
end
scm:log("Done")
else
scm:log("Download failed")
end

self.commands["add"]["args"] = programs
self.commands["require"]["args"] = libraries

repoScripts["libraries"] = libraries
repoScripts["programs"] = programs

local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "w")
if file then
file.write(textutils.serializeJSON(repoScripts))
file.close()
end
end

function scm:loadRepoScripts ()
local file = fs.open(self.config["configDirectory"] .. self.config["repoScriptsFile"], "r")

if not file then
self:refreshRepoScripts()
else
local repoScripts = textutils.unserializeJSON(file.readAll()) or nil
if repoScripts then
self.commands["add"]["args"] = repoScripts["programs"]
self.commands["require"]["args"] = repoScripts["libraries"]
end

file.close()
end
end

function scm:prepareAutocomplete ()
-- prepare update and remove
scm:loadScripts()
local installedScripts = {}
for i = 1, #self.scripts, 1 do
installedScripts[self.scripts[i].name] = {}
end
installedScripts["all"] = {}

self.commands["update"]["args"] = installedScripts
self.commands["remove"]["args"] = installedScripts

-- prepare add and require
self:loadRepoScripts()

-- prepare config
local availableConfigs = {}

for k, _ in pairs(self.config) do
availableConfigs[k] = {}
end

self.commands["config"]["args"] = availableConfigs

-- prepare help
local availableCommands = {}

for k, _ in pairs(self.commands) do
availableCommands[k] = {}
end

self.commands["help"]["args"] = availableCommands
end

---@param shell table
---@param index integer
---@param argument string
---@param previous table
---@return table | nil
local function completionFunction (shell, index, argument, previous)
local commands = {}
for k, _ in pairs(scm.commands) do
commands[k] = scm.commands[k]["args"] or {}
end

local currArg = commands
for i = 2, #previous do
if currArg[previous[i]] then
currArg = currArg[previous[i]]
else
return nil
end
end

local results = {}
for word, _ in pairs(currArg) do
if word:sub(1, #argument) == argument then
results[#results+1] = word:sub(#argument + 1)
end
end
return results;
end

local function updateAutocomplete ()
shell.setCompletionFunction("scm", completionFunction)
end

function scm:refreshAutocomplete ()
scm:refreshRepoScripts()
scm:prepareAutocomplete()
updateAutocomplete()
end

---@param message string
function scm:log (message)
local datetime = ""
Expand Down Expand Up @@ -392,21 +542,30 @@ function scm:addScript (sourceObject, success)
if self.scripts[i].source[sourceObject.sourceName] then
self.scripts[i].source[sourceObject.sourceName] = sourceObject.source[sourceObject.sourceName]
self:saveScripts()

return true
end
end
end

if not scriptExists then
scm:log("Script added: " .. sourceObject.name)
table.insert(self.scripts, sourceObject)
table.insert(self.scripts, sourceObject)
else
scm:log("Script already exists.")
return false
end

self:saveScripts()

-- update for autocomplete
self.commands["update"]["args"] = self.commands["update"]["args"] or {}
self.commands["remove"]["args"] = self.commands["remove"]["args"] or {}
self.commands["update"]["args"][sourceObject.name] = {}
self.commands["remove"]["args"][sourceObject.name] = {}
self:prepareAutocomplete()
updateAutocomplete()

return true
end

Expand Down Expand Up @@ -454,6 +613,7 @@ function scm:removeScript (name, keepScriptConfig)
self:saveScripts()
end

-- delete file
if scriptType and fs.exists(self.config[scriptType .. "Directory"] .. name .. ".lua") then
fs.delete(self.config[scriptType .. "Directory"] .. name .. self.config[scriptType .. "Suffix"])
if scriptType == "library" then
Expand All @@ -464,6 +624,10 @@ function scm:removeScript (name, keepScriptConfig)
if scriptType == "program" then
fs.delete(name)
end

-- update autocomplete
self:prepareAutocomplete()
updateAutocomplete()
end

function scm:removeAllScripts ()
Expand Down Expand Up @@ -689,10 +853,59 @@ function scm:init ()
self:loadScripts()
end

---@param resetPosition boolean | nil
function scm:cli (resetPosition, args)
if resetPosition ~= nil and resetPosition == true then
term.setCursorPos(1, 7)
end

-- enable autocomplete
self:prepareAutocomplete()
updateAutocomplete()

-- enable newline starting with `scm `
if self.config["allowCLIPrefix"] then
self.config["cliPrefix"] = true
self:saveConfig()
end

-- some interface
local _, cursorY = term.getCursorPos()
if cursorY < 7 then cursorY = 7 end
term.setCursorPos(1, cursorY)
term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444")
term.setCursorPos(1, cursorY)
term.scroll(1)
term.blit(" SCM - Script Manager ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444")
term.setCursorPos(1, cursorY)
term.scroll(1)
term.blit(" Autocomplete enabled. ","77777777777777777777777777777777","44444444444444444444444444444444")
term.setCursorPos(1, cursorY)
term.scroll(1)
term.blit(" Type `scm help` to learn more. ","77777777ffffffff7777777777777777","44444444444444444444444444444444")
term.setCursorPos(1, cursorY)
term.scroll(1)
term.blit(" ","ffffffffffffffffffffffffffffffff","44444444444444444444444444444444")
term.setCursorPos(1, cursorY)
term.scroll(2)

if self.config["cliPrefix"] then
shell.run(read(nil, nil, shell.complete, "scm "))
end
end

---@param args table
function scm:handleArguments (args)
if #args == 0 then
self:cli(false, args)
return
end

if args[1] and self.commands[args[1]] then
self.commands[args[1]]["func"](args)
if self.config["cliPrefix"] then
shell.run(read(nil, nil, shell.complete, "scm "))
end
end
end

Expand Down