Lua Nested Require Path

1k Views Asked by At

I'm writing a tool to parse lua plugins created by other users. The only guarentee about the plugin is that it has a data.lua file in a known directory. Inside there users are free to do anything they wish. This particular plugin using require to load a file and that file loads another file. Both are relative paths but the second is relative to the location of the first file.

  • data.lua
  • foo/bar.lua
  • foo/baz.lua

data.lua:

require("foo.bar")

foo/bar.lua:

require("baz")

When I try to execute data.lua I get an error when foo/bar.lua tries to require "baz". None of the paths it tries are ./foo/.

Any idea how I can fix this? I could find any documentation specifically about this case, it seemed like I need to hard code /foo/ into the path but I don't know it ahead of time. This seems like something that should be automatic is there a setting I'm missing or am I running the wrong version of lua? I'm using NLua 4.0

Thanks

2

There are 2 best solutions below

0
On BEST ANSWER

I tested this script using node-lua and it fixes the issue for me!

https://gist.github.com/hoelzro/1299679

Relavent code:

local oldrequire = require

function require(modname)
  local regular_loader = package.loaders[2]
  local loader = function(inner)
    if string.match(modname, '(.*)%.') then
      return regular_loader(string.match(modname, '(.*)%.') .. '.' .. inner)
    end
  end

  table.insert(package.loaders, 1, loader)
  local retval = oldrequire(modname)
  table.remove(package.loaders, 1)

  return retval
end

To get this to work with Lua 5.2 change all uses of package.loaders to package.searchers.

Also if you want to override the global require function you need this snippet as well:

_G.require = require
2
On

You can alter the search behavior of require by changing the package.path variable.

Resources on package.path:

https://www.lua.org/manual/5.3/manual.html#pdf-package.path

http://lua-users.org/wiki/PackagePath

Example adding foo folder to search locations:

package.path = package.path .. ';./foo/?.lua'

the ? character will be where the string passed to require is placed.


Alternatively you can add a default file to load, to the package.path:

package.path = package.path .. ';./nested_require.lua' 

Then define the behavior you would like within this file. You can use the global variable _REQUIREDNAME to reference the value passed to the require function.

The documentation for this method can be found here at the bottom of the page: https://www.lua.org/pil/8.1.html