Created
December 20, 2022 01:43
-
-
Save Anaminus/135999033fa01a3b1491b0d0e54b6f68 to your computer and use it in GitHub Desktop.
Wrangle package-structured projects to be more DataModel-friendly via Rojo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--[[ | |
NOTICE: Requires unreleased version of rbxmk | |
https://github.com/Anaminus/rbxmk | |
Usage: | |
local Build = rbxmk.runFile("Build.rbxmk.lua")) | |
Build.package: | |
Build.package("pkg", { | |
server = "src/server", | |
client = "src/client", | |
shared = "src/shared", | |
}) | |
Unpacks "packages" of modules. The first argument is a path to a directory | |
containing packages. The second argument is a map of package component names | |
to destination paths. | |
Each directory under the packages directory is a package. A file under a | |
package is a component if its stem name matches a specified component name. | |
In the destination, a "pointer" file is created to point back to the package | |
component. For example: | |
src/server/package.project.json => pkg/package/server.lua | |
Build.ref: | |
Build.ref("data, "src/data") | |
Creates a project file from the second argument that points back to the | |
first argument. For example: | |
src/data.project.json: | |
{ | |
"name": "data", | |
"tree": { | |
"$path": "../data" | |
} | |
} | |
Build.clean: | |
Build.clean("src") | |
Remove any files and directories from the first argument that haven't been | |
touched by the library. | |
]] | |
local export = {} | |
local touchedFiles = {} | |
local function touch(file) | |
touchedFiles[file] = true | |
end | |
local function clean(dir) | |
local t = {} | |
for touched in pairs(touchedFiles) do | |
local touchedFile = "" | |
for _, element in ipairs({path.explode(touched)}) do | |
touchedFile = path.join(touchedFile, element) | |
t[touchedFile] = true | |
end | |
end | |
for _, file in ipairs(fs.dir(dir)) do | |
local fullPath = path.join(dir, file.Name) | |
if t[fullPath] then | |
if file.IsDir then | |
clean(fullPath) | |
end | |
else | |
fs.remove(fullPath, true) | |
print("remove", fullPath) | |
end | |
end | |
end | |
export.clean = clean | |
local function ref(target, project) | |
local dir, name = path.split(project, "dir", "stem") | |
project = path.join(dir, name .. ".project.json") | |
local relPath = path.rel(dir, target) | |
if relPath == nil then | |
error(string.format("cannot make target %q relative to base %q", target, dir)) | |
end | |
if fs.stat(project) then | |
print("write", project) | |
else | |
print("create", project) | |
end | |
fs.mkdir(dir, true) | |
touch(project) | |
fs.write(project, {name=name, tree={["$path"]=relPath}}, {Format="json", Indent=""}) | |
end | |
export.ref = ref | |
function export.package(packagesDir, components) | |
local packageNames = {} | |
local packages = fs.dir(packagesDir) | |
for _, file in ipairs(packages) do | |
if file.IsDir then | |
packageNames[file.Name] = true | |
end | |
end | |
-- Generate references. | |
local toWrite = {} | |
for _, package in ipairs(packages) do | |
if package.IsDir then | |
local packageDir = path.join(packagesDir, package.Name) | |
for _, file in ipairs(fs.dir(packageDir)) do | |
local component = path.split(file.Name, "stem") | |
local basePath = components[component] | |
if basePath then | |
local target = path.join(packageDir, file.Name) | |
local project = path.join(basePath, package.Name) | |
table.insert(toWrite, {target=target, project=project}) | |
end | |
end | |
end | |
end | |
table.sort(toWrite, function(a,b) return a.project < b.project end) | |
-- Apply changes. | |
for _, file in ipairs(toWrite) do | |
ref(file.target, file.project) | |
end | |
end | |
return export |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment