2020-04-03 16:13:37 +03:00
|
|
|
module NoDebug.TodoOrToString exposing (rule)
|
2020-03-07 01:45:39 +03:00
|
|
|
|
|
|
|
{-|
|
|
|
|
|
|
|
|
@docs rule
|
|
|
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
import Elm.Syntax.Expression as Expression exposing (Expression)
|
|
|
|
import Elm.Syntax.Node as Node exposing (Node)
|
2021-01-24 18:43:58 +03:00
|
|
|
import Review.ModuleNameLookupTable as ModuleNameLookupTable exposing (ModuleNameLookupTable)
|
2020-03-07 01:45:39 +03:00
|
|
|
import Review.Rule as Rule exposing (Error, Rule)
|
|
|
|
|
|
|
|
|
2020-04-03 16:13:37 +03:00
|
|
|
{-| Forbid the use of [`Debug.todo`] and [`Debug.toString`].
|
2020-03-07 01:45:39 +03:00
|
|
|
|
|
|
|
config =
|
2020-04-03 16:13:37 +03:00
|
|
|
[ NoDebug.TodoOrToString.rule
|
2020-03-07 01:45:39 +03:00
|
|
|
]
|
|
|
|
|
2020-04-03 16:13:37 +03:00
|
|
|
The reason why there is a is separate rule for handling [`Debug.log`] and one for
|
|
|
|
handling [`Debug.todo`] and [`Debug.toString`], is because these two functions
|
|
|
|
are reasonable and useful to have in tests.
|
2020-03-07 01:45:39 +03:00
|
|
|
|
|
|
|
You can for instance create test data without having to handle the error case
|
|
|
|
everywhere. If you do enter the error case in the following example, then tests
|
|
|
|
will fail.
|
|
|
|
|
|
|
|
testEmail : Email
|
|
|
|
testEmail =
|
|
|
|
case Email.fromString "some.email@domain.com" of
|
|
|
|
Just email ->
|
|
|
|
email
|
|
|
|
|
|
|
|
Nothing ->
|
|
|
|
Debug.todo "Supplied an invalid email in tests"
|
|
|
|
|
|
|
|
If you want to allow these functions in tests but not in production code, you
|
|
|
|
can configure the rule like this.
|
|
|
|
|
2020-04-03 16:13:37 +03:00
|
|
|
import Review.Rule as Rule exposing (Rule)
|
|
|
|
|
2020-03-07 01:45:39 +03:00
|
|
|
config =
|
2020-04-03 16:13:37 +03:00
|
|
|
[ NoDebug.TodoOrToString.rule
|
2020-03-07 01:45:39 +03:00
|
|
|
|> Rule.ignoreErrorsForDirectories [ "tests/" ]
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
## Fail
|
|
|
|
|
|
|
|
_ =
|
|
|
|
if condition then
|
|
|
|
a
|
|
|
|
|
|
|
|
else
|
|
|
|
Debug.todo ""
|
|
|
|
|
|
|
|
_ =
|
|
|
|
Debug.toString data
|
|
|
|
|
|
|
|
|
|
|
|
## Success
|
|
|
|
|
|
|
|
if condition then
|
|
|
|
a
|
|
|
|
|
|
|
|
else
|
|
|
|
b
|
|
|
|
|
2020-08-09 19:55:15 +03:00
|
|
|
|
|
|
|
## Try it out
|
|
|
|
|
|
|
|
You can try this rule out by running the following command:
|
|
|
|
|
|
|
|
```bash
|
2020-09-22 20:40:30 +03:00
|
|
|
elm-review --template jfmengels/elm-review-debug/example --rules NoDebug.TodoOrToString
|
2020-08-09 19:55:15 +03:00
|
|
|
```
|
|
|
|
|
2020-03-07 01:45:39 +03:00
|
|
|
[`Debug.log`]: https://package.elm-lang.org/packages/elm/core/latest/Debug#log
|
|
|
|
[`Debug.todo`]: https://package.elm-lang.org/packages/elm/core/latest/Debug#todo
|
|
|
|
[`Debug.toString`]: https://package.elm-lang.org/packages/elm/core/latest/Debug#toString
|
|
|
|
|
|
|
|
-}
|
|
|
|
rule : Rule
|
|
|
|
rule =
|
2021-01-24 18:43:58 +03:00
|
|
|
Rule.newModuleRuleSchemaUsingContextCreator "NoDebug.TodoOrToString" init
|
|
|
|
|> Rule.withExpressionEnterVisitor expressionVisitor
|
2020-06-28 08:49:27 +03:00
|
|
|
|> Rule.fromModuleRuleSchema
|
2020-03-07 01:45:39 +03:00
|
|
|
|
|
|
|
|
|
|
|
type alias Context =
|
2021-01-24 18:43:58 +03:00
|
|
|
ModuleNameLookupTable
|
2020-09-22 20:40:30 +03:00
|
|
|
|
|
|
|
|
2021-01-24 18:43:58 +03:00
|
|
|
init : Rule.ContextCreator () Context
|
2020-09-22 20:40:30 +03:00
|
|
|
init =
|
2021-01-24 18:43:58 +03:00
|
|
|
Rule.initContextCreator (\lookupTable () -> lookupTable)
|
|
|
|
|> Rule.withModuleNameLookupTable
|
2020-03-07 01:45:39 +03:00
|
|
|
|
|
|
|
|
2021-01-24 18:43:58 +03:00
|
|
|
expressionVisitor : Node Expression -> Context -> ( List (Error {}), Context )
|
|
|
|
expressionVisitor node context =
|
2020-03-07 01:45:39 +03:00
|
|
|
case Node.value node of
|
2021-01-24 18:43:58 +03:00
|
|
|
Expression.FunctionOrValue _ name ->
|
|
|
|
if name == "todo" || name == "toString" then
|
|
|
|
case ModuleNameLookupTable.moduleNameFor context node of
|
|
|
|
Just [ "Debug" ] ->
|
|
|
|
( [ Rule.error
|
|
|
|
{ message = "Remove the use of `Debug." ++ name ++ "` before shipping to production"
|
|
|
|
, details =
|
|
|
|
[ "`Debug." ++ name ++ "` can be useful when developing, but is not meant to be shipped to production or published in a package. I suggest removing its use before committing and attempting to push to production."
|
|
|
|
]
|
|
|
|
}
|
|
|
|
(Node.range node)
|
|
|
|
]
|
|
|
|
, context
|
|
|
|
)
|
|
|
|
|
|
|
|
_ ->
|
|
|
|
( [], context )
|
2020-06-28 13:21:13 +03:00
|
|
|
|
2020-09-22 20:40:30 +03:00
|
|
|
else
|
2020-06-28 13:21:13 +03:00
|
|
|
( [], context )
|
2020-09-22 20:40:30 +03:00
|
|
|
|
|
|
|
_ ->
|
|
|
|
( [], context )
|