semverve 0.3.0 → 0.4.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/Gemfile.lock +1 -1
- data/README.md +147 -27
- data/UPGRADING.md +78 -0
- data/lib/semverve/adapters.rb +292 -0
- data/lib/semverve/configuration.rb +52 -27
- data/lib/semverve/finding.rb +55 -0
- data/lib/semverve/fix_result.rb +39 -0
- data/lib/semverve/{version_metadata.rb → package_metadata.rb} +36 -116
- data/lib/semverve/presets.rb +4 -100
- data/lib/semverve/project_metadata.rb +8 -5
- data/lib/semverve/rails_config_metadata.rb +176 -0
- data/lib/semverve/railtie.rb +1 -1
- data/lib/semverve/task.rb +94 -150
- data/lib/semverve/version.rb +1 -1
- data/lib/semverve/version_checks.rb +518 -0
- data/lib/semverve/version_code_references.rb +32 -94
- data/lib/semverve/version_literal_rewriter.rb +78 -0
- data/lib/semverve/version_match_policy.rb +62 -0
- data/lib/semverve/version_references.rb +22 -87
- data/lib/semverve.rb +4 -0
- metadata +10 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9d9765e973d77ca7011cb819202246f5ea7ef2faef574c66a58fc6ad5c058988
|
|
4
|
+
data.tar.gz: dea8769f32c6f6b70c81d05e2d46129cd9820a8289fbd032f42303dfc0b8dea3
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 38b4aca2a29cfc750a7b6b7164219595ec35f76c9c5d526f441e469868686a6588170ee0e88c02942b97b59725d1c72c79b1496cad5880264042d99c8049846a
|
|
7
|
+
data.tar.gz: 7cf79a5a6d90a0f454ce03272e5592b140fff266893fee323b6e831ab28956104e7865bb5a141614e6cae6466a4bacbbd738850f299fd98d7f1024f391d61b7c
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
|
@@ -34,6 +34,8 @@ and RDoc.
|
|
|
34
34
|
You can view the documentation
|
|
35
35
|
[here](https://evanthegrayt.github.io/semverve/).
|
|
36
36
|
|
|
37
|
+
If you are upgrading across breaking changes, see [UPGRADING.md](UPGRADING.md).
|
|
38
|
+
|
|
37
39
|
## Installation
|
|
38
40
|
Add the gem to your Gemfile:
|
|
39
41
|
|
|
@@ -62,8 +64,10 @@ rake semverve:check:references
|
|
|
62
64
|
rake semverve:fix:references
|
|
63
65
|
rake semverve:check:code
|
|
64
66
|
rake semverve:fix:code
|
|
65
|
-
rake semverve:check:
|
|
66
|
-
rake semverve:fix:
|
|
67
|
+
rake semverve:check:package_metadata
|
|
68
|
+
rake semverve:fix:package_metadata
|
|
69
|
+
rake semverve:check:rails_config_metadata
|
|
70
|
+
rake semverve:fix:rails_config_metadata
|
|
67
71
|
rake semverve:check:rubygems
|
|
68
72
|
rake semverve:check:release
|
|
69
73
|
```
|
|
@@ -90,7 +94,7 @@ Semverve.configure do |config|
|
|
|
90
94
|
config.bundle_lock = true
|
|
91
95
|
config.version_file = "lib/my_gem/version.rb"
|
|
92
96
|
config.module_name = "MyGem"
|
|
93
|
-
config.version_checks = [:doc_references, :code_references, :
|
|
97
|
+
config.version_checks = [:doc_references, :code_references, :package_metadata]
|
|
94
98
|
config.release_checks = [:rubygems]
|
|
95
99
|
config.rubygems_host = "https://rubygems.org"
|
|
96
100
|
config.version_code_reference_files.append("lib/**/*.rb")
|
|
@@ -103,10 +107,11 @@ The core defaults are equivalent to:
|
|
|
103
107
|
|
|
104
108
|
```ruby
|
|
105
109
|
Semverve.configure do |config|
|
|
110
|
+
config.adapter = nil
|
|
106
111
|
config.format = :module
|
|
107
112
|
config.bundle_lock = false
|
|
108
113
|
config.root = Dir.pwd
|
|
109
|
-
config.version_checks = [:doc_references, :code_references, :
|
|
114
|
+
config.version_checks = [:doc_references, :code_references, :package_metadata]
|
|
110
115
|
config.release_checks = []
|
|
111
116
|
config.rubygems_host = "https://rubygems.org"
|
|
112
117
|
config.version_match_mode = :older
|
|
@@ -124,7 +129,8 @@ end
|
|
|
124
129
|
|
|
125
130
|
The empty `version_code_reference_files` default only applies to arbitrary code
|
|
126
131
|
literal scanning. `rake semverve:check` still checks the resolved `.gemspec`
|
|
127
|
-
version and matching `Gemfile.lock` entry through its default metadata
|
|
132
|
+
version and matching `Gemfile.lock` entry through its default package metadata
|
|
133
|
+
check.
|
|
128
134
|
Release checks are empty by default because they may make network requests and
|
|
129
135
|
are intended for release pipelines rather than every local or pull-request run.
|
|
130
136
|
|
|
@@ -169,6 +175,11 @@ Semverve::Task.new do |config|
|
|
|
169
175
|
end
|
|
170
176
|
```
|
|
171
177
|
|
|
178
|
+
## Framework adapters
|
|
179
|
+
Framework adapters provide app-oriented defaults without requiring a gemspec or
|
|
180
|
+
package identity. `config.adapter` is the preferred API; `config.preset` remains
|
|
181
|
+
supported as a backward-compatible alias.
|
|
182
|
+
|
|
172
183
|
## Rails apps
|
|
173
184
|
Rails applications do not need gem-style version files, but an application
|
|
174
185
|
version can still be useful for release notes, support/debug screens,
|
|
@@ -176,17 +187,21 @@ deployment metadata, or API output.
|
|
|
176
187
|
|
|
177
188
|
When Rails is loaded, Semverve's Railtie installs the same `semverve:*` Rake
|
|
178
189
|
tasks for `bin/rails`/`rails` automatically. To use Rails-style defaults, set
|
|
179
|
-
the Rails
|
|
190
|
+
the Rails adapter:
|
|
180
191
|
|
|
181
192
|
```ruby
|
|
182
193
|
Semverve.configure do |config|
|
|
183
|
-
config.
|
|
194
|
+
config.adapter = :rails
|
|
184
195
|
end
|
|
185
196
|
```
|
|
186
197
|
|
|
187
|
-
|
|
198
|
+
`config.preset = :rails` is still accepted for existing setups.
|
|
199
|
+
|
|
200
|
+
The Rails adapter uses `Rails.root`, stores the version in
|
|
188
201
|
`config/version.rb`, uses the `:simple` format, and infers the module name from
|
|
189
|
-
your Rails application module when possible.
|
|
202
|
+
your Rails application module when possible. Its default checks are app-oriented:
|
|
203
|
+
documentation references, configured code literals, and optional Rails config
|
|
204
|
+
metadata. It does not run package metadata checks unless you opt in.
|
|
190
205
|
|
|
191
206
|
Generate the file with:
|
|
192
207
|
|
|
@@ -198,14 +213,49 @@ If your app keeps the version somewhere else, override the path:
|
|
|
198
213
|
|
|
199
214
|
```ruby
|
|
200
215
|
Semverve.configure do |config|
|
|
201
|
-
config.
|
|
216
|
+
config.adapter = :rails
|
|
202
217
|
config.version_file = "config/releases/version.rb"
|
|
203
218
|
end
|
|
204
219
|
```
|
|
205
220
|
|
|
206
|
-
Rails support is only
|
|
221
|
+
Rails support is only an adapter and a Railtie; Semverve does not require a dummy
|
|
207
222
|
app, a Rails plugin layout, or a Rails dependency.
|
|
208
223
|
|
|
224
|
+
Rails config metadata is optional. When present, Semverve checks safe literals
|
|
225
|
+
in `config/application.rb`, `config/environments/*.rb`, and
|
|
226
|
+
`config/initializers/**/*.rb`:
|
|
227
|
+
|
|
228
|
+
```ruby
|
|
229
|
+
config.x.version = "1.2.2"
|
|
230
|
+
Rails.application.config.x.version = "1.2.2"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Dynamic assignments are treated as self-managed and left alone:
|
|
234
|
+
|
|
235
|
+
```ruby
|
|
236
|
+
config.x.version = Storefront::VERSION
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Rails engines or apps that publish gems can opt into package metadata checks by
|
|
240
|
+
setting `config.gem_name` and including `:package_metadata` in
|
|
241
|
+
`config.version_checks`. Deployment and container metadata, such as Docker,
|
|
242
|
+
Kamal, and Helm, are intentionally left for future adapter support.
|
|
243
|
+
|
|
244
|
+
## Sinatra apps
|
|
245
|
+
Sinatra applications can use the Sinatra adapter for app-style defaults:
|
|
246
|
+
|
|
247
|
+
```ruby
|
|
248
|
+
Semverve.configure do |config|
|
|
249
|
+
config.adapter = :sinatra
|
|
250
|
+
end
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
The Sinatra adapter stores the version in `config/version.rb`, uses the
|
|
254
|
+
`:simple` format, infers the module name from the project directory, and checks
|
|
255
|
+
documentation references plus configured code literals by default. It does not
|
|
256
|
+
infer a package name from `config/version.rb` and does not run package metadata
|
|
257
|
+
checks unless you opt in.
|
|
258
|
+
|
|
209
259
|
## Formats
|
|
210
260
|
The default `:module` format stores `MAJOR`, `MINOR`, and `PATCH` constants
|
|
211
261
|
under a `Version` module and exposes a top-level `VERSION` constant.
|
|
@@ -329,12 +379,15 @@ rake semverve:check
|
|
|
329
379
|
This task is designed for normal CI. It uses local project files, prints
|
|
330
380
|
parseable findings, and exits non-zero when it finds drift.
|
|
331
381
|
|
|
332
|
-
By default,
|
|
382
|
+
By default, gem/package projects check:
|
|
333
383
|
|
|
334
384
|
- README version references, plus any configured docs or comment files
|
|
335
385
|
- configured code files for safe version literals
|
|
336
386
|
- the gemspec version and `Gemfile.lock` entry
|
|
337
387
|
|
|
388
|
+
Rails adapter projects instead check README references, configured code literals,
|
|
389
|
+
and optional Rails config metadata.
|
|
390
|
+
|
|
338
391
|
Findings are printed in parseable formats and the task exits non-zero:
|
|
339
392
|
|
|
340
393
|
```text
|
|
@@ -355,11 +408,13 @@ Choose which surfaces the umbrella `check` and `fix` tasks run with
|
|
|
355
408
|
|
|
356
409
|
```ruby
|
|
357
410
|
Semverve.configure do |config|
|
|
358
|
-
config.version_checks = [:doc_references, :
|
|
411
|
+
config.version_checks = [:doc_references, :package_metadata]
|
|
359
412
|
end
|
|
360
413
|
```
|
|
361
414
|
|
|
362
|
-
The allowed values
|
|
415
|
+
The allowed values come from Semverve's check registry. Built-in checks are
|
|
416
|
+
`:doc_references`, `:code_references`, and `:package_metadata`; framework
|
|
417
|
+
adapters can add their own checks, such as Rails' `:rails_config_metadata`.
|
|
363
418
|
|
|
364
419
|
Use focused tasks when you want only one surface:
|
|
365
420
|
|
|
@@ -368,12 +423,15 @@ rake semverve:check:references
|
|
|
368
423
|
rake semverve:fix:references
|
|
369
424
|
rake semverve:check:code
|
|
370
425
|
rake semverve:fix:code
|
|
371
|
-
rake semverve:check:
|
|
372
|
-
rake semverve:fix:
|
|
426
|
+
rake semverve:check:package_metadata
|
|
427
|
+
rake semverve:fix:package_metadata
|
|
428
|
+
rake semverve:check:rails_config_metadata
|
|
429
|
+
rake semverve:fix:rails_config_metadata
|
|
373
430
|
```
|
|
374
431
|
|
|
375
|
-
`semverve:fix:
|
|
376
|
-
runs `bundle lock` for `Gemfile.lock` drift.
|
|
432
|
+
`semverve:fix:package_metadata` rewrites literal gemspec versions when safe and
|
|
433
|
+
runs `bundle lock` for `Gemfile.lock` drift. `semverve:fix:rails_config_metadata`
|
|
434
|
+
rewrites safe Rails config version literals.
|
|
377
435
|
|
|
378
436
|
Pass a semantic version when you want to check or fix only that exact version in
|
|
379
437
|
doc references and code literals:
|
|
@@ -383,9 +441,55 @@ rake 'semverve:check[1.2.2]'
|
|
|
383
441
|
rake 'semverve:fix:references[1.2.2]'
|
|
384
442
|
```
|
|
385
443
|
|
|
386
|
-
|
|
387
|
-
current version
|
|
388
|
-
the text is already
|
|
444
|
+
Package metadata and adapter-owned metadata checks still compare metadata to the
|
|
445
|
+
current version. If you target the current version, check tasks list
|
|
446
|
+
reference/code matches but fix tasks are no-ops because the text is already
|
|
447
|
+
current.
|
|
448
|
+
|
|
449
|
+
## Extension API
|
|
450
|
+
Semverve exposes small public objects for framework adapters and version checks.
|
|
451
|
+
These APIs are intentionally local registration APIs; Semverve does not yet
|
|
452
|
+
autoload third-party adapter gems.
|
|
453
|
+
|
|
454
|
+
Register a framework adapter with `Semverve::Adapters.register`. An adapter
|
|
455
|
+
must expose `name`, `defaults(configuration)`, and `checks`. It can also expose
|
|
456
|
+
`infer_package_name?` to control whether app-style version files should be
|
|
457
|
+
treated as package names.
|
|
458
|
+
|
|
459
|
+
Register a check with `Semverve::VersionChecks.register`, or return adapter-owned
|
|
460
|
+
checks from an adapter's `checks` method. A check object should expose:
|
|
461
|
+
|
|
462
|
+
- `name` and `task_name`
|
|
463
|
+
- `check_description`, `fix_description`, `finding_label`, and `fix_label`
|
|
464
|
+
- `clean_message`, `targetable?`, and `exact_target_fix_noop_notice?`
|
|
465
|
+
- `findings(configuration, current_version, include_ignored:, target_version:)`
|
|
466
|
+
- `fix(configuration, current_version, target_version:)`
|
|
467
|
+
|
|
468
|
+
Checks should return `Semverve::Finding` objects from `findings` and a
|
|
469
|
+
`Semverve::FixResult` from `fix`. `Semverve::VersionMatchPolicy` and
|
|
470
|
+
`Semverve::VersionLiteralRewriter` are available for checks that need Semverve's
|
|
471
|
+
standard stale-version matching or named-capture literal rewriting.
|
|
472
|
+
|
|
473
|
+
For example:
|
|
474
|
+
|
|
475
|
+
```ruby
|
|
476
|
+
class MyConfigVersionCheck < Semverve::VersionChecks::Check
|
|
477
|
+
def name = :my_config_metadata
|
|
478
|
+
def task_name = :my_config_metadata
|
|
479
|
+
def check_description = "Check app config metadata for version mismatches"
|
|
480
|
+
def fix_description = "Fix safe app config metadata version mismatches"
|
|
481
|
+
def finding_label = "app config version"
|
|
482
|
+
def clean_message = "App config metadata is current."
|
|
483
|
+
|
|
484
|
+
def findings(configuration, current_version, include_ignored: false, target_version: nil)
|
|
485
|
+
[]
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
def fix(configuration, current_version, target_version: nil)
|
|
489
|
+
Semverve::FixResult.new(changed_files: [], replacement_count: 0)
|
|
490
|
+
end
|
|
491
|
+
end
|
|
492
|
+
```
|
|
389
493
|
|
|
390
494
|
### Version references
|
|
391
495
|
Version references are prose-like references to versions. These are usually in
|
|
@@ -457,7 +561,7 @@ SEMVERVE_REPORT_IGNORED=true rake 'semverve:check[1.2.2]'
|
|
|
457
561
|
|
|
458
562
|
### Code version literals
|
|
459
563
|
Code scanning is opt-in to avoid false positives. This is for arbitrary project
|
|
460
|
-
code, not
|
|
564
|
+
code, not package metadata. The default is:
|
|
461
565
|
|
|
462
566
|
```ruby
|
|
463
567
|
Semverve.configure do |config|
|
|
@@ -532,14 +636,14 @@ The custom value must be a `Regexp` and must include a named capture called
|
|
|
532
636
|
`rake semverve:fix:code`, and the captured value still has to parse as a
|
|
533
637
|
semantic version.
|
|
534
638
|
|
|
535
|
-
###
|
|
536
|
-
|
|
537
|
-
current version file against:
|
|
639
|
+
### Package metadata
|
|
640
|
+
Package metadata checks are part of `rake semverve:check` by default for
|
|
641
|
+
gem/package projects. They compare the current version file against:
|
|
538
642
|
|
|
539
643
|
- the resolved `.gemspec` version
|
|
540
644
|
- the matching `Gemfile.lock` entry, when a lockfile exists
|
|
541
645
|
|
|
542
|
-
|
|
646
|
+
Package metadata always requires an exact match, regardless of
|
|
543
647
|
`config.version_match_mode`.
|
|
544
648
|
|
|
545
649
|
No file-list configuration is needed for these checks. Semverve resolves the
|
|
@@ -565,9 +669,25 @@ Gem::Specification.new do |spec|
|
|
|
565
669
|
end
|
|
566
670
|
```
|
|
567
671
|
|
|
568
|
-
`rake semverve:fix:
|
|
672
|
+
`rake semverve:fix:package_metadata` updates safe literal gemspec assignments and
|
|
569
673
|
runs `bundle lock` when the lockfile has drifted.
|
|
570
674
|
|
|
675
|
+
### Rails config metadata
|
|
676
|
+
Rails config metadata checks are part of `rake semverve:check` when the Rails
|
|
677
|
+
adapter is active. They scan `config/application.rb`,
|
|
678
|
+
`config/environments/*.rb`, and `config/initializers/**/*.rb` for optional Rails
|
|
679
|
+
config literals:
|
|
680
|
+
|
|
681
|
+
```ruby
|
|
682
|
+
config.x.version = "1.2.2"
|
|
683
|
+
Rails.application.config.x.version = "1.2.2"
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
These checks always require an exact match with the current Semverve version.
|
|
687
|
+
`rake semverve:fix:rails_config_metadata` rewrites only those safe string
|
|
688
|
+
literals. Dynamic assignments, including `config.x.version = Storefront::VERSION`,
|
|
689
|
+
are considered self-managed and ignored.
|
|
690
|
+
|
|
571
691
|
## Checking release readiness
|
|
572
692
|
Release checks are separate from `rake semverve:check`. They are useful in CI,
|
|
573
693
|
but they are meant for release workflows, tag builds, or pre-publish jobs rather
|
data/UPGRADING.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Upgrading Semverve
|
|
2
|
+
|
|
3
|
+
## Version 0.4.0
|
|
4
|
+
|
|
5
|
+
This release changes Semverve's version-check API so Rails and other app
|
|
6
|
+
frameworks can be supported without pretending every project is a gem package.
|
|
7
|
+
|
|
8
|
+
### Breaking changes
|
|
9
|
+
|
|
10
|
+
- `:metadata` was removed from `config.version_checks`.
|
|
11
|
+
- `semverve:check:metadata` and `semverve:fix:metadata` were removed.
|
|
12
|
+
- Use `:package_metadata`, `semverve:check:package_metadata`, and
|
|
13
|
+
`semverve:fix:package_metadata` for gemspec and `Gemfile.lock` checks.
|
|
14
|
+
- Rails defaults no longer include package metadata checks.
|
|
15
|
+
- Rails apps no longer infer a package name from `config/version.rb`.
|
|
16
|
+
|
|
17
|
+
### Rails apps
|
|
18
|
+
|
|
19
|
+
Use the Rails adapter:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
Semverve.configure do |config|
|
|
23
|
+
config.adapter = :rails
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`config.preset = :rails` still works for compatibility, but `config.adapter` is
|
|
28
|
+
the preferred API.
|
|
29
|
+
|
|
30
|
+
Rails defaults now use:
|
|
31
|
+
|
|
32
|
+
```ruby
|
|
33
|
+
[:doc_references, :code_references, :rails_config_metadata]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Rails config metadata is optional. If Semverve finds safe literals like these,
|
|
37
|
+
it checks and can fix them:
|
|
38
|
+
|
|
39
|
+
```ruby
|
|
40
|
+
config.x.version = "1.2.3"
|
|
41
|
+
Rails.application.config.x.version = "1.2.3"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Dynamic assignments are treated as self-managed:
|
|
45
|
+
|
|
46
|
+
```ruby
|
|
47
|
+
config.x.version = Storefront::VERSION
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Rails engines or apps that publish gems can opt back into package metadata:
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
Semverve.configure do |config|
|
|
54
|
+
config.adapter = :rails
|
|
55
|
+
config.gem_name = "my_engine"
|
|
56
|
+
config.version_checks = [:doc_references, :code_references, :rails_config_metadata, :package_metadata]
|
|
57
|
+
end
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Sinatra apps
|
|
61
|
+
|
|
62
|
+
Sinatra apps can opt into app-style defaults:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
Semverve.configure do |config|
|
|
66
|
+
config.adapter = :sinatra
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
The Sinatra adapter uses `config/version.rb`, `:simple` format, and default
|
|
71
|
+
checks of `[:doc_references, :code_references]`.
|
|
72
|
+
|
|
73
|
+
### Extension API
|
|
74
|
+
|
|
75
|
+
Framework integration now goes through `Semverve::Adapters`, and version-check
|
|
76
|
+
integration goes through `Semverve::VersionChecks`. Checks should return
|
|
77
|
+
`Semverve::Finding` objects from `findings` and `Semverve::FixResult` from
|
|
78
|
+
`fix`.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "error"
|
|
4
|
+
require_relative "version_checks"
|
|
5
|
+
|
|
6
|
+
module Semverve
|
|
7
|
+
##
|
|
8
|
+
# Framework-specific configuration adapters.
|
|
9
|
+
module Adapters
|
|
10
|
+
class << self
|
|
11
|
+
##
|
|
12
|
+
# Registers a framework adapter.
|
|
13
|
+
#
|
|
14
|
+
# @param [#name, #defaults, #checks] adapter
|
|
15
|
+
#
|
|
16
|
+
# @return [#name, #defaults, #checks]
|
|
17
|
+
def register(adapter)
|
|
18
|
+
adapters[adapter.name] = adapter
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Returns an adapter by name.
|
|
23
|
+
#
|
|
24
|
+
# @param [Symbol, String] name
|
|
25
|
+
#
|
|
26
|
+
# @return [#name, #defaults, #checks]
|
|
27
|
+
def fetch(name)
|
|
28
|
+
normalized_name = normalize_name(name)
|
|
29
|
+
adapter = adapters[normalized_name]
|
|
30
|
+
return adapter if adapter
|
|
31
|
+
|
|
32
|
+
raise Error, unknown_adapter_message(name)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Defaults for the configured adapter.
|
|
37
|
+
#
|
|
38
|
+
# @param [Symbol, String, nil] name
|
|
39
|
+
# @param [Semverve::Configuration] configuration
|
|
40
|
+
#
|
|
41
|
+
# @return [Hash]
|
|
42
|
+
def defaults_for(name, configuration)
|
|
43
|
+
return {} unless name
|
|
44
|
+
|
|
45
|
+
fetch(name).defaults(configuration)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Checks supplied by all registered adapters.
|
|
50
|
+
#
|
|
51
|
+
# @return [Array<#name>]
|
|
52
|
+
def checks
|
|
53
|
+
adapters.values.flat_map(&:checks).each_with_object({}) do |check, checks|
|
|
54
|
+
checks[check.name] = check
|
|
55
|
+
end.values
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
##
|
|
59
|
+
# Checks supplied by the configured adapter.
|
|
60
|
+
#
|
|
61
|
+
# @param [Symbol, String, nil] name
|
|
62
|
+
#
|
|
63
|
+
# @return [Array<#name>]
|
|
64
|
+
def checks_for(name)
|
|
65
|
+
return [] unless name
|
|
66
|
+
|
|
67
|
+
fetch(name).checks
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# Whether package names should be inferred for the configured adapter.
|
|
72
|
+
#
|
|
73
|
+
# @param [Symbol, String, nil] name
|
|
74
|
+
#
|
|
75
|
+
# @return [Boolean]
|
|
76
|
+
def infer_package_name?(name)
|
|
77
|
+
return true unless name
|
|
78
|
+
|
|
79
|
+
fetch(name).infer_package_name?
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# Registered adapter names.
|
|
84
|
+
#
|
|
85
|
+
# @return [Array<Symbol>]
|
|
86
|
+
def names
|
|
87
|
+
adapters.keys
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
##
|
|
93
|
+
# Adapter registry.
|
|
94
|
+
#
|
|
95
|
+
# @return [Hash<Symbol, #name>]
|
|
96
|
+
def adapters
|
|
97
|
+
@adapters ||= {}
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Normalizes an adapter name.
|
|
102
|
+
#
|
|
103
|
+
# @param [Object] name
|
|
104
|
+
#
|
|
105
|
+
# @return [Symbol, Object]
|
|
106
|
+
def normalize_name(name)
|
|
107
|
+
name.respond_to?(:to_sym) ? name.to_sym : name
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
##
|
|
111
|
+
# Error message for invalid adapters.
|
|
112
|
+
#
|
|
113
|
+
# @param [Object] name
|
|
114
|
+
#
|
|
115
|
+
# @return [String]
|
|
116
|
+
def unknown_adapter_message(name)
|
|
117
|
+
adapter_names = names.map(&:inspect)
|
|
118
|
+
valid_adapters = "#{adapter_names[0...-1].join(", ")}, or #{adapter_names.last}"
|
|
119
|
+
"Unknown adapter #{name.inspect}. Use #{valid_adapters}."
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
##
|
|
124
|
+
# Shared adapter helpers.
|
|
125
|
+
class Base
|
|
126
|
+
##
|
|
127
|
+
# Framework-specific checks.
|
|
128
|
+
#
|
|
129
|
+
# @return [Array<#name>]
|
|
130
|
+
def checks
|
|
131
|
+
[]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
##
|
|
135
|
+
# Whether Semverve should infer package names from version files or gemspecs.
|
|
136
|
+
#
|
|
137
|
+
# @return [Boolean]
|
|
138
|
+
def infer_package_name?
|
|
139
|
+
true
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
##
|
|
145
|
+
# Module name fallback based on the project directory.
|
|
146
|
+
#
|
|
147
|
+
# @param [String] root
|
|
148
|
+
#
|
|
149
|
+
# @return [String]
|
|
150
|
+
def project_module_name(root)
|
|
151
|
+
camelize(File.basename(File.expand_path(root)))
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
##
|
|
155
|
+
# Converts a project directory into a Ruby module name.
|
|
156
|
+
#
|
|
157
|
+
# @param [String] value
|
|
158
|
+
#
|
|
159
|
+
# @return [String]
|
|
160
|
+
def camelize(value)
|
|
161
|
+
value.split(/[_-]/).map(&:capitalize).join
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
##
|
|
166
|
+
# Rails application adapter.
|
|
167
|
+
class Rails < Base
|
|
168
|
+
##
|
|
169
|
+
# Adapter name.
|
|
170
|
+
#
|
|
171
|
+
# @return [Symbol]
|
|
172
|
+
def name
|
|
173
|
+
:rails
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
##
|
|
177
|
+
# Rails-specific Semverve defaults.
|
|
178
|
+
#
|
|
179
|
+
# @param [Semverve::Configuration] _configuration
|
|
180
|
+
#
|
|
181
|
+
# @return [Hash]
|
|
182
|
+
def defaults(_configuration)
|
|
183
|
+
root = rails_root || Dir.pwd
|
|
184
|
+
|
|
185
|
+
{
|
|
186
|
+
format: :simple,
|
|
187
|
+
module_name: rails_module_name || project_module_name(root),
|
|
188
|
+
root: root,
|
|
189
|
+
version_checks: [:doc_references, :code_references, :rails_config_metadata],
|
|
190
|
+
version_file: File.join("config", "version.rb")
|
|
191
|
+
}
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
##
|
|
195
|
+
# Rails-specific checks.
|
|
196
|
+
#
|
|
197
|
+
# @return [Array<#name>]
|
|
198
|
+
def checks
|
|
199
|
+
[VersionChecks::RailsConfigMetadataCheck.new]
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
##
|
|
203
|
+
# Rails apps should not infer a package name from config/version.rb.
|
|
204
|
+
#
|
|
205
|
+
# @return [Boolean]
|
|
206
|
+
def infer_package_name?
|
|
207
|
+
false
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
private
|
|
211
|
+
|
|
212
|
+
##
|
|
213
|
+
# Rails.root when Rails is available.
|
|
214
|
+
#
|
|
215
|
+
# @return [String, nil]
|
|
216
|
+
def rails_root
|
|
217
|
+
return unless rails_defined?
|
|
218
|
+
return unless ::Rails.respond_to?(:root)
|
|
219
|
+
return unless ::Rails.root
|
|
220
|
+
|
|
221
|
+
::Rails.root.to_s
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
##
|
|
225
|
+
# Application module name inferred from Rails.application.
|
|
226
|
+
#
|
|
227
|
+
# @return [String, nil]
|
|
228
|
+
def rails_module_name
|
|
229
|
+
return unless rails_defined?
|
|
230
|
+
return unless ::Rails.respond_to?(:application)
|
|
231
|
+
return unless ::Rails.application
|
|
232
|
+
|
|
233
|
+
application_class = ::Rails.application.class
|
|
234
|
+
return application_class.module_parent_name if application_class.respond_to?(:module_parent_name)
|
|
235
|
+
|
|
236
|
+
class_name = application_class.name
|
|
237
|
+
return unless class_name&.include?("::")
|
|
238
|
+
|
|
239
|
+
class_name.split("::").first
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
##
|
|
243
|
+
# Whether Rails is loaded.
|
|
244
|
+
#
|
|
245
|
+
# @return [Boolean]
|
|
246
|
+
def rails_defined?
|
|
247
|
+
Object.const_defined?(:Rails)
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
##
|
|
252
|
+
# Sinatra application adapter.
|
|
253
|
+
class Sinatra < Base
|
|
254
|
+
##
|
|
255
|
+
# Adapter name.
|
|
256
|
+
#
|
|
257
|
+
# @return [Symbol]
|
|
258
|
+
def name
|
|
259
|
+
:sinatra
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
##
|
|
263
|
+
# Sinatra-specific Semverve defaults.
|
|
264
|
+
#
|
|
265
|
+
# @param [Semverve::Configuration] _configuration
|
|
266
|
+
#
|
|
267
|
+
# @return [Hash]
|
|
268
|
+
def defaults(_configuration)
|
|
269
|
+
root = Dir.pwd
|
|
270
|
+
|
|
271
|
+
{
|
|
272
|
+
format: :simple,
|
|
273
|
+
module_name: project_module_name(root),
|
|
274
|
+
root: root,
|
|
275
|
+
version_checks: [:doc_references, :code_references],
|
|
276
|
+
version_file: File.join("config", "version.rb")
|
|
277
|
+
}
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
##
|
|
281
|
+
# Sinatra apps should not infer a package name from config/version.rb.
|
|
282
|
+
#
|
|
283
|
+
# @return [Boolean]
|
|
284
|
+
def infer_package_name?
|
|
285
|
+
false
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
Semverve::Adapters.register(Semverve::Adapters::Rails.new)
|
|
292
|
+
Semverve::Adapters.register(Semverve::Adapters::Sinatra.new)
|