Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SC1090/SC1091: sourcing should find files relative to script #769

Closed
petersohn opened this issue Nov 4, 2016 · 27 comments
Closed

SC1090/SC1091: sourcing should find files relative to script #769

petersohn opened this issue Nov 4, 2016 · 27 comments

Comments

@petersohn
Copy link

When using the directive source=foobar.sh, then it seems to look up the source relative to the path shellcheck is being run from. For example, I have the following scripts: foo.sh and foobar.sh in the same directory (for example bar/baz from the project root).

Suppose there is the following line in foo.sh:

source "${0%/*}/foobar.sh"

I will get a SC1090 error because shellcheck is unable to resolve the path. I have to do this:

# shellcheck source bar/baz/foobar.sh
source "${0%/*}/foobar.sh"

This works, but only if I run the checker from the project root (either by specifying foo/bar/foobar.sh as an input file, or with -x), but not if I run it from anywhere else. There should be a way to tell shellcheck to look for a file relative to the checked file's location, not where shellcheck is run. For example, this way:

# shellcheck source ./foobar.sh
source "${0%/*}/foobar.sh"
@timvisher
Copy link

timvisher commented Nov 4, 2016 via email

@petersohn
Copy link
Author

I know that $0 is not the best solution to it. I should have used $BASH_SOURCE or something else. But it's besides the point. What I want is to tell ShellCheck where a certain file is located relative to the script. I think it is generally a bad idea to make something work differently (in this case, not work at all) depending on where you run it from.

@koalaman
Copy link
Owner

koalaman commented Nov 5, 2016

source foo would also read from the current directory rather than the directory with the script, but I see how that could be useful. Maybe there should be some option to set the directory from which to resolve these paths.

@rbroemeling
Copy link

rbroemeling commented Feb 6, 2017

@koalaman I can see the argument that the behaviour as it stands could be useful in some edge cases, but generally I would expect that "resolve relative source= directives from the location of the containing script" would make by far the most sense.

As it currently works (where shellcheck resolves relative source= directives from the location that it is executed from) is a bit surprising and disappointing. It makes it so that there is no good way to ensure that it works when executing shellcheck against a script that contains a relative inclusion (this is not an uncommon occurrence) based off of its own path (using either $0 or $BASH_SOURCE, which is again not exactly unheard of).

I'd claim (at least in my work environment) that this scenario is actually far more common than the environment wherein using the current working directory makes more sense. For us, it is rather unequivocal that the script's parent directory would be a far, far better default.

At the least, I'd like to see a command-line argument to switch behaviours, but I really think that serious thought should be given to making relative links resolve from the script's parent directory, rather than from the current working directory that shellcheck has been executed from.

@pszalko
Copy link

pszalko commented Feb 22, 2017

If directive #shellcheck source= is used then we explicitly say shellcheck where to look for included files, however there is currently no way to make this path relative to the script file itself.

I agree with @rbroemeling and @petersohn currently #shellcheck source= directive is not very usable.

@viraptor
Copy link

I'm also interested in getting the relative sources to resolve.

source foo would also read from the current directory rather than the directory with the script

If you're worried about existing scripts, you could always make both options explicit. For example:

# shellcheck source=relative/to/pwd
# shellcheck rel-source=relative/to/analysed-script

@nihilus
Copy link

nihilus commented Nov 6, 2017

Actually 'proot' solved my problems enabling me to chroot to the target directory without modifying it and invoke shellcheck as if it was part of the target directory.

@jpresley23
Copy link

In a CI/CD pipeline this isn't an issue, since I control which directory shellcheck is executed from. The issue I have is when using a shellcheck in an IDE. It would be useful to have an argument I can pass to shellcheck to indicate the root path it should use to resolve the directives.

@docwhat
Copy link

docwhat commented Oct 23, 2018

This seems to be a duplicate of #539 — Maybe we should move everything into one place (and possible edit the subject to be easier to find).

@stdedos
Copy link
Contributor

stdedos commented Dec 3, 2018

@koalaman Wiki for https://github.com/koalaman/shellcheck/wiki/SC1090 is confusing: The path there looks relative. However, if I have 2 files in the same directory (and I get SC1090 on one of them) I cannot write # shellcheck source=./script.bash or # shellcheck source=script.bash on the other one (consistent with this ticket).

"Who is right", "is there any fix coming", "any status update"? (shellcheck 0.6.0 static)

@koalaman
Copy link
Owner

koalaman commented Dec 9, 2018

The path is relative, and it's relative to shellcheck's current working directory. It is not relative to the file in which you put this directive.

@austin987
Copy link
Contributor

This presents a problem if i.e. I want to run shellcheck as part of the unit tests, from the top of the project. If I then want to run shellcheck individually while editing a file, the path may be incorrect.

Maybe two (or more) parts could be provided, to account for that?

@DanielJoyce
Copy link

This really needs to be fixed, makes it a pain to run shellcheck as part of builds, etc, as paths wrt where shellcheck is run can change.

@nthexwn
Copy link

nthexwn commented Feb 26, 2019

Specifying the path relative to where shellcheck is running from is only realistic for a single user/system. Using # shellcheck source=/dev/null as a workaround seems to be the best approach until this is fixed.

@austin987
Copy link
Contributor

Just because it's hard doesn't mean it can't be improved. The path isn't relative to shellcheck, but rather the current working directory.

Allowing relative paths and/or multiple paths would help for automated builds among other cases.

@ee987
Copy link

ee987 commented Apr 23, 2019

We also have big problems with source-directive being relative cwd and not script location.
While relative paths would be very useful for resolving this, why not look at the actual root cause: shellcheck not being able to resolve dynamic paths such as these:

