Skip to content

Commit 2dafd5a

Browse files
authored
(WIP) update documentation for 1.0 (#166)
- begins documenting every rewrite styler does via a cheatsheet - adds TODOs to readme
1 parent 9fd1d91 commit 2dafd5a

File tree

8 files changed

+397
-111
lines changed

8 files changed

+397
-111
lines changed

README.md

Lines changed: 36 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -5,158 +5,88 @@ you what's wrong, it just rewrites the code for you to fit its style rules.
55

66
You can learn more about the history, purpose and implementation of Styler from our talk: [Styler: Elixir Style-Guide Enforcer @ GigCity Elixir 2023](https://www.youtube.com/watch?v=6pF8Hl5EuD4)
77

8+
-----------------------
9+
10+
Styler's documentation is under work as part of releasing 1.0.
11+
12+
You can find the [0.11.9 documentation and readme here.](https://hexdocs.pm/styler/readme.html)
13+
814
## Installation
915

1016
Add `:styler` as a dependency to your project's `mix.exs`:
1117

1218
```elixir
1319
def deps do
1420
[
15-
{:styler, "~> 0.11", only: [:dev, :test], runtime: false},
21+
{:styler, "~> 1.0.0-rc.0", only: [:dev, :test], runtime: false},
1622
]
1723
end
1824
```
1925

26+
Please excuse the mess below as I find spare to to update our documentation =)
27+
28+
29+
@TODO put this somewhere more reasonable
30+
**Note** Styler's only public API is its usage as a formatter plugin. While you're welcome to play with its internals,
31+
they can and will change without that change being reflected in Styler's semantic version.
32+
2033
Then add `Styler` as a plugin to your `.formatter.exs` file
2134

2235
```elixir
2336
[
2437
plugins: [Styler]
38+
# optionally: include styler configuration
39+
# , styler: [alias_lifting_excludes: []]
2540
]
2641
```
2742

28-
And that's it! Now when you run `mix format` you'll also get the benefits of Styler's *definitely-always-right* style fixes.
43+
And that's it! Now when you run `mix format` you'll also get the benefits of Styler's Stylish Stylings.
2944

3045
### Configuration
3146

32-
There isn't any! This is intentional.
47+
@TODO document: config for lifting, and why we won't add options other configs
3348

3449
Styler is @adobe's internal Style Guide Enforcer - allowing exceptions to the styles goes against that ethos. Happily, it's open source and thus yours to do with as you will =)
3550

3651
## Features (or as we call them, "Styles")
3752

38-
At this point, Styler does a lot. We've catalogued a list of Credo rules that it automatically fixes, but it does some things -
39-
like shrinking function heads down to a single line when possible - that Credo doesn't care about.
40-
41-
Ultimately, the best way to see what Styler does is to just try it out! What could go wrong? (You're using version control, right?)
53+
@TODO link examples
4254

43-
### Credo Rules Styler Replaces
55+
https://hexdocs.pm/styler/1.0.0-rc.0/styles.html
4456

45-
If you're using Credo and Styler, **we recommend disabling these rules in `.credo.exs`** to save on unnecessary checks in CI.
57+
## Styler & Credo
4658

47-
Disabling the rules means updating your `.credo.exs` depending on your configuration:
48-
49-
- if you're using `checks: %{enabled: [...]}`, ensure none of the checks are listed in your enabled checks
50-
- if you're using `checks: %{disabled: [...]}`, copy/paste the snippet below into the list
51-
- if you're using `checks: [...]`, copy/paste the snippet below into the list and ensure none of the checks appear earlier in the list
52-
53-
```elixir
54-
# Styler Rewrites
55-
#
56-
# The following rules are automatically rewritten by Styler and so disabled here to save time
57-
# Some of the rules have `priority: :high`, meaning Credo runs them unless we explicitly disable them
58-
# (removing them from this file wouldn't be enough, the `false` is required)
59-
#
60-
# Some rules have a comment before them explaining ways Styler deviates from the Credo rule.
61-
#
62-
# always expands `A.{B, C}`
63-
{Credo.Check.Consistency.MultiAliasImportRequireUse, false},
64-
# including `case`, `fn` and `with` statements
65-
{Credo.Check.Consistency.ParameterPatternMatching, false},
66-
# Styler implements this rule with a depth of 3 and minimum repetition of 2
67-
{Credo.Check.Design.AliasUsage, false},
68-
{Credo.Check.Readability.AliasOrder, false},
69-
{Credo.Check.Readability.BlockPipe, false},
70-
# goes further than formatter - fixes bad underscores, eg: `100_00` -> `10_000`
71-
{Credo.Check.Readability.LargeNumbers, false},
72-
# adds `@moduledoc false`
73-
{Credo.Check.Readability.ModuleDoc, false},
74-
{Credo.Check.Readability.MultiAlias, false},
75-
{Credo.Check.Readability.OneArityFunctionInPipe, false},
76-
# removes parens
77-
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, false},
78-
{Credo.Check.Readability.PipeIntoAnonymousFunctions, false},
79-
{Credo.Check.Readability.PreferImplicitTry, false},
80-
{Credo.Check.Readability.SinglePipe, false},
81-
# **potentially breaks compilation** - see **Troubleshooting** section below
82-
{Credo.Check.Readability.StrictModuleLayout, false},
83-
{Credo.Check.Readability.StringSigils, false},
84-
{Credo.Check.Readability.UnnecessaryAliasExpansion, false},
85-
{Credo.Check.Readability.WithSingleClause, false},
86-
{Credo.Check.Refactor.CaseTrivialMatches, false},
87-
{Credo.Check.Refactor.CondStatements, false},
88-
# in pipes only
89-
{Credo.Check.Refactor.FilterCount, false},
90-
# in pipes only
91-
{Credo.Check.Refactor.MapInto, false},
92-
# in pipes only
93-
{Credo.Check.Refactor.MapJoin, false},
94-
{Credo.Check.Refactor.NegatedConditionsInUnless, false},
95-
{Credo.Check.Refactor.NegatedConditionsWithElse, false},
96-
# allows ecto's `from
97-
{Credo.Check.Refactor.PipeChainStart, false},
98-
{Credo.Check.Refactor.RedundantWithClauseResult, false},
99-
{Credo.Check.Refactor.UnlessWithElse, false},
100-
{Credo.Check.Refactor.WithClauses, false},
101-
```
59+
@TODO link credo doc
10260

10361
## Your first Styling
10462

10563
**Speed**: Expect the first run to take some time as `Styler` rewrites violations of styles.
10664

10765
Once styled the first time, future styling formats shouldn't take noticeably more time.
10866

109-
### Troubleshooting: Compilation broke due to Module Directive rearrangement
110-
111-
Styler naively moves module attributes, which can break compilation. For now, the only fix is some elbow grease.
112-
113-
#### Module Attribute dependency
114-
115-
Another common compilation break on the first run is a `@moduledoc` that depended on another module attribute which
116-
was moved below it.
117-
118-
For example, given the following broken code after an initial `mix format`:
67+
## Styler can break your code
11968

120-
```elixir
121-
defmodule MyGreatLibrary do
122-
@moduledoc make_pretty_docs(@library_options)
123-
use OptionsMagic, my_opts: @library_options
124-
125-
@library_options [ ... ]
126-
end
127-
```
128-
129-
You can fix the code by moving the static value outside of the module into a naked variable and then reference it in the module. (Note that `use` macros need an `unquote` wrapping the variable!)
130-
131-
Yes, this is a thing you can do in a `.ex` file =)
132-
133-
```elixir
134-
library_options = [ ... ]
135-
136-
defmodule MyGreatLibrary do
137-
@moduledoc make_pretty_docs(library_options)
138-
use OptionsMagic, my_opts: unquote(library_options)
139-
140-
@library_options library_options
141-
end
142-
```
69+
@TODO link troubleshooting
70+
mention our rewrite of case true false to if and how we're OK with this being _Styler_, not _SemanticallyEquivalentRewriter_.
14371

14472
## Thanks & Inspiration
14573

14674
### [Sourceror](https://github.com/doorgan/sourceror/)
14775

148-
This work was inspired by earlier large-scale rewrites of an internal codebase that used the fantastic tool `Sourceror`.
76+
Styler's first incarnation was as one-off scripts to rewrite an internal codebase to allow Credo rules to be turned on.
14977

150-
The initial implementation of Styler used Sourceror, but Sourceror's AST-embedding comment algorithm slows Styler down to
151-
the point that it's no longer an appropriate drop-in for `mix format`.
78+
These rewrites were entirely powered by the terrific `Sourceror` library.
15279

153-
Still, we're grateful for the inspiration Sourceror provided and the changes to the Elixir AST APIs that it drove.
80+
While `Styler` no longer relies on `Sourceror`, we're grateful for its author's help with those scripts, the inspiration
81+
Sourceror provided in showing us what was possible, and the changes to the Elixir AST APIs that it drove.
15482

155-
The AST-Zipper implementation in this project was forked from Sourceror's implementation.
83+
Styler's [AST-Zipper](`m:Styler.Zipper`) implementation in this project was forked from Sourceror. Zipper has been a crucial
84+
part of our ability to ergonomically zip around (heh) Elixir AST.
15685

15786
### [Credo](https://github.com/rrrene/credo/)
15887

159-
Similarly, this project originated from one-off scripts doing large scale rewrites of an enormous codebase as part of an
160-
effort to enable particular Credo rules for that codebase. Credo's tests and implementations were referenced for implementing
161-
Styles that took the work the rest of the way. Thanks to Credo & the Elixir community at large for coalescing around
162-
many of these Elixir style credos.
88+
We never would've bothered trying to rewrite our codebase if we didn't have Credo rules we wanted to apply.
89+
90+
Credo's tests and implementations were referenced for implementing Styles that took the work the rest of the way.
91+
92+
Thanks to Credo & the Elixir community at large for coalescing around many of these Elixir style credos.

docs/credo.cheatmd

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
### Credo Rules Styler Replaces
2+
3+
If you're using Credo and Styler, **we recommend disabling these rules in `.credo.exs`** to save on unnecessary checks in CI.
4+
5+
Disabling the rules means updating your `.credo.exs` depending on your configuration:
6+
7+
- if you're using `checks: %{enabled: [...]}`, ensure none of the checks are listed in your enabled checks
8+
- if you're using `checks: %{disabled: [...]}`, copy/paste the snippet below into the list
9+
- if you're using `checks: [...]`, copy/paste the snippet below into the list and ensure none of the checks appear earlier in the list
10+
11+
```elixir
12+
# Styler Rewrites
13+
#
14+
# The following rules are automatically rewritten by Styler and so disabled here to save time
15+
# Some of the rules have `priority: :high`, meaning Credo runs them unless we explicitly disable them
16+
# (removing them from this file wouldn't be enough, the `false` is required)
17+
#
18+
{Credo.Check.Consistency.MultiAliasImportRequireUse, false},
19+
{Credo.Check.Consistency.ParameterPatternMatching, false},
20+
{Credo.Check.Design.AliasUsage, false},
21+
{Credo.Check.Readability.AliasOrder, false},
22+
{Credo.Check.Readability.BlockPipe, false},
23+
{Credo.Check.Readability.LargeNumbers, false},
24+
{Credo.Check.Readability.ModuleDoc, false},
25+
{Credo.Check.Readability.MultiAlias, false},
26+
{Credo.Check.Readability.OneArityFunctionInPipe, false},
27+
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, false},
28+
{Credo.Check.Readability.PipeIntoAnonymousFunctions, false},
29+
{Credo.Check.Readability.PreferImplicitTry, false},
30+
{Credo.Check.Readability.SinglePipe, false},
31+
{Credo.Check.Readability.StrictModuleLayout, false},
32+
{Credo.Check.Readability.StringSigils, false},
33+
{Credo.Check.Readability.UnnecessaryAliasExpansion, false},
34+
{Credo.Check.Readability.WithSingleClause, false},
35+
{Credo.Check.Refactor.CaseTrivialMatches, false},
36+
{Credo.Check.Refactor.CondStatements, false},
37+
{Credo.Check.Refactor.FilterCount, false},
38+
{Credo.Check.Refactor.MapInto, false},
39+
{Credo.Check.Refactor.MapJoin, false},
40+
{Credo.Check.Refactor.NegatedConditionsInUnless, false},
41+
{Credo.Check.Refactor.NegatedConditionsWithElse, false},
42+
{Credo.Check.Refactor.PipeChainStart, false},
43+
{Credo.Check.Refactor.RedundantWithClauseResult, false},
44+
{Credo.Check.Refactor.UnlessWithElse, false},
45+
{Credo.Check.Refactor.WithClauses, false},
46+
```

0 commit comments

Comments
 (0)