Skip to content

Shellcheck optionals #25

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

Merged
merged 3 commits into from
Jun 2, 2020
Merged

Shellcheck optionals #25

merged 3 commits into from
Jun 2, 2020

Conversation

06kellyjac
Copy link
Contributor

Added the ability to use optional shellcheck checks.

Testing Script:

#!/usr/bin/env bash

yo="a"
[ -z "$yo" ]

which ls

Testing pre-commit config:

---
repos:
  - repo: local
    hooks:
      - id: shellcheck
        name: Shellcheck Bash Linter
        description: Performs linting on bash scripts
        entry: ../pre-commit/hooks/shellcheck.sh
        language: script
        # args: ["--enable require-variable-braces,deprecate-which"] # comment and uncomment

logging the command that would be ran, forcing exit 1 to show the logs:

With:

pre-commit run -a
Shellcheck Bash Linter...................................................Failed
- hook id: shellcheck
- exit code: 1

shellcheck --enable="require-variable-braces,deprecate-which" "sample.sh"

In sample.sh line 4:
[ -z "$yo" ]
      ^-^ SC2250: Prefer putting braces around variable references even when not strictly required.
...
...

Without:

pre-commit run -a
Shellcheck Bash Linter...................................................Failed
- hook id: shellcheck
- exit code: 1

shellcheck "sample.sh"

--enable will only be ran if it's provided in the pre-commit config. This is to avoid issues with shellcheck before 0.7.0 when --enable was added

Copy link
Contributor

@yorinasub17 yorinasub17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for your contribution and apologies for the delay in reviewing this! This feature makes sense and this looks like a good start, but have some suggestions for improvements.

…k shells

* `sh`
* `ash`
* `dash`
* `bash`
* `bats`
* `ksh`
[src](https://github.com/koalaman/shellcheck/blob/c2a15ce8e906ae6a12bcbe32eac7ac586fbcb59b/src/ShellCheck/Parser.hs#L3186-L3193)

---

Shebang regex:
Was: `'^#!.*sh'`
Now: `'^#!\(/\|/.*/\|/.* \)\(\(ba\|da\|k\|a\)*sh\|bats\)$'`

Test cases:
https://pastebin.com/BKB92wx2

Previous regex matched a lot of invalid shebangs & missed the 6 valid `bats` shebangs.

Current regex matches just the 6 correct shebangs from each valid shell.
There are probably some cases that I can't think of but it's a lot safer than the existing one.
A compromise would be something like: `'^#!/.*\(\(ba\|da\|k\|a\)*sh\|bats\)$'`
It matches the `zsh` `fish` and extra characters + valid shell ones but they're all at least valid.

---

File ending regex:
Was: `\.sh$|bash$`
Now: `.+\.(sh|bash|dash|ksh|ash|bats)$`

Test cases:
https://pastebin.com/JRJg8N13

Testing script:
```
test() {
	if [[ "$1" =~ .+\.(sh|bash|dash|ksh|ash|bats)$ ]]; then
		echo "match     - $1"
	else
		echo "not match - $1"
	fi
}

while IFS= read -r FILE; do
	if [[ "$FILE" != "" ]]; then
		test "$FILE"
	fi
done <<EOF
TEST CASES HERE
EOF
```

Previous regex would match `.sh` `bash` and miss `file.ksh` `file.dash` `file.ash` `file.bats`

Current regex only matches the 3 normal file names + also matches just `.sh` `.bash` etc, which are very unusual but valid file names.
There's no extra checking for slashes etc because file names & escapes could confuse things, just the extension should be enough.
@06kellyjac
Copy link
Contributor Author

I've updated the regex used for the shebang & file ending as shellcheck should match the following shells:

  • sh
  • ash
  • dash
  • bash
  • bats
  • ksh
    src

Shebang regex:
Was: '^#!.*sh'
Now: '^#!\(/\|/.*/\|/.* \)\(\(ba\|da\|k\|a\)*sh\|bats\)$'

Test cases:
https://pastebin.com/BKB92wx2

Previous regex matched a lot of invalid shebangs & missed the 6 valid bats shebangs.

Current regex matches just the 6 correct shebangs from each valid shell.
There are probably some cases that I can't think of but it's a lot safer than the existing one.
A compromise would be something like: '^#!/.*\(\(ba\|da\|k\|a\)*sh\|bats\)$'
It matches the zsh fish and extra characters + valid shell ones but they're all at least valid.


File ending regex:
Was: \.sh$|bash$
Now: .+\.(sh|bash|dash|ksh|ash|bats)$

Test cases:
https://pastebin.com/JRJg8N13

Testing script:

#!/usr/bin/env bash
test() {
	if [[ "$1" =~ .+\.(sh|bash|dash|ksh|ash|bats)$ ]]; then
		echo "match     - $1"
	else
		echo "not match - $1"
	fi
}

while IFS= read -r FILE; do
	if [[ "$FILE" != "" ]]; then
		test "$FILE"
	fi
done <<EOF
TEST CASES HERE
EOF

Previous regex would match .sh bash and miss file.ksh file.dash file.ash file.bats

Current regex only matches the 3 normal file names + also matches just .sh .bash etc, which are very unusual but valid file names.
There's no extra checking for slashes etc because file names & escapes could confuse things, just the extension should be enough.

Copy link
Contributor

@yorinasub17 yorinasub17 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay in getting back to you on this! I have a few style nits (tabbing should be 2 spaces, and the while loop should use $# -gt 0), but since they're minor will apply them in a separate PR after merging.

@yorinasub17 yorinasub17 merged commit 0fdadbe into gruntwork-io:master Jun 2, 2020
@06kellyjac
Copy link
Contributor Author

No problem

tabbing should be 2 spaces
Ahh. I think the original changes had 2 spaces. I think I ran shfmt at some point or something

the while loop should use $# -gt 0
The google style guide says it's fine to use (( )) in the testing strings section, and focuses on (( )) in the arithmetic section. But it's up to you :)

@06kellyjac 06kellyjac deleted the shellcheck_optionals branch June 2, 2020 22:10
@yorinasub17
Copy link
Contributor

The google style guide says it's fine to use (( )) in the testing strings section, and focuses on (( )) in the arithmetic section. But it's up to you :)

shellcheck actually flags this because $# is a number, not a string, so you need to use -gt not >.

@06kellyjac
Copy link
Contributor Author

06kellyjac commented Jun 3, 2020

SC2071 only complains about the use of > and < within [[ ]]
2020-06-03T10:26:20+01:00

(( )) can only handle numbers and shellcheck has no issues
2020-06-03T10:26:49+01:00

Using -gt doesn't work with (( )) and causes the following shellcheck issues
2020-06-03T10:30:33+01:00

@yorinasub17
Copy link
Contributor

Ahhh I think you are right. Apologies for that! I was so used to switching to [[]] everywhere I think I missed the first pass of shellcheck.

@06kellyjac
Copy link
Contributor Author

06kellyjac commented Jun 3, 2020

no problem 😃
I'll pop in a PR swapping back to spaces soon ah you've got one already, nice

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

Successfully merging this pull request may close these issues.

2 participants