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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +230 -34
  3. data/Gemfile.lock +254 -0
  4. data/README.md +143 -48
  5. data/lib/veragem/citation.rb +116 -0
  6. data/lib/veragem/generator.rb +105 -56
  7. data/lib/veragem/license.rb +27 -0
  8. data/lib/veragem/name.rb +110 -48
  9. data/lib/veragem/options.rb +116 -30
  10. data/lib/veragem/project.rb +200 -39
  11. data/lib/veragem/questions.rb +163 -0
  12. data/lib/veragem/summary.rb +62 -0
  13. data/lib/veragem/version.rb +2 -1
  14. data/lib/veragem.rb +12 -3
  15. data/plugins.rb +4 -0
  16. data/sig/veragem.rbs +151 -23
  17. data/template/.gitattributes +3 -0
  18. data/template/.githooks/pre-commit +2 -3
  19. data/template/.github/PULL_REQUEST_TEMPLATE.md +2 -1
  20. data/template/.github/dependabot.yml +4 -8
  21. data/template/.github/image-registries.sh +4 -3
  22. data/template/.github/workflows/dependabot-automerge.yml +29 -34
  23. data/template/.github/workflows/dependency-review.yml +19 -15
  24. data/template/.github/workflows/image.yml +65 -14
  25. data/template/.github/workflows/links.yml +35 -0
  26. data/template/.github/workflows/nix.yml +3 -3
  27. data/template/.github/workflows/release.yml +135 -22
  28. data/template/.github/workflows/ruby-ci.yml +31 -9
  29. data/template/.github/workflows/security.yml +15 -9
  30. data/template/.github/workflows/style-check-cocogitto.yml +3 -4
  31. data/template/.github/workflows/style-check-dprint.yml +10 -10
  32. data/template/.gitignore +5 -0
  33. data/template/.mutineer.yml +28 -0
  34. data/template/.rubocop.yml +49 -10
  35. data/template/.simplecov.erb +10 -0
  36. data/template/.yard-lint.yml +386 -0
  37. data/template/.yardopts +2 -0
  38. data/template/AGENTS.md.erb +76 -38
  39. data/template/CITATION.cff.erb +50 -0
  40. data/template/CODE_OF_CONDUCT.md.erb +1 -1
  41. data/template/CONTRIBUTING.md.erb +107 -48
  42. data/template/Gemfile +10 -7
  43. data/template/README.md.erb +12 -12
  44. data/template/Rakefile +167 -31
  45. data/template/Steepfile.erb +1 -1
  46. data/template/bin/setup +2 -0
  47. data/template/cliff.toml +40 -23
  48. data/template/dprint.json +1 -6
  49. data/template/flake.lock +3 -3
  50. data/template/flake.nix +25 -10
  51. data/template/lib/%path%/cli.rb.erb +19 -15
  52. data/template/lib/%path%/version.rb.erb +1 -1
  53. data/template/lib/%path%.rb.erb +3 -1
  54. data/template/sig/%path%.rbs.erb +1 -1
  55. data/template/test/test_%underscored%.rb.erb +4 -3
  56. data/template/test/test_cli.rb.erb +37 -12
  57. data/template/test/test_helper.rb.erb +15 -7
  58. metadata +16 -4
  59. 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
@@ -0,0 +1,2 @@
1
+ --query 'object.visibility == :public'
2
+ lib/**/*.rb
@@ -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. The lint and type policy is the design
7
+ ## 1. Lints and Types
8
8
 
9
- RuboCop runs with its defaults and every new cop as it ships (`NewCops: enable`), its Minitest,
10
- packaging, performance and Rake extensions on, and the project indexed first (`UseProjectIndex`, the
11
- rubydex gem) for the cops that look across files (`.rubocop.yml`). Steep checks `lib/` against the
12
- signatures in `sig/`, its strictest diagnostics on (`Steepfile`): every method of `lib/` is declared
13
- in `sig/`, and a warning fails as an error does. Gemfile.lock pins both, so the verdict is the same
14
- locally and in CI.
15
-
16
- **Never silence a new cop or diagnostic wholesale.** Either fix the site, or configure it in
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
- ## 2. Types: signatures by hand, TypeProf to start them
24
-
25
- `sig/` is written by hand and Steep holds `lib/` to it. `bundle exec rake typeprof` prints the
26
- signatures TypeProf infers from `lib/`: a start for a new method's, never a replacement for
27
- reading them -- it says `untyped` where it cannot tell. A signature is as narrow as the code
28
- allows: `untyped` only where the value truly is any value.
29
-
30
- ## 3. Silence a cop or a diagnostic at the site, with a reason
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
- eval(code) # rubocop:disable Security/Eval -- code is this gem's own, never its input
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
- Name the cop or diagnostic. A reason that restates the rule is not a reason: say what makes the
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
- ## 5. Commits
72
+ ## 3. Commits
50
73
 
51
- [Conventional Commits](https://www.conventionalcommits.org/) are enforced by `cog check` locally
52
- and in CI. The changelog is generated from the commits (`cliff.toml`), so the subject line is
53
- user-facing text; `chore`, `ci` and `style` commits stay out of it, and `!` or a `BREAKING CHANGE`
54
- footer lists a commit first:
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 a trailing newline from the name
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
- ## 6. Before you claim a change is done
68
-
69
- Run `bundle exec rake checks`. It is what CI runs: RuboCop, Steep, the tests with every line,
70
- branch and method covered, bundler-audit, dprint, the commit messages, the shell, the workflows,
71
- and the flake's checks. Reporting "done" on a change that has not passed it is the one thing that
72
- wastes the most time here.
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)