Add StyLua/Selene/luau-lsp toolchain and make the scaffold lint-clean

Pin stylua, selene, and luau-lsp in rokit.toml so local dev and CI use the
same versions, and add their configs (stylua.toml, selene.toml, .luaurc).
Two behavior-preserving source touches make the existing scaffold pass:
guard the optional iteration in Components.readAttributes (clears a luau-lsp
type error) and normalize Gatherable.luau to StyLua's canonical form. Ignore
the CI-fetched globalTypes.d.luau.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Samuel Lison
2026-06-18 18:05:33 +10:00
co-authored by Claude Opus 4.8
parent 759d9e148d
commit 3d76332c38
7 changed files with 40 additions and 6 deletions
+1
View File
@@ -1,5 +1,6 @@
# Rojo / Roblox
sourcemap.json
globalTypes.d.luau
*.rbxl
*.rbxlx
*.rbxl.lock
+5
View File
@@ -0,0 +1,5 @@
{
"languageMode": "nonstrict",
"lintErrors": false,
"globals": []
}
+4
View File
@@ -1,4 +1,8 @@
# Toolchain pins (https://github.com/rojo-rbx/rokit). Run `rokit install`.
# CI installs this exact set; pin versions so local dev and CI stay identical.
[tools]
rojo = "rojo-rbx/rojo@7.6.1"
wally = "UpliftGames/wally@0.3.2"
stylua = "JohnnyMorganz/stylua@2.5.2"
selene = "Kampfkarren/selene@0.31.0"
luau-lsp = "JohnnyMorganz/luau-lsp@1.68.1"
+12
View File
@@ -0,0 +1,12 @@
# Selene lint configuration — CI runs `selene .` on every push/PR.
# Uses the Roblox standard library (globals like `game`, `task`, `typeof`, `warn`).
std = "roblox"
# Generated Wally/Rojo artifacts are not ours to lint.
exclude = ["Packages", "ServerPackages", "DevPackages"]
[lints]
# Roblox code legitimately leaves some values unused (e.g. connection handles);
# keep the high-signal lints and let the formatter own style.
empty_if = "warn"
unused_variable = "warn"
+1 -3
View File
@@ -24,9 +24,7 @@ return Components.define({
onSetup = function(instance, values)
instance:SetAttribute("_HP", values.HP)
local host = if instance:IsA("BasePart")
then instance
else instance:FindFirstChildWhichIsA("BasePart")
local host = if instance:IsA("BasePart") then instance else instance:FindFirstChildWhichIsA("BasePart")
if not host then
warn(`[Gatherable] '{instance:GetFullName()}' has no BasePart to host a prompt`)
return
+5 -3
View File
@@ -37,9 +37,11 @@ end
local function readAttributes(instance: Instance, attributes: { [string]: any }?)
local values = {}
for attrName, default in attributes or {} do
local v = instance:GetAttribute(attrName)
values[attrName] = if v == nil then default else v
if attributes then
for attrName, default in attributes do
local v = instance:GetAttribute(attrName)
values[attrName] = if v == nil then default else v
end
end
return values
end
+12
View File
@@ -0,0 +1,12 @@
# StyLua formatting rules — CI runs `stylua --check` on every push/PR.
# Tabs match the existing source; format with `stylua src demo` before committing.
column_width = 120
line_endings = "Unix"
indent_type = "Tabs"
indent_width = 4
quote_style = "AutoPreferDouble"
call_parentheses = "Always"
collapse_simple_statement = "Never"
[sort_requires]
enabled = false