brighterscript is a Roku BrightScript compiler featuring many diagnostics out of the box: syntax check, function calls validation, script imports verification...
bslint
is:
- a CLI tool to lint your code without compiling your project,
- a
brighterscript
plugin offering additional insights on your code.
You need Node 10+ and npm
or yarn
:
# if you don't have a package.json
npm init -y
# install modules
npm install brighterscript @rokucommunity/bslint
Important: add the plugin to your bsconfig.json
file in the root of your project,
or create a minimal bsconfig.json
like that:
{
"plugins": [ "@rokucommunity/bslint" ]
}
Otherwise, you will only see issues coming from the brighterscript compiler.
The bslint
command will run the BrighterScript compiler without publishing
step, only outputing the diagnostics.
Note: the CLI can be used without adding the bslint
plugin; you will only
get the default brighterscript
diagnostics.
npx bslint --help
# lint with default options
npx bslint
# lint and fix basic code-style issues (see below)
npx bslint --fix
# lint and attempt to identify unused components and scripts (see below)
npx bslint --checkUsage
or add a npm
script in package.json
, e.g.:
{
...
"scripts": {
"lint": "bslint"
}
...
}
and call npm run lint
.
bslint
can be configured using a bslint.json
file in the root of your project.
Note: bslint.json
is not the same file as bsconfig.json
!
{
"rules": {},
"globals": [],
"ignores": []
}
Where each value is optional:
rules
: see belowglobals
: a list of tokens which should always be considered as safe (ex._brs_
)ignores
: a list of files or globs of files to omit from linting
If you are using brighterscript
with the Visual Studio Code plugin, you might want to mention your configuration file in brighterscript
's bsconfig.json
as follow:
{
"plugins": [ "@rokucommunity/bslint" ],
"lintConfig": "path/to/bslint.json"
}
Unlike brighterscripts
's diagnosticFilter
which hides issues, bslint
will completely
skip ignored files when running the extra linting rules.
Note: it won't remove issues reported by the compiler itself!
Format should follow "glob search" rules, as implemented in minimatch module.
Examples:
"lib/**/*"
: ignore everything under anylib
folder,"**/lib/**/*"
: same with explicit initial wildcard (added automatically if missing)"specific-script.brs"
: ignore specific file name"*.test.brs"
: partial match of file name
Linting rules can be set in a bslint.json
file in the root of your project.
Rules are organised in 3 categories:
- "Code style": how the code should look like for consistency
- "Strictness": requirement to ensure code safety
- "Code flow": tracks the code flow to identify risky patterns
Default rules:
{
"rules": {
"inline-if-style": "then",
"block-if-style": "no-then",
"condition-style": "no-group",
"named-function-style": "auto",
"anon-function-style": "auto",
"aa-comma-style": "no-dangling",
"no-print": "off",
"no-todo": "off",
"todo-pattern": "TODO|todo|FIXME",
"no-stop": "warn",
"type-annotations": "off",
"assign-all-paths": "error",
"unsafe-path-loop": "error",
"unsafe-iterators": "error",
"unreachable-code": "info",
"case-sensitivity": "warn",
"unused-variable": "warn",
"consistent-return": "error"
}
}
-
inline-if-style
: validation of inlineif/then
statements.never
: do not allow,no-then
: do not usethen
keywordthen
: always usethen
keyword (default)off
: do not validate
-
block-if-style
: validation of regular blockif/then
statements.no-then
: do not usethen
keyword (default)then
: always usethen
keywordoff
: do not validate
-
condition-style
: validation ofif/while
statements conditions: should the condition be wrapped around parenthesis?no-group
: do not wrap with parenthesis (default)group
: always wrap with parenthesesoff
: do not validate
-
named-function-style
,anon-function-style
: validation of function style (function/sub
)no-function
: always usesub
no-sub
: always usefunction
auto
: usesub
forVoid
functions, otherwise usefunction
(default)off
: no not validate
-
aa-comma-style
: validation of commas in Associative Array (AA) literalsall-except-single-line
: enforce the presence of dangling commas except for single line Associative Array (AA)always
: enforce the presence of commas, alwaysno-dangling
: enforce the presence of commas but don't leave one dangling (default)never
: enforce that optional commas aren't usedoff
: do not validate
-
no-print
: prevent usage ofprint
statements in code (error | warn | info | off
) -
no-todo
: prevent usage oftodo
comments in code (error | warn | info | off
) -
todo-pattern
: string regex pattern to determine what a TODO is. default isTODO|todo|FIXME
(do not include surrounding/
characters). -
no-stop
: prevent usage ofSTOP
statements in the code (error | warn | info | off
) -
eol-last
: enforces at least one newline (or absence thereof) at the end of non-empty filesalways
: enforces that files end with a newline (default)never
enforces that files do not end with a newlineoff
: do not validate
-
type-annotations
: validation of presence ofas
type annotations, for function arguments and return values.all
: enforce both arguments and return type annotationsreturn
: enforce return type annotationsargs
: enforce arguments type annotationsoff
: do not validate (default)
Valid values for the rules severity are: error | warn | info | off
.
-
assign-all-paths
: a variable is not assigned in all the possible code paths,if a then b = "something" end if print b ' error
-
unsafe-path-loop
: loops are considered as unsafe code paths: assignment in a loop may not happen.for i = 0 to n b = "something" end if print b ' b may not have been assigned
-
unsafe-iterators
: loop iterator variable should not be used outside a loopfor i = 0 to n b = "something" end if print i ' value could be invalid
-
case-sensitivity
: inform of inconsistent variable casing -
unused-variable
: inform of variable being set but never used -
unreachable-code
: inform of unreachable codereturn print "is unreachable"
-
consistent-return
: verifies consistency ofsub
/function
returned values (missing return, missing value, returned value while function isas void
,...)
Running bslint
with --fix
parameter will attempt to fix common code-style issues:
- Using wrong
sub
orfunction
keyword, - Using/missing the optional
then
keyword, - Using/missing parenthesis around
if/while
conditions. - Adding/removing Associative Array (AA) literals' commas where needed.
- Case sensitivity (align with first occurence)
- Adding/removing newlines the end of non-empty files.
Running bslint
with --checkUsage
parameter will attempt to identify unused components and scripts:
- Starting from
main.brs
the scripts and components are "walked", - All the literal strings are matched (case insensitive) with XML component names,
- All the component included scripts are walked,
- All the component's explicit children (under
<children>
tag) are walked, - Any script/component not walked will produce a warning.
Click here to view the changelog