20 August 2019 Link


Many2One is a utility to combine multiple lua source files into 1 file for easy usage and distribution. It consists of a lua file (many2one.lua) and an associated configuration file containing all the run information.


Suppose you have an application with 2 files. main.lua which requires req.lua and their contents are:
  1. require("req")
  3. a = 4
  4. print(a+b)
  5. print(c)

  1. local _G = G
  3. local M = {}
  4. _ENV = M
  6. _G.c=10

After running many2one with the config.lua of:
  1. -- Config.Lua file for many2one
  2. fileList = { "req.lua"}
  4. mainFile = "main.lua"
  5. outputFile = "MainApp.lua"

The MainApp.lua file is something like:
  1. do
  2. local __MANY2ONEFILES={}
  3. local reqCopy = require
  4. require = function(str)
  5. if __MANY2ONEFILES[str] then
  6. if not package.loaded[str] then
  7. package.loaded[str] = true
  8. local res = load(__MANY2ONEFILES[str])
  9. res = res(str)
  10. if res ~= nil then
  11. package.loaded[str] = res
  12. end
  13. end
  14. return package.loaded[str]
  15. else
  16. return reqCopy(str)
  17. end
  18. end
  19. __MANY2ONEFILES['req']="local _G = G\
  20. \
  21. local M = {}\
  22. _ENV = M\
  23. \
  24. _G.c=10"
  25. end
  26. require("req")
  28. a = 4
  29. print(a+b)
  30. print(c)


Default configuration file config.lua

At the command prompt type:
> lua many2one.lua

This command opens up config.lua and combines all the source files listed into the indicated output file

Specified configuration file

At the command prompt type:
> lua many2one.lua myconfig.lua

This command uses the configuration file myconfig.lua and combines all the source files listed in the indicated output file

The configuration file

A sample configuration file is shown below:
  1. -- Config.Lua file for many2one
  2. fileList = {
  3. "req.lua",
  4. "req1.lua",
  5. "req2.lua",
  6. {"ssl/https.lua","ssl.https"},
  7. {"socket/http.lua","socket.http"},
  8. {"socket/url.lua","socket.url"},
  9. }
  11. mainFile = "main.lua"
  12. outputFile = "MainApp.lua"

It's simple to understand. The main program file is added in the variable mainFile. The output file name is added in the variable outputFile. All the other files required by the mainFile or other files during run time are added as a list in the table fileList. If the list element is a table then the 1st item of the table is the path where to find that file and the 2nd item is the string which when required points to that file. So in the above case a require "ssl.https" would return the module that was loaded from ssl/https.lua file.

And that is it.

How does it work

many2one takes the main program file and wraps the require function so that when require is called it first checked if the required file is present in the files packed in. If yes it returns the packed file otherwise it lets the original require function (stored in reqCopy) do the job.
  1. require = function(str)
  2. if __MANY2ONEFILES[str] then
  3. if not package.loaded[str] then
  4. package.loaded[str] = true
  5. local res = load(__MANY2ONEFILES[str])
  6. res = res(str)
  7. if res ~= nil then
  8. package.loaded[str] = res
  9. end
  10. end
  11. return package.loaded[str]
  12. else
  13. return reqCopy(str)
  14. end
  15. end

It includes all the Lua files listed in the fileList of the config file as a string in the table __MANY2ONEFILES.

Download and Install

Download from the github repository. It is just a single script file called many2one.lua
You can also install using LuaRocks:
luarocks install many2one
Once installed through LuaRocks you can directly run the script from the command line as:
>many2one.lua config.lua