style: apply stylua formatter

This commit is contained in:
Erica Marigold 2024-12-08 17:42:05 +00:00
parent be2ae619c6
commit 0045c01c72
Signed by: DevComp
GPG key ID: 429EF1C337871656
7 changed files with 383 additions and 385 deletions

View file

@ -1,7 +1,7 @@
--> Run stylua to check for formatting errors --> Run stylua to check for formatting errors
local process = require("@lune/process") local process = require("@lune/process")
local CommandBuilder = require("./lib/exec") local CommandBuilder = require("./lib/exec")
process.exit(CommandBuilder.new("stylua"):withArg("."):withArgs(process.args):withStdioStrategy("forward"):exec().code) process.exit(CommandBuilder.new("stylua"):withArg("."):withArgs(process.args):withStdioStrategy("forward"):exec().code)

View file

@ -1,48 +1,48 @@
--- An MPSC synchronization primitive powered by Lua upvalues which retains only --- An MPSC synchronization primitive powered by Lua upvalues which retains only
--- one value at a time. --- one value at a time.
--- ## Usage --- ## Usage
--- ```luau --- ```luau
--- local send, recv = watch((nil :: any) :: string) --- local send, recv = watch((nil :: any) :: string)
--- task.delay(5, send, "hello, world!") --- task.delay(5, send, "hello, world!")
--- task.spawn(function() --- task.spawn(function()
--- local value = recv() --- local value = recv()
--- print("received value:", value) --- print("received value:", value)
--- end) --- end)
--- ``` --- ```
type Watch<T> = { type Watch<T> = {
value: T?, value: T?,
receivers: { thread }, receivers: { thread },
} }
--- Crates a new `Watch` channel, returning its send and receive handles. --- Crates a new `Watch` channel, returning its send and receive handles.
local function chan<T>(_phantom: T): ((T) -> (), () -> T?) local function chan<T>(_phantom: T): ((T) -> (), () -> T?)
local watch: Watch<T> = { local watch: Watch<T> = {
value = nil, value = nil,
receivers = {}, receivers = {},
} }
local function send(value: T) local function send(value: T)
watch.value = value watch.value = value
for _, receiver in watch.receivers do for _, receiver in watch.receivers do
coroutine.resume(receiver, value) coroutine.resume(receiver, value)
end end
end end
local function recv(): T local function recv(): T
local value = watch.value local value = watch.value
watch.value = nil watch.value = nil
if value == nil then if value == nil then
table.insert(watch.receivers, coroutine.running()) table.insert(watch.receivers, coroutine.running())
return coroutine.yield() return coroutine.yield()
end end
return value :: T return value :: T
end end
return send, recv return send, recv
end end
return chan return chan

View file

