koalaman / shellcheck

ShellCheck, a static analysis tool for shell scripts
https://www.shellcheck.net
GNU General Public License v3.0
36.45k stars 1.78k forks source link

regression(0.9.0): "not following: does not exist" #2899

Open ghost opened 10 months ago

ghost commented 10 months ago

For bugs

Here's a snippet or screenshot that shows the problem:

==> lib/env.sh <==

export X=3

==> lib/my.sh <==

#!/bin/bash
set -e
HERE="$(cd "$(dirname "$0")"; pwd)"
. "$HERE/"env.sh
echo "$X"

Here's what shellcheck currently says:

$ shellcheck -x lib/my.sh
In lib/my.sh line 4:
. "$HERE/"env.sh
  ^------------^ SC1091 (info): Not following: ./env.sh: openBinaryFile: does not exist (No such file or directory)
exit code: 1

Here's what I wanted or expected to see:

$ shellcheck my.sh
exit code: 0

In shellcheck 0.8.0, this code (correctly) had no lint issues. It seems that in 0.9.0, the behavior changed from source-file-relative path evaluation to cwd-relative path evaluation. Indeed, if I simply change directories, shellcheck 0.9.0 finds different results:

$ cd lib
$ shellcheck my.sh
exit code: 0

I checked the changelog and didn't find any reference to an intended change, so I believe this was inadvertent. It certainly makes shellcheck easier to use in various contexts if my $PWD has no effect on the results of linting.

ghost commented 10 months ago

Even worse, in an lsp-server context, the results now depend on the current working directory of the server which may have no relation to the user's cwd, making such errors (apparently) come and go at random.

UtkarshVerma commented 9 months ago

I am also facing this issue. I have shellcheck executed in an LSP context difference in the current working directory is messing up my source directives.

koalaman commented 8 months ago

I'm unable to reproduce this with v0.8.0 and master. In both cases I'm getting SC1091 with shellcheck -x lib/my.sh and no output with cd lib && shellcheck -x my.sh

ShellCheck can't really follow dynamically determined paths like "$HERE/"env.sh due to the difficulty of resolving $HERE in the general case, but it will strip one leading variable component before looking at its --source-path. In this case it will look for env.sh.

You can use --source-path=lib or --source-path=SCRIPTDIR (a special name meaning the directory of the currently checked script) to tell it where to look for sourced files. In this case, it will find the file both with v0.8.0 and latest.