Showing 39 of 40 total issues
Similar blocks of code found in 2 locations. Consider refactoring. Open
describe('liveness route', async () => {
it('should succeed when bot is connected', async () => {
const endpoint = await createEndpoint(HealthEndpoint, true, true);
const { response, status } = createRequest();
await endpoint.getLiveness(ineeda<Request>({}), response);
- Read upRead up
Duplicated Code
Duplicated code can lead to software that is hard to understand and difficult to change. The Don't Repeat Yourself (DRY) principle states:
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
When you violate DRY, bugs and maintenance problems are sure to follow. Duplicated code has a tendency to both continue to replicate and also to diverge (leaving bugs as two similar implementations differ in subtle ways).
Tuning
This issue has a mass of 231.
We set useful threshold defaults for the languages we support but you may want to adjust these settings based on your project guidelines.
The threshold configuration represents the minimum mass a code block must have to be analyzed for duplication. The lower the threshold, the more fine-grained the comparison.
If the engine is too easily reporting duplication, try raising the threshold. If you suspect that the engine isn't catching enough duplication, try lowering the threshold. The best setting tends to differ from language to language.
See codeclimate-duplication
's documentation for more information about tuning the mass threshold in your .codeclimate.yml
.
Refactorings
- Extract Method
- Extract Class
- Form Template Method
- Introduce Null Object
- Pull Up Method
- Pull Up Field
- Substitute Algorithm
Further Reading
- Don't Repeat Yourself on the C2 Wiki
- Duplicated Code on SourceMaking
- Refactoring: Improving the Design of Existing Code by Martin Fowler. Duplicated Code, p76
Function getToken
has a Cognitive Complexity of 7 (exceeds 6 allowed). Consider refactoring. Open
@Handler(NOUN_TOKEN, CommandVerb.Get)
@CheckRBAC()
public async getToken(cmd: Command, ctx: Context): Promise<void> {
if (cmd.has('token')) {
try {
- Read upRead up
Cognitive Complexity
Cognitive Complexity is a measure of how difficult a unit of code is to intuitively understand. Unlike Cyclomatic Complexity, which determines how difficult your code will be to test, Cognitive Complexity tells you how difficult your code will be to read and comprehend.
A method's cognitive complexity is based on a few simple rules:
- Code is not considered more complex when it uses shorthand that the language provides for collapsing multiple statements into one
- Code is considered more complex for each "break in the linear flow of the code"
- Code is considered more complex when "flow breaking structures are nested"
Further reading
Declare and assign separately to avoid masking return values. Open
export GITHUB_PR="$(echo "${DATA}" | jq '.data.data[] | select(.[0] == "check_run") | .[1].pull_requests')"
- Read upRead up
- Exclude checks
Declare and assign separately to avoid masking return values.
Problematic code:
export foo="$(mycmd)"
Correct code:
foo=$(mycmd)
export foo
Rationale:
In the original code, the return value of mycmd
is ignored, and export
will instead always return true. This may prevent conditionals, set -e
and traps from working correctly.
When first marked for export and assigned separately, the return value of the assignment will be that of mycmd
. This avoids the problem.
Exceptions:
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export foo
Shellcheck does not warn about export foo=bar
because bar
is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd)
, where declaration and assignment must be in the same command.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Declare and assign separately to avoid masking return values. Open
export GITHUB_PROJECT="$(echo "${DATA}" | jq -r '.data.context.channel.id')"
- Read upRead up
- Exclude checks
Declare and assign separately to avoid masking return values.
Problematic code:
export foo="$(mycmd)"
Correct code:
foo=$(mycmd)
export foo
Rationale:
In the original code, the return value of mycmd
is ignored, and export
will instead always return true. This may prevent conditionals, set -e
and traps from working correctly.
When first marked for export and assigned separately, the return value of the assignment will be that of mycmd
. This avoids the problem.
Exceptions:
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export foo
Shellcheck does not warn about export foo=bar
because bar
is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd)
, where declaration and assignment must be in the same command.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Double quote to prevent globbing and word splitting. Open
if [ ${GITHUB_PR_LEN} -eq 0 ];
- Read upRead up
- Exclude checks
Double quote to prevent globbing and word splitting.
Problematic code:
echo $1
for i in $*; do :; done # this done and the next one also applies to expanding arrays.
for i in $@; do :; done
Correct code:
echo "$1"
for i in "$@"; do :; done # or, 'for i; do'
Rationale
The first code looks like "print the first argument". It's actually "Split the first argument by IFS (spaces, tabs and line feeds). Expand each of them as if it was a glob. Join all the resulting strings and filenames with spaces. Print the result."
The second one looks like "iterate through all arguments". It's actually "join all the arguments by the first character of IFS (space), split them by IFS and expand each of them as globs, and iterate on the resulting list". The third one skips the joining part.
Quoting variables prevents word splitting and glob expansion, and prevents the script from breaking when input contains spaces, line feeds, glob characters and such.
Strictly speaking, only expansions themselves need to be quoted, but for stylistic reasons, entire arguments with multiple variable and literal parts are often quoted as one:
$HOME/$dir/dist/bin/$file # Unquoted (bad)
"$HOME"/"$dir"/dist/bin/"$file" # Minimal quoting (good)
"$HOME/$dir/dist/bin/$file" # Canonical quoting (good)
When quoting composite arguments, make sure to exclude globs and brace expansions, which lose their special meaning in double quotes: "$HOME/$dir/src/*.c"
will not expand, but "$HOME/$dir/src"/*.c
will.
Note that $( )
starts a new context, and variables in it have to be quoted independently:
echo "This $variable is quoted $(but this $variable is not)"
echo "This $variable is quoted $(and now this "$variable" is too)"
Exceptions
Sometimes you want to split on spaces, like when building a command line:
options="-j 5 -B"
make $options file
Just quoting this doesn't work. Instead, you should have used an array (bash, ksh, zsh):
options=(-j 5 -B) # ksh: set -A options -- -j 5 -B
make "${options[@]}" file
or a function (POSIX):
make_with_flags() { make -j 5 -B "$@"; }
make_with_flags file
To split on spaces but not perform glob expansion, Posix has a set -f
to disable globbing. You can disable word splitting by setting IFS=''
.
Similarly, you might want an optional argument:
debug=""
[[ $1 == "--trace-commands" ]] && debug="-x"
bash $debug script
Quoting this doesn't work, since in the default case, "$debug"
would expand to one empty argument while $debug
would expand into zero arguments. In this case, you can use an array with zero or one elements as outlined above, or you can use an unquoted expansion with an alternate value:
debug=""
[[ $1 == "--trace-commands" ]] && debug="yes"
bash ${debug:+"-x"} script
This is better than an unquoted value because the alternative value can be properly quoted, e.g. wget ${output:+ -o "$output"}
.
As always, this warning can be [[ignore]]d on a case-by-case basis.
this is especially relevant when BASH many not be available for the array work around. For example, use in eval or in command options where script has total control of the variables...
FLAGS="-av -e 'ssh -x' --delete --delete-excluded"
...
# shellcheck disable=SC2086
eval rsync $FLAGS ~/dir remote_host:dir
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Declare and assign separately to avoid masking return values. Open
export GITHUB_COMMIT="$(echo "${DATA}" | jq -r '.data.context.channel.thread')"
- Read upRead up
- Exclude checks
Declare and assign separately to avoid masking return values.
Problematic code:
export foo="$(mycmd)"
Correct code:
foo=$(mycmd)
export foo
Rationale:
In the original code, the return value of mycmd
is ignored, and export
will instead always return true. This may prevent conditionals, set -e
and traps from working correctly.
When first marked for export and assigned separately, the return value of the assignment will be that of mycmd
. This avoids the problem.
Exceptions:
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export foo
Shellcheck does not warn about export foo=bar
because bar
is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd)
, where declaration and assignment must be in the same command.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Declare and assign separately to avoid masking return values. Open
export GITHUB_PR_ID="$(echo "${GITHUB_PR}" | jq -r '.[] | .number')"
- Read upRead up
- Exclude checks
Declare and assign separately to avoid masking return values.
Problematic code:
export foo="$(mycmd)"
Correct code:
foo=$(mycmd)
export foo
Rationale:
In the original code, the return value of mycmd
is ignored, and export
will instead always return true. This may prevent conditionals, set -e
and traps from working correctly.
When first marked for export and assigned separately, the return value of the assignment will be that of mycmd
. This avoids the problem.
Exceptions:
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export foo
Shellcheck does not warn about export foo=bar
because bar
is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd)
, where declaration and assignment must be in the same command.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Useless echo? Instead of 'echo $(cmd)', just use 'cmd'. Open
echo "$(date)" >> /tmp/filter-github.log
- Read upRead up
- Exclude checks
Useless echo
? Instead of echo $(cmd)
, just use cmd
Problematic code:
echo "$(cat 1.txt)"
echo `< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6`
Correct code:
cat 1.txt # In bash, but faster and still sticks exactly one newline: printf '%s\n' "$(<1.txt)"
# The original `echo` sticks a newline; we want it too.
< /dev/urandom tr -dc _A-Z-a-z-0-9 | head -c6; echo
Rationale
The command substitution $(foo)
yields the result of command foo
with trailing newlines erased, and when it is passed to echo
it generally just gives the same result as foo
.
Exceptions
One may want to use command substitutions plus echo
to make sure there is exactly one trailing newline. The special command substitution $(<file)
in bash
is also un-outline-able.
Anyway, echo is still not that reliable (see [[SC2039#echo-flags]]) and printf
should be used instead.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
Declare and assign separately to avoid masking return values. Open
export GITHUB_PR_LEN="$(echo "${DATA}" | jq '.data.data[] | select(.[0] == "check_run") | .[1].pull_requests | length')"
- Read upRead up
- Exclude checks
Declare and assign separately to avoid masking return values.
Problematic code:
export foo="$(mycmd)"
Correct code:
foo=$(mycmd)
export foo
Rationale:
In the original code, the return value of mycmd
is ignored, and export
will instead always return true. This may prevent conditionals, set -e
and traps from working correctly.
When first marked for export and assigned separately, the return value of the assignment will be that of mycmd
. This avoids the problem.
Exceptions:
If you intend to ignore the return value of an assignment, you can either ignore this warning or use
foo=$(mycmd) || true
export foo
Shellcheck does not warn about export foo=bar
because bar
is a literal and not a command substitution with an independent return value. It also does not warn about local -r foo=$(cmd)
, where declaration and assignment must be in the same command.
Notice
Original content from the ShellCheck https://github.com/koalaman/shellcheck/wiki.
TODO found Open
// @TODO: fix these good
- Exclude checks
TODO found Open
* @TODO: check session start/end time
- Exclude checks
TODO found Open
const TEST_DELAY = 50; // TODO: why do these need a delay?
- Exclude checks
TODO found Open
* TODO: do this without hard-coded fallbacks
- Exclude checks
TODO found Open
}), ['--bar=2']); // TODO: next argument should not need prefix
- Exclude checks
TODO found Open
// TODO: list proper options for this
- Exclude checks
TODO found Open
TODO: implement and describe reloading config
- Exclude checks
TODO found Open
// TODO: verify this is a module constructor before instantiating
- Exclude checks
TODO found Open
// TODO: replace ineeda with sinon mocks (#327)
- Exclude checks
TODO found Open
job_status: string; // TODO: enum
- Exclude checks