Skip to content

Commit 558348e

Browse files
docs(readme): improve documentation (#99)
1 parent 2998d51 commit 558348e

File tree

2 files changed

+141
-118
lines changed

2 files changed

+141
-118
lines changed

AGENT.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
- Name GitHub pull requests using the **Conventional Commits** specification. Example: `feat(parser): support new syntax` or `fix(ci): correct clippy invocation`.
55

66
## Validation Steps
7-
- Before submitting a PR, run each command from `./run-all.sh` manually. It may
8-
include:
7+
- If a PR only changes Markdown documentation (excluding Rust doc comments),
8+
skip formatting, build and test steps.
9+
- If Rust source files or `Cargo.toml` were modified, run each command from
10+
`./run-all.sh` manually. It may include:
911
- `cargo build --release --all-targets`
1012
- `cargo test`
1113
- `cargo test --release`

README.md

Lines changed: 137 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -20,178 +20,199 @@ cargo install keepsorted
2020
- [Issue tracker](https://github.com/maksym-arutyunyan/keepsorted/issues)
2121
- [Architecture](docs/architecture.md)
2222

23-
## Usage
24-
25-
- `keepsorted --check <path>` verifies sorting without modifying files.
26-
- `keepsorted --diff <path>` shows a diff of required changes.
27-
- `keepsorted --fix <path>` updates files in place.
28-
- By default `keepsorted` processes a single file. Use `--recursive` (`-r`) to walk a directory and format every supported file. For complex include/exclude rules, combine `keepsorted` with shell tools like `git ls-files`. See [Architecture](docs/architecture.md) for details.
29-
30-
Run `keepsorted --check` in CI after filtering tracked files with
31-
`git ls-files` to prevent unsorted changes.
23+
## Overview
3224

33-
### Pre-commit hook
25+
`keepsorted` sorts lists of lines while keeping nearby comments with the lines
26+
that follow them. Add a comment like **`Keep sorted`** and the tool will reorder
27+
the next block. Some file types are sorted automatically.
3428

35-
keepsorted requires explicit paths unless you enable `--recursive`. To scan all tracked files except the test directories, save this script as `.git/hooks/pre-commit`:
29+
## Usage
3630

3731
```shell
38-
#!/bin/sh
39-
git ls-files -z \
40-
| grep -vzE '^tests/|^e2e-tests/|^README.md$' \
41-
| xargs -0 -n1 keepsorted --check || {
42-
echo 'Run keepsorted --fix' >&2
43-
exit 1
44-
}
32+
keepsorted --check <path> # verify without changes
33+
keepsorted --diff <path> # preview changes as a diff
34+
keepsorted --fix <path> # rewrite files in place (default)
4535
```
4636

47-
`keepsorted` is a command-line tool that helps you sort blocks of lines in your code files.
48-
The tool is inspired by the Bazel build tool `buildifier`, which sorts items marked with `# Keep sorted` comments. `keepsorted` brings this functionality to any text file.
37+
Use `--recursive` (`-r`) to process directories. Combine with `git ls-files` in
38+
CI to check only tracked files.
4939

50-
It works by sorting lines within a block that starts with the activation comment `# Keep sorted`.
51-
In some files, like `Cargo.toml`, it sorts automatically without needing an activation comment.
40+
### Keywords
5241

53-
The tool can also recognize comments attached to non-comment lines, like this:
42+
- `Keep sorted` or `keepsorted: keep sorted` – sort the next block.
43+
- `keepsorted: ignore file` – skip the whole file.
44+
- `keepsorted: ignore block` – skip a single block.
5445

55-
```py
56-
# Before:
57-
dependencies = [
58-
# Keep sorted.
59-
'ddd',
60-
'ccc',
61-
# TODO: remove this dependency.
62-
'bbb',
63-
'aaa',
64-
]
46+
Markers work with `#`, `//`, or `--` comments. Generic files and Bazel require
47+
one of these comments. `Cargo.toml`, `.gitignore`, and `CODEOWNERS` are sorted
48+
automatically when the matching feature flag is enabled.
6549

66-
# After:
67-
dependencies = [
68-
# Keep sorted.
69-
'aaa',
70-
# TODO: remove this dependency.
71-
'bbb',
72-
'ccc',
73-
'ddd',
74-
]
50+
### Examples
51+
52+
#### Generic text (Python)
53+
54+
```py
55+
# Keep sorted
56+
# comment B
57+
b
58+
# comment A
59+
a
7560
```
7661

77-
You can see more examples in the `./e2e-tests/files/` directory.
62+
becomes
7863

79-
## Keywords
64+
```py
65+
# Keep sorted
66+
# comment A
67+
a
68+
# comment B
69+
b
70+
```
8071

81-
Comments can begin with `#`, `//`, or `--`. The following examples use `#`.
72+
#### Generic text (C++)
73+
74+
```cpp
75+
// Keep sorted
76+
// comment two
77+
second
78+
// comment one
79+
first
80+
```
8281

83-
- `# Keep sorted` or `# keepsorted: keep sorted` sorts the next block of lines
84-
- `# keepsorted: ignore file` anywhere in the file skips sorting
85-
- `# keepsorted: ignore block` within a block skips sorting that block
82+
becomes
8683

87-
## Supported Files
84+
```cpp
85+
// Keep sorted
86+
// comment one
87+
first
88+
// comment two
89+
second
90+
```
8891

89-
### Generic Text Files
92+
#### Generic text (SQL/Lua)
9093

91-
For generic text files, the tool sorts blocks that start with `# Keep sorted` and end with a newline.
94+
```sql
95+
-- Keep sorted
96+
-- c comment
97+
c
98+
-- a comment
99+
a
100+
```
92101

93-
```txt
94-
# Names
95-
# Keep sorted
96-
Alice
97-
Bob
98-
Conrad
102+
becomes
99103

100-
# Colors
101-
# Keep sorted
102-
Blue
103-
Green
104-
Red
104+
```sql
105+
-- Keep sorted
106+
-- a comment
107+
a
108+
-- c comment
109+
c
105110
```
106111

107-
### Bazel
112+
#### Bazel
113+
114+
```bazel
115+
srcs = [
116+
# Keep sorted
117+
"b",
118+
# note for a
119+
"a",
120+
]
121+
```
108122

109-
In Bazel files, keepsorted sorts lines within `[...]` blocks that start with `# Keep sorted`.
123+
becomes
110124

111125
```bazel
112-
DEPENDENCIES = [
126+
srcs = [
113127
# Keep sorted
128+
# note for a
114129
"a",
115130
"b",
116131
]
117132
```
118133

119-
### Cargo.toml
120-
121-
In `Cargo.toml` files, the tool sorts lines within blocks that start with `[dependencies]`, `[dev-dependencies]`, etc., and end with an empty line.
134+
#### Cargo.toml
122135

123136
```toml
124137
[dependencies]
125-
a = "0.1.0"
126-
b = { workspace = true }
138+
b = "2"
139+
a = "1"
127140

128141
# keepsorted: ignore block
129142
[dev-dependencies]
130-
y = { workspace = true }
131-
x = "0.3.0"
143+
z = "1"
144+
y = "2"
132145
```
133146

134-
### .gitignore & CODEOWNERS
147+
becomes
135148

136-
*NOTE: These features are experimental and require feature flags.*
149+
```toml
150+
[dependencies]
151+
a = "1"
152+
b = "2"
137153

138-
```shell
139-
$ keepsorted <path> --features gitignore,codeowners
154+
# keepsorted: ignore block
155+
[dev-dependencies]
156+
z = "1"
157+
y = "2"
140158
```
141159

142-
In `.gitignore` and `CODEOWNERS` files, the tool sorts blocks separated by empty lines while keeping comments in place, except for the opening block comment.
160+
#### .gitignore
143161

144-
**(!) IMPORTANT**: the order of patterns can be important because it gets executed from top to bottom from more generic to more specific rules, therefore use this feature with extra care.
162+
```gitignore
163+
# Build
164+
/b
165+
/a
166+
```
145167

146-
```.gitignore
147-
# Various build artifacts
148-
**/build
149-
**/build-out
150-
**/build-tmp
151-
artifacts
168+
becomes
152169

153-
# Bazel outdir dirs
154-
# keepsorted: ignore block
155-
bazel-c.pb
156-
user.bazelrc
157-
bazel-b.txt
158-
/bazel-*
159-
bazel-a.txt
170+
```gitignore
171+
# Build
172+
/a
173+
/b
160174
```
161175

162-
### Rust Derive
176+
#### CODEOWNERS
163177

164-
*NOTE: These features are experimental and require feature flags.*
165-
166-
```shell
167-
$ keepsorted <path> --features rust_derive_alphabetical
168-
# or
169-
$ keepsorted <path> --features rust_derive_canonical
178+
```codeowners
179+
# Team
180+
b
181+
# Lead
182+
a
170183
```
171184

172-
The feature is inspired by a closed ticket to update rust style, [link](https://github.com/rust-lang/style-team/issues/154).
185+
becomes
173186

174-
### Formatting mode
187+
```codeowners
188+
# Team
189+
a
190+
# Lead
191+
b
192+
```
193+
194+
### Experimental features
175195

176-
The `--mode` option controls whether the file is modified. It accepts `check`,
177-
`diff`, or `fix` (the default). The flags `--check`, `--diff`, and `--fix` are
178-
aliases for `--mode check`, `--mode diff`, and `--mode fix` respectively.
196+
The following features are behind flags because sorting might change behaviour:
179197

180-
Use `--mode check` (or `--check`) to verify that a file is already sorted without modifying it.
181-
Use `--mode diff` (or `--diff`) to print a unified diff of the required changes.
182-
Use `--diff-command <command>` to delegate diff generation to an external program.
183-
Use `--mode fix` (or `--fix`) to rewrite the file in place.
198+
- `gitignore` and `codeowners` – order matters, so enable with care.
199+
- `rust_derive_alphabetical` and `rust_derive_canonical` – temporary helpers for
200+
sorting Rust `#[derive(...)]` lists until `rustfmt` gains this ability. These
201+
implementations are intentionally simple.
184202

185-
The command exits with these codes:
186-
- `0` — success
187-
- `1` — syntax errors in input
188-
- `2` — usage errors: invoked incorrectly
189-
- `3` — unexpected runtime errors
190-
- `4` — check mode failed (reformat is needed)
203+
Enable features with `--features`:
191204

192205
```shell
193-
$ keepsorted --check Cargo.toml
194-
$ keepsorted --diff Cargo.toml
195-
$ keepsorted --fix Cargo.toml
206+
keepsorted file --features gitignore,rust_derive_canonical
196207
```
197208

209+
### Limitations
210+
211+
`keepsorted` intentionally does **not**:
212+
213+
- Handle advanced directory traversal or ignore rules automatically.
214+
- Act as a full-fledged parser for every file type.
215+
- Handle ignore files or exclude paths automatically.
216+
- Automatically detect project structure or configuration files.
217+
- Replace formatting tools like `rustfmt` or `prettier`.
218+

0 commit comments

Comments
 (0)