@ -1,103 +1,103 @@
--> lib: Builder pattern class to spawn child processes --> lib: Builder pattern class to spawn child processes
local process = require("@lune/process") local process = require("@lune/process")
local stdio = require("@lune/stdio") local stdio = require("@lune/stdio")
local CommandBuilder = {} local CommandBuilder = {}
export type CommandBuilder = typeof(setmetatable({} :: CommandBuilderFields, { __index = CommandBuilder })) export type CommandBuilder = typeof(setmetatable({} :: CommandBuilderFields, { __index = CommandBuilder }))
type CommandBuilderFields = { type CommandBuilderFields = {
program: string, program: string,
args: { string }, args: { string },
stdioStrategy: IoStrategyMapping?, stdioStrategy: IoStrategyMapping?,
} }
export type StdioStrategy = "pipe" | "forward" | "none" export type StdioStrategy = "pipe" | "forward" | "none"
export type IoStrategyMapping = { export type IoStrategyMapping = {
stdout: StdioStrategy?, stdout: StdioStrategy?,
stderr: StdioStrategy?, stderr: StdioStrategy?,
} }
local DEFAULT_STDIO_STRATEGY: IoStrategyMapping = { local DEFAULT_STDIO_STRATEGY: IoStrategyMapping = {
stdout = "pipe", stdout = "pipe",
stderr = "pipe", stderr = "pipe",
} }
function CommandBuilder.new(program: string) function CommandBuilder.new(program: string)
return setmetatable( return setmetatable(
{ {
program = program, program = program,
args = {}, args = {},
stdioStrategy = nil, stdioStrategy = nil,
} :: CommandBuilderFields, } :: CommandBuilderFields,
{ {
__index = CommandBuilder, __index = CommandBuilder,
} }
) )
end end
function CommandBuilder.withArg(self: CommandBuilder, arg: string): CommandBuilder function CommandBuilder.withArg(self: CommandBuilder, arg: string): CommandBuilder
table.insert(self.args, arg) table.insert(self.args, arg)
return self return self
end end
function CommandBuilder.withArgs(self: CommandBuilder, args: { string }): CommandBuilder function CommandBuilder.withArgs(self: CommandBuilder, args: { string }): CommandBuilder
for _, arg in args do for _, arg in args do
self:withArg(arg) self:withArg(arg)
end end
return self return self
end end
function CommandBuilder.withStdioStrategy( function CommandBuilder.withStdioStrategy(
self: CommandBuilder, self: CommandBuilder,
strategy: StdioStrategy | IoStrategyMapping strategy: StdioStrategy | IoStrategyMapping
): CommandBuilder ): CommandBuilder
self.stdioStrategy = if typeof(strategy) == "string" self.stdioStrategy = if typeof(strategy) == "string"
then { then {
stdout = strategy, stdout = strategy,
stderr = strategy, stderr = strategy,
} }
else strategy else strategy
return self return self
end end
local function intoSpawnOptionsStdioKind(strategy: StdioStrategy): process.SpawnOptionsStdioKind local function intoSpawnOptionsStdioKind(strategy: StdioStrategy): process.SpawnOptionsStdioKind
if strategy == "pipe" then if strategy == "pipe" then
return "default" return "default"
end end
if strategy == "forward" then if strategy == "forward" then
return "forward" return "forward"
end end
if strategy == "none" then if strategy == "none" then
return "none" return "none"
end end
error(`Non-strategy provided: {strategy}`) error(`Non-strategy provided: {strategy}`)
end end
function CommandBuilder.exec(self: CommandBuilder): process.SpawnResult function CommandBuilder.exec(self: CommandBuilder): process.SpawnResult
print("$", stdio.style("dim") .. self.program, table.concat(self.args, " ") .. stdio.style("reset")) print("$", stdio.style("dim") .. self.program, table.concat(self.args, " ") .. stdio.style("reset"))
local function translateIoStrategyMappings(mappings: IoStrategyMapping) local function translateIoStrategyMappings(mappings: IoStrategyMapping)
local translatedMappings: process.SpawnOptionsStdio = {} local translatedMappings: process.SpawnOptionsStdio = {}
for field, value in mappings do for field, value in mappings do
translatedMappings[field] = intoSpawnOptionsStdioKind(value) translatedMappings[field] = intoSpawnOptionsStdioKind(value)
end end
return translatedMappings return translatedMappings
end end
local child = process.spawn(self.program, self.args, { local child = process.spawn(self.program, self.args, {
shell = true, shell = true,
stdio = translateIoStrategyMappings(self.stdioStrategy or DEFAULT_STDIO_STRATEGY), stdio = translateIoStrategyMappings(self.stdioStrategy or DEFAULT_STDIO_STRATEGY),
}) })
if not child.ok then if not child.ok then
print(`\n{stdio.color("red")}[luau-lsp]{stdio.color("reset")} Exited with code`, child.code) print(`\n{stdio.color("red")}[luau-lsp]{stdio.color("reset")} Exited with code`, child.code)
end end
return child return child
end end
return CommandBuilder return CommandBuilder

View file

