Update aftman tooling and allow compiling Luau scripts to Lua
This commit is contained in:
parent
ad7144c800
commit
379972bd61
|
|
@ -78,7 +78,7 @@ end
|
||||||
local idCount = 0
|
local idCount = 0
|
||||||
local nCount = 0
|
local nCount = 0
|
||||||
|
|
||||||
local function notify(text)
|
local function notify(text, willUpdate)
|
||||||
nCount = nCount + 1
|
nCount = nCount + 1
|
||||||
idCount = idCount + 1
|
idCount = idCount + 1
|
||||||
local id = idCount
|
local id = idCount
|
||||||
|
|
@ -86,18 +86,23 @@ local function notify(text)
|
||||||
local position = Value(UDim2.new(0, -WIDTH, 0, 60 * nCount - 50))
|
local position = Value(UDim2.new(0, -WIDTH, 0, 60 * nCount - 50))
|
||||||
local transparency = Value(0)
|
local transparency = Value(0)
|
||||||
local textValue = Value(text)
|
local textValue = Value(text)
|
||||||
local textChanged = Observer(textValue)
|
local textChanged
|
||||||
local arrowRotation = Value(0)
|
local arrowRotation = Value(0)
|
||||||
local done = Value(false)
|
local done = Value(not willUpdate)
|
||||||
local background = Value(Color3.new())
|
local background = Value(Color3.new())
|
||||||
local backgroundSpring = Spring(background, 4)
|
local backgroundSpring = Spring(background, 4)
|
||||||
local start = tick()
|
local start = tick()
|
||||||
|
|
||||||
local disconn = textChanged:onChange(function()
|
local disconn = function() end
|
||||||
if tick() - start > 0.5 then -- don't change color if it's just appearing
|
|
||||||
backgroundSpring:setPosition(Color3.new(0.4, 0.4, 0.4))
|
if willUpdate then
|
||||||
end
|
textChanged = Observer(textValue)
|
||||||
end)
|
disconn = textChanged:onChange(function()
|
||||||
|
if tick() - start > 0.5 then -- don't change color if it's just appearing
|
||||||
|
backgroundSpring:setPosition(Color3.new(0.4, 0.4, 0.4))
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
local t = New "Frame" {
|
local t = New "Frame" {
|
||||||
Name = "Notification",
|
Name = "Notification",
|
||||||
|
|
@ -173,11 +178,70 @@ local function notify(text)
|
||||||
t:Destroy()
|
t:Destroy()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
return {
|
if willUpdate then
|
||||||
text = textValue,
|
return {
|
||||||
arrowRotation = arrowRotation,
|
text = textValue,
|
||||||
done = done,
|
arrowRotation = arrowRotation,
|
||||||
}
|
done = done,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local function makeScript(s) -- because no continue
|
||||||
|
local path = s.path -- { "ServerScriptService", "script" }
|
||||||
|
local content = s.content
|
||||||
|
local type = s.type
|
||||||
|
|
||||||
|
local obj = game
|
||||||
|
local ok2 = pcall(function()
|
||||||
|
for i = 1, #path - 1 do
|
||||||
|
obj = obj:FindFirstChild(path[i])
|
||||||
|
if not obj then
|
||||||
|
local folder = Instance.new "Model"
|
||||||
|
folder.Name = path[i]
|
||||||
|
folder.Parent = obj
|
||||||
|
obj = folder
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
if not ok2 then
|
||||||
|
notify(
|
||||||
|
"Failed to sync "
|
||||||
|
.. table.concat(path, ".")
|
||||||
|
.. "! Is the path correct?"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = path[#path]
|
||||||
|
local existingObj = obj:FindFirstChild(name)
|
||||||
|
if existingObj then
|
||||||
|
if existingObj:IsA "Script" then
|
||||||
|
existingObj.Source = content
|
||||||
|
else
|
||||||
|
notify(
|
||||||
|
"Object already exists at path "
|
||||||
|
.. table.concat(path, ".")
|
||||||
|
.. "! Please remove it and try again."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local createScript
|
||||||
|
|
||||||
|
if type == "server" then
|
||||||
|
createScript = Instance.new "Script"
|
||||||
|
elseif type == "client" then
|
||||||
|
createScript = Instance.new "LocalScript"
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
createScript.Name = name
|
||||||
|
createScript.Source = content
|
||||||
|
createScript.Parent = obj
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local debounce
|
local debounce
|
||||||
|
|
@ -189,7 +253,7 @@ buttons[1].Click:connect(function()
|
||||||
debounce = true
|
debounce = true
|
||||||
initiate()
|
initiate()
|
||||||
|
|
||||||
local n = notify "Syncing..."
|
local n = notify("Syncing...", true)
|
||||||
|
|
||||||
Spawn(function()
|
Spawn(function()
|
||||||
while not peek(n.done) do
|
while not peek(n.done) do
|
||||||
|
|
@ -206,13 +270,34 @@ buttons[1].Click:connect(function()
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
if ok then
|
local function finish()
|
||||||
n.text:set("Synced: " .. res)
|
n.done:set(true)
|
||||||
else
|
wait(0.05)
|
||||||
n.text:set "Failed to sync! Is Mercury Sync Server running?"
|
debounce = false
|
||||||
end
|
end
|
||||||
n.done:set(true)
|
|
||||||
|
|
||||||
debounce = false
|
if not ok then
|
||||||
|
n.text:set "Failed to sync! Is Mercury Sync Server running?"
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
n.text:set "Decoding..."
|
||||||
|
local json = HttpService:JSONDecode(res) -- { files }
|
||||||
|
|
||||||
|
if not json.files or json.files == "null" then
|
||||||
|
n.text:set "No files to sync!"
|
||||||
|
finish()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
n.text:set "Applying..."
|
||||||
|
|
||||||
|
for _, v in pairs(json.files) do -- { path, content, type }
|
||||||
|
makeScript(v)
|
||||||
|
end
|
||||||
|
|
||||||
|
n.text:set "Successfully synchronised!"
|
||||||
|
|
||||||
|
finish()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
func CompileLuau(sourcePath string) (string, error) {
|
||||||
|
path, err := exec.LookPath("./tools/darklua")
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := exec.Command(path, "process", sourcePath, "./temp.lua")
|
||||||
|
cmd.Run()
|
||||||
|
|
||||||
|
// Return the compiled file
|
||||||
|
file, _ := os.ReadFile("./temp.lua")
|
||||||
|
|
||||||
|
return string(file), nil
|
||||||
|
}
|
||||||
|
|
@ -30,7 +30,8 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
r := gin.Default()
|
r := gin.New()
|
||||||
|
r.Use(gin.Recovery())
|
||||||
r.SetTrustedProxies([]string{"127.0.0.1"})
|
r.SetTrustedProxies([]string{"127.0.0.1"})
|
||||||
|
|
||||||
r.GET("/", func(cx *gin.Context) {
|
r.GET("/", func(cx *gin.Context) {
|
||||||
|
|
@ -41,13 +42,16 @@ func main() {
|
||||||
|
|
||||||
// Create struct for JSON response
|
// Create struct for JSON response
|
||||||
type File struct {
|
type File struct {
|
||||||
Path string
|
Path []string `json:"path"`
|
||||||
Content string
|
Content string `json:"content"`
|
||||||
|
Type string `json:"type"`
|
||||||
}
|
}
|
||||||
var Response struct {
|
var Response struct {
|
||||||
Files []File
|
Files []File `json:"files"`
|
||||||
|
// Message string `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usedFilenames := make(map[string]bool)
|
||||||
// Read files recursively and send them to the client
|
// Read files recursively and send them to the client
|
||||||
fmt.Println(target)
|
fmt.Println(target)
|
||||||
filepath.Walk(target, func(path string, info os.FileInfo, err error) error {
|
filepath.Walk(target, func(path string, info os.FileInfo, err error) error {
|
||||||
|
|
@ -61,47 +65,80 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
var filetype string
|
var filetype string
|
||||||
|
var scripttype string
|
||||||
|
|
||||||
switch strings.ToLower(filepath.Ext(path)) {
|
switch strings.ToLower(filepath.Ext(path)) {
|
||||||
case ".lua":
|
case ".lua":
|
||||||
filetype = "lua"
|
filetype = "lua"
|
||||||
case ".luau":
|
case ".luau":
|
||||||
filetype = "luau"
|
filetype = "luau"
|
||||||
|
case ".moon":
|
||||||
|
filetype = "moon"
|
||||||
|
case ".yue":
|
||||||
|
filetype = "yue"
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trim target directory and extension from path
|
// Trim target directory and extension from path, and remove suffix if it's a server/client script
|
||||||
formatPath := strings.TrimPrefix(path, target+string(os.PathSeparator))
|
formatPath := strings.TrimPrefix(path, target+string(os.PathSeparator))
|
||||||
formatPath = strings.TrimSuffix(formatPath, "."+filetype)
|
formatPath = strings.TrimSuffix(formatPath, "."+filetype)
|
||||||
|
if strings.Contains(formatPath, ".") {
|
||||||
|
scripttype = strings.Split(formatPath, ".")[1]
|
||||||
|
if scripttype == "server" || scripttype == "client" {
|
||||||
|
formatPath = strings.Split(formatPath, ".")[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if scripttype == "" {
|
||||||
|
// scripttype = "module"
|
||||||
|
fmt.Println(c.InRed("Unknown script type: ") + c.InUnderline(c.InPurple(formatPath)) + c.InRed("!"))
|
||||||
|
fmt.Println(c.InYellow("If you were trying to sync a ModuleScript, these are not supported by Mercury Sync. Please transpose them manually."))
|
||||||
|
}
|
||||||
|
formatPath = strings.ReplaceAll(formatPath, string(os.PathSeparator), ".")
|
||||||
|
|
||||||
fmt.Println(c.InGreen("Sending ")+c.InUnderline(c.InPurple(formatPath))+c.InGreen("..."))
|
if usedFilenames[formatPath] {
|
||||||
|
fmt.Println(c.InRed("Duplicate filename: ") + c.InUnderline(c.InPurple(formatPath)) + c.InRed("! Skipping..."))
|
||||||
file, err := os.Open(path)
|
|
||||||
if err != nil {
|
|
||||||
fmt.Println(c.InRed("Error while reading file:"), err.Error())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
usedFilenames[formatPath] = true
|
||||||
|
|
||||||
// Parse file contents
|
|
||||||
var content string
|
var content string
|
||||||
buf := make([]byte, 1024)
|
|
||||||
for {
|
switch filetype {
|
||||||
n, _ := file.Read(buf)
|
case "luau":
|
||||||
if n == 0 {
|
fmt.Println(c.InBlue("Compiling ") + c.InUnderline(c.InPurple(formatPath)) + c.InBlue("..."))
|
||||||
break
|
content, err = CompileLuau(path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(c.InRed("Error while compiling Luau file:"), err)
|
||||||
|
if strings.Contains(err.Error(), "file does not exist") ||
|
||||||
|
strings.Contains(err.Error(), "no such file or directory") {
|
||||||
|
|
||||||
|
fmt.Println(c.InYellow("Please place a copy of darklua (name \"darklua\" or \"darklua.exe\") in the tools folder."))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
content += string(buf[:n])
|
default:
|
||||||
|
file, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(c.InRed("Error while reading file:"), err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
content = string(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println(c.InGreen("Sending ") + c.InUnderline(c.InPurple(formatPath)) + c.InGreen("..."))
|
||||||
|
|
||||||
Response.Files = append(Response.Files, File{
|
Response.Files = append(Response.Files, File{
|
||||||
Path: formatPath,
|
Path: strings.Split(formatPath, "."),
|
||||||
Content: content,
|
Content: strings.ReplaceAll(content, "\r\n", "\n"),
|
||||||
|
Type: scripttype,
|
||||||
})
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
os.Remove("./temp.lua")
|
||||||
|
|
||||||
cx.JSON(200, Response)
|
cx.JSON(200, Response)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
# To add a new tool, add an entry to this table.
|
# To add a new tool, add an entry to this table.
|
||||||
[tools]
|
[tools]
|
||||||
rojo = "rojo-rbx/rojo@7.2.1"
|
selene = "Kampfkarren/selene@0.25.0"
|
||||||
selene = "Kampfkarren/selene@0.24.0"
|
stylua = "johnnymorganz/stylua@0.18.2"
|
||||||
stylua = "johnnymorganz/stylua@0.15.3"
|
darklua = "seaofvoices/darklua@0.10.3"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue