Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions src/base/_foundation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -227,8 +227,22 @@
table.insert(filenames, path.getabsolute(fname, _SCRIPT_DIR))
end

local compiled_chunk
local res = os.locate(table.unpack(filenames))
local compiled_chunk = nil
local res = nil

-- First try to find the file directly on file system.
for _, candidate in ipairs(filenames) do
if os.isfile(candidate) then
res = path.getabsolute(candidate)
break
end
end

-- If that fails, try to find the file using the search paths.
if res == nil then
res = os.locate(table.unpack(filenames))
end

if res == nil then
local caller = filelineinfo(3)
premake.error(caller .. ": Cannot find neither " .. table.implode(filenames, "", "", " nor "))
Expand Down
51 changes: 51 additions & 0 deletions tests/base/test_include.lua
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,54 @@
includeexternal (_TESTS_DIR .. "/folder/premake5.lua")
test.isequal("okokok", p.captured())
end


--
-- Tests for local-first search priority (fix for issue #1783):
-- Local files must be found before identically-named files in premake.path.
--

-- Helper: run fn with CWD and premake.path temporarily overridden.
local function withLocalPriority(cwd, searchPath, fn)
local savedPath = premake.path
local savedCwd = os.getcwd()
premake.path = searchPath
os.chdir(cwd)
local ok, err = pcall(fn)
os.chdir(savedCwd)
premake.path = savedPath
if not ok then error(err, 2) end
end

-- A local "name/premake5.lua" must be preferred over a plain file named
-- "name" that lives only in a premake.path search directory.
function suite.findProjectScript_prefersLocalSubdir_overPathDecoy()
local folder = _TESTS_DIR .. "/folder"
withLocalPriority(folder, folder .. "/subfolder", function()
local res, _ = premake.findProjectScript("shadowlib")
test.isequal(
path.normalize(folder .. "/shadowlib/premake5.lua"),
path.normalize(res))
end)
end

-- A local "name.lua" must be preferred over a plain file named "name"
-- (no extension) that lives only in a premake.path search directory.
function suite.findProjectScript_prefersLocalLuaFile_overPathDecoy()
local folder = _TESTS_DIR .. "/folder"
withLocalPriority(folder, folder .. "/subfolder", function()
local res, _ = premake.findProjectScript("ok")
test.isequal(
path.normalize(folder .. "/ok.lua"),
path.normalize(res))
end)
end

-- Verify the full include() call for the subdir-priority scenario.
function suite.include_prefersLocalSubdir_overPathDecoy()
local folder = _TESTS_DIR .. "/folder"
withLocalPriority(folder, folder .. "/subfolder", function()
include("shadowlib")
end)
test.isequal("shadowlocal", p.captured())
end
1 change: 1 addition & 0 deletions tests/folder/shadowlib/premake5.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
premake.out("shadowlocal")
1 change: 1 addition & 0 deletions tests/folder/subfolder/ok
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- decoy: this file should NOT be loaded by include("ok") when a local ok.lua exists
1 change: 1 addition & 0 deletions tests/folder/subfolder/shadowlib
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-- decoy: this file should NOT be loaded by include("shadowlib") when a local shadowlib/ directory exists
4 changes: 3 additions & 1 deletion website/docs/globals/include.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ include("path")

### Parameters ###

`path` is the file system path to a script file or a directory. If a directory is specified, Premake looks for a file named `premake5.lua` in that directory and runs it if found.
`path` is the file system path to a script file or a directory. If a directory is specified, Premake looks for a file named `premake5.lua` in that directory and runs it if found. If the `.lua` extension is omitted from the file name, Premake will also look for a file with that extension.

See [Locating Scripts](Locating-Scripts.md) for more information about how script files are located.

If the file or directory specified has already been included previously, the call is ignored. If you want to execute the same script multiple times, use Lua's [dofile()](http://www.lua.org/manual/5.1/manual.html#pdf-dofile) instead.

Expand Down
Loading