@ -1,71 +1,71 @@
local fs = require("@lune/fs") local fs = require("@lune/fs")
local serde = require("@lune/serde") local serde = require("@lune/serde")
export type SPDXLicense = export type SPDXLicense =
"MIT" "MIT"
| "Apache-2.0" | "Apache-2.0"
| "BSD-2-Clause" | "BSD-2-Clause"
| "BSD-3-Clause" | "BSD-3-Clause"
| "GPL-2.0" | "GPL-2.0"
| "GPL-3.0" | "GPL-3.0"
| "LGPL-2.1" | "LGPL-2.1"
| "LGPL-3.0" | "LGPL-3.0"
| "MPL-2.0" | "MPL-2.0"
| "ISC" | "ISC"
| "Unlicense" | "Unlicense"
| "WTFPL" | "WTFPL"
| "Zlib" | "Zlib"
| "CC0-1.0" | "CC0-1.0"
| "CC-BY-4.0" | "CC-BY-4.0"
| "CC-BY-SA-4.0" | "CC-BY-SA-4.0"
| "BSL-1.0" | "BSL-1.0"
| "EPL-2.0" | "EPL-2.0"
| "AGPL-3.0" | "AGPL-3.0"
export type DependencySpecifier = (( export type DependencySpecifier = ((
{ name: string, version: string, index: string? } { name: string, version: string, index: string? }
| { workspace: string, version: string } | { workspace: string, version: string }
| { repo: string, rev: string, path: string? } | { repo: string, rev: string, path: string? }
) & { ) & {
target: string?, target: string?,
}) | { wally: string, version: string, index: string? } }) | { wally: string, version: string, index: string? }
export type PackageTarget = { export type PackageTarget = {
environment: "luau" | "lune" | "roblox" | "roblox_server", environment: "luau" | "lune" | "roblox" | "roblox_server",
lib: string, lib: string,
} | ({ environment: "luau" | "lune" } & ({ } | ({ environment: "luau" | "lune" } & ({
bin: string, bin: string,
} | { } | {
scripts: { [string]: string }, scripts: { [string]: string },
})) }))
export type PesdeManifest<T = {}> = { export type PesdeManifest<T = {}> = {
name: string, name: string,
version: string, version: string,
description: string?, description: string?,
license: SPDXLicense?, license: SPDXLicense?,
authors: { string }?, authors: { string }?,
repository: string?, repository: string?,
private: boolean?, private: boolean?,
includes: { string }?, includes: { string }?,
pesde_version: string?, pesde_version: string?,
workspace_members: { string }?, workspace_members: { string }?,
target: PackageTarget, target: PackageTarget,
build_files: { string }?, build_files: { string }?,
scripts: { [string]: string }?, scripts: { [string]: string }?,
indices: { [string]: string }, indices: { [string]: string },
wally_indices: { [string]: string }?, wally_indices: { [string]: string }?,
overrides: { [string]: DependencySpecifier }?, overrides: { [string]: DependencySpecifier }?,
patches: { [string]: { [string]: string } }?, patches: { [string]: { [string]: string } }?,
place: { [string]: string }?, place: { [string]: string }?,
dependencies: { [string]: DependencySpecifier }?, dependencies: { [string]: DependencySpecifier }?,
peer_dependencies: { [string]: DependencySpecifier }?, peer_dependencies: { [string]: DependencySpecifier }?,
dev_dependencies: { [string]: DependencySpecifier }?, dev_dependencies: { [string]: DependencySpecifier }?,
} & T } & T
return function<T>(path: string?, _phantom: T): PesdeManifest<T> return function<T>(path: string?, _phantom: T): PesdeManifest<T>
local manifestContents = fs.readFile(path or "pesde.toml") local manifestContents = fs.readFile(path or "pesde.toml")
local decoded = serde.decode("toml", manifestContents) local decoded = serde.decode("toml", manifestContents)
return decoded :: PesdeManifest<T> return decoded :: PesdeManifest<T>
end end

View file

