rubocop-dev_doc 0.6.0.beta1 → 0.7.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dfa7b6778294801c95bb37bb3c15a2c4b30f81e9b915ba3ee548475c4adc9cd4
4
- data.tar.gz: 6606b6c2b6745b2c54f63a89a7b3ae1b4ce3bfb60dda96a471dc51e33232e802
3
+ metadata.gz: 2d7cebd4d2c1b85850d5a704dc26319f49526040c26d2573824f68461d42ae8c
4
+ data.tar.gz: 5fede674c17c29dd330e9499a1367c3f1174902b0a76c44d94c7f6683a35d130
5
5
  SHA512:
6
- metadata.gz: adc4743bfba263e139f6ca4cc5abbc213c427a46081e0aa5bc12be84ae96cc26f5b37eb218707449ca4566e5fca6958534f9581104c0d92c97f83e2ef17003b2
7
- data.tar.gz: f8aa2b1f19d0f1a628f86ae58b19ed71ba6c5f508fd3247203909f459fb22deeef7777fc5de17509af04a0e4618aebd95c1b19a6fdf78fe53c72f97db063e261
6
+ metadata.gz: 7b3666259413a6d37a6d13765c095005fd8395f1033a6d33de9539616b75d0e3d5091b26ab27ade88069ecd9c678231bd3126f116eb60a36db4e1220c50fefde
7
+ data.tar.gz: 2fcbae3b394369ab9e969a0edc7f1b7ba2379b4572f73e3311228fe265ab29285ebe34a7635d43f7bf02c9ab8e56921454b94817323c723a473fc37e20999726
data/config/default.yml CHANGED
@@ -66,6 +66,20 @@ DevDoc/Migration/AvoidNonNull:
66
66
  - "db/migrate/*.rb"
67
67
  - "db/migrate/**/*.rb"
68
68
 
69
+ DevDoc/Migration/AvoidBooleanColumn:
70
+ Description: "Avoid `boolean` columns; prefer a timestamp, enum, or model method that better models the data."
71
+ Enabled: true
72
+ Include:
73
+ - "db/migrate/*.rb"
74
+ - "db/migrate/**/*.rb"
75
+
76
+ DevDoc/Migration/BooleanColumnNotNull:
77
+ Description: "Boolean columns must carry `null: false` — NULL is outside {true, false}."
78
+ Enabled: true
79
+ Include:
80
+ - "db/migrate/*.rb"
81
+ - "db/migrate/**/*.rb"
82
+
69
83
  # Intentionally global (no Include) — these patterns are risky in any file, not only migrations.
70
84
  # Add project-specific Exclude entries (e.g. db/seeds.rb, lib/tasks/**/*.rb) in your .rubocop.yml
71
85
  # for places where bulk operations are intentional and performance-critical.