source "${0%/*}/foobar.sh"    
or
source "${BASH_SOURCE[0]}/foobar.sh"
or
SCRIPT_DIR=$(cd "$(dirname "$(readlink -f "$0")")" || exit 1; pwd)
source "$SCRIPT_DIR/foobar.sh"

That would remove the need for source-directive completely because the only time when we actually need source-directive in the first place is in such scenarios.

It might be runtime code but the pattern is easily identifiable so a small set of special cases could be defined to resolve script directory. Shellcheck could recommend one of them and make sure that source-following works with it. Or shellcheck could bundle a companion-library with built in functions for this.

@koalaman
Copy link
Owner

With 301705e you can specify -P SCRIPTDIR to search relative to the script's directory, or -P /my/path to search relative to a path in the filesystem. Hopefully this helps!

It would also be simple to make this the default, if that would make things even easier

@iyerusad
Copy link

I recently added shellcheck to my workflow within VS Code (via this extension). As such, shellcheck is called per file. Very helpful in IDE, I tend to jump between several languages/syntax in any given day - Thank you.

In my limited view, I'm thinking #shellcheck source= directive should attempt to be relative by default:

  1. If I'm specifying a shellcheck source directive, it means higher up helpers (such as recent 301705e) have been unsuccessful (or are undefined)
  2. shellcheck executable location not likely same as script being checked.

My particular instance of SC1090 is (where dotfiles is a repo):

if [ -f "$HOME/dotfiles/1" ];then
  . "$HOME/dotfiles/1"
fi

It would be nice if could handle case of $HOME - I rather avoid helper directives in code unless explicitly breaking a rule for a really good reason.

@solarmosaic-kflorence
Copy link

Agreed, -P SCRIPTDIR is great but hard to utilize in IDE.

@drAlberT
Copy link

With 301705e you can specify -P SCRIPTDIR to search relative to the script's directory, or -P /my/path to search relative to a path in the filesystem. Hopefully this helps!

It would also be simple to make this the default, if that would make things even easier

this is not useful for using shellcheck inside editors. for example vim and syntastic .. Please make the current-script-relative source the default one

@gotrevor
Copy link

gotrevor commented Feb 6, 2020

With 301705e you can specify -P SCRIPTDIR to search relative to the script's directory, or -P /my/path to search relative to a path in the filesystem. Hopefully this helps!
It would also be simple to make this the default, if that would make things even easier

this is not useful for using shellcheck inside editors. for example vim and syntastic .. Please make the current-script-relative source the default one

@drAlberT You can add this line to your .vimrc to pass options to shellcheck w/ syntastic:

[~] $ grep shellcheck .vimrc
let g:syntastic_sh_shellcheck_args = "-x -P SCRIPTDIR"

@drAlberT
Copy link

drAlberT commented Feb 7, 2020

With 301705e you can specify -P SCRIPTDIR to search relative to the script's directory, or -P /my/path to search relative to a path in the filesystem. Hopefully this helps!
It would also be simple to make this the default, if that would make things even easier

this is not useful for using shellcheck inside editors. for example vim and syntastic .. Please make the current-script-relative source the default one

@drAlberT You can add this line to your .vimrc to pass options to shellcheck w/ syntastic:

[~] $ grep shellcheck .vimrc
let g:syntastic_sh_shellcheck_args = "-x -P SCRIPTDIR"

My use case is to have relative scripts, not a global wide SCRIPTDIR .. I made a number of different combination of dirs in .vimrc but no luck

Have you any suggestion to add the current SCRIPT dir as SCRIPTDIR on a per file basis ?

@docwhat
Copy link

docwhat commented Feb 7, 2020

I totally did not understand that SCRIPTDIR is a magic value that allows relative-to-script's-directory lookups.

I thought SCRIPTDIR was meant to be "the path to the script's directory".

@JoshCooley
Copy link

JoshCooley commented Feb 25, 2020

@docwhat yeah I thought the same thing until I read your comment.
For anyone using SublimeLinter-shellcheck you can add the needed args to the user's SublimeLinter.sublime-settings file, e.g.

// SublimeLinter Settings - User
{
  "linters": {
    "shellcheck": {
      "args": [
        "--source-path=SCRIPTDIR",
        "--external-sources"
      ]
    }
  }
}

ElliotKillick added a commit to ElliotKillick/qvm-create-windows-qube that referenced this issue Jun 13, 2020
undergroundwires added a commit to undergroundwires/bump-everywhere that referenced this issue Feb 27, 2022
This way matches behavior for shellcheck extension in Visual Studio
Code so linting works in the editor correctly.

koalaman/shellcheck#769
@jeffomatic
Copy link

For folks using VSCode and Timon Wong's shellcheck extension, add the following to your user settings:

    "shellcheck.customArgs": [
        "--source-path=SCRIPTDIR",
        "--external-sources"
    ]

This is just a quick adaptation of @JoshCooley's Sublime config.

@armenr
Copy link

armenr commented Jan 18, 2023

For folks using VSCode and Timon Wong's shellcheck extension, add the following to your user settings:

@jeffomatic - This doesn't seem to work for me.

Config:

Screenshot 2023-01-18 at 3 28 33 PM

Code (some-script.sh)

# shellcheck source=../_shared/utils-shared_functions.sh
source ../_shared/utils-shared_functions.sh

IDE:

Screenshot 2023-01-18 at 3 29 31 PM

@cfgnunes
Copy link

cfgnunes commented Jun 18, 2023

Hi @armenr!

I think that the --source-path= should have the full path of the base directory, such as:
/home/armenr/app/_shared/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests