{"id":13896468,"url":"https://github.com/siffiejoe/lua-amalg","last_synced_at":"2025-12-27T15:04:16.873Z","repository":{"id":3893540,"uuid":"13974284","full_name":"siffiejoe/lua-amalg","owner":"siffiejoe","description":"Amalgamation of Lua modules/scripts","archived":false,"fork":false,"pushed_at":"2022-11-05T09:30:57.000Z","size":370,"stargazers_count":121,"open_issues_count":0,"forks_count":19,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-11-25T02:32:04.433Z","etag":null,"topics":["amalgamation","lua"],"latest_commit_sha":null,"homepage":null,"language":"Lua","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/siffiejoe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-10-30T01:46:25.000Z","updated_at":"2024-08-29T21:30:16.000Z","dependencies_parsed_at":"2023-01-11T16:33:41.677Z","dependency_job_id":null,"html_url":"https://github.com/siffiejoe/lua-amalg","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/siffiejoe/lua-amalg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-amalg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-amalg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-amalg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-amalg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/siffiejoe","download_url":"https://codeload.github.com/siffiejoe/lua-amalg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/siffiejoe%2Flua-amalg/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28080199,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-27T02:00:05.897Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["amalgamation","lua"],"created_at":"2024-08-06T18:02:56.562Z","updated_at":"2025-12-27T15:04:16.849Z","avatar_url":"https://github.com/siffiejoe.png","language":"Lua","readme":"#            Amalg -- Amalgamation of Lua Modules/Scripts            #\n\n[![Test Status](https://github.com/siffiejoe/lua-amalg/workflows/run-tests/badge.svg)](https://github.com/siffiejoe/lua-amalg/actions?workflow=run-tests)\n[![Linter Status](https://github.com/siffiejoe/lua-amalg/workflows/run-linters/badge.svg)](https://github.com/siffiejoe/lua-amalg/actions?workflow=run-linters)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/siffiejoe/lua-amalg#license)\n![Lua Versions](https://img.shields.io/badge/Lua-5.1%20|%205.2%20|%205.3%20|%205.4-blue.svg)\n\n\n##                           Introduction                           ##\n\nDeploying a Lua application that is split among multiple modules is a\nchallenge. A tool that can package a Lua script and its modules into\na single file is a valuable help. This is such a tool.\n\nFeatures:\n\n*   Pure Lua (compatible with Lua 5.1 and up), no other external\n    dependencies (plugins may have external dependencies).\n*   Even works for modules using the deprecated `module` function.\n*   You don't have to take care of the order in which the modules are\n    `require`'d.\n*   Can embed compiled C modules.\n*   Can collect `require`'d Lua (and C) modules automatically.\n*   Can compress/decompress or precompile using plugin modules.\n\nWhat it doesn't do:\n\n*   It doesn't do static analysis of Lua code to collect `require`'d\n    modules. That won't work reliably anyway. You can write your own\n    program for that (using the output of `luac -p -l`), or use\n    [squish][1], or [soar][2] instead.\n*   It doesn't handle the dependencies of C modules, so it is best\n    used on C modules without dependencies (e.g. LuaSocket, LFS,\n    etc.) or with statically linked C modules.\n\nThere are alternatives to this program: See [squish][1], [soar][2],\n[luac.lua][3], [luacc][4], [many2one][5], and [bundle.lua][6] (and\nprobably some more).\n\n  [1]: https://code.matthewwild.co.uk/squish/\n  [2]: http://lua-users.org/lists/lua-l/2012-02/msg00609.html\n  [3]: https://www.tecgraf.puc-rio.br/~lhf/ftp/lua/5.1/luac.lua\n  [4]: https://github.com/mihacooper/luacc\n  [5]: https://github.com/aryajur/many2one\n  [6]: https://github.com/akavel/scissors/blob/master/tools/bundle/bundle.lua\n\n\n##                          Getting Started                         ##\n\nYou can bundle a collection of modules in a single file by calling the\n`amalg.lua` script and passing the module names on the command-line.\n\n    ./amalg.lua module1 module2\n\nThe modules are collected using `package.path`, so they have to be\navailable there. You can use the usual environment variables (e.g.\n`LUA_PATH`) to adjust the contents of `package.path`. The resulting\nmerged Lua code will be written to the standard output stream. You\nhave to run the code to make the embedded Lua modules available for\n`require`.\n\nYou can specify an output file to use instead of the standard output\nstream.\n\n    LUA_PATH=\"../src/?.lua;;\" ./amalg.lua -o out.lua module1 module2\n\nYou can also embed the main script of your application in the merged\nLua code as well. Of course the embedded Lua modules can be\n`require`'d in the main script. The main script is specified as a\nfilename or path, not a module name (it isn't a module after all). (It\n*could* be a module, but in that case the amalgamation file has to be\n`require`'d before the other embedded modules become available!)\n\n    lua amalg.lua -o out.lua -s main.lua module1 module2\n\nIf you want the original filenames and line numbers to appear in\nerror messages, you have to activate debug mode. This will require\nslightly more memory, however.\n\n    ./amalg.lua -o out.lua -d -s main.lua module1 module2\n\nTo collect all Lua (and C) modules used by a program, you can load the\n`amalg.lua` script as a module, and it will intercept calls to\n`require` and save the necessary Lua module names in a file\n`amalg.cache` in the current directory.\n\n    lua -lamalg main.lua\n\nMultiple runs will add to this module cache. But don't access it from\nmultiple concurrent processes!\n\nYou can use the cache (in addition to all module names given on the\ncommand-line) using the `-c` flag.\n\n    ./amalg.lua -o out.lua -s main.lua -c\n\nTo use a custom file as cache specify `-C \u003cfile\u003e`:\n\n    ./amalg.lua -o out.lua -s main.lua -C myamalg.cache\n\nHowever, this will only embed the Lua modules. To also embed C modules\n(both from the cache and from the command-line), you have to specify\nthe `-x` flag:\n\n    ./amalg.lua -o out.lua -s main.lua -c -x\n\nThis will make the amalgamated script platform and Lua version\ndependent, obviously! And it will not embed any external shared\nlibraries that those modules might depend on. If your compiled C\nmodules do have external dependencies, your best bet is to bundle the\nDLLs with the amalgamated Lua script (on Windows) or install the\nrequired dependencies on the target machine using the OSes package\nmanager (e.g. on Linux).\n\nIn some cases you may want to ignore automatically listed modules in\nthe cache without editing the cache file. Use the `-i` option for that\nand specify a Lua pattern:\n\n    ./amalg.lua -o out.lua -s main.lua -c -i \"^luarocks%.\"\n\nThe `-i` option can be used multiple times to specify multiple\npatterns.\n\nUsually, the amalgamated modules take precedence over locally\ninstalled (possibly newer) versions of the same modules. If you want\nto use local modules when available and only fall back to the\namalgamated code otherwise, you can specify the `-f` flag.\n\n    ./amalg.lua -o out.lua -s main.lua -c -f\n\nThis installs another searcher/loader function at the end of the\n`package.searchers` (or `package.loaders` on Lua 5.1) and adds a new\ntable `package.postload` that serves the same purpose as the standard\n`package.preload` table.\n\nTo fix a compatibility issue with Lua 5.1's vararg handling,\n`amalg.lua` by default adds a local alias to the global `arg` table to\nevery loaded module. If for some reason you don't want that, use the\n`-a` flag (but be aware that in Lua 5.1 with `LUA_COMPAT_VARARG`\ndefined (the default) your modules can only access the global `arg`\ntable as `_G.arg`).\n\n    ./amalg.lua -o out.lua -a -s main.lua -c\n\nThere is also some compression/decompression support handled via\nplugins to `amalg`. To select a compression plugin by name use the\n`-z` option. The necessary decompression code typically is embedded in\nthe result and executed automatically at runtime (may depend on the\nplugin).\n\n    ./amalg.lua -o out.lua -s main.lua -c -z brieflz\n\nSome plugins generate valid Lua code (text or binary) and thus don't\nneed a decompression step. For those modules the `-t` option should be\nused instead to avoid embedding no-op decompression code in the final\namalgamation file. Multiple compression/transformation steps are\npossible, and they are executed in the given order.\n\n    ./amalg.lua -o out.lua -s main.lua -c -t luasrcdiet -t luac -z brieflz\n\nNote that compression is usually most effective when applied to the\ncomplete amalgamation script instead of just individual modules:\n\n    ./amalg.lua -s main.lua -c | ./amalg.lua -o out.lua -s- -t luasrcdiet -z brieflz\n\nTransformation plugins can also be used for transpiling some Lua\ndialect to plain Lua code during amalgamation. But plugins cannot\nmodify the shebang line of the resulting script, so you should set one\nyourself if your main script contains one unsuitable for plain Lua\ncode:\n\n    ./amalg.lua -o out.lua -s main.moon -S \"/usr/bin/env lua\" -c -t moonscript\n\nIf you want to bundle some other read-only files with your amalgamated\nscript, you can do so with virtual IO and the `-v` switch:\n\n    ./amalg.lua -s main.lua -c -v template.txt\n\nThis will embed `template.txt` in the amalgamated script and\nmonkey-patch the file IO functions if (and only if) the resource is\nopened *read-only*. This command-line switch may be used multiple times\nfor multiple virtual resources. The file path has to match exactly or\nelse normal file IO is used.\n\n    ./amalg.lua -h\n\nwill list all available options (most options are also available as\nlong options).\n\nThat's it. For further info consult the source (there's a nice\n[annotated HTML file][7] rendered with [Docco][8] on the GitHub\npages). Have fun!\n\n  [7]: https://siffiejoe.github.io/lua-amalg/\n  [8]: https://ashkenas.com/docco/\n\n\n##                              Plugins                             ##\n\n`amalg.lua` uses two kinds of plugins: transformation plugins and\ncompression plugins. Transformation plugins are Lua modules that are\ncalled only during amalgamation. Compression plugins consist of two\nseparate Lua modules that are called during amalgamation and at\nruntime to undo the modifications made during amalgamation,\nrespectively. Since transformation plugins don't have a reverse\ntransformation step, they are expected to produce valid Lua code (or\nLua binary code). They are used only on pure Lua files (modules or\nmain script). Compression plugins on the other hand are used on both\nLua files and compiled C modules.\n\nA transformation plugin (used with the command-line option `-t\n\u003cname\u003e`) is implemented as a Lua module `amalg.\u003cname\u003e.transform`. The\nmodule exports a function that takes a string (the input source), a\nboolean (whether the input source is in Lua source code format), and\nthe original file path as arguments. It must return a string (the\ntransformed input) and a boolean indicating whether the result is Lua\nsource code. It is good practice to handle the case where the input is\nnot in Lua source code format (but Lua binary code) by skipping the\ntransformation in this case.\n\nA compression plugin (used with the command-line option `-z \u003cname\u003e`)\nis implemented as two separate Lua modules `amalg.\u003cname\u003e.deflate` and\n`amalg.\u003cname\u003e.inflate`. The deflate part of the plugin works exactly\nlike a transformation plugin module. It is called during amalgamation\nand may freely use external dependencies. The inflate module should be\nimplemented as a self-contained pure Lua module as it is embedded into\nthe amalgamation for the decompression step during runtime. This\nmodule exports a function taking the compressed input as a string and\nreturning the decompressed output as string as well.\n\nThere are currently a few predefined plugins available:\n\n###                           luac Plugin                          ###\n\nThe `luac` plugin is a transformation plugin that compiles Lua source\ncode into stripped Lua binary code. It doesn't have any external\ndependencies and passes through binary input (i.e. already compiled\nLua code) unmodified. Note that binary Lua code may be larger than Lua\nsource code, especially when encoded in Lua's decimal escape notation.\nBinary Lua code is also platform dependent. It may or may not load\nfaster than regular Lua source code. It might make sense to\nadditionally precompile the entire amalgamated result using `luac`\nbecause you otherwise still depend on Lua source code lexer and\nparser, and compressed/binary code in the amalgamated script is bigger\nthan it needs to be because of the Lua decimal escape notation.\n\n###                        luasrcdiet Plugin                       ###\n\nThe `luasrcdiet` plugin is a transformation plugin that minifies Lua\nsource code by replacing names of local variables, stripping white\nspace, removing comments, etc. It passes through binary input (i.e.\nalready compiled Lua code) unmodified. You need to install the\n[luasrcdiet][9] module for the amalgamation step. The amalgamated\nscript doesn't have any extra dependencies. This transformation is a\ngood choice for reducing the size of the resulting amalgamated Lua\nscript.\n\n  [9]: https://luarocks.org/modules/jirutka/luasrcdiet\n\n###                      dumbluaparser Plugin                      ###\n\nThe `dumbluaparser` transformation plugin is a more recent alternative\nto the `luasrcdiet` plugin, and also minifies Lua source code. It may\nwork better with Lua 5.4-specific source code. As the name implies,\nthe [DumbLuaParser][16] module has to be available during amalgamation.\n\n  [16]: https://luarocks.org/modules/refreezed/dumbluaparser\n\n###                         brieflz Plugin                         ###\n\nThe `brieflz` plugin is a compression plugin that compresses its input\nduring amalgamation and decompresses it on the fly during runtime. The\ncompression step relies on the [brieflz][10] module which must be\navailable during amalgamation. The decompression step is performed by\na pure Lua port of the `blz_depack_safe` function from the\n[original C code][11] by Jørgen Ibsen (@jibsen). The decompression\ncode is embedded into the resulting amalgamation script, so no extra\ndependency is needed at runtime, but it adds about 2kB (1kB when\nminified with `luasrcdiet`) size overhead. Note that binary data in\nthe amalgamation is stored in standard Lua decimal escape notation, so\nit may be larger than usual. However, brieflz compression still\nreduces the size of the resulting amalgamation script in many cases,\nand you could precompile the result using the `luac` program (Lua\nbytecode doesn't need decimal escape notation).\n\n  [10]: https://luarocks.org/modules/jirutka/brieflz\n  [11]: https://github.com/jibsen/brieflz\n\n###                        moonscript Plugin                       ###\n\nThe `moonscript` plugin extends `package.path` when it is first loaded\nto search for `.moon` files in the same directories as for `.lua`\nfiles. `.moon` files take precedence. Then the plugin translates all\nnon-binary modules and scripts from moonscript code to Lua code during\namalgamation if the filename of the module or script ends in `.moon`.\nThe Lua modules of the [moonscript compiler][12] are used for this\ntranslation, so it needs to be installed for the amalgamation step.\nTransformation plugins don't have a way to change the shebang lines of\nthe amalgamated script, so you'll have to do that by hand if necessary\nusing the `-S`/`--shebang` option.\nThis plugin is well-behaved in the sense that it checks the file\nextension, so you can mix moonscript code, plain Lua code, and code\nfor other well-behaved transpiler plugins in one amalgamation.\n\n  [12]: https://luarocks.org/modules/leafo/moonscript\n\n###                           teal Plugin                          ###\n\nThe `teal` plugin works in a similar way as the `moonscript` plugin,\nbut it searches for and processes `.tl` files. The [`tl`][13] module\nis used for the source code transformation, so it must be available\nduring amalgamation.\n\n  [13]: https://luarocks.org/modules/hisham/tl\n\n###                          fennel Plugin                         ###\n\nThe `fennel` plugin works in a similar way as the `moonscript` and\n`tl` plugin, but it searches for and processes `.fnl` files. The\n[`fennel`][14] module is used for the source code transformation, so\nit must be available during amalgamation.\n\n  [14]: https://luarocks.org/modules/technomancy/fennel\n\n\n##                          Troubleshooting                         ##\n\n\u003e `amalg.lua` does not find modules in the cache file generated via\n\u003e `lua -lamalg`\n\n`lua -lamalg` records the module names exactly as they are used\n(`require`d) by the application. Therefore, you should always tweak\n`package.path` instead of \"fixing\" the cache file if a module can't be\nfound during amalgamation. This can happen if the application modifies\nits own `package.path` at runtime or changes its working directory.\n\n\u003e My environment does not support `require` or the `package` module!\n\nThat's unfortunate. This tool relies on a working `require` function\nand a minimal `package` module. See [this Stack Overflow post][15] for\nhow you can provide minimal stubs for the World of Warcraft\nenvironment. If you can't provide a shared `require` (and `package`)\nimplementation in your environment, you can use the `-p \u003cfile\u003e` switch\nto embed one very early in the amalgamation. Obviously this may cause\nproblems if multiple scripts use this technique, so a common, shared\napproach is preferred.\n\n  [15]: https://stackoverflow.com/questions/36871859/lua-emulating-the-require-function/36892318#36892318\n\n\n##                              Contact                             ##\n\nPhilipp Janda, siffiejoe(a)gmx.net\n\nComments and feedback are always welcome.\n\n\n##                              License                             ##\n\n`amalg` is *copyrighted free software* distributed under the MIT\nlicense (the same license as Lua 5.1). The full license text follows:\n\n    amalg (c) 2013-2021 Philipp Janda\n\n    Permission is hereby granted, free of charge, to any person obtaining\n    a copy of this software and associated documentation files (the\n    \"Software\"), to deal in the Software without restriction, including\n    without limitation the rights to use, copy, modify, merge, publish,\n    distribute, sublicense, and/or sell copies of the Software, and to\n    permit persons to whom the Software is furnished to do so, subject to\n    the following conditions:\n\n    The above copyright notice and this permission notice shall be\n    included in all copies or substantial portions of the Software.\n\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHOR OR COPYRIGHT HOLDER BE LIABLE FOR ANY\n    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","funding_links":[],"categories":["Lua"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiffiejoe%2Flua-amalg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsiffiejoe%2Flua-amalg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsiffiejoe%2Flua-amalg/lists"}