@@ -0,0 +1,135 @@
1
+ module RuboCop
2
+ module Cop
3
+ module DevDoc
4
+ module Migration
5
+ # Avoid `boolean` columns; prefer an alternative that better models
6
+ # the data.
7
+ #
8
+ # ## Rationale
9
+ # A boolean column collapses a domain into exactly two states, but
10
+ # most "is X?" questions are richer than that in practice. The
11
+ # constraint pushes developers past the path-of-least-resistance
12
+ # `add_column :boolean` toward a shape that captures what the data
13
+ # actually means.
14
+ #
15
+ # The question to ask before reaching for `t.boolean` is:
16
+ # "what does NULL mean here?" — and if the answer is "unset" or
17
+ # "not yet decided", that semantic should be explicit in the
18
+ # schema, not silently smuggled in as a third boolean state.
19
+ #
20
+ # Consider the alternatives in order:
21
+ #
22
+ # ### 1. Timestamp — when the flag implies a moment in time
23
+ # If the boolean answers "did X happen?", a timestamp gives both
24
+ # the answer (`approved_at.present?`) AND the moment it happened
25
+ # (`approved_at`), for free. A boolean gives only the first.
26
+ #
27
+ # ❌ `approved` loses the moment of approval
28
+ # add_column :submissions, :approved, :boolean
29
+ #
30
+ # ✔️ `approved_at` answers both "is it approved?" and "when?"
31
+ # add_column :submissions, :approved_at, :datetime
32
+ #
33
+ # This pattern dominates the codebase (`published_at`, `deleted_at`,
34
+ # `archived_at`, `completed_at`, etc.) for good reason.
35
+ #
36
+ # ### 2. Enum — when "unset" is a meaningful state, or a third
37
+ # value is plausible
38
+ # An enum with an explicit "no_X_needed" value models "unset"
39
+ # honestly. NULL is outside an enum's domain (a type violation),
40
+ # so the column can carry `null: false` without controversy — see
41
+ # `DevDoc/Rails/EnumColumnNotNull`.
42
+ #
43
+ # ❌ nullable boolean; nil is a silent third state
44
+ # add_column :checklists, :approval_required, :boolean
45
+ #
46
+ # ✔️ enum; "unset" is explicit, null: false is justified
47
+ # # rubocop:disable DevDoc/Migration/AvoidNonNull -- enum
48
+ # add_column :checklists, :approval_requirement, :integer, null: false
49
+ # # rubocop:enable DevDoc/Migration/AvoidNonNull
50
+ #
51
+ # class Checklist < ApplicationRecord
52
+ # enum :approval_requirement, { no_approval_needed: 0, approval_by_admins: 1 }
53
+ # end
54
+ #
55
+ # ### 3. Model method — when the flag is derived from other data
56
+ # If the answer can be computed from existing columns or
57
+ # associations, do not store it. A method keeps the source of
58
+ # truth singular.
59
+ #
60
+ # ❌ denormalises role into a column
61
+ # add_column :users, :is_admin, :boolean
62
+ #
63
+ # ✔️ derived from `role`
64
+ # class User < ApplicationRecord
65
+ # def admin?
66
+ # role == "admin"
67
+ # end
68
+ # end
69
+ #
70
+ # ### 4. Boolean — only when none of the above apply
71
+ # A genuine binary preference with no meaningful third state
72
+ # (e.g. `auto_renew`, `communication_allowed`). Inline-disable
73
+ # this cop with a brief `-- boolean` reason. The column MUST also
74
+ # carry `null: false` — enforced by the sibling cop
75
+ # `DevDoc/Migration/BooleanColumnNotNull`.
76
+ #
77
+ # ✔️ true binary preference, justified
78
+ # # rubocop:disable DevDoc/Migration/AvoidBooleanColumn -- true binary preference; user opt-in
79
+ # add_column :service_subscriptions, :auto_renew, :boolean, null: false
80
+ # # rubocop:enable DevDoc/Migration/AvoidBooleanColumn
81
+ #
82
+ # NOTE: This cop catches `t.boolean`, `add_column ..., :boolean`,
83
+ # and `change_column ..., :boolean` (a type change to boolean).
84
+ # `change_column_type` migrations to a non-boolean type are not
85
+ # flagged — that is the cleanup direction.
86
+ #
87
+ # NOTE: This cop is deliberately NOT timestamp-aware. It cannot
88
+ # tell whether a `:datetime` column would have been a better fit;
89
+ # that judgment is the developer's at review time. The role of
90
+ # this cop is to force the moment of judgment, not to make it.
91
+ #
92
+ # @example
93
+ # # bad
94
+ # add_column :users, :is_admin, :boolean
95
+ #
96
+ # # bad
97
+ # t.boolean :approved
98
+ #
99
+ # # good (timestamp alternative)
100
+ # add_column :submissions, :approved_at, :datetime
101
+ #
102
+ # # good (enum alternative)
103
+ # add_column :checklists, :approval_requirement, :integer
104
+ #
105
+ # # good (justified boolean)
106
+ # # rubocop:disable DevDoc/Migration/AvoidBooleanColumn -- true binary preference
107
+ # add_column :service_subscriptions, :auto_renew, :boolean, null: false
108
+ # # rubocop:enable DevDoc/Migration/AvoidBooleanColumn
109
+ class AvoidBooleanColumn < Base
110
+ MSG = 'Avoid `boolean` columns; consider a timestamp (approved_at), enum, or model method. ' \
111
+ 'If a boolean is genuinely the right shape, disable this cop with a brief `-- boolean` reason ' \
112
+ 'and ensure the column carries `null: false` (see DevDoc/Migration/BooleanColumnNotNull).'.freeze
113
+
114
+ def_node_matcher :boolean_column?, <<~PATTERN
115
+ (send _ {:boolean} ...)
116
+ PATTERN
117
+
118
+ def_node_matcher :add_column_boolean?, <<~PATTERN
119
+ (send _ :add_column _ _ (sym :boolean) ...)
120
+ PATTERN
121
+
122
+ def_node_matcher :change_column_to_boolean?, <<~PATTERN
123
+ (send _ :change_column _ _ (sym :boolean) ...)
124
+ PATTERN
125
+
126
+ def on_send(node)
127
+ return unless boolean_column?(node) || add_column_boolean?(node) || change_column_to_boolean?(node)
128
+
129
+ add_offense(node)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -26,6 +26,12 @@ module RuboCop
26
26
  # ❌ Regular column
