sonicop 26.8.108 → 26.8.110
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CONFORMANCE.md +55 -15
- data/Cargo.lock +1 -1
- data/Cargo.toml +1 -1
- data/NOTICE +152 -6
- data/README.ja.md +39 -7
- data/README.md +36 -8
- data/lib/sonicop/version.rb +1 -1
- data/src/config/loader.rs +11 -1
- data/src/engine.rs +173 -14
- data/src/nul_bytes.rs +130 -16
- data/src/rules/layout/block_alignment.rs +5 -0
- data/src/rules/layout/empty_comment.rs +5 -1
- data/src/rules/layout/empty_line_after_guard_clause.rs +33 -13
- data/src/rules/layout/leading_comment_space.rs +6 -4
- data/src/rules/layout/trailing_whitespace.rs +19 -1
- data/src/rules/lint/ambiguity.rs +6 -1
- data/src/rules/lint/duplicate_hash_key.rs +11 -8
- data/src/rules/lint/literal_as_condition.rs +20 -20
- data/src/rules/lint/literal_in_interpolation.rs +10 -4
- data/src/rules/lint/node_equality.rs +106 -0
- data/src/rules/lint/regexp_tree.rs +94 -6
- data/src/rules/lint/safe_navigation_chain.rs +91 -33
- data/src/rules/lint/syntax.rs +97 -0
- data/src/rules/send_node.rs +55 -0
- data/src/rules/style/collection_compact.rs +14 -8
- data/src/rules/style/conditional_assignment.rs +23 -22
- data/src/rules/style/double_negation.rs +18 -22
- data/src/rules/style/each_with_object.rs +5 -1
- data/src/rules/style/explicit_block_argument.rs +53 -6
- data/src/rules/style/if_with_boolean_literal_branches.rs +7 -11
- data/src/rules/style/invertible_unless_condition.rs +20 -13
- data/src/rules/style/map_into_array.rs +10 -2
- data/src/rules/style/multiline_ternary_operator.rs +12 -0
- data/src/rules/style/negated_if.rs +10 -22
- data/src/rules/style/negated_if_else_condition.rs +10 -22
- data/src/rules/style/negated_unless.rs +3 -6
- data/src/rules/style/negated_while.rs +13 -21
- data/src/rules/style/partition_instead_of_double_select.rs +3 -10
- data/src/rules/style/redundant_condition.rs +71 -21
- data/src/rules/style/redundant_parentheses.rs +40 -4
- data/src/rules/style/redundant_return.rs +49 -39
- data/src/rules/style/single_argument_dig.rs +20 -10
- data/src/rules/style/tally_method.rs +10 -0
- data/src/rules/support.rs +53 -8
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a00a7d0dc817fde927c8f9a5eb24db975f85aa2f4dda36ae1f7de548aa6557f6
|
|
4
|
+
data.tar.gz: 2c09e86e186f680c8f31cf5fd0e979fb974bc23ad173fa14e4f100f98dc95ce3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 786c6eb994b2d5020f9f035623ec0f54ab95ad3f0359f747efd0bf97fd1bd4cca00d21b7a652b483861aef2af80dabb18dea4185bf9320a214307c4ea8780a8a
|
|
7
|
+
data.tar.gz: 8c0b93e14e6e7a56f497cc55aad95ce730c681515f9e2f8d67efcfe3c8ae44d98dc8f5ab1bf9c25b60f6de0791b0ed077bc3df0b4a679d3c07416a731426c66d
|
data/CONFORMANCE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# RuboCop conformance
|
|
2
2
|
|
|
3
|
-
Snapshot date:
|
|
3
|
+
Snapshot date: per row — see the `Measured` column of *Results*
|
|
4
4
|
Reference: RuboCop 1.89.0 on Ruby 4.0.6
|
|
5
5
|
Configuration: RuboCop 1.89.0 built-in defaults (`--force-default-config`) on both sides
|
|
6
6
|
|
|
@@ -30,7 +30,11 @@ sequence in UTF-8` on it — and `test/ruby/test_file_exhaustive.rb` holds an of
|
|
|
30
30
|
not valid UTF-8, which stops the JSON formatter from emitting a document. The comparison for that
|
|
31
31
|
corpus therefore covers 7,464 of its 7,466 files.
|
|
32
32
|
|
|
33
|
-
The **target file lists match exactly** on all five — not just the counts but the paths
|
|
33
|
+
The **target file lists match exactly** on all five — not just the counts but the paths, compared as
|
|
34
|
+
sets: rubocop/rubocop (1,765), rails/rails (3,551), mastodon/mastodon (3,290), Homebrew/brew (2,179)
|
|
35
|
+
and ruby/ruby (7,466), with nothing on either side of any of the five. Counts alone would not settle
|
|
36
|
+
it — a set that loses one file and gains another keeps its count — so the check compares the sorted
|
|
37
|
+
lists and reports what only one side holds. That is
|
|
34
38
|
worth stating separately because file discovery is where a port silently diverges first: RuboCop
|
|
35
39
|
never reads `.gitignore`, applies a shebang test only to extensionless files, descends through
|
|
36
40
|
directory symlinks, and treats a hidden path by its *first* component rather than by any dot in it.
|
|
@@ -51,19 +55,47 @@ sonicop --force-default-config --format json
|
|
|
51
55
|
|
|
52
56
|
## Results
|
|
53
57
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
58
|
+
The two kinds of difference are counted separately because they mean different things. A
|
|
59
|
+
`Lint/Syntax` difference says the two disagree about whether a file parses, and everything else in
|
|
60
|
+
that file follows from it; a difference in any other cop says the port reads the same tree and
|
|
61
|
+
draws a different conclusion. Only the second is a defect in a cop.
|
|
62
|
+
|
|
63
|
+
| Corpus | Excess | Missing | of which `Lint/Syntax` | Other cops | Field differences | Measured |
|
|
64
|
+
|---|---:|---:|---|---:|---|---|
|
|
65
|
+
| rubocop/rubocop | 0 | 0 | — | 0 | correctable ×1 | 2026-08-17 |
|
|
66
|
+
| rails/rails | 0 | 0 | — | 0 | none | 2026-08-17 |
|
|
67
|
+
| mastodon/mastodon | 0 | 0 | — | 0 | none | 2026-08-17 |
|
|
68
|
+
| Homebrew/brew | 263 | 997 | **all of them** | **0** | none | 2026-08-17 |
|
|
69
|
+
| ruby/ruby | 142 | 585 | 117 missing, 44 excess | 92 | 5 | 2026-08-16 |
|
|
70
|
+
|
|
71
|
+
The last column is per row on purpose. A single date at the top of the file would say the five were
|
|
72
|
+
measured together, and they were not: the first four are re-measured on every release, ruby/ruby is
|
|
73
|
+
not — it is the one corpus whose reference cannot be produced in a single run (see above), so it is
|
|
74
|
+
re-measured deliberately rather than routinely. Its row is the older of the two and should be read
|
|
75
|
+
as such.
|
|
76
|
+
|
|
77
|
+
**No cop other than `Lint/Syntax` differs on four of the five corpora**, Homebrew included: across
|
|
78
|
+
its 2,179 files and 49,920 offenses the two agree on every position, message, severity and
|
|
79
|
+
correctability that is not a syntax diagnostic.
|
|
80
|
+
|
|
81
|
+
Homebrew's 1,260 differences — 997 missing and 263 excess — share one cause, and it is not a parser
|
|
82
|
+
bug on either side. Homebrew is a Ruby 4.0
|
|
83
|
+
codebase — `Library/Homebrew/.ruby-version` says `4.0.6` — but that file sits below the directory the
|
|
84
|
+
run starts from, and `TargetRubyVersion` is only inferred from the working directory's ancestors. Both
|
|
85
|
+
tools therefore fall back to the default of 2.7 (RuboCop says so itself: `Using Ruby 2.7 parser`) and
|
|
86
|
+
both call `dry_run:,` — a hash value omission, valid since 3.1 — a syntax error. **Run the same corpus
|
|
87
|
+
at 3.1 and both report zero `Lint/Syntax`.** What is left is not disagreement about which files parse:
|
|
88
|
+
the file sets are identical, 569 on each side, and the first diagnostic in each file lands at the same
|
|
89
|
+
position. Only the second and later diagnostics diverge, because the two parsers recover from the
|
|
90
|
+
error differently — which is what puts offenses on both sides of the ledger rather than only on
|
|
91
|
+
RuboCop's. Those are not chased; see *Known divergences*.
|
|
92
|
+
|
|
93
|
+
What is checked here is that every one of the 1,260 is a `Lint/Syntax` offense, in both directions.
|
|
94
|
+
What is not checked is which recovery produced which diagnostic: the 263 Sonicop reports and RuboCop
|
|
95
|
+
does not have not been read one by one. They are accounted for as a class, not individually.
|
|
96
|
+
|
|
97
|
+
Much of ruby/ruby's difference is the same shape,
|
|
98
|
+
with 117 of the 585 missing and 44 of the 142 excess being `Lint/Syntax` itself,
|
|
67
99
|
and the rest follows from it: a file the two disagree about is inspected by one tool and skipped by
|
|
68
100
|
the other, so every offense in it lands on one side of the ledger. Counting that through, 635 of the
|
|
69
101
|
727 differences sit in files one tool or the other calls a syntax error, and they are spread thinly
|
|
@@ -271,6 +303,14 @@ current list of what these corpora never exercise; the main ones are non-default
|
|
|
271
303
|
values, extension plugins, and Windows line endings. Cops that never fire contribute nothing to a
|
|
272
304
|
match count, and their silence is indistinguishable from agreement.
|
|
273
305
|
|
|
306
|
+
That limit is not hypothetical, and one instance is now measured. `Style/HashSyntax` defaults
|
|
307
|
+
`EnforcedShorthandSyntax` to `either`, under which neither tool reports anything; the port
|
|
308
|
+
implements none of the other four values, so half the cop is missing. Both the corpus runs and a
|
|
309
|
+
sweep of RuboCop's own specs report agreement for it, because both run at the default. A cop can be
|
|
310
|
+
half absent and still match everywhere the default reaches. Where a cop's behaviour is selected by
|
|
311
|
+
configuration, this document covers the default branch only — the others are neither measured nor
|
|
312
|
+
claimed.
|
|
313
|
+
|
|
274
314
|
The 215 cops RuboCop ships switched off are a limit of a different kind. They are implemented, but a
|
|
275
315
|
default run never reaches them, so the corpus numbers above say nothing about them. What stands
|
|
276
316
|
behind those is a separate measurement: the same corpora linted with all 609 cops switched on, on
|
data/Cargo.lock
CHANGED
data/Cargo.toml
CHANGED
data/NOTICE
CHANGED
|
@@ -1,7 +1,153 @@
|
|
|
1
|
-
|
|
2
|
-
RuboCop is Copyright (c) 2012-26 Bozhidar Batsov and contributors,
|
|
3
|
-
licensed under the MIT License. See licenses/RUBOCOP.txt.
|
|
1
|
+
NOTICE
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
sonicop is distributed under the MIT License (see LICENSE). It also carries
|
|
4
|
+
material generated from, or copied verbatim out of, the projects listed below.
|
|
5
|
+
Each is redistributed under its own licence, reproduced in full at the end of
|
|
6
|
+
this file.
|
|
7
|
+
|
|
8
|
+
This file is an inventory as much as an attribution: it records **what is taken,
|
|
9
|
+
from where, and how to regenerate it**. Keeping it current is what makes the
|
|
10
|
+
licence position checkable rather than remembered.
|
|
11
|
+
|
|
12
|
+
**Adding anything derived from another project means adding it here in the
|
|
13
|
+
same change.** This file was written only after a routine attempt to list what
|
|
14
|
+
we vendor turned up a corpus nobody had recorded -- the inventory found it,
|
|
15
|
+
not the attribution. An entry that is added late is an entry that was, for a
|
|
16
|
+
while, undocumented in a public repository.
|
|
17
|
+
|
|
18
|
+
Known to be coming: tests/fixtures/upstream_spec_cases.jsonl, which will hold
|
|
19
|
+
input text from RuboCop's specs. It is deliberately **not** listed yet -- this
|
|
20
|
+
file describes what is here now, not what is planned.
|
|
21
|
+
|
|
22
|
+
================================================================================
|
|
23
|
+
WHAT IS TAKEN
|
|
24
|
+
================================================================================
|
|
25
|
+
|
|
26
|
+
RuboCop -- https://github.com/rubocop/rubocop -- MIT
|
|
27
|
+
Copyright (c) 2012-26 Bozhidar Batsov
|
|
28
|
+
|
|
29
|
+
config/default.yml
|
|
30
|
+
The upstream configuration, taken verbatim at v1.89.0. It is the sole
|
|
31
|
+
source of truth for which cops exist and what their defaults are.
|
|
32
|
+
Regenerate: scripts/sync_default_yml.sh 1.89.0
|
|
33
|
+
Full text also kept at licenses/RUBOCOP.txt
|
|
34
|
+
|
|
35
|
+
Ruby on Rails -- https://github.com/rails/rails -- MIT
|
|
36
|
+
Copyright (c) David Heinemeier Hansson
|
|
37
|
+
|
|
38
|
+
Ruby -- https://github.com/ruby/ruby -- 2-clause BSDL
|
|
39
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto
|
|
40
|
+
|
|
41
|
+
Ruby is dual-licensed. Its COPYING offers a choice:
|
|
42
|
+
|
|
43
|
+
"You can redistribute it and/or modify it under either the terms of the
|
|
44
|
+
2-clause BSDL (see the file BSDL), or the conditions below"
|
|
45
|
+
|
|
46
|
+
**sonicop takes the 2-clause BSDL**, reproduced below. This is written down
|
|
47
|
+
because the alternative -- saying nothing -- leaves the next reader to work
|
|
48
|
+
out why the longer Ruby License is absent.
|
|
49
|
+
|
|
50
|
+
Homebrew -- https://github.com/Homebrew/brew -- BSD 2-Clause
|
|
51
|
+
Copyright (c) 2009-present, Homebrew contributors
|
|
52
|
+
|
|
53
|
+
Rails, Ruby and Homebrew contribute to one file, together with RuboCop:
|
|
54
|
+
|
|
55
|
+
tests/fixtures/regexp_trees.jsonl
|
|
56
|
+
Every distinct regular-expression literal appearing in those projects'
|
|
57
|
+
Ruby sources, paired with the tree the `regexp_parser` gem builds for it.
|
|
58
|
+
It is the differential check for this port's own regexp scanner.
|
|
59
|
+
Corpora, commit hashes and the regeneration command are recorded in
|
|
60
|
+
tests/fixtures/regexp_trees.PROVENANCE.
|
|
61
|
+
|
|
62
|
+
Note: mastodon is **not** among the corpora. It is AGPL-3.0, and this
|
|
63
|
+
repository is MIT; the two are not obviously compatible, so it is left
|
|
64
|
+
out rather than reasoned about. Only permissively licensed corpora are
|
|
65
|
+
used, and dropping mastodon cost 218 of 10,966 patterns.
|
|
66
|
+
|
|
67
|
+
tree-sitter-ruby -- https://github.com/owayo/tree-sitter-ruby -- MIT
|
|
68
|
+
Copyright (c) 2016 Rob Rix and contributors
|
|
69
|
+
|
|
70
|
+
Linked as a dependency (see Cargo.toml). sonicop uses a fork; the grammar
|
|
71
|
+
itself is derived from the original. Full text: licenses/TREE_SITTER_RUBY.txt
|
|
72
|
+
|
|
73
|
+
================================================================================
|
|
74
|
+
MIT License -- applies to RuboCop and to Ruby on Rails
|
|
75
|
+
================================================================================
|
|
76
|
+
|
|
77
|
+
Copyright (c) 2012-26 Bozhidar Batsov
|
|
78
|
+
Copyright (c) David Heinemeier Hansson
|
|
79
|
+
|
|
80
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
81
|
+
a copy of this software and associated documentation files (the
|
|
82
|
+
"Software"), to deal in the Software without restriction, including
|
|
83
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
84
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
85
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
86
|
+
the following conditions:
|
|
87
|
+
|
|
88
|
+
The above copyright notice and this permission notice shall be
|
|
89
|
+
included in all copies or substantial portions of the Software.
|
|
90
|
+
|
|
91
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
92
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
93
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
94
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
95
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
96
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
97
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
98
|
+
================================================================================
|
|
99
|
+
2-clause BSDL -- applies to Ruby
|
|
100
|
+
================================================================================
|
|
101
|
+
|
|
102
|
+
Copyright (C) 1993-2013 Yukihiro Matsumoto. All rights reserved.
|
|
103
|
+
|
|
104
|
+
Redistribution and use in source and binary forms, with or without
|
|
105
|
+
modification, are permitted provided that the following conditions
|
|
106
|
+
are met:
|
|
107
|
+
1. Redistributions of source code must retain the above copyright
|
|
108
|
+
notice, this list of conditions and the following disclaimer.
|
|
109
|
+
2. Redistributions in binary form must reproduce the above copyright
|
|
110
|
+
notice, this list of conditions and the following disclaimer in the
|
|
111
|
+
documentation and/or other materials provided with the distribution.
|
|
112
|
+
|
|
113
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
114
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
115
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
116
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
117
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
118
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
119
|
+
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
120
|
+
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
121
|
+
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
122
|
+
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
123
|
+
SUCH DAMAGE.
|
|
124
|
+
|
|
125
|
+
================================================================================
|
|
126
|
+
BSD 2-Clause License -- applies to Homebrew
|
|
127
|
+
================================================================================
|
|
128
|
+
|
|
129
|
+
BSD 2-Clause License
|
|
130
|
+
|
|
131
|
+
Copyright (c) 2009-present, Homebrew contributors
|
|
132
|
+
All rights reserved.
|
|
133
|
+
|
|
134
|
+
Redistribution and use in source and binary forms, with or without
|
|
135
|
+
modification, are permitted provided that the following conditions are met:
|
|
136
|
+
|
|
137
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
138
|
+
list of conditions and the following disclaimer.
|
|
139
|
+
|
|
140
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
141
|
+
this list of conditions and the following disclaimer in the documentation
|
|
142
|
+
and/or other materials provided with the distribution.
|
|
143
|
+
|
|
144
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
145
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
146
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
147
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
148
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
149
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
150
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
151
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
152
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
153
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.ja.md
CHANGED
|
@@ -41,6 +41,10 @@ sonicop --show-cops
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
**RuboCop 1.89 の全 609 Cop を実装しています。** 本家のレジストリと名前まで一致しており、
|
|
44
|
+
ただしこれは**レジストリについての主張**であって、すべての設定についての主張ではありません。
|
|
45
|
+
`Style/HashSyntax` は存在し既定の届く範囲では一致しますが、`EnforcedShorthandSyntax` の
|
|
46
|
+
既定以外の 4 つの値はいずれも未実装です。**Cop は半分欠けたまま、既定の届く範囲では
|
|
47
|
+
一致し続けられます** — [CONFORMANCE.md](CONFORMANCE.md) の *Limits* を参照してください。
|
|
44
48
|
`Enabled: pending` の 159 個と `Enabled: false` の 56 個も含みます。この 215 個は本家でも
|
|
45
49
|
既定の実行では走らないので、`--only` で名指しするか設定で有効にしてください。本家にも
|
|
46
50
|
存在しない Cop 名だけをエラーにし、必要なら `--ignore-unrecognized-cops` で続行できます。
|
|
@@ -103,8 +107,26 @@ Style/StringLiterals:
|
|
|
103
107
|
```
|
|
104
108
|
|
|
105
109
|
既存コマンドとの互換性を保つため、server/LSP/MCP、plugin、cache 系の引数も受理します。
|
|
106
|
-
|
|
107
|
-
|
|
110
|
+
サーバートランスポート、Ruby プラグイン実行、キャッシュ再利用、カスタム Cop、実装済み以外の
|
|
111
|
+
Cop は実行しません。
|
|
112
|
+
|
|
113
|
+
そのうち大半は、その旨を出力します。`--server` / `--no-server` / `--lsp` / `--mcp` /
|
|
114
|
+
`--plugin` は stderr に 1 行の注記を出します。cache 系は何も出しませんが、
|
|
115
|
+
無言でよいのは片方だけです。
|
|
116
|
+
|
|
117
|
+
- `--cache=false` はキャッシュを使わないことを求めるもので、sonicop はそれを満たしているため、
|
|
118
|
+
無言が正しい応答です。
|
|
119
|
+
- `--cache=true` はキャッシュ再利用を求めるものですが、sonicop はこれを提供しておらず、
|
|
120
|
+
それでも無言です。
|
|
121
|
+
|
|
122
|
+
Cop の設定値も後者と同じ挙動です。sonicop が実装していない設定値 — たとえば
|
|
123
|
+
`Style/HashSyntax` の `EnforcedShorthandSyntax` — は**警告なしに無視されます**。
|
|
124
|
+
名前を綴り間違えた設定値も同様に無視されます。つまり
|
|
125
|
+
**offense が 0 件であることは、その設定が効いた証拠にはなりません**。
|
|
126
|
+
無視された設定値と、違反の無いファイルが、同じ出力になるためです。
|
|
127
|
+
|
|
128
|
+
Cop の*名前*は検査されます。設定ファイルに未知の Cop 名があれば、実行はエラーで止まります。
|
|
129
|
+
素通りするのは、既知の Cop の中の設定値です。
|
|
108
130
|
|
|
109
131
|
### 適合性
|
|
110
132
|
|
|
@@ -114,8 +136,12 @@ Ruby プラグイン実行、キャッシュ再利用、カスタム Cop、実
|
|
|
114
136
|
|
|
115
137
|
5 つのうち 3 つが**完全一致**です。RuboCop 自身のツリー(5,766 件)、Rails(167,760 件)、
|
|
116
138
|
Mastodon(15,286 件)で、過剰も不足もメタデータ差もありません。対象ファイル一覧は 5 つすべてで
|
|
117
|
-
|
|
118
|
-
|
|
139
|
+
**件数だけでなくパスまで**一致します(集合として比較。どの側にも余りはありません)。
|
|
140
|
+
残る差分は `Lint/Syntax` に集中しています。その大半は、本家の LALR パーサが
|
|
141
|
+
構文エラーから回復して出す追加診断を tree-sitter では再現できないことによるもので、
|
|
142
|
+
**これが説明するのは不足の向きだけ**です。**過剰の向きは別の問題で、未調査です** —
|
|
143
|
+
Homebrew の 263 件はすべて `Lint/Syntax` であることまでは確認していますが、
|
|
144
|
+
移植版だけが構文エラーと呼ぶその中身は調べていません。autocorrect は RuboCop 自身のツリーと
|
|
119
145
|
Mastodon でバイト単位に一致します。この 2 つは死守ラインとして扱い、バイト一致が崩れた場合は
|
|
120
146
|
既知差分ではなく退行として直します。
|
|
121
147
|
|
|
@@ -126,10 +152,15 @@ Mastodon でバイト単位に一致します。この 2 つは死守ライン
|
|
|
126
152
|
|
|
127
153
|
適合性検証に使う 5 コーパスすべてで測定しました。両者とも同梱の既定設定
|
|
128
154
|
(`--force-default-config`)で走らせているためプロジェクト側の `.rubocop.yml` は読まず、
|
|
129
|
-
|
|
155
|
+
どのコーパスでも**対象ファイル数は一致**しています。この計測に必要なのはそこまでで、
|
|
156
|
+
どちらの側も少なく検査してはいない、と言えます。パス単位の一致はより強い主張で、
|
|
157
|
+
上の*適合性*の節で 5 つすべてについて示していますが、それは固定したリビジョンでの測定であって
|
|
158
|
+
この速度計測の run そのものではありません。
|
|
130
159
|
|
|
131
160
|
両者とも既定の全 Cop で走らせています。**同じ 394 Cop** が名前まで一致しているため、
|
|
132
161
|
どちらも絞る必要がなく、素の実行がそのまま対等な比較になります。
|
|
162
|
+
(394 は 609 から `Enabled: pending` の 159 個と `Enabled: false` の 56 個を除いた残りで、
|
|
163
|
+
既定の実行はどちらの群にも届きません。)
|
|
133
164
|
各値は暖機後 2 回の最速値です。
|
|
134
165
|
|
|
135
166
|
| コーパス | ファイル | RuboCop 並列 | Sonicop 並列 | RuboCop 単一 | Sonicop 単一 |
|
|
@@ -147,8 +178,9 @@ Mastodon でバイト単位に一致します。この 2 つは死守ライン
|
|
|
147
178
|
エンジンを測っていますが、並列はエンジンに加えて「その実行でスケジューリングがそのツリーに
|
|
148
179
|
どれだけ噛み合ったか」を測っています。
|
|
149
180
|
|
|
150
|
-
仕事を省いて速いわけではありません。この同じ 394 Cop について、RuboCop
|
|
151
|
-
Mastodon
|
|
181
|
+
仕事を省いて速いわけではありません。この同じ 394 Cop について、RuboCop 自身のツリー・
|
|
182
|
+
Rails・Mastodon の 3 つで**すべての offense が一致**します(計 188,812 件、どちらの側にも
|
|
183
|
+
残りません)。autocorrect は前者と後者でバイト単位に一致します。
|
|
152
184
|
|
|
153
185
|
再現時に注意が必要な点が 2 つあります。RuboCop は **`--cache false` と併用すると
|
|
154
186
|
`--parallel` を黙って無効化します**。そのためここでの並列実行はキャッシュを有効にしたうえで
|
data/README.md
CHANGED
|
@@ -41,6 +41,10 @@ sonicop --show-cops
|
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
**All 609 RuboCop 1.89 cops are implemented**, matched name for name against the upstream registry.
|
|
44
|
+
That is a claim about the registry, not about every configuration: `Style/HashSyntax` is present and
|
|
45
|
+
matches everywhere its default reaches, yet none of the four non-default values of its
|
|
46
|
+
`EnforcedShorthandSyntax` are implemented. **A cop can be half absent and still match everywhere the
|
|
47
|
+
default reaches** — see *Limits* in [CONFORMANCE.md](CONFORMANCE.md).
|
|
44
48
|
That includes the 159 shipped as `Enabled: pending` and the 56 shipped as `Enabled: false`, which a
|
|
45
49
|
default run does not reach on either side — name them with `--only` or switch them on in a
|
|
46
50
|
configuration, exactly as with RuboCop. Unknown cop names still fail validation unless
|
|
@@ -111,9 +115,24 @@ Style/StringLiterals:
|
|
|
111
115
|
```
|
|
112
116
|
|
|
113
117
|
The CLI accepts RuboCop's server/LSP/MCP, plugin, and cache flags to keep existing command lines
|
|
114
|
-
parse-compatible.
|
|
115
|
-
|
|
116
|
-
|
|
118
|
+
parse-compatible. Sonicop does not provide server transports, Ruby plugin execution, cache reuse,
|
|
119
|
+
custom Ruby cops, or cops outside the implemented set.
|
|
120
|
+
|
|
121
|
+
Most of those flags say so. `--server`, `--no-server`, `--lsp`, `--mcp`, and `--plugin` each print
|
|
122
|
+
a one-line notice on stderr. The cache flags print nothing, and only one of them is silent for a
|
|
123
|
+
good reason:
|
|
124
|
+
|
|
125
|
+
- `--cache=false` asks for no caching, which sonicop already satisfies, so silence is the correct
|
|
126
|
+
answer.
|
|
127
|
+
- `--cache=true` asks for cache reuse, which sonicop does not provide, and it is silent anyway.
|
|
128
|
+
|
|
129
|
+
Cop settings behave like the second case. A setting sonicop does not implement — for example
|
|
130
|
+
`EnforcedShorthandSyntax` under `Style/HashSyntax` — is ignored without any warning, and so is a
|
|
131
|
+
setting whose name is simply misspelled. **A run that reports no offenses is therefore not evidence
|
|
132
|
+
that a setting took effect**, because an ignored setting and a clean file produce the same output.
|
|
133
|
+
|
|
134
|
+
Cop *names* are checked: an unrecognised cop in a configuration file stops the run with an error.
|
|
135
|
+
It is the settings inside a recognised cop that pass unvalidated.
|
|
117
136
|
|
|
118
137
|
### Conformance
|
|
119
138
|
|
|
@@ -124,8 +143,12 @@ column, length, message, severity and correctability.
|
|
|
124
143
|
|
|
125
144
|
Three of the five match **exactly**: RuboCop's own tree (5,766 offenses), Rails (167,760) and
|
|
126
145
|
Mastodon (15,286), with no excess, no shortfall and no metadata differences. The target file lists
|
|
127
|
-
match exactly on all five. What remains is concentrated in
|
|
128
|
-
|
|
146
|
+
match exactly on all five — paths, not just counts, compared as sets. What remains is concentrated in
|
|
147
|
+
`Lint/Syntax`. Most of it is RuboCop's
|
|
148
|
+
LALR parser recovering from an error and emitting diagnostics a tree-sitter parse cannot
|
|
149
|
+
reconstruct — that direction accounts for the shortfall. **The excess is a separate question and has
|
|
150
|
+
not been investigated**; on Homebrew all 263 of it is `Lint/Syntax` too, but what Sonicop calls a
|
|
151
|
+
syntax error there and RuboCop does not is unexamined.
|
|
129
152
|
Autocorrect is byte-identical on RuboCop's own tree and on Mastodon, the two corpora held as a hard
|
|
130
153
|
line: a change that breaks byte equality there is a regression, not a new known divergence.
|
|
131
154
|
|
|
@@ -136,10 +159,14 @@ measured at, and the two ways a measurement of this kind can mislead you.
|
|
|
136
159
|
|
|
137
160
|
Measured over all five conformance corpora. Both tools were given their own bundled default
|
|
138
161
|
configuration (`--force-default-config`), so neither reads the project's `.rubocop.yml`, and on every
|
|
139
|
-
corpus the two resolve **the same
|
|
162
|
+
corpus the two resolve **the same number of files** — which is what these timings need, since it
|
|
163
|
+
means neither side is inspecting less. Path-by-path equality is a stronger claim, established under
|
|
164
|
+
*Conformance* above for all five, but on the pinned corpus revisions rather than on these timing runs.
|
|
140
165
|
|
|
141
166
|
Both tools run their full default set — **the same 394 cops**, matched name for name — so neither
|
|
142
|
-
side is restricted and the comparison is like-for-like as it stands.
|
|
167
|
+
side is restricted and the comparison is like-for-like as it stands. (394 is what is left of the 609
|
|
168
|
+
once the 159 RuboCop ships as `Enabled: pending` and the 56 it ships as `Enabled: false` are set
|
|
169
|
+
aside; a default run reaches neither group on either side.) Times are the fastest of two
|
|
143
170
|
warmed runs.
|
|
144
171
|
|
|
145
172
|
| Corpus | Files | RuboCop parallel | Sonicop parallel | RuboCop single | Sonicop single |
|
|
@@ -158,7 +185,8 @@ else the machine was doing. Single-process measures the engines; parallel measur
|
|
|
158
185
|
how well each one's scheduling happens to fit that tree on that run.
|
|
159
186
|
|
|
160
187
|
The speed is not bought by skipping work: over those same 394 cops the two agree on **every offense**
|
|
161
|
-
on RuboCop's own tree and on Mastodon,
|
|
188
|
+
on RuboCop's own tree, on Rails and on Mastodon — 188,812 offenses with nothing on either side of the
|
|
189
|
+
ledger — and autocorrect is byte-identical on the first and the last.
|
|
162
190
|
|
|
163
191
|
Two details matter for reproducing this. RuboCop **silently turns `--parallel` off when combined
|
|
164
192
|
with `--cache false`**, so its parallel runs here use a cache directory that is deleted before each
|
data/lib/sonicop/version.rb
CHANGED
data/src/config/loader.rs
CHANGED
|
@@ -11,7 +11,17 @@ pub(super) fn find_config(start: &Path) -> Option<PathBuf> {
|
|
|
11
11
|
if candidate.is_file() {
|
|
12
12
|
return fs::canonicalize(candidate).ok();
|
|
13
13
|
}
|
|
14
|
-
if
|
|
14
|
+
// `break if dir == stop_dir || dir == FileFinder.root_level`
|
|
15
|
+
//
|
|
16
|
+
// **`stop_dir` が無いことは「止まらない」であって「止まる」ではない。**
|
|
17
|
+
// 上流の `find_project_dotfile` は `find_file_upwards(DOTFILE, target_dir, project_root)`
|
|
18
|
+
// で、`project_root` が nil のときは何とも一致しないので**ファイルシステムの根まで
|
|
19
|
+
// 昇る**。ここを `is_none_or` で書いていたため、Gemfile の無い木では最初の 1 段で
|
|
20
|
+
// 止まり、**`.rubocop.yml` がリポジトリ直下・コードが `lib/` という標準の配置で
|
|
21
|
+
// 設定が 1 つも効かなかった。**
|
|
22
|
+
//
|
|
23
|
+
// `ancestors()` は根で終わるので、`root_level` の側は自然に満たされる。
|
|
24
|
+
if project_root.as_deref() == Some(directory) {
|
|
15
25
|
break;
|
|
16
26
|
}
|
|
17
27
|
}
|