diff options
author | citrons <citrons@mondecitronne.com> | 2024-04-10 18:16:41 -0500 |
---|---|---|
committer | citrons <citrons@mondecitronne.com> | 2024-04-10 18:24:14 -0500 |
commit | 86425c8c93c8529cd2c88db1d0303fe980048896 (patch) | |
tree | 87d160b058ba0990d8c66631f3b776a6d2deb82f |
initial commit
-rw-r--r-- | README.md | 5 | ||||
-rw-r--r-- | bundler/init.lua | 81 | ||||
-rw-r--r-- | bundler/platform.lua | 69 | ||||
-rw-r--r-- | main.lua | 18 | ||||
-rw-r--r-- | makefile | 4 |
5 files changed, 177 insertions, 0 deletions
diff --git a/README.md b/README.md new file mode 100644 index 0000000..ba83255 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# lua bundling tool + +a bundler for lua programs. works inside and outside of computercraft. + +[public domain](https://creativecommons.org/publicdomain/zero/1.0/). diff --git a/bundler/init.lua b/bundler/init.lua new file mode 100644 index 0000000..799a398 --- /dev/null +++ b/bundler/init.lua @@ -0,0 +1,81 @@ +-- bundler. public domain. +-- https://citrons.xyz/git/cc-bundler.git + +local platform = require "bundler.platform" + +local function stringize(str, multiline) + local equal_signs = "=" + for e in string.gmatch(str, "](=*)]") do + if #e > #equal_signs then + equal_signs = e .. "=" + end + end + if multiline then + str = "\n"..str.."\n" + end + return ("[%s[%s]%s]"):format(equal_signs, str, equal_signs) +end + +local function module_name(path) + path = path:match "^(.*).lua$" or path + path = path:match "^%./(.*)$" or path + path = path:gsub("/+", ".") + path = path:gsub("^%.+", "") + path = path:gsub("%.+$", "") + path = path:match "^(.*)%.init$" or path + return path +end + +local function bundle_module(path) + if platform.is_dir(path) then + local modules = {} + for f in platform.list_dir(path) do + if f ~= "." and f ~= ".." then + table.insert( + modules, bundle_module(path.."/"..f)) + end + end + return table.concat(modules, "\n") + else + local name = module_name(path) + local content = platform.read(path) + return ("modules[ %s ] = %s"):format( + stringize(name), stringize(content, true)) + end +end + +local loader = [[ + +-- https://citrons.xyz/git/cc-bundler.git + +local load = loadstring or load + +local function loader(name) + if modules[name] then + local f = load(modules[name], name) + if setfenv then + setfenv(f, getfenv()) + end + return f + end +end +table.insert(package.loaders or package.searchers, 1, loader) + +return loader( %s )(...) + +]] + +local function bundle(main_module, other_modules) + local output = {"local modules = {}"} + + table.insert(output, bundle_module(main_module)) + for _, m in ipairs(other_modules) do + table.insert(output, bundle_module(m)) + end + + local loader = loader:format(stringize(module_name(main_module))) + + return table.concat(output, "\n")..loader +end + +return {bundle = bundle} diff --git a/bundler/platform.lua b/bundler/platform.lua new file mode 100644 index 0000000..2a69653 --- /dev/null +++ b/bundler/platform.lua @@ -0,0 +1,69 @@ +-- bundler. public domain. +-- https://citrons.xyz/git/cc-bundler.git + +local cc_host = {} + +function cc_host.error(msg) + printError(msg) +end + +function cc_host.list_dir(path) + local list = fs.list(shell.resolve(path)) + local i = 0 + return function() + i = i + 1 + return list[i] + end +end + +function cc_host.is_dir(path) + return fs.isDir(shell.resolve(path)) +end + +function cc_host.read(path) + local file = assert(fs.open(shell.resolve(path), "r")) + local data = assert(file.readAll()) + file.close() + return data +end + +function cc_host.write(path, content) + local file = assert(fs.open(shell.resolve(path), "w")) + file.write(content) + file.close() +end + +local normal_host = {} + +function normal_host.error(msg) + io.stderr:write(tostring(msg).."\n") + os.exit(-1) +end + +function normal_host.list_dir(path) + return require "lfs".dir(path) +end + +function normal_host.is_dir(path) + return require "lfs".attributes(path).mode == "directory" +end + +function normal_host.read(path) + local file = assert(io.open(path, "r")) + local data = assert(file:read "a") + file:close() + return data +end + +function normal_host.write(path, content) + local file = assert(io.open(path, "w")) + assert(file:write(content)) + file:close() +end + +if _HOST and _HOST:match "ComputerCraft" then + return cc_host +else + return normal_host +end + diff --git a/main.lua b/main.lua new file mode 100644 index 0000000..ac380c4 --- /dev/null +++ b/main.lua @@ -0,0 +1,18 @@ +-- bundler. public domain. +-- https://citrons.xyz/git/cc-bundler.git + +local bundler = require "bundler" +local platform = require "bundler.platform" + +local out, main_module = ... +local other_modules = {} +for i = 3, select("#", ...) do + table.insert(other_modules, (select(i, ...))) +end + +if not out or not main_module then + platform.error "usage: [output file] [main module] [other modules]..." + return +end + +platform.write(out, bundler.bundle(main_module, other_modules)) diff --git a/makefile b/makefile new file mode 100644 index 0000000..f85cddb --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +out/bundler.lua: main.lua bundler/* + mkdir -p out + lua main.lua out/bundler.lua main.lua bundler + chmod +x out/bundler.lua |