27
27
  # add_column :users, :profile_completion_rate, :float, null: false
28
28
  #
29
+ # ❌ Tightening an existing column to NOT NULL
30
+ # change_column_null :users, :name, false
31
+ #
32
+ # ❌ Same tightening, via change_column
33
+ # change_column :users, :name, :string, null: false
34
+ #
29
35
  # ✔️ Regular column
30
36
  # add_column :users, :profile_completion_rate, :float
31
37
  #
@@ -47,6 +53,12 @@ module RuboCop
47
53
  # integer, so THIS cop cannot detect it and WILL flag it. Disable it on
48
54
  # the line with a brief reason — `-- enum` — so the migration is
49
55
  # self-documenting: a reader sees at a glance that the column is an enum.
56
+ # - **Boolean columns justified via `DevDoc/Migration/AvoidBooleanColumn`**
57
+ # — once the developer has justified a boolean through that cop's
58
+ # escape hatch, NULL is outside {true, false} (just as it is outside an
59
+ # enum's domain), so `null: false` is required and enforced by the
60
+ # sibling cop `DevDoc/Migration/BooleanColumnNotNull`. Disable this cop
61
+ # on the line with `-- boolean` so the migration is self-documenting.
50
62
  #
51
63
  # ✔️ Required foreign key (never flagged)
52
64
  # t.belongs_to :user, null: false, foreign_key: true
@@ -56,20 +68,41 @@ module RuboCop
56
68
  # add_column :orders, :status, :integer, null: false
57
69
  # # rubocop:enable DevDoc/Migration/AvoidNonNull
58
70
  #
71
+ # ✔️ Boolean (flagged here — disable with a brief `-- boolean` reason)
72
+ # # rubocop:disable DevDoc/Migration/AvoidNonNull -- boolean
73
+ # # rubocop:disable DevDoc/Migration/AvoidBooleanColumn -- true binary preference
74
+ # add_column :things, :flag, :boolean, null: false
75
+ # # rubocop:enable DevDoc/Migration/AvoidBooleanColumn
76
+ # # rubocop:enable DevDoc/Migration/AvoidNonNull
77
+ #
59
78
  # NOTE: This cop is deliberately NOT enum-aware. It could read the
60
79
  # model's `enum` declarations and skip those columns, but requiring an
61
80
  # explicit per-line disable is intentional: it forces the developer to
62
81
  # signal that the column is an enum, which documents the migration. A
63
82
  # silent skip would hide that intent.
64
83
  #
65
- # NOTE: This cop only flags `null: false`. It does not flag `null: true`
66
- # (redundant but harmless), and it does not require foreign keys to carry
67
- # `null: false` adding it to an FK is encouraged but not enforced here.
84
+ # NOTE: This cop also flags NOT NULL set on an existing column, by either
85
+ # API: `change_column_null(table, column, false)` and
86
+ # `change_column(table, column, type, null: false)`. Both express the same
87
+ # constraint as `null: false` on a definition (the add-nullable -> backfill
88
+ # -> tighten step), so a legit enum/boolean tightening disables this cop
89
+ # inline with `-- enum`/`-- boolean`, exactly as for a new column.
90
+ #
91
+ # NOTE: This cop only flags `null: false` (and the equivalent `false` arg
92
+ # of `change_column_null`). It does not flag `null: true` (redundant but
93
+ # harmless), and it does not require foreign keys to carry `null: false`
94
+ # — adding it to an FK is encouraged but not enforced here.
68
95
  #
