rubocop-dev_doc 0.16.0 → 0.18.0
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/config/default.yml +312 -60
- data/config/obsoletion.yml +7 -3
- data/lib/dev_doc/i18n/tasks.rb +68 -0
- data/lib/dev_doc/railtie.rb +19 -0
- data/lib/dev_doc/test/lints/cross_tenant_canary_sweep.rb +2 -0
- data/lib/dev_doc/test/lints/domain_class_base.rb +138 -0
- data/lib/dev_doc/test/lints/http_driven_controller_tests.rb +2 -0
- data/lib/dev_doc/test/pseudo_i18n_crawler.rb +5 -0
- data/lib/rubocop/cop/dev_doc/i18n/hardcoded_text.rb +243 -0
- data/lib/rubocop/cop/dev_doc/i18n/localizable_props.rb +69 -19
- data/lib/rubocop/cop/dev_doc/i18n/require_translation.rb +13 -17
- data/lib/rubocop/cop/dev_doc/i18n/text_shape.rb +94 -0
- data/lib/rubocop/cop/dev_doc/rails/application_model_base.rb +56 -0
- data/lib/rubocop/cop/dev_doc/rails/avoid_bypassing_validation.rb +81 -26
- data/lib/rubocop/cop/dev_doc/rails/no_errors_add_in_controller.rb +177 -0
- data/lib/rubocop/cop/dev_doc/rails/no_form_param_lookup_in_controller.rb +236 -0
- data/lib/rubocop/cop/dev_doc/style/in_memory_association_find.rb +162 -0
- data/lib/rubocop/cop/dev_doc/style/no_silent_rescue.rb +269 -0
- data/lib/rubocop/cop/dev_doc/style/prefer_allowlist_symbol_param.rb +193 -0
- data/lib/rubocop/cop/dev_doc/style/use_g_log.rb +133 -0
- data/lib/rubocop/cop/dev_doc/test/prefer_find_sole_by.rb +146 -0
- data/lib/rubocop/cop/dev_doc/test/test_name_special_characters.rb +108 -0
- data/lib/rubocop/cop/dev_doc/view/prefer_prop_over_name.rb +11 -1
- data/lib/rubocop/dev_doc/version.rb +1 -1
- metadata +16 -3
- data/lib/rubocop/cop/dev_doc/i18n/report_text.rb +0 -76
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3852833893968d60a5c0c198ffd3a2f34cb524a71998464a27803de2d56b44de
|
|
4
|
+
data.tar.gz: 1b4f675aa6967bca65d6f706997c06c73fe3b954b4092f6f8586e5c17b1e16b8
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3b4be761462f9974fa8caa317e1df9d71ead56160dc4d9d0e7b98407af11a8835f09a888e4b8677448981c6e8e032129312d6e469f7134426714351e594cdc64
|
|
7
|
+
data.tar.gz: 5aca39f093385aae489a8c1a18fcf43eff4995dd7a5d575d237e5a472a8477457789a9cb201ce5ba09abdc6c49fcbf80fbd761467ee2d46447f5ee943111292f
|
data/config/default.yml
CHANGED
|
@@ -199,6 +199,29 @@ DevDoc/Rails/NoCollectionIdsWriterInController:
|
|
|
199
199
|
Include:
|
|
200
200
|
- "app/controllers/**/*.rb"
|
|
201
201
|
|
|
202
|
+
# Route params are resource identity (a bad URL SHOULD 404), but a
|
|
203
|
+
# form-submitted attribute fed to a finder turns an expected form state
|
|
204
|
+
# (nothing picked yet) into RecordNotFound, and drags the validity check
|
|
205
|
+
# into the controller. The remedy is assignment: put the id on the model
|
|
206
|
+
# and let its validations render the failure.
|
|
207
|
+
DevDoc/Rails/NoFormParamLookupInController:
|
|
208
|
+
Description: "A record finder in a controller must not be fed by a form-submitted attribute (`params[:form][:attribute]`, `params.dig(:form, :attribute)`); assign the id to the model and let its validations decide."
|
|
209
|
+
Enabled: true
|
|
210
|
+
Include:
|
|
211
|
+
- "app/controllers/**/*.rb"
|
|
212
|
+
|
|
213
|
+
# The controller is the assignment bridge, not the validity judge: a
|
|
214
|
+
# controller-side `errors.add` is a validation living in the wrong layer,
|
|
215
|
+
# guarded once for one POST while every other write path skips it. The
|
|
216
|
+
# three delivery shapes (rescue, policy guard, verification bang) are
|
|
217
|
+
# auto-exempted — there the check already lives in the right layer and the
|
|
218
|
+
# line only renders its outcome.
|
|
219
|
+
DevDoc/Rails/NoErrorsAddInController:
|
|
220
|
+
Description: "Controllers must not write errors onto a model (`record.errors.add`); the rule belongs in a model validation or form-object PORO. Delivery of an outcome from a rescue, policy, or verification method is auto-exempted."
|
|
221
|
+
Enabled: true
|
|
222
|
+
Include:
|
|
223
|
+
- "app/controllers/**/*.rb"
|
|
224
|
+
|
|
202
225
|
DevDoc/Rails/EnumMustBeSymbolized:
|
|
203
226
|
Description: "Declare enums with `enum_symbolize :foo, { … }` instead of a bare `enum`, so the attribute type is set before the enum and the reader returns a symbol."
|
|
204
227
|
Enabled: true
|
|
@@ -240,6 +263,14 @@ DevDoc/Style/AvoidInsecureSend:
|
|
|
240
263
|
Description: "Avoid insecure dynamic `send`/`public_send` — `send` is always flagged; `public_send` requires a prefix or trusted source (validator/mailer)."
|
|
241
264
|
Enabled: true
|
|
242
265
|
|
|
266
|
+
DevDoc/Style/PreferAllowlistSymbolParam:
|
|
267
|
+
Description: "Flag a hand-rolled `find`/`detect` allow-list lookup against params/request.headers; use `glib_allowlist_symbol_param` instead."
|
|
268
|
+
Enabled: true
|
|
269
|
+
|
|
270
|
+
DevDoc/Style/InMemoryAssociationFind:
|
|
271
|
+
Description: "Flag block-form `find`/`detect` on an association declared in the same file; use `find_by` unless the in-memory view is required, or disable with a reason."
|
|
272
|
+
Enabled: true
|
|
273
|
+
|
|
243
274
|
DevDoc/Style/PreferPublicSend:
|
|
244
275
|
Description: "Prefer `public_send` over `send` — visibility-respecting dispatch surfaces typos/misconfig and documents intent."
|
|
245
276
|
Enabled: true
|
|
@@ -403,6 +434,18 @@ DevDoc/Rails/ApplicationRecordTransaction:
|
|
|
403
434
|
Exclude:
|
|
404
435
|
- "app/models/**/*.rb"
|
|
405
436
|
|
|
437
|
+
DevDoc/Rails/ApplicationModelBase:
|
|
438
|
+
Description: "Inherit the app's ApplicationModel root instead of including ActiveModel::Model directly (three-way rule, backend/03_model.md item 9)."
|
|
439
|
+
# Disabled by default: requires the project to have an ApplicationModel root
|
|
440
|
+
# over glib-web's Glib::Model. Enable per project, scoped to app/models; the
|
|
441
|
+
# root itself and any engine-side base need excluding where they legitimately
|
|
442
|
+
# carry the include.
|
|
443
|
+
Enabled: false
|
|
444
|
+
Include:
|
|
445
|
+
- "app/models/**/*.rb"
|
|
446
|
+
Exclude:
|
|
447
|
+
- "app/models/application_model.rb"
|
|
448
|
+
|
|
406
449
|
DevDoc/Style/AvoidOptionsHash:
|
|
407
450
|
Description: "Use keyword arguments instead of `**options` — typos raise `ArgumentError`; options hashes swallow them silently."
|
|
408
451
|
Enabled: true
|
|
@@ -593,6 +636,29 @@ Style/SafeNavigationChainLength:
|
|
|
593
636
|
Enabled: true
|
|
594
637
|
Max: 1
|
|
595
638
|
|
|
639
|
+
# Early returns over nesting. Core default is already on; listed here because
|
|
640
|
+
# best_practices/backend/en/01a_defensive_programming.md #2 relies on it (the
|
|
641
|
+
# doc dropped its nested-vs-early-return example in favour of this cop and
|
|
642
|
+
# keeps only the guard-SHAPE guidance the cop cannot judge).
|
|
643
|
+
Style/GuardClause:
|
|
644
|
+
Enabled: true
|
|
645
|
+
|
|
646
|
+
# Core default is `MinNameLength: 1`, which never fires. Raised to 3 so a bare
|
|
647
|
+
# `|e|` / `|u|` / `|s|` block parameter is an offense — the reader should not
|
|
648
|
+
# have to infer the type from the receiver (see
|
|
649
|
+
# best_practices/intro/en/01_principle.md, Code Intent). The core AllowedNames
|
|
650
|
+
# for this cop is empty (the `at/by/id/…` list belongs to
|
|
651
|
+
# Naming/MethodParameterName); the one exemption here is `t`, the
|
|
652
|
+
# `create_table do |t|` idiom, which made up half of the hits when this was
|
|
653
|
+
# measured against a consuming app (2026-09-09: 87 offenses, 44 of them `|t|`
|
|
654
|
+
# in db/; the other 43 were real). AllowNamesEndingInNumbers stays at its core
|
|
655
|
+
# default (true), so `emp1` passes; `e1` still fails on length.
|
|
656
|
+
Naming/BlockParameterName:
|
|
657
|
+
Enabled: true
|
|
658
|
+
MinNameLength: 3
|
|
659
|
+
AllowedNames:
|
|
660
|
+
- t
|
|
661
|
+
|
|
596
662
|
# `has_X?` reads more naturally than the cop's preferred `X?` in many cases —
|
|
597
663
|
# `has_active_subscription?` vs `active_subscription?`, `has_assignee?(member)`
|
|
598
664
|
# vs `assignee?(member)`. Disabled cross-project so individual `.rubocop.yml`
|
|
@@ -684,6 +750,40 @@ DevDoc/Test/NoPersistenceInMailerPreviews:
|
|
|
684
750
|
- "spec/mailers/previews/**/*.rb"
|
|
685
751
|
- "lib/mailer_previews/**/*.rb"
|
|
686
752
|
|
|
753
|
+
# A test name containing shell- or regex-significant characters breaks running
|
|
754
|
+
# that single test by name: unquoted `-n name` is mis-parsed by the shell
|
|
755
|
+
# (syntax error, redirect, expansion, substitution), and in the `/name/` regex
|
|
756
|
+
# filter form the regex-significant ones match nothing, so the runner reports
|
|
757
|
+
# 0 runs — which reads as a pass. Every character in the default set has a
|
|
758
|
+
# verified failure in at least one of the two forms (checked against a real
|
|
759
|
+
# minitest single-test run); `? { } / !` are deliberately NOT forbidden — see
|
|
760
|
+
# the cop docstring for their caveats. ForbiddenCharacters must list the same
|
|
761
|
+
# characters, in the same order, as the cop's DEFAULT_FORBIDDEN_CHARACTERS
|
|
762
|
+
# (specs enforce set parity; order keeps runtime messages matching specs).
|
|
763
|
+
DevDoc/Test/TestNameSpecialCharacters:
|
|
764
|
+
Description: "Test names must not contain characters that break single-test runs (shell mis-parse unquoted; `/name/` regex form runs 0 tests)."
|
|
765
|
+
Enabled: true
|
|
766
|
+
ForbiddenCharacters: "()[]*+^$\\&;|<>'\"`"
|
|
767
|
+
Include:
|
|
768
|
+
- "test/**/*.rb"
|
|
769
|
+
- "spec/**/*.rb"
|
|
770
|
+
|
|
771
|
+
# A bare-class `find_by` in a test returns whichever matching row the database
|
|
772
|
+
# yields first. When the attribute is not unique across the table (an email in
|
|
773
|
+
# a tenant-scoped membership table, a slug that repeats per country) the test
|
|
774
|
+
# binds to a different fixture per seed and fails far from the cause — the
|
|
775
|
+
# observed case reproduced only under one seed and read as a flake.
|
|
776
|
+
# `find_sole_by` raises unless exactly one row matches, turning the assumption
|
|
777
|
+
# into an assertion. `find_by!` autocorrects; `find_by` (nil-returning) does
|
|
778
|
+
# not, because a test may assert the nil — rewrite those to `exists?`.
|
|
779
|
+
# Requires Rails 7.0+ (`find_sole_by`); disable on older consumers.
|
|
780
|
+
DevDoc/Test/PreferFindSoleBy:
|
|
781
|
+
Description: "In tests, `Model.find_by`/`find_by!` on a bare class must be `find_sole_by` — an unscoped lookup by a non-unique attribute silently picks a row per run. Primary-key lookups and association-scoped receivers are not flagged."
|
|
782
|
+
Enabled: true
|
|
783
|
+
Include:
|
|
784
|
+
- "test/**/*.rb"
|
|
785
|
+
- "spec/**/*.rb"
|
|
786
|
+
|
|
687
787
|
DevDoc/Test/RequireUnitTestJustification:
|
|
688
788
|
Description: "Every test file must live in a recognized directory; unit-test directories additionally require a justification header (marker phrase: 'deliberate exception')."
|
|
689
789
|
Enabled: true
|
|
@@ -903,6 +1003,159 @@ DevDoc/I18n/AvoidTitleizeHumanize:
|
|
|
903
1003
|
- "app/views/**/*.jbuilder"
|
|
904
1004
|
- "app/views/**/*.rb"
|
|
905
1005
|
|
|
1006
|
+
DevDoc/I18n/HardcodedText:
|
|
1007
|
+
Description: "Warn on any string literal that reads like user-facing copy, in any position — not only glib text props. Use `t(...)`."
|
|
1008
|
+
# A review aid, not a clean lint: it judges strings by shape (prose vs
|
|
1009
|
+
# identifier) and position, so it cannot tell copy a user sees from prose
|
|
1010
|
+
# that never leaves the server. Off by default and `warning` severity; run
|
|
1011
|
+
# it during a localization pass alongside RequireTranslation, which is
|
|
1012
|
+
# precise for glib props but blind to ternary/`||` fallbacks, hashes built in
|
|
1013
|
+
# locals, controller/model/mailer strings and constants.
|
|
1014
|
+
Enabled: false
|
|
1015
|
+
Severity: warning
|
|
1016
|
+
# ExemptKeys: hash keys whose values are never copy (style, routing, model
|
|
1017
|
+
# metadata, i18n plumbing). Every value under them is skipped.
|
|
1018
|
+
ExemptKeys:
|
|
1019
|
+
- styleClass
|
|
1020
|
+
- styleClasses
|
|
1021
|
+
- style
|
|
1022
|
+
- class
|
|
1023
|
+
- id
|
|
1024
|
+
- targetId
|
|
1025
|
+
- name
|
|
1026
|
+
- url
|
|
1027
|
+
- href
|
|
1028
|
+
- src
|
|
1029
|
+
- path
|
|
1030
|
+
- partial
|
|
1031
|
+
- template
|
|
1032
|
+
- layout
|
|
1033
|
+
- controller
|
|
1034
|
+
- action
|
|
1035
|
+
- as
|
|
1036
|
+
- format
|
|
1037
|
+
- content_type
|
|
1038
|
+
- mime_type
|
|
1039
|
+
- accept
|
|
1040
|
+
- class_name
|
|
1041
|
+
- source_type
|
|
1042
|
+
- foreign_key
|
|
1043
|
+
- primary_key
|
|
1044
|
+
- table_name
|
|
1045
|
+
- inverse_of
|
|
1046
|
+
- scope
|
|
1047
|
+
- locale
|
|
1048
|
+
# ExemptMethods: string receivers and direct arguments of these are
|
|
1049
|
+
# patterns, SQL, lookup keys or formats rather than copy.
|
|
1050
|
+
ExemptMethods:
|
|
1051
|
+
- "where"
|
|
1052
|
+
- "rewhere"
|
|
1053
|
+
- "not"
|
|
1054
|
+
- "or"
|
|
1055
|
+
- "having"
|
|
1056
|
+
- "order"
|
|
1057
|
+
- "reorder"
|
|
1058
|
+
- "group"
|
|
1059
|
+
- "select"
|
|
1060
|
+
- "joins"
|
|
1061
|
+
- "left_joins"
|
|
1062
|
+
- "from"
|
|
1063
|
+
- "pluck"
|
|
1064
|
+
- "pick"
|
|
1065
|
+
- "find_by_sql"
|
|
1066
|
+
- "count_by_sql"
|
|
1067
|
+
- "exec_query"
|
|
1068
|
+
- "execute"
|
|
1069
|
+
- "sql"
|
|
1070
|
+
- "sanitize_sql"
|
|
1071
|
+
- "sanitize_sql_array"
|
|
1072
|
+
- "sanitize_sql_for_conditions"
|
|
1073
|
+
- "=="
|
|
1074
|
+
- "!="
|
|
1075
|
+
- "==="
|
|
1076
|
+
- "eql?"
|
|
1077
|
+
- "equal?"
|
|
1078
|
+
- "=~"
|
|
1079
|
+
- "!~"
|
|
1080
|
+
- "include?"
|
|
1081
|
+
- "in?"
|
|
1082
|
+
- "start_with?"
|
|
1083
|
+
- "end_with?"
|
|
1084
|
+
- "match?"
|
|
1085
|
+
- "match"
|
|
1086
|
+
- "casecmp"
|
|
1087
|
+
- "casecmp?"
|
|
1088
|
+
- "gsub"
|
|
1089
|
+
- "gsub!"
|
|
1090
|
+
- "sub"
|
|
1091
|
+
- "sub!"
|
|
1092
|
+
- "tr"
|
|
1093
|
+
- "tr_s"
|
|
1094
|
+
- "delete"
|
|
1095
|
+
- "delete_prefix"
|
|
1096
|
+
- "delete_suffix"
|
|
1097
|
+
- "split"
|
|
1098
|
+
- "squeeze"
|
|
1099
|
+
- "partition"
|
|
1100
|
+
- "rpartition"
|
|
1101
|
+
- "[]"
|
|
1102
|
+
- "[]="
|
|
1103
|
+
- "dig"
|
|
1104
|
+
- "fetch"
|
|
1105
|
+
- "key?"
|
|
1106
|
+
- "has_key?"
|
|
1107
|
+
- "slice"
|
|
1108
|
+
- "except"
|
|
1109
|
+
- "values_at"
|
|
1110
|
+
- "fetch_values"
|
|
1111
|
+
- "send"
|
|
1112
|
+
- "public_send"
|
|
1113
|
+
- "__send__"
|
|
1114
|
+
- "respond_to?"
|
|
1115
|
+
- "const_get"
|
|
1116
|
+
- "const_defined?"
|
|
1117
|
+
- "instance_variable_get"
|
|
1118
|
+
- "instance_variable_set"
|
|
1119
|
+
- "attribute"
|
|
1120
|
+
- "require"
|
|
1121
|
+
- "require_relative"
|
|
1122
|
+
- "load"
|
|
1123
|
+
- "autoload"
|
|
1124
|
+
- "strftime"
|
|
1125
|
+
- "strptime"
|
|
1126
|
+
- "parse"
|
|
1127
|
+
- "header"
|
|
1128
|
+
- "set_header"
|
|
1129
|
+
- "add_header"
|
|
1130
|
+
- "image_url"
|
|
1131
|
+
- "image_path"
|
|
1132
|
+
- "image_tag"
|
|
1133
|
+
- "asset_url"
|
|
1134
|
+
- "asset_path"
|
|
1135
|
+
# DeveloperFacingMethods: receiver-less calls whose whole subtree is
|
|
1136
|
+
# developer-facing (exception and console text). `logger.*` calls are
|
|
1137
|
+
# always skipped.
|
|
1138
|
+
DeveloperFacingMethods:
|
|
1139
|
+
- raise
|
|
1140
|
+
- fail
|
|
1141
|
+
- warn
|
|
1142
|
+
- abort
|
|
1143
|
+
- puts
|
|
1144
|
+
- print
|
|
1145
|
+
- p
|
|
1146
|
+
- pp
|
|
1147
|
+
# DeveloperFacingReceivers: constants whose every call reports to developers
|
|
1148
|
+
# (error trackers), so string arguments to them are never copy.
|
|
1149
|
+
DeveloperFacingReceivers:
|
|
1150
|
+
- Rollbar
|
|
1151
|
+
- Sentry
|
|
1152
|
+
- Honeybadger
|
|
1153
|
+
- Bugsnag
|
|
1154
|
+
- Airbrake
|
|
1155
|
+
Include:
|
|
1156
|
+
- "app/**/*.rb"
|
|
1157
|
+
- "app/**/*.jbuilder"
|
|
1158
|
+
|
|
906
1159
|
DevDoc/View/PreferPropOverName:
|
|
907
1160
|
Description: "Bind form fields to model attributes with `prop:` (i18n-resolved label/placeholder) instead of a raw `name: 'model[attr]'` with hardcoded text."
|
|
908
1161
|
# Disabled by default (new department) — enable per consumer .rubocop.yml.
|
|
@@ -917,10 +1170,17 @@ DevDoc/View/PreferPropOverName:
|
|
|
917
1170
|
# credit-card fields capture transient credentials that must never bind to
|
|
918
1171
|
# a persisted model, and dynamic-group names are array-param structural keys
|
|
919
1172
|
# with no label/placeholder to derive.
|
|
1173
|
+
# fields_file (deprecated field class) posts a raw upload the controller
|
|
1174
|
+
# often parses and discards (CSV imports, server-side processing) — its
|
|
1175
|
+
# prop: machinery calls `.attached?` on the bound model value, so a
|
|
1176
|
+
# conversion of a non-attachment param raises at render and the unsafe
|
|
1177
|
+
# autocorrect would produce exactly that. Attachment-backed uploads belong
|
|
1178
|
+
# on fields_upload, which binds prop: fine.
|
|
920
1179
|
ExemptFieldMethods:
|
|
921
1180
|
- fields_hidden
|
|
922
1181
|
- fields_creditCard
|
|
923
1182
|
- fields_dynamicGroup
|
|
1183
|
+
- fields_file
|
|
924
1184
|
Include:
|
|
925
1185
|
- "app/views/**/*.jbuilder"
|
|
926
1186
|
- "app/views/**/*.rb"
|
|
@@ -949,17 +1209,35 @@ DevDoc/I18n/RequireTranslation:
|
|
|
949
1209
|
- shareButton
|
|
950
1210
|
- fields_text
|
|
951
1211
|
- fields_number
|
|
952
|
-
-
|
|
1212
|
+
- fields_email
|
|
1213
|
+
- fields_url
|
|
953
1214
|
- fields_password
|
|
1215
|
+
- fields_timer
|
|
1216
|
+
- fields_submit
|
|
954
1217
|
- fields_textarea
|
|
1218
|
+
- fields_richText
|
|
1219
|
+
- fields_select
|
|
1220
|
+
- fields_dynamicSelect
|
|
1221
|
+
- fields_dynamicGroup
|
|
955
1222
|
- fields_check
|
|
956
1223
|
- fields_checkGroup
|
|
957
1224
|
- fields_chipGroup
|
|
958
|
-
-
|
|
1225
|
+
- fields_radio
|
|
959
1226
|
- fields_radioGroup
|
|
1227
|
+
- fields_timeZone
|
|
960
1228
|
- fields_date
|
|
961
1229
|
- fields_datetime
|
|
1230
|
+
- fields_file
|
|
962
1231
|
- fields_upload
|
|
1232
|
+
- fields_sign
|
|
1233
|
+
- fields_location
|
|
1234
|
+
- fields_phone
|
|
1235
|
+
- fields_otp
|
|
1236
|
+
- fields_captcha
|
|
1237
|
+
- fields_rating
|
|
1238
|
+
- fields_creditCard
|
|
1239
|
+
- fields_stripeToken
|
|
1240
|
+
- fields_stripeExternalAccount
|
|
963
1241
|
- dialogs_alert
|
|
964
1242
|
- dialogs_notification
|
|
965
1243
|
- snackbars_alert
|
|
@@ -972,6 +1250,7 @@ DevDoc/I18n/RequireTranslation:
|
|
|
972
1250
|
- subsubtitle
|
|
973
1251
|
- label
|
|
974
1252
|
- placeholder
|
|
1253
|
+
- hint
|
|
975
1254
|
- text
|
|
976
1255
|
- message
|
|
977
1256
|
- description
|
|
@@ -1009,62 +1288,35 @@ DevDoc/Rails/NoManualRecordInvalid:
|
|
|
1009
1288
|
Include:
|
|
1010
1289
|
- "app/models/**/*.rb"
|
|
1011
1290
|
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
Enabled: false
|
|
1019
|
-
Severity: info
|
|
1020
|
-
WatchedMethods:
|
|
1021
|
-
- h1
|
|
1022
|
-
- h2
|
|
1023
|
-
- h3
|
|
1024
|
-
- h4
|
|
1025
|
-
- h5
|
|
1026
|
-
- h6
|
|
1027
|
-
- p
|
|
1028
|
-
- label
|
|
1029
|
-
- markdown
|
|
1030
|
-
- html
|
|
1031
|
-
- button
|
|
1032
|
-
- switch
|
|
1033
|
-
- chip
|
|
1034
|
-
- progressCircle
|
|
1035
|
-
- shareButton
|
|
1036
|
-
- fields_text
|
|
1037
|
-
- fields_number
|
|
1038
|
-
- fields_select
|
|
1039
|
-
- fields_password
|
|
1040
|
-
- fields_textarea
|
|
1041
|
-
- fields_check
|
|
1042
|
-
- fields_checkGroup
|
|
1043
|
-
- fields_chipGroup
|
|
1044
|
-
- fields_timeZone
|
|
1045
|
-
- fields_radioGroup
|
|
1046
|
-
- fields_date
|
|
1047
|
-
- fields_datetime
|
|
1048
|
-
- fields_upload
|
|
1049
|
-
- dialogs_alert
|
|
1050
|
-
- dialogs_notification
|
|
1051
|
-
- snackbars_alert
|
|
1052
|
-
- snackbars_select
|
|
1053
|
-
- banners_alert
|
|
1054
|
-
- banners_select
|
|
1055
|
-
LocalizableKeys:
|
|
1056
|
-
- title
|
|
1057
|
-
- subtitle
|
|
1058
|
-
- subsubtitle
|
|
1059
|
-
- label
|
|
1060
|
-
- placeholder
|
|
1061
|
-
- text
|
|
1062
|
-
- message
|
|
1063
|
-
- description
|
|
1064
|
-
- uploadText
|
|
1065
|
-
- leftText
|
|
1066
|
-
- rightText
|
|
1067
|
-
- onLabel
|
|
1291
|
+
# Strict superset of Lint/SuppressedException at its default settings — disable
|
|
1292
|
+
# the stock cop when enabling this one (see the cop docstring). Modifier
|
|
1293
|
+
# rescues stay out of scope: Style/RescueModifier owns them.
|
|
1294
|
+
DevDoc/Style/NoSilentRescue:
|
|
1295
|
+
Description: "A rescue body must re-raise, report the failure (a logger/error-monitor call), or state a justification — never swallow it silently."
|
|
1296
|
+
Enabled: true
|
|
1068
1297
|
Include:
|
|
1069
|
-
- "app
|
|
1070
|
-
- "
|
|
1298
|
+
- "app/**/*.rb"
|
|
1299
|
+
- "lib/**/*.rb"
|
|
1300
|
+
JustificationMarker: "silent-rescue:"
|
|
1301
|
+
ReportingMethods:
|
|
1302
|
+
- "log"
|
|
1303
|
+
- "warn"
|
|
1304
|
+
- "error"
|
|
1305
|
+
- "errors"
|
|
1306
|
+
- "exception"
|
|
1307
|
+
- "fatal"
|
|
1308
|
+
- "critical"
|
|
1309
|
+
- "notify"
|
|
1310
|
+
- "notice"
|
|
1311
|
+
- "report"
|
|
1312
|
+
- "capture"
|
|
1313
|
+
- "track"
|
|
1314
|
+
- "instrument"
|
|
1315
|
+
- "monitor"
|
|
1316
|
+
- "alert"
|
|
1317
|
+
- "breadcrumb"
|
|
1318
|
+
- "handle"
|
|
1319
|
+
|
|
1320
|
+
DevDoc/Style/UseGLog:
|
|
1321
|
+
Description: "Route logging through GLog (glib-web) — flag Rails.logger.<any> and Rollbar's reporting methods (error/warning/info/debug/critical/log) outside the facade; Rollbar.configure and other setup calls are not reporting."
|
|
1322
|
+
Enabled: true
|
data/config/obsoletion.yml
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
# Cop renames across rubocop-dev_doc versions. RuboCop surfaces
|
|
2
|
-
# actionable "has been renamed" errors when a
|
|
3
|
-
# directives use the old name.
|
|
1
|
+
# Cop renames and removals across rubocop-dev_doc versions. RuboCop surfaces
|
|
2
|
+
# these as actionable "has been renamed"/"has been removed" errors when a
|
|
3
|
+
# project's config or inline directives use the old name.
|
|
4
4
|
renamed:
|
|
5
5
|
DevDoc/Migration/AvoidBypassingValidation: DevDoc/Rails/AvoidBypassingValidation
|
|
6
|
+
|
|
7
|
+
removed:
|
|
8
|
+
DevDoc/I18n/ReportText:
|
|
9
|
+
alternatives: DevDoc/I18n/HardcodedText
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Rake tasks wrapping the commands in docs/localization.md, so a project runs
|
|
2
|
+
# `bin/rails dev_doc:i18n:scan` instead of copying long rubocop invocations.
|
|
3
|
+
#
|
|
4
|
+
# Loaded by DevDoc::Railtie (lib/dev_doc/railtie.rb) in projects that bundle
|
|
5
|
+
# the gem with `require: 'dev_doc/railtie'`.
|
|
6
|
+
#
|
|
7
|
+
# Tasks (paths default to `app`; pass several as `[app/views,app/mailers]`):
|
|
8
|
+
#
|
|
9
|
+
# bin/rails dev_doc:i18n:scan[paths] Recipe A — hardcoded text
|
|
10
|
+
# bin/rails dev_doc:i18n:rekey[paths] Recipe B — keys to move
|
|
11
|
+
#
|
|
12
|
+
# Each task accepts OUT=<file> to save the findings instead of printing
|
|
13
|
+
# them (Recipe C hands that file to an AI assistant), and exit with rubocop's
|
|
14
|
+
# status: 0 clean, 1 findings, 2 error.
|
|
15
|
+
require 'rake'
|
|
16
|
+
require 'fileutils'
|
|
17
|
+
|
|
18
|
+
module DevDoc
|
|
19
|
+
module I18n
|
|
20
|
+
# `dev_doc:i18n:*` rake tasks: the localization recipes' commands, runnable
|
|
21
|
+
# from a project that bundles the gem.
|
|
22
|
+
module Tasks
|
|
23
|
+
extend Rake::DSL
|
|
24
|
+
|
|
25
|
+
HARDCODED_COPS = %w[
|
|
26
|
+
DevDoc/I18n/RequireTranslation
|
|
27
|
+
DevDoc/I18n/HardcodedText
|
|
28
|
+
DevDoc/I18n/AvoidTitleizeHumanize
|
|
29
|
+
].freeze
|
|
30
|
+
RUBOCOP_TASKS = {
|
|
31
|
+
scan: [HARDCODED_COPS, 'List hardcoded user-facing text (Recipe A)'],
|
|
32
|
+
rekey: [%w[DevDoc/I18n/TranslationKeyPrefix], 'List lazy keys and keys outside AllowedPrefixes (Recipe B)']
|
|
33
|
+
}.freeze
|
|
34
|
+
DEFAULT_PATHS = %w[app].freeze
|
|
35
|
+
|
|
36
|
+
def self.define
|
|
37
|
+
namespace :dev_doc do
|
|
38
|
+
namespace :i18n do
|
|
39
|
+
RUBOCOP_TASKS.each do |name, (cops, summary)|
|
|
40
|
+
desc "#{summary}; OUT=<file> saves the findings"
|
|
41
|
+
task(name) { |_t, args| run_rubocop(cops, args.to_a) }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def self.rubocop_args(cops, paths, out: nil)
|
|
48
|
+
args = %w[--format clang]
|
|
49
|
+
# --out binds to the --format before it, so it must follow it directly.
|
|
50
|
+
args += ['--out', out] if out
|
|
51
|
+
args + ['--only', cops.join(','), *(paths.empty? ? DEFAULT_PATHS : paths)]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def self.run_rubocop(cops, paths)
|
|
55
|
+
require 'rubocop'
|
|
56
|
+
|
|
57
|
+
out = ENV.fetch('OUT', '')
|
|
58
|
+
out = nil if out.empty?
|
|
59
|
+
FileUtils.mkdir_p(File.dirname(out)) if out
|
|
60
|
+
status = RuboCop::CLI.new.run(rubocop_args(cops, paths, out: out))
|
|
61
|
+
puts "Findings written to #{out}" if out && status != 2
|
|
62
|
+
exit(status) unless status.zero?
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
DevDoc::I18n::Tasks.define
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Registers dev-doc's rake tasks in a Rails app. Projects name this file as the
|
|
2
|
+
# gem's require instead of `require: false`:
|
|
3
|
+
#
|
|
4
|
+
# group :development, :test do
|
|
5
|
+
# gem 'rubocop-dev_doc', require: 'dev_doc/railtie'
|
|
6
|
+
# end
|
|
7
|
+
#
|
|
8
|
+
# Booting the app loads only this Railtie; RuboCop itself is loaded when a task
|
|
9
|
+
# runs, so app boot stays as light as with `require: false`.
|
|
10
|
+
require 'rails/railtie'
|
|
11
|
+
|
|
12
|
+
module DevDoc
|
|
13
|
+
# Loads the `dev_doc:*` rake tasks when Rails loads the app's tasks.
|
|
14
|
+
class Railtie < Rails::Railtie
|
|
15
|
+
rake_tasks do
|
|
16
|
+
require 'dev_doc/i18n/tasks'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|