lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

lua-language-server --check always return subprocess::spawn: (system:2)No such file or directory

Open Freed-Wu opened this issue 1 year ago • 1 comments

How are you using the lua-language-server?

Command Line

Which OS are you using?

Linux

What is the issue affecting?

Diagnostics/Syntax Checking

Expected Behaviour

NO error.

Actual Behaviour

❯ lua-language-server --check
subprocess::spawn: (system:2)No such file or directory

Reproduction steps

lua-language-server --check

Additional Notes

No response

Log File

No response

Freed-Wu avatar May 27 '24 14:05 Freed-Wu

It seems to me, that this patch https://github.com/LuaLS/lua-language-server/commit/38d83324671b4110614dbef30acef4a1543ee065 made it stop working.

The offending line is this one https://github.com/LuaLS/lua-language-server/blob/e2ca72dd54da1cafda36ff9e1266526fec54081f/script/cli/check.lua#L11

It looks like the executable name is in arg[-2] instead of arg[-1]. For me, arg[-1] holds -E, which is used as the program name when executing the check workers (confirmed by strace)

syyyr avatar Jun 04 '24 07:06 syyyr

Strange enough 😕 on windows and macos, arg[-1] works perfectly while arg[-2] is nil

Moreover I've been using LuaLS in my projects github action lint workflow, which uses the ubuntu-latest vm and it works normally as well. The gha step cmd that I used is simply:

      - name: Run LuaLS
        run: |
          ${LUALS_PATH}/bin/lua-language-server --check=. --num_threads=2 --checklevel=Error

Would the issue that you encountered is environment specific?

  • Which shell did you use?
  • Did you use symlink for the lua-language-server binary, or use some custom launch script?

And as a side note, after PR #2638 added multi-thread support, now the --check needs a directory string argument. i.e. if you want to check the current directory, you have to use --check=. otherwise you will get an error The argument of CHECK must be a string, but got boolean

tomlau10 avatar Jul 30 '24 01:07 tomlau10

Can you print out all the values of negative index of arg[] until it is nil? Use something like this:

local exe = arg[-1]
local minIndex = -1
while arg[minIndex] do minIndex = minIndex - 1 end
for i = minIndex+1, #arg do
    print(i, arg[i])
end

  • On my win10 desktop triggering through powershell, arg[-1] is the correct argument for exe 😕
PS C:\Users\TomLau> C:\Users\TomLau\.vscode\extensions\sumneko.lua-3.9.3-win32-x64\server\bin\lua-language-server.exe --check
-1      C:\Users\TomLau\.vscode\extensions\sumneko.lua-3.9.3-win32-x64\server\bin\lua-language-server.exe
0       C:/Users/TomLau/.vscode/extensions/sumneko.lua-3.9.3-win32-x64/server\main.lua
1       --check
The argument of CHECK must be a string, but got boolean
  • On my macbook macOS 11.6 triggering through bash terminal, arg[-1] is also correct
$ ~/.vscode/extensions/sumneko.lua-3.9.3-darwin-x64/server/bin/lua-language-server --check
-1	/Users/tomlau10/.vscode/extensions/sumneko.lua-3.9.3-darwin-x64/server/bin/lua-language-server
0	/Users/tomlau10/.vscode/extensions/sumneko.lua-3.9.3-darwin-x64/server/main.lua
1	--check
The argument of CHECK must be a string, but got boolean

tomlau10 avatar Jul 30 '24 01:07 tomlau10

For me, arg[-1] holds -E

From the manpage of lua cli:

$ lua --help
lua: unrecognized option '--help'
usage: lua [options] [script [args]]
Available options are:
  -e stat   execute string 'stat'
  -i        enter interactive mode after executing 'script'
  -l mod    require library 'mod' into global 'mod'
  -l g=mod  require library 'mod' into global 'g'
  -v        show version information
  -E        ignore environment variables
  -W        turn warnings on
  --        stop handling options
  -         stop handling options and execute stdin
  • -E means ignore environment variables