69
96
  # @example
70
97
  # # bad
71
98
  # add_column :users, :name, :string, null: false
72
99
  #
100
+ # # bad (tightening an existing column to NOT NULL)
101
+ # change_column_null :users, :name, false
102
+ #
103
+ # # bad (same tightening, via change_column)
104
+ # change_column :users, :name, :string, null: false
105
+ #
73
106
  # # bad (enum without a disable — the cop flags it; disable with `-- enum`)
74
107
  # t.integer :processing_status, null: false
75
108
  #
@@ -91,28 +124,56 @@ module RuboCop
91
124
  json jsonb bigint
92
125
  ].freeze
93
126
 
94
- RESTRICT_ON_SEND = (COLUMN_METHODS + %i[add_column]).freeze
127
+ RESTRICT_ON_SEND = (COLUMN_METHODS + %i[add_column change_column change_column_null]).freeze
95
128
 
96
129
  def_node_matcher :null_false_pair, <<~PATTERN
97
130
  (hash <$(pair (sym :null) (false)) ...>)
98
131
  PATTERN
99
132
 
133
+ # Matches `change_column_null :table, :column, false` (and the optional
134
+ # trailing-default 4-arg form). The `false` arg IS the NOT NULL directive
135
+ # — the same constraint as `null: false` on a definition, just applied to
136
+ # an existing column via the standard add-nullable -> backfill -> tighten
137
+ # step. Flagged so the cop cannot be sidestepped by choice of API: a
138
+ # regular column tightened to NOT NULL is held to the same standard as one
139
+ # declared NOT NULL up front. A legit enum/boolean tightening resolves at
140
+ # the disable site, exactly as for a new column.
141
+ def_node_matcher :change_column_null_false, <<~PATTERN
142
+ (send _ :change_column_null _ _ $false ...)
143
+ PATTERN
144
+
100
145
  def on_send(node)
146
+ flag = offense_node(node)
147
+ add_offense(flag) if flag
148
+ end
149
+
150
+ private
151
+
152
+ # The node whose NOT NULL directive offends: the `false` arg of
153
+ # `change_column_null`, or the `null: false` pair on a regular column
154
+ # definition. nil when there is nothing to flag.
155
+ def offense_node(node)
156
+ change_column_null_false(node) || column_null_false_pair(node)
157
+ end
158
+
159
+ def column_null_false_pair(node)
101
160
  return unless column_method?(node)
102
161
 
103
162
  options = node.arguments.find(&:hash_type?)
104
163
  return unless options
105
164
 
106
- pair = null_false_pair(options)
107
- return unless pair
108
-
109
- add_offense(pair)
165
+ null_false_pair(options)
110
166
  end
111
167
 
112
- private
113
-
168
+ # Methods that define or change a regular column and carry an options
169
+ # hash where `null:` may appear: the `t.<type>` helpers plus
170
+ # `add_column`/`change_column`. (`change_column_null` is handled
171
+ # separately — its NOT NULL directive is a positional `false`, not an
172
+ # options pair.)
114
173
  def column_method?(node)
115
- node.method?(:add_column) || COLUMN_METHODS.include?(node.method_name)
174
+ node.method?(:add_column) ||
175
+ node.method?(:change_column) ||
176
+ COLUMN_METHODS.include?(node.method_name)
116
177
  end
117
178
  end
118
179
  end
