elm-review/tests/NoImportingEverything.elm

102 lines
2.6 KiB
Elm
Raw Normal View History

2020-04-08 01:14:03 +03:00
module NoImportingEverything exposing (rule)
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
{-|
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
@docs rule
2019-07-03 15:19:29 +03:00
2019-06-03 01:30:24 +03:00
-}
import Elm.Syntax.Exposing as Exposing
import Elm.Syntax.Import exposing (Import)
import Elm.Syntax.Node as Node exposing (Node)
import Review.Rule as Rule exposing (Error, Rule)
2020-04-08 01:14:03 +03:00
import Set exposing (Set)
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
{-| Forbids importing everything from a module.
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
When you import everything from a module, it becomes harder to know where a function
or a type comes from. The official guide even
[recommends against importing everything](https://guide.elm-lang.org/webapps/modules.html#using-modules).
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
config =
[ NoImportingEverything.rule []
]
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
Teams often have an agreement on the list of imports from which it is okay to expose everything, so
you can configure a list of exceptions.
config =
2020-04-08 01:14:03 +03:00
[ NoImportingEverything.rule [ "Html", "Some.Module" ]
]
## Fail
2020-04-08 01:14:03 +03:00
import A exposing (..)
import A as B exposing (..)
## Success
2020-04-08 01:14:03 +03:00
import A as B exposing (B(..), C, d)
2020-04-08 01:14:03 +03:00
-- If configured with `[ "Html" ]`
import Html exposing (..)
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-common/example --rules NoImportingEverything
2020-08-09 19:55:15 +03:00
```
2019-06-03 01:30:24 +03:00
-}
2020-04-08 01:14:03 +03:00
rule : List String -> Rule
rule exceptions =
2020-06-28 08:49:27 +03:00
Rule.newModuleRuleSchema "NoImportingEverything" ()
|> Rule.withSimpleImportVisitor (importVisitor <| exceptionsToSet exceptions)
|> Rule.fromModuleRuleSchema
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
exceptionsToSet : List String -> Set (List String)
exceptionsToSet exceptions =
exceptions
|> List.map (String.split ".")
|> Set.fromList
2019-06-03 01:30:24 +03:00
2020-04-08 01:14:03 +03:00
importVisitor : Set (List String) -> Node Import -> List (Error {})
importVisitor exceptions node =
if Set.member (moduleName node) exceptions then
[]
2019-06-03 01:30:24 +03:00
else
2020-04-08 01:14:03 +03:00
case
Node.value node
|> .exposingList
|> Maybe.map Node.value
of
2019-06-03 01:30:24 +03:00
Just (Exposing.All range) ->
2020-04-08 01:14:03 +03:00
[ Rule.error
{ message = "Prefer listing what you wish to import and/or using qualified imports"
2020-08-09 19:55:15 +03:00
, details = [ "When you import everything from a module it becomes harder to know where a function or a type comes from." ]
2020-04-08 01:14:03 +03:00
}
{ start = { row = range.start.row, column = range.start.column - 1 }
, end = { row = range.end.row, column = range.end.column + 1 }
}
]
2019-06-03 01:30:24 +03:00
_ ->
[]
2020-04-08 01:14:03 +03:00
moduleName : Node Import -> List String
moduleName node =
node
|> Node.value
|> .moduleName
|> Node.value