2017-09-03 49 views
3

失敗我試圖重新打包爲泊塢容器是由主模塊和一些輔助模塊的一些Lua的庫。助手模塊保持在庫的子文件夾內,以便從主文件導入作爲的Lua:相對進口來自不同的工作目錄

require 'helpers/SomeHelper' 

的問題是做:因爲這樣,我想泊塢窗容器中運行,這將是,如果非常有幫助我可以從不同的工作文件夾調用這個庫。也就是說,我打電話給主程序就像

th /app/main.lua 

不管我的實際工作目錄。不幸的是,當工作目錄與主文件所在的目錄不同時,相對導入似乎失敗。

有什麼辦法我可以配置LUA_PATH或任何其他機制,使這些進口正常工作?請注意,更改庫本身的代碼將是一個糟糕的解決方案,因爲它不是我開發的,我希望能夠輕鬆地將它更新到新版本。

回答

1

如果你不關心的工作目錄,你可以加載lfs/LuaFileSytem和使用lfs.chdir(src_dir)更改爲源目錄(可能挽救當前的工作目錄與lfs.currentdir()第一。)

你也可以擴展Lua的search path,以便它將搜索那些額外的目錄。搜索由package.searchpath驅動。到一個目錄/foo/bar/添加到支持所有通常支持的庫佈局的方式搜索,添加

  • /foo/bar/?.lua;/foo/bar/?/init.luapackage.path
  • /foo/bar/?.so(或.dylib.dll其他OSEN)到package.cpath

您可以使用多種方式來擴展路徑。行之有效

一種選擇是設置LUA_PATH/LUA_CPATH環境變量。 (在其中之一的;;序列將擴展爲完整的默認路徑。)這可以從.profile或其他安裝腳本通過早期export LUA_PATH="..."來完成,或通過設置變量,只是該呼叫LUA_PATH="..." lua /foo/bar.lua內聯(如果從包裝腳本啓動)。 (請注意,如果你在太廣泛的範圍導出此變量,其他的Lua腳本也將讓他們的路徑延伸,可能會發現潛在的不兼容的Lua庫)。

(您也可以手動從LUA_INIT修改package.(c)path。這樣,你將不能夠獨立地禁用LUA_INITLUA_PATH,但你可以使用所有的Lua動態生成的路徑。)

第三個選項(這可能是最好的在您的具體情況),是把的package.path延伸你的主要腳本的頂部,如

do 
    local dir = (arg[0]:match "^(.*)/$") 
    if dir then -- else cwd is . which works by default 
     package.path = dir.."/?.lua;"..dir.."/?/init.lua;"..package.path 
     package.cpath = dir.."/?.so;"..package.cpath 
    end 
end 

-- rest of your program goes here 

運行時使用Lua解釋腳本,arg[0]是腳本。因此,這擴展了包含程序目錄的路徑,無論它位於何處,它只會影響此特定腳本/程序的搜索路徑。

+0

完整的命名空間非常完整的答案!由於我在Docker容器中打包了應用程序,並且不想修改它的代碼,所以最適合我的選項是更改LUA_PATH環境變量。我只需聲明LUA_PATH =「/ app/?. lua;/app/helpers/?. lua ;;」使需求操作起作用。 – albarji

0

你不應該忘記,並非所有的模塊都直接從FS加載。 例如爲了提高性能,可以將文件讀取/編譯到內存,然後使用預加載表來提供從內存加載模塊的方式。 基本例如

--- preload code. It can be done by host application. 
local FooUtils = function() 
    return { 
    print = function(...) 
     print("foo", ...) 
    end 
    } 
end 

local Foo = function() 
    local Utils = require "foo.utils" 
    return { 
    foo = function() 
     Utils.print"hello" 
    end 
    } 
end 

package.preload['foo.utils'] = FooUtils 
package.preload['foo'] = Foo 

--- main application 
require "foo".foo() 

在這個例子中假設FooUtilsFoo編譯的模塊只是例子。 例如它可以像FooUtils = loadstring('path/to/utils.lua),即使在單獨的Lua狀態下也可以完成 ,然後在任何其他狀態下使用。 請務必記住Foo模塊不知道主機應用程序如何查找foo.utils。 所以沒有提供原始文件路徑或相關路徑的標準方法。 所以,如果你寫了一些模塊,在相對路徑上有中繼,那麼這個模塊 可能在某些環境下不起作用。 因此,我只是建議使用像require 'foo.utils'而不是require 'utils'

+0

我不明白這應該如何幫助解決這個問題。特別是,這是如何解決_「請注意,更改庫本身的代碼本身將是一個糟糕的解決方案,因爲它不是我開發的,我希望能夠輕鬆地將它更新到新版本。」_部分? ('require「foo.bar」'_inside_使用的庫是問題的一部分。) – nobody

+0

我只是說不要使用相對路徑,因爲lua並不能很好地支持它。可以將'/ app/?. lua'添加到LUA_PATH中。但是它不應該在系統範圍內,而只適用於這個特定的腳本。例如。通過一些啓動腳本 – moteus