@@ -0,0 +1,122 @@
1
+ module RuboCop
2
+ module Cop
3
+ module DevDoc
4
+ module Migration
5
+ # Boolean columns must carry `null: false`.
6
+ #
7
+ # ## Rationale
8
+ # `null: false` is reserved for cases where NULL has no meaningful
9
+ # interpretation — and a justified boolean is one of those cases.
10
+ # NULL is outside the column's stated domain of {true, false}: it
11
+ # is neither value, and every read site has to silently coerce it
12
+ # (`nil || false == false`) or risk a footgun.
13
+ #
14
+ # The line is drawn here for standardization and non-subjectivity.
15
+ # Whether a *regular* column should be present is a business
16
+ # decision open to debate (see `DevDoc/Migration/AvoidNonNull`),
17
+ # but once the developer has justified a boolean via
18
+ # `DevDoc/Migration/AvoidBooleanColumn`'s escape hatch, the
19
+ # boolean's non-null-ness is objective — it does not depend on
20
+ # any further business decision — so it is enforced mechanically
21
+ # rather than argued column-by-column.
22
+ #
23
+ # This cop is the inverse of `DevDoc/Migration/AvoidNonNull` for
24
+ # the boolean case: that cop flags `null: false` on regular
25
+ # columns (including booleans, which it cannot distinguish from
26
+ # other types); this cop REQUIRES `null: false` on booleans. The
27
+ # contradiction is resolved at the disable site: when the
28
+ # developer disables `AvoidNonNull` on a boolean with `-- boolean`
29
+ # (alongside the `AvoidBooleanColumn` disable), this cop fires if
30
+ # `null: false` is missing.
31
+ #
32
+ # ## Adding `null: false` to a table with existing rows
33
+ # Postgres refuses to add a NOT NULL column to a non-empty table
34
+ # without a backfill. Use the model-validations backfill pattern
35
+ # (sanctioned by `DevDoc/Migration/AvoidColumnDefault`):
36
+ #
37
+ # def change
38
+ # add_column :table, :flag, :boolean
39
+ #
40
+ # reversible do |dir|
41
+ # dir.up do
42
+ # Table.reset_column_information
43
+ # Table.where(flag: nil).find_each do |t|
44
+ # t.flag = false
45
+ # t.save!
46
+ # end
47
+ # end
48
+ # end
49
+ #
50
+ # # rubocop:disable DevDoc/Migration/AvoidNonNull -- boolean
51
+ # change_column_null :table, :flag, false
52
+ # # rubocop:enable DevDoc/Migration/AvoidNonNull
53
+ # end
54
+ #
55
+ # The application layer is the source of truth for the default
56
+ # value on new records (e.g. via `after_initialize` or a factory).
57
+ # `default:` in the migration is still disallowed by
58
+ # `DevDoc/Migration/AvoidColumnDefault`.
59
+ #
60
+ # ## Interaction with AvoidBooleanColumn
61
+ # These two cops fire together on every boolean addition:
62
+ #
63
+ # - `AvoidBooleanColumn`: "reconsider using a boolean at all"
64
+ # - `BooleanColumnNotNull`: "if you do, it must be NOT NULL"
65
+ #
66
+ # Satisfy both by either changing the column type (timestamp /
67
+ # enum / model method) or, for a justified boolean, disabling
68
+ # `AvoidBooleanColumn` with `-- boolean` AND ensuring `null: false`
69
+ # is present so this cop does not fire.
70
+ #
71
+ # NOTE: This cop catches `t.boolean`, `add_column ..., :boolean`, and
72
+ # `change_column ..., :boolean` (a type change to boolean) without
73
+ # `null: false`. It does NOT scan `db/schema.rb` for legacy debt — it
74
+ # only enforces the invariant on declarations it can see. Existing
75
+ # nullable booleans are surfaced by inspection, not by this cop.
76
+ #
77
+ # @example
78
+ # # bad - nullable boolean
79
+ # add_column :users, :active, :boolean
80
+ #
81
+ # # bad - nullable boolean in a create_table block
82
+ # create_table :things do |t|
83
+ # t.boolean :flag
84
+ # end
85
+ #
86
+ # # good - boolean carries null: false
87
+ # # rubocop:disable DevDoc/Migration/AvoidBooleanColumn -- true binary preference
88
+ # add_column :things, :flag, :boolean, null: false
89
+ # # rubocop:enable DevDoc/Migration/AvoidBooleanColumn
90
+ class BooleanColumnNotNull < Base
91
+ MSG = 'Boolean columns must carry `null: false` — NULL is outside {true, false}. ' \
92
+ 'Backfill existing rows via the model, then `change_column_null`.'.freeze
93
+
94
+ def_node_matcher :boolean_column?, <<~PATTERN
95
+ (send _ {:boolean} ...)
96
+ PATTERN
97
+
98
+ def_node_matcher :add_column_boolean?, <<~PATTERN
99
+ (send _ :add_column _ _ (sym :boolean) ...)
100
+ PATTERN
101
+
102
+ def_node_matcher :change_column_to_boolean?, <<~PATTERN
103
+ (send _ :change_column _ _ (sym :boolean) ...)
104
+ PATTERN
105
+
106
+ def_node_matcher :null_false_pair, <<~PATTERN
107
+ (hash <$(pair (sym :null) (false)) ...>)
108
+ PATTERN
109
+
110
+ def on_send(node)
111
+ return unless boolean_column?(node) || add_column_boolean?(node) || change_column_to_boolean?(node)
112
+
113
+ options = node.arguments.find(&:hash_type?)
114
+ return if options && null_false_pair(options)
115
+
116
+ add_offense(node)
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
@@ -1,5 +1,5 @@
1
1
  module RuboCop