And all the cmd line arguments before the script name will go to arg[negavtive index] (ref: https://www.lua.org/pil/1.4.html) Somehow in your environment / launch script, luals is invoked with a -E option 😕

tomlau10 avatar Jul 30 '24 04:07 tomlau10

Hi, this is the output, if I add

local minIndex = -1
while arg[minIndex] do minIndex = minIndex - 1 end
for i = minIndex+1, #arg do
    print(i, arg[i])
end
$ lua-language-server --check=.
-2	/usr/lib/lua-language-server/bin/lua-language-server
-1	-E
0	/usr/lib/lua-language-server/main.lua
1	--logpath=/tmp/lua-language-server-1000/instance.RjoR/log
2	--metapath=/tmp/lua-language-server-1000/instance.RjoR/meta
3	--check=.
subprocess::spawn: (system:2)No such file or directory

I'm not so sure what /usr/lib/lua-language-server/bin/lua-language-server is, but this is what ships lua-language-server on Arch Linux: https://gitlab.archlinux.org/archlinux/packaging/packages/lua-language-server/-/blob/main/PKGBUILD

syyyr avatar Jul 30 '24 13:07 syyyr

Yes, I found this out here https://github.com/LuaLS/lua-language-server/pull/2775#issuecomment-2257602799

In this archlinux lua-lanugage-server package, lua-language-server points to a launch script in /usr/sbin/lua-language-server, and the -E comes from this launch script:

#!/usr/bin/env sh
TMPPATH="/tmp/lua-language-server-$(id -u)"
mkdir -p "$TMPPATH"
INSTANCEPATH=$(mktemp -d "$TMPPATH/instance.XXXX")
DEFAULT_LOGPATH="$INSTANCEPATH/log"
DEFAULT_METAPATH="$INSTANCEPATH/meta"

exec /usr/lib/lua-language-server/bin/lua-language-server -E /usr/lib/lua-language-server/main.lua \
  --logpath="$DEFAULT_LOGPATH" --metapath="$DEFAULT_METAPATH" \
  "$@"

https://gitlab.archlinux.org/archlinux/packaging/packages/lua-language-server/-/blob/main/wrapper

I would say that this wrapper is overly complicated. 😕 It should be simply exec /usr/lib/lua-language-server/bin/lua-language-server "$@" as suggested in LuaLS Q&A here: https://luals.github.io/#other-install If possible, I suggest creating an issue to the package maintainer to simplify the wrapper script.

But I agree that we cannot just assume arg[-1] is the exe name, we should find it at the most negative index of arg[] that is non nil and #2775 by @Freed-Wu should fix this 👍 🎉


I'm not so sure what /usr/lib/lua-language-server/bin/lua-language-server

It is the real binary path of LuaLS. And if you execute /usr/lib/lua-language-server/bin/lua-language-server --check=., everything will work perfectly. So before LuaLS releasing a new version, in the meantime you can either modify you launch script locally, or use full exe path to trigger a check. 😄 @syyyr

tomlau10 avatar Jul 30 '24 15:07 tomlau10

And if you execute /usr/lib/lua-language-server/bin/lua-language-server --check=.,

There is definitely a need for some sort of a wrapper, otherwise I do get a few errors:

$ /usr/lib/lua-language-server/bin/lua-language-server --check=.
create_directories: "/usr/lib/lua-language-server/meta/Lua 5.1 en-us utf8": (generic:13)Permission denied
stack traceback:
	[C]: in function 'bee.filesystem.create_directories'
	script/library.lua:233: in function <script/library.lua:231>
	[C]: in function 'xpcall'
	script/library.lua:231: in upvalue 'initBuiltIn'
	script/library.lua:670: in upvalue 'callback'
	script/workspace/workspace.lua:31: in function <script/workspace/workspace.lua:30>
create_directories: "/usr/lib/lua-language-server/meta/Lua 5.4 en-us utf8": (generic:13)Permission denied
stack traceback:
	[C]: in function 'bee.filesystem.create_directories'
	script/library.lua:233: in function <script/library.lua:231>
	[C]: in function 'xpcall'
	script/library.lua:231: in upvalue 'initBuiltIn'
	script/library.lua:670: in upvalue 'callback'
	script/workspace/workspace.lua:31: in function <script/workspace/workspace.lua:30>
Diagnosis complete, 117 problems found, see /usr/lib/lua-language-server/log/check.json

AFAIK, this is due to logpath and metapath defaults not being writable by a normal user. Anyway, it seems to me, that just removing -E from the wrapper is a correct thing. I'm currently in the process of reporting that to Arch Linux upstream (waiting until the create my account).

It should be simply exec /usr/lib/lua-language-server/bin/lua-language-server "$@"

I think the reason the wrapper specifies the entrypoint is to be 100% sure it is the one that the PKGBUILD script installs (and I suppose just for readability's sake). Also, it could be that '... omitted, the application will attempt to load bin/../main.lua' is not clear enough (but that might just be me).

syyyr avatar Jul 30 '24 17:07 syyyr

There is definitely a need for some sort of a wrapper, otherwise I do get a few errors:

OIC, I just tested that in docker environment yesterday, so maybe I did not encounter these kinds of permission errors.


Also, it could be that '... omitted, the application will attempt to load bin/../main.lua' is not clear enough

You got your point. I never noticed that luals cli supports an entry argument. 🙈 I just always invoke it by the binary file directly on windows / macos / ubuntu (github action) platforms.

And from the bootstrap logic, luals will try the find if there is an entry argument (the script file) and treat it as the main script index => put it at arg[0]. All the arguments before that will goes to negative index. So I think #2775 would be a proper fix for this issue 👍

tomlau10 avatar Jul 31 '24 01:07 tomlau10

As far as I can tell, there's no reason to run lua-language-server with the -E flag (or at least there is none documented here), so I opened up an issue in Arch Linux: https://gitlab.archlinux.org/archlinux/packaging/packages/lua-language-server/-/issues/1

syyyr avatar Jul 31 '24 08:07 syyyr