@ -1,80 +1,79 @@
--> Run tests using frktest runner --> Run tests using frktest runner
local fs = require("@lune/fs") local fs = require("@lune/fs")
local process = require("@lune/process") local process = require("@lune/process")
local frktest = require("../../lune_packages/frktest") local frktest = require("../../lune_packages/frktest")
local reporter = require("./reporter") local reporter = require("./reporter")
-- HACK: Cast require to allow for dynamic paths in strict mode -- HACK: Cast require to allow for dynamic paths in strict mode
-- A more proper solution would be to use luau.load instead, but -- A more proper solution would be to use luau.load instead, but
-- frktest requires its global state to be modified by test suites -- frktest requires its global state to be modified by test suites
local require = require :: ( local require = require :: (
path: string path: string
) -> ( ) -> (
test: typeof(setmetatable( test: typeof(setmetatable(
{} :: { {} :: {
case: (name: string, fn: () -> nil) -> (), case: (name: string, fn: () -> nil) -> (),
suite: (name: string, fn: () -> ()) -> (), suite: (name: string, fn: () -> ()) -> (),
}, },
{ __index = frktest.test } { __index = frktest.test }
)) ))
) -> () ) -> ()
local function discoverTests(dir: string) local function discoverTests(dir: string)
local tests = {} local tests = {}
for _, file in fs.readDir(dir) do for _, file in fs.readDir(dir) do
local fullPath = `{dir}/{file}` local fullPath = `{dir}/{file}`
-- Look for files ending in `.spec.luau` as tests -- Look for files ending in `.spec.luau` as tests
if fs.isFile(fullPath) and string.sub(file, -10) == ".spec.luau" then if fs.isFile(fullPath) and string.sub(file, -10) == ".spec.luau" then
table.insert(tests, fullPath) table.insert(tests, fullPath)
end end
-- Recurse for directories -- Recurse for directories
if fs.isDir(fullPath) then if fs.isDir(fullPath) then
local moreTests = discoverTests(fullPath) local moreTests = discoverTests(fullPath)
-- Why are the indices starting at 0???? What???? -- Why are the indices starting at 0???? What????
table.move(moreTests, 0, #moreTests, #tests, tests) table.move(moreTests, 0, #moreTests, #tests, tests)
end end
end end
return tests return tests
end end
local allowedTests = process.args local allowedTests = process.args
for _, test in discoverTests("src") do for _, test in discoverTests("src") do
-- If we are given any arguments, we only run those tests, otherwise, -- If we are given any arguments, we only run those tests, otherwise,
-- we run all the tests -- we run all the tests
-- So, to include only a certain set of test files, you can provide either -- So, to include only a certain set of test files, you can provide either
-- the full path of the test file or name of the test file, with or without -- the full path of the test file or name of the test file, with or without
-- the `.spec.luau` extension -- the `.spec.luau` extension
local baseName = string.match(test, "([^/\\]+)$") local baseName = string.match(test, "([^/\\]+)$")
local withoutExt = string.sub(test, 1, -11) local withoutExt = string.sub(test, 1, -11)
local baseNameWithoutExt = string.match(withoutExt, "([^/\\]+)$") local baseNameWithoutExt = string.match(withoutExt, "([^/\\]+)$")
local isAllowed = #process.args == 0 local isAllowed = #process.args == 0
or table.find(allowedTests, test) or table.find(allowedTests, test)
or table.find(allowedTests, withoutExt) or table.find(allowedTests, withoutExt)
or table.find(allowedTests, baseName) or table.find(allowedTests, baseName)
or table.find(allowedTests, baseNameWithoutExt) or table.find(allowedTests, baseNameWithoutExt)
local constructors = {
local constructors = { case = frktest.test.case,
case = frktest.test.case, suite = frktest.test.suite,
suite = frktest.test.suite, }
}
if not isAllowed then
if not isAllowed then constructors.case = frktest.test.skip.case
constructors.case = frktest.test.skip.case constructors.suite = frktest.test.skip.suite
constructors.suite = frktest.test.skip.suite end
end
require(`../../{test}`)(setmetatable(constructors, { __index = frktest.test }))
require(`../../{test}`)(setmetatable(constructors, { __index = frktest.test })) end
end
reporter.init()
reporter.init() process.exit(tonumber(frktest.run()))
process.exit(tonumber(frktest.run()))

View file

@ -1,60 +1,59 @@
local stdio = require("@lune/stdio") local stdio = require("@lune/stdio")
local frktest = require("../../lune_packages/frktest") local frktest = require("../../lune_packages/frktest")
local Reporter = frktest._reporters.lune_console_reporter local Reporter = frktest._reporters.lune_console_reporter
local watch = require("../lib/channel") local watch = require("../lib/channel")
local STYLE = table.freeze({ local STYLE = table.freeze({
suite = function(name: string) suite = function(name: string)
return `{stdio.style("bold")}{stdio.color("purple")}SUITE{stdio.style("reset")} {name}` return `{stdio.style("bold")}{stdio.color("purple")}SUITE{stdio.style("reset")} {name}`
end, end,
report = function(name: string, state: "success" | "error" | "skip", elapsed: number) report = function(name: string, state: "success" | "error" | "skip", elapsed: number)
local state_color: stdio.Color = if state == "success" then "green" local state_color: stdio.Color = if state == "success"
elseif state == "error" then "red" then "green"
elseif state == "skip" then "yellow" elseif state == "error" then "red"
else error("Invalid test state") elseif state == "skip" then "yellow"
return ` {stdio.style("bold")}{stdio.color(state_color)}{if state == "skip" then "SKIP" else "TEST"}{stdio.style( else error("Invalid test state")
"reset" return ` {stdio.style("bold")}{stdio.color(state_color)}{if state == "skip" then "SKIP" else "TEST"}{stdio.style(
)} {name} [{stdio.style("dim")}{string.format("%.2fms", elapsed)}{stdio.style("reset")}]` "reset"
end, )} {name} [{stdio.style("dim")}{string.format("%.2fms", elapsed)}{stdio.style("reset")}]`
}) end,
})
local ReporterExt = {}
function ReporterExt.init() local ReporterExt = {}
frktest.test.on_suite_enter(function(suite) function ReporterExt.init()
print(STYLE.suite(suite.name)) frktest.test.on_suite_enter(function(suite)
end) print(STYLE.suite(suite.name))
end)
frktest.test.on_suite_leave(function()
stdio.write("\n") frktest.test.on_suite_leave(function()
end) stdio.write("\n")
end)
local send_ts, recv_ts = watch((nil :: any) :: number)
local send_ts, recv_ts = watch((nil :: any) :: number)
frktest.test.on_test_enter(function()
-- Send over some high precision timestamp when the test starts frktest.test.on_test_enter(function()
return send_ts(os.clock()) -- Send over some high precision timestamp when the test starts
end) return send_ts(os.clock())
end)
frktest.test.on_test_leave(function(test)
print( frktest.test.on_test_leave(function(test)
STYLE.report( print(STYLE.report(
test.name, test.name,
if test.failed then "error" else "success", if test.failed then "error" else "success",
-- Await receival of the timestamp and convert the difference to ms -- Await receival of the timestamp and convert the difference to ms
(os.clock() - recv_ts()) * 1000 (os.clock() - recv_ts()) * 1000
) ))
) end)
end)
frktest.test.on_test_skipped(function(test)
frktest.test.on_test_skipped(function(test) print(STYLE.report(test.name, "skip", 0))
print(STYLE.report(test.name, "skip", 0)) end)
end)
Reporter.init()
Reporter.init() end
end
return setmetatable(ReporterExt, { __index = Reporter })
return setmetatable(ReporterExt, { __index = Reporter })

View file

@ -1,16 +1,16 @@
--> Run luau-lsp analysis to check for type errors --> Run luau-lsp analysis to check for type errors
local process = require("@lune/process") local process = require("@lune/process")
local CommandBuilder = require("./lib/exec") local CommandBuilder = require("./lib/exec")
process.exit( process.exit(
CommandBuilder.new("~/.rokit/bin/luau-lsp") CommandBuilder.new("~/.rokit/bin/luau-lsp")
:withArg("analyze") :withArg("analyze")
:withArgs({ "--settings", ".vscode/settings.json" }) :withArgs({ "--settings", ".vscode/settings.json" })
:withArgs({ "--ignore", "'**/.pesde/**'" }) :withArgs({ "--ignore", "'**/.pesde/**'" })
:withArgs({ "--ignore", "'./test-files/**'" }) :withArgs({ "--ignore", "'./test-files/**'" })
:withArg(".") :withArg(".")
:withStdioStrategy("forward") :withStdioStrategy("forward")
:exec().code :exec().code
) )