2
2
  module DevDoc
3
- VERSION = "0.6.0.beta1".freeze
3
+ VERSION = "0.7.0".freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,13 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-dev_doc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0.beta1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dev-doc contributors
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
- date: 1980-01-02 00:00:00.000000000 Z
11
+ date: 2026-07-03 00:00:00.000000000 Z
11
12
  dependencies:
12
13
  - !ruby/object:Gem::Dependency
13
14
  name: activesupport
@@ -71,14 +72,16 @@ dependencies:
71
72
  requirements:
72
73
  - - ">="
73
74
  - !ruby/object:Gem::Version
74
- version: '2.0'
75
+ version: '2.29'
75
76
  type: :runtime
76
77
  prerelease: false
77
78
  version_requirements: !ruby/object:Gem::Requirement
78
79
  requirements:
79
80
  - - ">="
80
81
  - !ruby/object:Gem::Version
81
- version: '2.0'
82
+ version: '2.29'
83
+ description:
84
+ email:
82
85
  executables: []
83
86
  extensions: []
84
87
  extra_rdoc_files: []
@@ -97,12 +100,14 @@ files:
97
100
  - lib/rubocop/cop/dev_doc/i18n/require_translation.rb
98
101
  - lib/rubocop/cop/dev_doc/i18n/translation_key_prefix.rb
99
102
  - lib/rubocop/cop/dev_doc/migration/amount_column_in_cents.rb
103
+ - lib/rubocop/cop/dev_doc/migration/avoid_boolean_column.rb
100
104
  - lib/rubocop/cop/dev_doc/migration/avoid_bypassing_validation.rb
101
105
  - lib/rubocop/cop/dev_doc/migration/avoid_column_default.rb
102
106
  - lib/rubocop/cop/dev_doc/migration/avoid_conditional_schema_changes.rb
103
107
  - lib/rubocop/cop/dev_doc/migration/avoid_json_column.rb
104
108
  - lib/rubocop/cop/dev_doc/migration/avoid_non_null.rb
105
109
  - lib/rubocop/cop/dev_doc/migration/avoid_vague_column_names.rb
110
+ - lib/rubocop/cop/dev_doc/migration/boolean_column_not_null.rb
106
111
  - lib/rubocop/cop/dev_doc/migration/date_column_naming.rb
107
112
  - lib/rubocop/cop/dev_doc/migration/no_create_join_table.rb
108
113
  - lib/rubocop/cop/dev_doc/migration/prefer_belongs_to.rb
@@ -139,10 +144,12 @@ files:
139
144
  - lib/rubocop/dev_doc.rb
140
145
  - lib/rubocop/dev_doc/plugin.rb
141
146
  - lib/rubocop/dev_doc/version.rb
147
+ homepage:
142
148
  licenses: []
143
149
  metadata:
144
150
  default_lint_roller_plugin: RuboCop::DevDoc::Plugin
145
151
  rubygems_mfa_required: 'true'
152
+ post_install_message:
146
153
  rdoc_options: []
147
154
  require_paths:
148
155
  - lib
@@ -157,7 +164,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
164
  - !ruby/object:Gem::Version
158
165
  version: '0'
159
166
  requirements: []
160
- rubygems_version: 4.0.6
167
+ rubygems_version: 3.4.6
168
+ signing_key:
161
169
  specification_version: 4
162
170
  summary: RuboCop cops enforcing dev-doc best practices
163
171
  test_files: []