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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c12b376c6b4cb56170cff17c35f9545137b3011f1e1fe6314541dfe259351367
4
- data.tar.gz: fae2d93ad6f546f69e081cfa5a7449d7d6de0c9eb25430421dbe41a274171d8c
3
+ metadata.gz: 9d9765e973d77ca7011cb819202246f5ea7ef2faef574c66a58fc6ad5c058988
4
+ data.tar.gz: dea8769f32c6f6b70c81d05e2d46129cd9820a8289fbd032f42303dfc0b8dea3
5
5
  SHA512:
6
- metadata.gz: 92980247baef342765f07bf2f9a398e38b191a3707302ae84f25ca0a322a9bfd428335f680c6da34cebc1039f533cdf7298117e1e062f159413c663e58966f2c
7
- data.tar.gz: b9016a36d15e78aa46c6e7fea92feaa48bd5dec2627fcd8e47420e11a55eed4c7083f56eaeb06f95cb1a9baa50f3559f5c9d3e63fb2bc42dae720a49447df775
6
+ metadata.gz: 38b4aca2a29cfc750a7b6b7164219595ec35f76c9c5d526f441e469868686a6588170ee0e88c02942b97b59725d1c72c79b1496cad5880264042d99c8049846a
7
+ data.tar.gz: 7cf79a5a6d90a0f454ce03272e5592b140fff266893fee323b6e831ab28956104e7865bb5a141614e6cae6466a4bacbbd738850f299fd98d7f1024f391d61b7c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- semverve (0.3.0)
4
+ semverve (0.4.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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:metadata
66
- rake semverve:fix:metadata
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, :metadata]
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, :metadata]
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 check.
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 preset:
190
+ the Rails adapter:
180
191
 
181
192
  ```ruby
182
193
  Semverve.configure do |config|
183
- config.preset = :rails
194
+ config.adapter = :rails
184
195
  end
185
196
  ```
186
197
 
187
- The Rails preset uses `Rails.root`, stores the version in
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.preset = :rails
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 a preset and a Railtie; Semverve does not require a dummy
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, this checks:
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, :metadata]
411
+ config.version_checks = [:doc_references, :package_metadata]
359
412
  end
360
413
  ```
361
414
 
362
- The allowed values are `:doc_references`, `:code_references`, and `:metadata`.
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:metadata
372
- rake semverve:fix:metadata
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:metadata` rewrites literal gemspec versions when safe and
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
- Metadata checks still compare metadata to the current version. If you target the
387
- current version, check tasks list those matches but fix tasks are no-ops because
388
- the text is already current.
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 gem metadata. The default is:
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
- ### Metadata
536
- Metadata checks are part of `rake semverve:check` by default. They compare the
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
- Metadata always requires an exact match, regardless of
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:metadata` updates safe literal gemspec assignments and
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)