veragem 0.1.0 → 0.2.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/CHANGELOG.md +230 -34
- data/Gemfile.lock +254 -0
- data/README.md +143 -48
- data/lib/veragem/citation.rb +116 -0
- data/lib/veragem/generator.rb +105 -56
- data/lib/veragem/license.rb +27 -0
- data/lib/veragem/name.rb +110 -48
- data/lib/veragem/options.rb +116 -30
- data/lib/veragem/project.rb +200 -39
- data/lib/veragem/questions.rb +163 -0
- data/lib/veragem/summary.rb +62 -0
- data/lib/veragem/version.rb +2 -1
- data/lib/veragem.rb +12 -3
- data/plugins.rb +4 -0
- data/sig/veragem.rbs +151 -23
- data/template/.gitattributes +3 -0
- data/template/.githooks/pre-commit +2 -3
- data/template/.github/PULL_REQUEST_TEMPLATE.md +2 -1
- data/template/.github/dependabot.yml +4 -8
- data/template/.github/image-registries.sh +4 -3
- data/template/.github/workflows/dependabot-automerge.yml +29 -34
- data/template/.github/workflows/dependency-review.yml +19 -15
- data/template/.github/workflows/image.yml +65 -14
- data/template/.github/workflows/links.yml +35 -0
- data/template/.github/workflows/nix.yml +3 -3
- data/template/.github/workflows/release.yml +135 -22
- data/template/.github/workflows/ruby-ci.yml +31 -9
- data/template/.github/workflows/security.yml +15 -9
- data/template/.github/workflows/style-check-cocogitto.yml +3 -4
- data/template/.github/workflows/style-check-dprint.yml +10 -10
- data/template/.gitignore +5 -0
- data/template/.mutineer.yml +28 -0
- data/template/.rubocop.yml +49 -10
- data/template/.simplecov.erb +10 -0
- data/template/.yard-lint.yml +386 -0
- data/template/.yardopts +2 -0
- data/template/AGENTS.md.erb +76 -38
- data/template/CITATION.cff.erb +50 -0
- data/template/CODE_OF_CONDUCT.md.erb +1 -1
- data/template/CONTRIBUTING.md.erb +107 -48
- data/template/Gemfile +10 -7
- data/template/README.md.erb +12 -12
- data/template/Rakefile +167 -31
- data/template/Steepfile.erb +1 -1
- data/template/bin/setup +2 -0
- data/template/cliff.toml +40 -23
- data/template/dprint.json +1 -6
- data/template/flake.lock +3 -3
- data/template/flake.nix +25 -10
- data/template/lib/%path%/cli.rb.erb +19 -15
- data/template/lib/%path%/version.rb.erb +1 -1
- data/template/lib/%path%.rb.erb +3 -1
- data/template/sig/%path%.rbs.erb +1 -1
- data/template/test/test_%underscored%.rb.erb +4 -3
- data/template/test/test_cli.rb.erb +37 -12
- data/template/test/test_helper.rb.erb +15 -7
- metadata +16 -4
- data/template/.github/workflows/rubocop-autocorrect.yml +0 -114
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
# yard-lint's strict preset (https://github.com/mensfeld/yard-lint): each enabled validator an
|
|
2
|
+
# error, coverage at 100%.
|
|
3
|
+
|
|
4
|
+
AllValidators:
|
|
5
|
+
# YARD command-line options (applied to all validators by default). The public API alone is
|
|
6
|
+
# documented: .yardopts's query, which yard-lint's coverage reads too.
|
|
7
|
+
YardOptions: []
|
|
8
|
+
|
|
9
|
+
Exclude:
|
|
10
|
+
- '\.git'
|
|
11
|
+
- 'vendor/**/*'
|
|
12
|
+
- 'node_modules/**/*'
|
|
13
|
+
- 'spec/**/*'
|
|
14
|
+
- 'test/**/*'
|
|
15
|
+
|
|
16
|
+
# error, warning, convention or never
|
|
17
|
+
FailOnSeverity: error
|
|
18
|
+
|
|
19
|
+
# percent (0-100); a lower coverage fails
|
|
20
|
+
MinCoverage: 100.0
|
|
21
|
+
|
|
22
|
+
DiffMode:
|
|
23
|
+
# --diff's base ref; ~ detects main or master
|
|
24
|
+
DefaultBaseRef: ~
|
|
25
|
+
|
|
26
|
+
Documentation/UndocumentedObjects:
|
|
27
|
+
Description: 'Checks for classes, modules, and methods without documentation.'
|
|
28
|
+
Enabled: true
|
|
29
|
+
Severity: error
|
|
30
|
+
ExcludedMethods:
|
|
31
|
+
- 'initialize/0'
|
|
32
|
+
- '/^_/' # private by convention
|
|
33
|
+
# unset: ExcludedObjects, any object's full name (a constant's too): exact, name/arity or /regex/
|
|
34
|
+
# ('MyApp::Api#call/1'); AllowedParentClasses (StandardError: its subclasses skipped)
|
|
35
|
+
|
|
36
|
+
Documentation/UndocumentedMethodArguments:
|
|
37
|
+
Description: 'Checks for method parameters without @param tags.'
|
|
38
|
+
Enabled: true
|
|
39
|
+
Severity: error
|
|
40
|
+
# each parameter matched to its @param by name: a misnamed @param caught
|
|
41
|
+
CheckParameterNames: true
|
|
42
|
+
# true skips a method with no documentation at all: Documentation/UndocumentedObjects reports it
|
|
43
|
+
SkipFullyUndocumented: false
|
|
44
|
+
# unset: AllowedParentClasses; AllowedMethods, skipped (exact name, name/arity or /regex/)
|
|
45
|
+
|
|
46
|
+
Documentation/UndocumentedBooleanMethods:
|
|
47
|
+
Description: 'Checks that question mark methods document their boolean return.'
|
|
48
|
+
Enabled: true
|
|
49
|
+
Severity: error
|
|
50
|
+
# unset: AllowedParentClasses
|
|
51
|
+
|
|
52
|
+
Documentation/UndocumentedOptions:
|
|
53
|
+
Description: 'Detects methods with options hash parameters but no @option tags.'
|
|
54
|
+
Enabled: true
|
|
55
|
+
Severity: error
|
|
56
|
+
# unset: AllowedParentClasses
|
|
57
|
+
|
|
58
|
+
Documentation/MissingReturn:
|
|
59
|
+
Description: 'Requires @return tags on all methods (opt-in for strict documentation).'
|
|
60
|
+
Enabled: true
|
|
61
|
+
Severity: error
|
|
62
|
+
ExcludedMethods:
|
|
63
|
+
- 'initialize'
|
|
64
|
+
# - '/^_/' # private by convention, once uncommented
|
|
65
|
+
# unset: AllowedParentClasses
|
|
66
|
+
|
|
67
|
+
Documentation/OrphanedDocComment:
|
|
68
|
+
Description: 'Detects YARD comment blocks with tags not attached to any documentable construct.'
|
|
69
|
+
Enabled: true
|
|
70
|
+
Severity: error
|
|
71
|
+
|
|
72
|
+
Documentation/MarkdownSyntax:
|
|
73
|
+
Description: 'Detects common markdown syntax errors in documentation.'
|
|
74
|
+
Enabled: true
|
|
75
|
+
Severity: error
|
|
76
|
+
|
|
77
|
+
Documentation/EmptyCommentLine:
|
|
78
|
+
Description: 'Detects empty comment lines at the start or end of documentation blocks.'
|
|
79
|
+
Enabled: true
|
|
80
|
+
Severity: error
|
|
81
|
+
EnabledPatterns:
|
|
82
|
+
Leading: true
|
|
83
|
+
Trailing: true
|
|
84
|
+
|
|
85
|
+
Documentation/BlankLineBeforeDefinition:
|
|
86
|
+
Description: 'Detects blank lines between YARD documentation and method definition.'
|
|
87
|
+
Enabled: true
|
|
88
|
+
Severity: error
|
|
89
|
+
OrphanedSeverity: error
|
|
90
|
+
EnabledPatterns:
|
|
91
|
+
SingleBlankLine: true
|
|
92
|
+
OrphanedDocs: true
|
|
93
|
+
# unset: IgnoredCommentPatterns, comment lines (/regex/ or a literal at word boundaries) taken for
|
|
94
|
+
# no documentation, so no detached docstring above a blank line: commented-out code, FIXME notes
|
|
95
|
+
|
|
96
|
+
Documentation/LineLength:
|
|
97
|
+
Description: 'Detects documentation comment lines that exceed the configured maximum length.'
|
|
98
|
+
Enabled: false
|
|
99
|
+
Severity: error
|
|
100
|
+
MaxLength: 120
|
|
101
|
+
|
|
102
|
+
Documentation/UnderfilledLines:
|
|
103
|
+
Description: 'Detects documentation prose that wraps before using the available line width.'
|
|
104
|
+
Enabled: false # heuristic; convention even in strict
|
|
105
|
+
Severity: convention
|
|
106
|
+
MaxLength: 120
|
|
107
|
+
MinTrailingSpace: 20
|
|
108
|
+
MinParagraphLines: 2
|
|
109
|
+
SentenceEndChars: ['.', '?', '!', ':', ';']
|
|
110
|
+
SkipNonAscii: true
|
|
111
|
+
|
|
112
|
+
Documentation/TextSubstitution:
|
|
113
|
+
Description: 'Detects forbidden characters or strings in documentation and suggests replacements.'
|
|
114
|
+
Enabled: true
|
|
115
|
+
Severity: error
|
|
116
|
+
Substitutions:
|
|
117
|
+
"—": "-" # em-dash (U+2014)
|
|
118
|
+
"–": "-" # en-dash (U+2013)
|
|
119
|
+
|
|
120
|
+
Documentation/DuplicateNamespaceComment:
|
|
121
|
+
Description: 'Detects namespaces (modules and classes) documented in more than one file.'
|
|
122
|
+
Enabled: true
|
|
123
|
+
Severity: error
|
|
124
|
+
|
|
125
|
+
Documentation/ReferenceTypo:
|
|
126
|
+
Description: 'Detects probable typos in method and constant references.'
|
|
127
|
+
Enabled: true
|
|
128
|
+
Severity: error
|
|
129
|
+
|
|
130
|
+
Tags/Order:
|
|
131
|
+
Description: 'Enforces consistent ordering of YARD tags.'
|
|
132
|
+
Enabled: true
|
|
133
|
+
Severity: error
|
|
134
|
+
EnforcedOrder:
|
|
135
|
+
- param
|
|
136
|
+
- option
|
|
137
|
+
- yield
|
|
138
|
+
- yieldparam
|
|
139
|
+
- yieldreturn
|
|
140
|
+
- return
|
|
141
|
+
- raise
|
|
142
|
+
- see
|
|
143
|
+
- example
|
|
144
|
+
- note
|
|
145
|
+
- todo
|
|
146
|
+
|
|
147
|
+
Tags/InvalidTypes:
|
|
148
|
+
Description: 'Validates type definitions in @param, @return, @option tags.'
|
|
149
|
+
Enabled: true
|
|
150
|
+
Severity: error
|
|
151
|
+
YardOptions: [] # the public API alone, as the others: it reads every visibility otherwise
|
|
152
|
+
ValidatedTags:
|
|
153
|
+
- param
|
|
154
|
+
- option
|
|
155
|
+
- return
|
|
156
|
+
- yieldreturn
|
|
157
|
+
- yieldparam
|
|
158
|
+
- raise
|
|
159
|
+
# flags a CamelCase type neither a loaded constant nor defined in the code: a typo, or a
|
|
160
|
+
# dependency's type, which ExtraTypes admits
|
|
161
|
+
StrictConstantNames: true
|
|
162
|
+
|
|
163
|
+
Tags/TypeSyntax:
|
|
164
|
+
Description: 'Validates YARD type syntax using YARD parser.'
|
|
165
|
+
Enabled: true
|
|
166
|
+
Severity: error
|
|
167
|
+
ValidatedTags:
|
|
168
|
+
- param
|
|
169
|
+
- option
|
|
170
|
+
- return
|
|
171
|
+
- yieldreturn
|
|
172
|
+
- yieldparam
|
|
173
|
+
- raise
|
|
174
|
+
|
|
175
|
+
Tags/MeaninglessTag:
|
|
176
|
+
Description: 'Detects @param/@option tags on classes, modules, or constants.'
|
|
177
|
+
Enabled: true
|
|
178
|
+
Severity: error
|
|
179
|
+
CheckedTags:
|
|
180
|
+
- param
|
|
181
|
+
- option
|
|
182
|
+
InvalidObjectTypes:
|
|
183
|
+
- class
|
|
184
|
+
- module
|
|
185
|
+
- constant
|
|
186
|
+
|
|
187
|
+
Tags/MissingYield:
|
|
188
|
+
Description: 'Detects methods that yield to a block without a @yield, @yieldparam, or @yieldreturn tag.'
|
|
189
|
+
Enabled: true
|
|
190
|
+
Severity: error
|
|
191
|
+
YardOptions: [] # the public API alone, as the others: it reads every visibility otherwise
|
|
192
|
+
|
|
193
|
+
Tags/CollectionType:
|
|
194
|
+
Description: 'Validates Hash collection syntax consistency.'
|
|
195
|
+
Enabled: true
|
|
196
|
+
Severity: error
|
|
197
|
+
EnforcedStyle: long # 'long' for Hash{K => V} (YARD standard), 'short' for {K => V}
|
|
198
|
+
ValidatedTags:
|
|
199
|
+
- param
|
|
200
|
+
- option
|
|
201
|
+
- return
|
|
202
|
+
- yieldreturn
|
|
203
|
+
- yieldparam
|
|
204
|
+
- raise
|
|
205
|
+
|
|
206
|
+
Tags/TagTypePosition:
|
|
207
|
+
Description: 'Validates type annotation position in tags.'
|
|
208
|
+
Enabled: true
|
|
209
|
+
Severity: error
|
|
210
|
+
CheckedTags:
|
|
211
|
+
- param
|
|
212
|
+
- option
|
|
213
|
+
# type_after_name, @param name [Type] (YARD's), or type_first, @param [Type] name
|
|
214
|
+
EnforcedStyle: type_after_name
|
|
215
|
+
|
|
216
|
+
Tags/ApiTags:
|
|
217
|
+
Description: 'Enforces @api tags on public objects.'
|
|
218
|
+
Enabled: false
|
|
219
|
+
Severity: error
|
|
220
|
+
AllowedApis:
|
|
221
|
+
- public
|
|
222
|
+
- private
|
|
223
|
+
- internal
|
|
224
|
+
|
|
225
|
+
Tags/OptionTags:
|
|
226
|
+
Description: 'Requires @option tags for methods with options parameters.'
|
|
227
|
+
Enabled: true
|
|
228
|
+
Severity: error
|
|
229
|
+
YardOptions: [] # the public API alone, as the others: it reads every visibility otherwise
|
|
230
|
+
|
|
231
|
+
Tags/ExampleSyntax:
|
|
232
|
+
Description: 'Validates Ruby syntax in @example tags.'
|
|
233
|
+
Enabled: true
|
|
234
|
+
Severity: error
|
|
235
|
+
# true skips @example console transcripts (irb or pry, `=>` output, `$` prompts): off, so no real
|
|
236
|
+
# syntax error hides
|
|
237
|
+
SkipNonRuby: false
|
|
238
|
+
|
|
239
|
+
Tags/ExampleStyle:
|
|
240
|
+
Description: 'Validates code style in @example tags using RuboCop/StandardRB.'
|
|
241
|
+
Enabled: false # requires RuboCop or StandardRB
|
|
242
|
+
Severity: convention
|
|
243
|
+
# unset: Linter (auto, rubocop, standard or none); SkipPatterns, examples skipped ('/skip-lint/i')
|
|
244
|
+
|
|
245
|
+
Tags/RedundantParamDescription:
|
|
246
|
+
Description: 'Detects meaningless parameter descriptions that add no value.'
|
|
247
|
+
Enabled: true
|
|
248
|
+
Severity: error
|
|
249
|
+
CheckedTags:
|
|
250
|
+
- param
|
|
251
|
+
- option
|
|
252
|
+
Articles:
|
|
253
|
+
- The
|
|
254
|
+
- the
|
|
255
|
+
- A
|
|
256
|
+
- a
|
|
257
|
+
- An
|
|
258
|
+
- an
|
|
259
|
+
MaxRedundantWords: 6
|
|
260
|
+
GenericTerms:
|
|
261
|
+
- object
|
|
262
|
+
- instance
|
|
263
|
+
- value
|
|
264
|
+
- data
|
|
265
|
+
- item
|
|
266
|
+
- element
|
|
267
|
+
EnabledPatterns:
|
|
268
|
+
ArticleParam: true
|
|
269
|
+
PossessiveParam: true
|
|
270
|
+
TypeRestatement: true
|
|
271
|
+
ParamToVerb: true
|
|
272
|
+
IdPattern: true
|
|
273
|
+
DirectionalDate: true
|
|
274
|
+
TypeGeneric: true
|
|
275
|
+
ArticleParamPhrase: true
|
|
276
|
+
|
|
277
|
+
Tags/InformalNotation:
|
|
278
|
+
Description: 'Detects informal tag notation patterns like "Note:" instead of @note.'
|
|
279
|
+
Enabled: true
|
|
280
|
+
Severity: error
|
|
281
|
+
CaseSensitive: false
|
|
282
|
+
RequireStartOfLine: true
|
|
283
|
+
# true skips indented Markdown code blocks too, not only fenced ones: off, as list continuations
|
|
284
|
+
# and wrapped prose are indented too
|
|
285
|
+
SkipIndentedCodeBlocks: false
|
|
286
|
+
Patterns:
|
|
287
|
+
Note: '@note'
|
|
288
|
+
IMPORTANT: '@note'
|
|
289
|
+
Important: '@note'
|
|
290
|
+
Todo: '@todo'
|
|
291
|
+
TODO: '@todo'
|
|
292
|
+
FIXME: '@todo'
|
|
293
|
+
See: '@see'
|
|
294
|
+
See also: '@see'
|
|
295
|
+
Warning: '@note'
|
|
296
|
+
Deprecated: '@deprecated'
|
|
297
|
+
Author: '@author'
|
|
298
|
+
Version: '@version'
|
|
299
|
+
Since: '@since'
|
|
300
|
+
Returns: '@return'
|
|
301
|
+
Raises: '@raise'
|
|
302
|
+
Example: '@example'
|
|
303
|
+
|
|
304
|
+
Tags/NonAsciiType:
|
|
305
|
+
Description: 'Detects non-ASCII characters in type annotations.'
|
|
306
|
+
Enabled: true
|
|
307
|
+
Severity: error
|
|
308
|
+
ValidatedTags:
|
|
309
|
+
- param
|
|
310
|
+
- option
|
|
311
|
+
- return
|
|
312
|
+
- yieldreturn
|
|
313
|
+
- yieldparam
|
|
314
|
+
- raise
|
|
315
|
+
|
|
316
|
+
Tags/TagGroupSeparator:
|
|
317
|
+
Description: 'Enforces blank line separators between different YARD tag groups.'
|
|
318
|
+
Enabled: false
|
|
319
|
+
Severity: error
|
|
320
|
+
TagGroups:
|
|
321
|
+
param: [param, option]
|
|
322
|
+
return: [return]
|
|
323
|
+
error: [raise, throws]
|
|
324
|
+
example: [example]
|
|
325
|
+
meta: [see, note, todo, deprecated, since, version, api]
|
|
326
|
+
yield: [yield, yieldparam, yieldreturn]
|
|
327
|
+
RequireAfterDescription: false
|
|
328
|
+
|
|
329
|
+
Tags/TagSeparator:
|
|
330
|
+
Description: 'Enforces a blank line between every consecutive YARD tag.'
|
|
331
|
+
Enabled: false
|
|
332
|
+
Severity: error
|
|
333
|
+
Exempt: []
|
|
334
|
+
RequireAfterDescription: false
|
|
335
|
+
|
|
336
|
+
Tags/ForbiddenTags:
|
|
337
|
+
Description: 'Detects forbidden tag and type combinations.'
|
|
338
|
+
Enabled: false
|
|
339
|
+
Severity: error
|
|
340
|
+
ForbiddenPatterns: []
|
|
341
|
+
# e.g. {Tag: return, Types: [void]}; a Tag without Types forbids the tag outright
|
|
342
|
+
|
|
343
|
+
Tags/OverloadConsistency:
|
|
344
|
+
Description: 'Checks the tags of each @overload against its own signature.'
|
|
345
|
+
Enabled: true
|
|
346
|
+
Severity: error
|
|
347
|
+
|
|
348
|
+
Warnings/SyntaxError:
|
|
349
|
+
Description: 'Detects Ruby files YARD cannot parse (syntax errors).'
|
|
350
|
+
Enabled: true
|
|
351
|
+
Severity: error
|
|
352
|
+
|
|
353
|
+
Warnings/UnknownTag:
|
|
354
|
+
Description: 'Detects unknown YARD tags.'
|
|
355
|
+
Enabled: true
|
|
356
|
+
Severity: error
|
|
357
|
+
|
|
358
|
+
Warnings/UnknownDirective:
|
|
359
|
+
Description: 'Detects unknown YARD directives.'
|
|
360
|
+
Enabled: true
|
|
361
|
+
Severity: error
|
|
362
|
+
|
|
363
|
+
Warnings/InvalidTagFormat:
|
|
364
|
+
Description: 'Detects malformed tag syntax.'
|
|
365
|
+
Enabled: true
|
|
366
|
+
Severity: error
|
|
367
|
+
|
|
368
|
+
Warnings/InvalidDirectiveFormat:
|
|
369
|
+
Description: 'Detects malformed directive syntax.'
|
|
370
|
+
Enabled: true
|
|
371
|
+
Severity: error
|
|
372
|
+
|
|
373
|
+
Warnings/DuplicatedParameterName:
|
|
374
|
+
Description: 'Detects duplicate @param tags.'
|
|
375
|
+
Enabled: true
|
|
376
|
+
Severity: error
|
|
377
|
+
|
|
378
|
+
Warnings/UnknownParameterName:
|
|
379
|
+
Description: 'Detects @param tags for non-existent parameters.'
|
|
380
|
+
Enabled: true
|
|
381
|
+
Severity: error
|
|
382
|
+
|
|
383
|
+
Semantic/AbstractMethods:
|
|
384
|
+
Description: 'Ensures @abstract methods do not have real implementations.'
|
|
385
|
+
Enabled: true
|
|
386
|
+
Severity: error
|
data/template/.yardopts
ADDED
data/template/AGENTS.md.erb
CHANGED
|
@@ -4,58 +4,83 @@ Repository rules for `<%= name %>`. These apply to every contributor, human or A
|
|
|
4
4
|
Adding a dependency or a tool, the tests' rules and the release are
|
|
5
5
|
[CONTRIBUTING.md](CONTRIBUTING.md)'s.
|
|
6
6
|
|
|
7
|
-
## 1.
|
|
7
|
+
## 1. Lints and Types
|
|
8
8
|
|
|
9
|
-
RuboCop runs with its defaults and every new cop as it ships
|
|
10
|
-
packaging, performance and Rake extensions on, and the project
|
|
11
|
-
rubydex gem) for the cops that look across files
|
|
12
|
-
signatures in `sig/`, its
|
|
13
|
-
in `sig/`,
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
`.rubocop.yml` (or the Steepfile) with a comment saying why it is wrong for this codebase.
|
|
9
|
+
RuboCop runs with its defaults, a few cops beyond them, and every new cop as it ships
|
|
10
|
+
(`NewCops: enable`), its Minitest, packaging, performance and Rake extensions on, and the project
|
|
11
|
+
indexed first (`UseProjectIndex`, the rubydex gem) for the cops that look across files
|
|
12
|
+
(`.rubocop.yml`). Steep checks `lib/` against the signatures in `sig/`, its `strict` diagnostics on
|
|
13
|
+
(`Steepfile`): every method of `lib/` is declared in `sig/`, a warning fails as an error does, and
|
|
14
|
+
so does a call on an untyped receiver (`rake steep:typed`, from `steep stats`). Gemfile.lock pins
|
|
15
|
+
both, so the verdict is the same locally and in CI. YARD documents `lib/`, and yard-lint holds it
|
|
16
|
+
(`.yard-lint.yml`).
|
|
18
17
|
|
|
19
18
|
The shell is held as the code is: shfmt formats it (`.editorconfig` holds its style) and it passes
|
|
20
19
|
ShellCheck. The Nix is nixfmt's. The workflows pass actionlint and, with Dependabot's
|
|
21
20
|
configuration, zizmor's security audit.
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
### 1.1. RuboCop
|
|
23
|
+
|
|
24
|
+
- Before finishing, check the files you changed since your branch left main with
|
|
25
|
+
`bundle exec rake rubocop:changed` (every file where there is no origin/main yet).
|
|
26
|
+
- Fix offenses with `bundle exec rubocop -a FILES`. Don't use `-A` unless asked.
|
|
27
|
+
- If an offense is unclear, run `bundle exec rubocop --explain Department/CopName`.
|
|
28
|
+
- Don't edit `.rubocop.yml` to make offenses go away.
|
|
29
|
+
- When an offense has to stay, disable the cop on that line, or the next (`# rubocop:disable-next`
|
|
30
|
+
on the line above), and say why:
|
|
31
|
+
`# rubocop:disable Department/CopName -- the reason`.
|
|
32
|
+
|
|
33
|
+
### 1.2. YARD
|
|
34
|
+
|
|
35
|
+
- Every public object of `lib/` is documented (yard-lint, at 100% coverage; `.yardopts` keeps the
|
|
36
|
+
public API): what it is for, then its tags -- each `@param`, `@yield`, `@return` and `@raise`, in
|
|
37
|
+
that order (Tags/Order) -- their types the signatures' in YARD's syntax (`Array<String>`,
|
|
38
|
+
`Hash{Symbol => String}`, `String, nil`). A private one takes a comment only as §2 has it, and no
|
|
39
|
+
tags: its signature holds its types.
|
|
40
|
+
- `bundle exec rake yard_lint` lints it (`yard-lint lib --stats`); `bundle exec rake yard` writes
|
|
41
|
+
it to `doc/`.
|
|
42
|
+
- `bundle exec yard list --query '@return && @param'` lists the objects a query of the tags
|
|
43
|
+
matches.
|
|
44
|
+
- `bundle exec rake graph` prints the classes and modules as a Graphviz graph
|
|
45
|
+
(`yard graph --protected --private --full --dependencies`): `| dot -Tsvg -o graph.svg`.
|
|
46
|
+
|
|
47
|
+
### 1.3. Types: signatures by hand, TypeProf to start them
|
|
48
|
+
|
|
49
|
+
`sig/` is written by hand and Steep holds `lib/` to it, so every method's types are there, a private
|
|
50
|
+
one's too (it has no YARD tags): look a method's up in `sig/<%= path %>.rbs`.
|
|
51
|
+
`bundle exec rake typeprof` prints the signatures TypeProf infers from `lib/`: a start for a new
|
|
52
|
+
method's, never a replacement for reading them -- it says `untyped` where it cannot tell. A
|
|
53
|
+
signature is as narrow as the code allows: `untyped` only where the value truly is any value, and a
|
|
54
|
+
call on one fails `rake steep:typed` until `when String` or an assertion (`value #: String`) narrows
|
|
55
|
+
it (`value.is_a?(String)` is itself such a call). A library Steep has no signatures of is an error
|
|
56
|
+
to it: name one that ships them in the Steepfile (`library "json"`), take a gem's from
|
|
57
|
+
gem_rbs_collection (CONTRIBUTING.md), and declare in `sig/` what `lib/` calls of one with none. When
|
|
58
|
+
a diagnostic has to stay, ignore it on its line, the reason on the line above (text after the
|
|
59
|
+
diagnostic's name voids the ignore; an ignore leaves an untyped call untyped):
|
|
31
60
|
|
|
32
61
|
```ruby
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
# the library declares no signature -- above: text after Steep's diagnostic name voids the ignore
|
|
62
|
+
# the library's signature lacks the method
|
|
36
63
|
value = client.fetch # steep:ignore NoMethod
|
|
37
64
|
```
|
|
38
65
|
|
|
39
|
-
|
|
40
|
-
site safe. RuboCop reports a disable that no longer applies (`Lint/RedundantCopDisableDirective`),
|
|
41
|
-
so a justification cannot outlive the code it justified.
|
|
42
|
-
|
|
43
|
-
## 4. Comments: only what is essential
|
|
66
|
+
## 2. Comments: only what is essential
|
|
44
67
|
|
|
45
68
|
A comment says what the code cannot: why it is so, the source it follows, the constraint it keeps.
|
|
46
69
|
Make it concise and precise -- a line where a line does -- and never restate the code: that is
|
|
47
70
|
noise, and it goes stale. A change that falsifies a comment rewrites it.
|
|
48
71
|
|
|
49
|
-
##
|
|
72
|
+
## 3. Commits
|
|
50
73
|
|
|
51
|
-
[Conventional Commits](https://www.conventionalcommits.org/) are enforced by `cog check` locally
|
|
52
|
-
|
|
53
|
-
user-facing text
|
|
54
|
-
|
|
74
|
+
[Conventional Commits](https://www.conventionalcommits.org/) are enforced by `cog check` locally and
|
|
75
|
+
in CI. The changelog is generated from the commits (`cliff.toml`) and shows each one's subject
|
|
76
|
+
alone, so a subject is user-facing text, and a commit holds only the change its subject names:
|
|
77
|
+
anything else gets its own commit. The changelog lists every commit cog checks but the release's
|
|
78
|
+
own, `chore` and `ci` as Miscellaneous Tasks, and `!` or a `BREAKING CHANGE` footer lists a commit
|
|
79
|
+
first:
|
|
55
80
|
|
|
56
81
|
```
|
|
57
82
|
feat: accept the name as a symbol too
|
|
58
|
-
fix: strip
|
|
83
|
+
fix: strip Unicode whitespace from the name too
|
|
59
84
|
docs: explain the greeting's fallback
|
|
60
85
|
build(deps): depend on json
|
|
61
86
|
```
|
|
@@ -64,12 +89,25 @@ The git hooks (`bundle exec rake hooks`) check the same before a commit and a pu
|
|
|
64
89
|
them with `--no-verify`. `git revert` writes `Revert "..."`, which CI refuses: reword it as
|
|
65
90
|
`revert: ...`.
|
|
66
91
|
|
|
67
|
-
##
|
|
68
|
-
|
|
69
|
-
Run `bundle exec rake checks`. It
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
92
|
+
## 4. Before you claim a change is done
|
|
93
|
+
|
|
94
|
+
Run `bundle exec rake checks`. It runs CI's gates: RuboCop, Steep, the tests with every line, branch
|
|
95
|
+
and method covered and no warning of their own, yard-lint, bundler-audit, dprint, the commit
|
|
96
|
+
messages, the shell, the workflows, the links (CI's, monthly), the mutations of the changed lines
|
|
97
|
+
(CI's, of every line), and the flake's checks. It stops at the first that fails: run the rest by
|
|
98
|
+
name (`bundle exec rake mutation:changed nix`). Reporting "done" on a change that has not passed it
|
|
99
|
+
is the one thing that wastes the most time here.
|
|
100
|
+
|
|
101
|
+
A fix comes with a test that fails without it: run it before the fix, then after. The gates hold
|
|
102
|
+
what the tests run, so they pass code nothing needs, which a change deletes rather than hides:
|
|
103
|
+
|
|
104
|
+
- a signature with no method behind it (Steep accepts one), a `require` nothing needs, a constant
|
|
105
|
+
nothing reads;
|
|
106
|
+
- an option no test sets: its default alone runs;
|
|
107
|
+
- code kept from coverage (`# simplecov:disable`, a `.simplecov` skip): mutineer scores no mutant no
|
|
108
|
+
test runs, so it passes both. `.simplecov` skips only what loads before coverage starts
|
|
109
|
+
(`version.rb`), and `.mutineer.yml` ignores only a mutant that keeps the behaviour, with its
|
|
110
|
+
reason.
|
|
73
111
|
|
|
74
112
|
If a check fails for reasons unrelated to your change, say so explicitly rather than working
|
|
75
113
|
around it -- a broken check that everyone routes around stops protecting anything.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# The citation GitHub's "Cite this repository" and Zenodo read (Citation File Format 1.2.0);
|
|
2
|
+
# `rake bump` sets version and date-released at each release.
|
|
3
|
+
cff-version: 1.2.0
|
|
4
|
+
message: "If you use this software, please cite it using the metadata from this file."
|
|
5
|
+
title: <%= yaml(name) %>
|
|
6
|
+
abstract: <%= yaml(summary) %>
|
|
7
|
+
authors:
|
|
8
|
+
- family-names: <%= yaml(family_names) %>
|
|
9
|
+
<%- if given_names -%>
|
|
10
|
+
given-names: <%= yaml(given_names) %>
|
|
11
|
+
<%- end -%>
|
|
12
|
+
<%- if alias_name -%>
|
|
13
|
+
alias: <%= yaml(alias_name) %>
|
|
14
|
+
<%- end -%>
|
|
15
|
+
<%- if orcid -%>
|
|
16
|
+
orcid: "<%= orcid %>"
|
|
17
|
+
<%- end -%>
|
|
18
|
+
<%- if keywords -%>
|
|
19
|
+
keywords:
|
|
20
|
+
<%- keywords.each do |keyword| -%>
|
|
21
|
+
- <%= yaml(keyword) %>
|
|
22
|
+
<%- end -%>
|
|
23
|
+
<%- end -%>
|
|
24
|
+
version: "0.1.0"
|
|
25
|
+
date-released: "<%= today %>"
|
|
26
|
+
<%- if licenses.one? -%>
|
|
27
|
+
license: <%= licenses.first %>
|
|
28
|
+
<%- else -%>
|
|
29
|
+
# MIT OR Apache-2.0, as CFF writes an OR; Zenodo's import refuses a list, so it archives no release
|
|
30
|
+
# until zenodo/zenodo-rdm#1509 is fixed
|
|
31
|
+
license:
|
|
32
|
+
<%- licenses.each do |spdx| -%>
|
|
33
|
+
- <%= spdx %>
|
|
34
|
+
<%- end -%>
|
|
35
|
+
<%- end -%>
|
|
36
|
+
repository-code: "https://github.com/<%= github %>/<%= name %>"
|
|
37
|
+
repository-artifact: "https://rubygems.org/gems/<%= name %>"
|
|
38
|
+
# the API documentation rubydoc.info serves for each gem on RubyGems: there from the first release
|
|
39
|
+
url: "https://rubydoc.info/gems/<%= name %>"
|
|
40
|
+
# Zenodo's DOIs, to uncomment once it has archived a release: the concept DOI, every version's
|
|
41
|
+
# (Zenodo's "Cite all versions"), and a version's own -- minted after its release is tagged, so the
|
|
42
|
+
# file can hold an earlier version's alone
|
|
43
|
+
# doi: "10.5281/zenodo.0000000"
|
|
44
|
+
# identifiers:
|
|
45
|
+
# - type: doi
|
|
46
|
+
# value: "10.5281/zenodo.0000000"
|
|
47
|
+
# description: "The concept DOI, of every version"
|
|
48
|
+
# - type: doi
|
|
49
|
+
# value: "10.5281/zenodo.0000001"
|
|
50
|
+
# description: "The DOI of version 0.1.0"
|
|
@@ -10,7 +10,7 @@ This repository is for technical development.
|
|
|
10
10
|
removed.
|
|
11
11
|
|
|
12
12
|
<%- if email -%>
|
|
13
|
-
Report conduct concerns to the maintainers at <%= email %>.
|
|
13
|
+
Report conduct concerns to the maintainers at <%= markdown(email) %>.
|
|
14
14
|
<%- else -%>
|
|
15
15
|
Report conduct concerns to the maintainers, or through GitHub's
|
|
16
16
|
[report content](https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam)
|