feat: include argon core logic in library

* Include sourcemap, and sync config generators for Argon as a sync
  tool.
* Add tests for aforementioned Argon generators.
* Refactor and fix test discovery logic in test runner script.
* Temporarily unpin fixed pesde version.
This commit is contained in:
Erica Marigold 2024-12-18 12:32:16 +00:00
parent b9658c7638
commit d2c41e0d03
Signed by: DevComp
GPG key ID: 429EF1C337871656
9 changed files with 297 additions and 11 deletions

3
.gitmodules vendored
View file

@ -1,3 +1,6 @@
[submodule "test-files/rojo"] [submodule "test-files/rojo"]
path = test-files/rojo path = test-files/rojo
url = https://github.com/rojo-rbx/rojo.git url = https://github.com/rojo-rbx/rojo.git
[submodule "test-files/argon"]
path = test-files/argon
url = https://github.com/argon-rbx/examples.git

View file

@ -21,28 +21,33 @@ local require = require :: (
)) ))
) -> () ) -> ()
local function discoverTests(dir: string)
local function discoverTests(dir: string): { string }
local tests = {} local tests = {}
for _, file in fs.readDir(dir) do
local fullPath = `{dir}/{file}` local entries = fs.readDir(dir)
for _, entry in entries do
local path = `{dir}/{entry}`
-- 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(path) and string.match(entry, "%.spec%.luau$") then
table.insert(tests, fullPath) table.insert(tests, path)
continue
end end
-- Recurse for directories -- Recurse for directories
if fs.isDir(fullPath) then if fs.isDir(path) then
local moreTests = discoverTests(fullPath) local dirResults = discoverTests(path)
table.move(dirResults, 1, #dirResults, #tests + 1, tests)
-- Why are the indices starting at 0???? What???? continue
table.move(moreTests, 0, #moreTests, #tests, tests)
end end
end end
return tests return tests
end end
print(discoverTests("src"))
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,

View file

@ -161,6 +161,34 @@ index_url = "https://github.com/daimond113/pesde-index"
environment = "luau" environment = "luau"
lib = "lib/init.luau" lib = "lib/init.luau"
[graph."pesde/argon"."2.0.21 lune"]
direct = ["argon", { name = "pesde/argon", version = "^2.0.21" }, "dev"]
resolved_ty = "dev"
[graph."pesde/argon"."2.0.21 lune".target]
environment = "lune"
bin = "init.luau"
[graph."pesde/argon"."2.0.21 lune".dependencies]
"lukadev_0/option" = ["1.2.0 lune", "option"]
"lukadev_0/result" = ["1.2.0 lune", "result"]
"pesde/toolchainlib" = ["0.1.2 lune", "core"]
[graph."pesde/argon"."2.0.21 lune".pkg_ref]
ref_ty = "pesde"
name = "pesde/argon"
version = "2.0.21"
index_url = "https://github.com/pesde-pkg/index"
[graph."pesde/argon"."2.0.21 lune".pkg_ref.dependencies]
core = [{ name = "pesde/toolchainlib", version = "^0.1.2", index = "https://github.com/daimond113/pesde-index", target = "lune" }, "standard"]
option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "standard"]
result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "standard"]
[graph."pesde/argon"."2.0.21 lune".pkg_ref.target]
environment = "lune"
bin = "init.luau"
[graph."pesde/luau_lsp"."1.36.0 lune"] [graph."pesde/luau_lsp"."1.36.0 lune"]
direct = ["luau-lsp", { name = "pesde/luau_lsp", version = "^1.36.0" }, "dev"] direct = ["luau-lsp", { name = "pesde/luau_lsp", version = "^1.36.0" }, "dev"]
resolved_ty = "dev" resolved_ty = "dev"
@ -189,6 +217,34 @@ result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://gith
environment = "lune" environment = "lune"
bin = "init.luau" bin = "init.luau"
[graph."pesde/rojo"."7.4.4 lune"]
direct = ["rojo", { name = "pesde/rojo", version = "^7.4.4" }, "dev"]
resolved_ty = "dev"
[graph."pesde/rojo"."7.4.4 lune".target]
environment = "lune"
bin = "init.luau"
[graph."pesde/rojo"."7.4.4 lune".dependencies]
"lukadev_0/option" = ["1.2.0 lune", "option"]
"lukadev_0/result" = ["1.2.0 lune", "result"]
"pesde/toolchainlib" = ["0.1.2 lune", "core"]
[graph."pesde/rojo"."7.4.4 lune".pkg_ref]
ref_ty = "pesde"
name = "pesde/rojo"
version = "7.4.4"
index_url = "https://github.com/pesde-pkg/index"
[graph."pesde/rojo"."7.4.4 lune".pkg_ref.dependencies]
core = [{ name = "pesde/toolchainlib", version = "^0.1.1", index = "https://github.com/daimond113/pesde-index", target = "lune" }, "standard"]
option = [{ name = "lukadev_0/option", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "standard"]
result = [{ name = "lukadev_0/result", version = "^1.2.0", index = "https://github.com/daimond113/pesde-index" }, "standard"]
[graph."pesde/rojo"."7.4.4 lune".pkg_ref.target]
environment = "lune"
bin = "init.luau"
[graph."pesde/stylua"."2.0.1 lune"] [graph."pesde/stylua"."2.0.1 lune"]
direct = ["stylua", { name = "pesde/stylua", version = "^2.0.1" }, "dev"] direct = ["stylua", { name = "pesde/stylua", version = "^2.0.1" }, "dev"]
resolved_ty = "dev" resolved_ty = "dev"

View file

@ -1,6 +1,6 @@
name = "pesde/scripts_core" name = "pesde/scripts_core"
version = "0.0.1" version = "0.0.1"
pesde_version = "0.5.0-rc.16" # pesde_version = "0.5.1+registry.0.1.0" # FIXME: pesde needs to fix versioning here
description = "Scripts and other utilities for use with pesde" description = "Scripts and other utilities for use with pesde"
authors = [ authors = [
"daimond113 <contact@daimond113.com> (https://www.daimond113.com/)", "daimond113 <contact@daimond113.com> (https://www.daimond113.com/)",
@ -31,6 +31,8 @@ frktest = { name = "itsfrank/frktest", version = "^0.0.2" }
pathfs = { name = "jiwonz/pathfs", version = "^0.1.0" } pathfs = { name = "jiwonz/pathfs", version = "^0.1.0" }
luau-lsp = { name = "pesde/luau_lsp", version = "^1.36.0" } luau-lsp = { name = "pesde/luau_lsp", version = "^1.36.0" }
stylua = { name = "pesde/stylua", version = "^2.0.1" } stylua = { name = "pesde/stylua", version = "^2.0.1" }
argon = { name = "pesde/argon", version = "^2.0.21" }
rojo = { name = "pesde/rojo", version = "^7.4.4" }
[indices] [indices]
default = "https://github.com/pesde-pkg/index" default = "https://github.com/pesde-pkg/index"

View file

@ -0,0 +1,52 @@
local fs = require("@lune/fs")
local process = require("@lune/process")
local serde = require("@lune/serde")
local stdio = require("@lune/stdio")
local PLATFORM_SEP = if process.os == "windows" then "\\" else "/"
-- A mapping of things to do depending on the file present
local PATH_ACTION_MAP: { [string]: (dir: string) -> number? } = {
["default.project.json"] = function(dir)
return process.spawn("argon", { "sourcemap", dir }, {
cwd = process.cwd,
env = process.env,
stdio = "forward",
}).code
end,
["init.lua"] = function()
return stdio.write(
serde.encode("json", { filePaths = { "init.lua" } }, false)
)
end,
["init.luau"] = function()
return stdio.write(
serde.encode("json", { filePaths = { "init.luau" } }, false)
)
end,
}
--- Writes a Argon sourcemap for the project in the provided directory or the current
--- working directory to standard output.
--- ## Errors
--- * The current process lacks permissions to a file
--- * Failure to spawn `argon` command
--- * Any I/O error occurs
return function(packageDirectory: string?): boolean
packageDirectory = packageDirectory or process.cwd
-- We go through the action mappings in order of priority and check for the
-- file predicates, if present, we execute the action and report our status
for path, action in PATH_ACTION_MAP do
if fs.isFile(`{packageDirectory}{PLATFORM_SEP}{path}`) then
local status = action(packageDirectory)
return if status ~= nil then status == 0 else true
end
end
-- If we reached so far, that must mean none of the file predicates matched,
-- so we return a `false` signifying an error
return false
end

View file

@ -0,0 +1,100 @@
local fs = require("@lune/fs")
local luau = require("@lune/luau")
local process = require("@lune/process")
local regex = require("@lune/regex")
local serde = require("@lune/serde")
local frktest = require("../../../lune_packages/frktest")
local check = frktest.assert.check
local TEST_PROJECTS_DIR = "./test-files/argon"
local BUILTIN_PATCHES: {
[string]: { [string]: (...any) -> ...any? },
} = {
["@lune/process"] = {
spawn = function(
program: string,
params: { string },
options: process.SpawnOptions
): process.SpawnResult
local patchedOptions: process.SpawnOptions = options or {}
patchedOptions.stdio = "default"
local result = process.spawn(program, params, patchedOptions)
-- First we make sure the command exited properly
assert(
result.ok,
`Expected \`rojo\` command to not error, got:\n{string.rep(
" ",
6
)}{result.stderr}`
)
-- We also make sure that the output JSON was valid
serde.decode("json", result.stdout)
return result
end,
},
["@lune/stdio"] = {
write = function(msg: string)
-- Only make sure output JSON is valid
serde.decode("json", msg)
end,
},
}
local function requireWithPatches(path: string)
for builtin, patch in BUILTIN_PATCHES do
if path == builtin then
return setmetatable(patch, { __index = require(builtin) })
end
end
return require(path)
end
return function(test: typeof(frktest.test))
test.suite(
"Generates Argon sourcemaps for test projects successfully",
function()
for _, file in fs.readDir(TEST_PROJECTS_DIR) do
local testProject = `{TEST_PROJECTS_DIR}/{file}`
if not fs.isDir(testProject) or file == ".git" then
-- Skip files that are not project directories
continue
end
test.case(file, function()
-- If a file starts with `bad_` but not `bad_meta_`, we should expect a failure
-- Also, sorry about this shitty regex, regex-rs does not support look-around :(
local isBadMeta = regex.new(
"^bad_[^m]|^bad_m[^e]|^bad_me[^t]|^bad_met[^a]"
)
local expect = if isBadMeta:isMatch(file)
then check.should_error
else check.should_not_error
expect(function()
-- We override the require which applies some patches to some builtins, mainly preventing
-- command stdout forwarding and `stdio.write` outputs to stdout in order to not fill
-- test ouput with large amounts of JSON data
local sourcemap: (string) -> boolean = luau.load(
fs.readFile("./src/generators/argon/sourcemap.luau"),
{
environment = {
require = requireWithPatches,
},
}
)()
return check.is_true(sourcemap(testProject))
end)
end)
end
end
)
end

View file

@ -0,0 +1,28 @@
local rojoSyncConfig = require("../rojo/sync_config")
export type TreeProperties = rojoSyncConfig.TreeProperties
export type TreeBase = rojoSyncConfig.TreeBase
export type TreeNormal = rojoSyncConfig.TreeNormal
export type TreeService = rojoSyncConfig.TreeService
export type DataModelTree = rojoSyncConfig.DataModelTree
export type Tree = rojoSyncConfig.Tree
export type SyncConfig = rojoSyncConfig.SyncConfig
--- Generates an Argon sync configuration file (`default.project.json`) from a list of
--- input files to be included.
--- ## Errors
--- * The current process lacks permissions to a file
--- * Any I/O error occurs
return function(
packageDirectory: string?,
files: { string },
options: {
writeToFile: boolean?,
force: boolean?,
}
): (boolean, string?)
-- Purely alias to the Rojo sync config generator, since Argon uses the same
-- config format
return rojoSyncConfig(packageDirectory, files, options)
end

View file

@ -0,0 +1,39 @@
local fs = require("@lune/fs")
local serde = require("@lune/serde")
local frktest = require("../../../lune_packages/frktest")
local check = frktest.assert.check
local syncConfig = require("./sync_config")
local TEST_PROJECTS_DIR = "./test-files/argon"
return function(test: typeof(frktest.test))
test.suite("Generates valid Argon sync configs", function()
for _, dir in fs.readDir(TEST_PROJECTS_DIR) do
local fullPath = `{TEST_PROJECTS_DIR}/{dir}`
if not fs.isDir(fullPath) or dir == ".git" then
continue
end
test.case(`{dir}`, function()
local ok, config = syncConfig(
fullPath,
fs.readDir(fullPath),
{ writeToFile = false, force = true }
)
check.is_true(ok)
-- Make sure that the generated config and the real configs are similar
local generatedConfig, realConfig =
serde.decode("json", config),
serde.decode(
"json",
fs.readFile(`{fullPath}/default.project.json`)
)
check.table.contains(realConfig, generatedConfig)
end)
end
end)
end

1
test-files/argon Submodule

@ -0,0 +1 @@
Subproject commit 9c092f06420d9068bb312c3547dcc3f2f19f2cc4