semverve 0.2.1 → 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/CONTRIBUTING.md +4 -0
- data/Gemfile.lock +1 -1
- data/README.md +166 -32
- data/UPGRADING.md +78 -0
- data/lib/semverve/adapters.rb +292 -0
- data/lib/semverve/configuration.rb +64 -39
- 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 +166 -114
- data/lib/semverve/version.rb +2 -2
- data/lib/semverve/version_checks.rb +518 -0
- data/lib/semverve/version_code_references.rb +53 -89
- data/lib/semverve/version_literal_rewriter.rb +78 -0
- data/lib/semverve/version_match_policy.rb +62 -0
- data/lib/semverve/version_references.rb +32 -88
- data/lib/semverve.rb +4 -0
- metadata +10 -2
data/lib/semverve/task.rb
CHANGED
|
@@ -3,13 +3,12 @@
|
|
|
3
3
|
require "rake"
|
|
4
4
|
|
|
5
5
|
require_relative "../semverve"
|
|
6
|
+
require_relative "adapters"
|
|
6
7
|
require_relative "generator"
|
|
7
8
|
require_relative "published_version"
|
|
8
9
|
require_relative "semantic_version"
|
|
9
10
|
require_relative "version_file"
|
|
10
|
-
require_relative "
|
|
11
|
-
require_relative "version_metadata"
|
|
12
|
-
require_relative "version_references"
|
|
11
|
+
require_relative "version_checks"
|
|
13
12
|
|
|
14
13
|
module Semverve
|
|
15
14
|
##
|
|
@@ -115,24 +114,16 @@ module Semverve
|
|
|
115
114
|
end
|
|
116
115
|
|
|
117
116
|
desc "Check version references, code literals, and metadata"
|
|
118
|
-
task :check do
|
|
119
|
-
check
|
|
117
|
+
task :check, [:version] do |_task, args|
|
|
118
|
+
check(args)
|
|
120
119
|
end
|
|
121
120
|
|
|
122
121
|
namespace :check do
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
desc "Check configured code files for version literals"
|
|
129
|
-
task :code do
|
|
130
|
-
check_code
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
desc "Check gem metadata for version mismatches"
|
|
134
|
-
task :metadata do
|
|
135
|
-
check_metadata
|
|
122
|
+
version_checks.each do |version_check|
|
|
123
|
+
desc version_check.check_description
|
|
124
|
+
task version_check.task_name, version_check.task_arguments do |_task, args|
|
|
125
|
+
check_version_check(version_check, args)
|
|
126
|
+
end
|
|
136
127
|
end
|
|
137
128
|
|
|
138
129
|
desc "Check whether the current gem version is already published"
|
|
@@ -147,24 +138,16 @@ module Semverve
|
|
|
147
138
|
end
|
|
148
139
|
|
|
149
140
|
desc "Fix version references, code literals, and metadata"
|
|
150
|
-
task :fix do
|
|
151
|
-
fix
|
|
141
|
+
task :fix, [:version] do |_task, args|
|
|
142
|
+
fix(args)
|
|
152
143
|
end
|
|
153
144
|
|
|
154
145
|
namespace :fix do
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
desc "Replace safe code version literals in configured files"
|
|
161
|
-
task :code do
|
|
162
|
-
fix_code
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
desc "Fix safe gem metadata version mismatches"
|
|
166
|
-
task :metadata do
|
|
167
|
-
fix_metadata
|
|
146
|
+
version_checks.each do |version_check|
|
|
147
|
+
desc version_check.fix_description
|
|
148
|
+
task version_check.task_name, version_check.task_arguments do |_task, args|
|
|
149
|
+
fix_version_check(version_check, args)
|
|
150
|
+
end
|
|
168
151
|
end
|
|
169
152
|
end
|
|
170
153
|
end
|
|
@@ -203,11 +186,14 @@ module Semverve
|
|
|
203
186
|
# Checks all version-maintenance surfaces.
|
|
204
187
|
#
|
|
205
188
|
# @return [void]
|
|
206
|
-
def check
|
|
189
|
+
def check(args = nil)
|
|
207
190
|
configuration, current_version = check_context
|
|
191
|
+
target_version = target_version_argument(args, "semverve:check")
|
|
208
192
|
report_findings(
|
|
209
|
-
check_groups(configuration, current_version),
|
|
193
|
+
check_groups(configuration, current_version, target_version),
|
|
210
194
|
current_version,
|
|
195
|
+
target_version: target_version,
|
|
196
|
+
fix_task_name: "semverve:fix",
|
|
211
197
|
clean_message: "Version checks passed."
|
|
212
198
|
)
|
|
213
199
|
end
|
|
@@ -216,72 +202,79 @@ module Semverve
|
|
|
216
202
|
# Fixes all check surfaces.
|
|
217
203
|
#
|
|
218
204
|
# @return [void]
|
|
219
|
-
def fix
|
|
205
|
+
def fix(args = nil)
|
|
220
206
|
configuration, current_version = check_context
|
|
221
|
-
|
|
207
|
+
target_version = target_version_argument(args, "semverve:fix")
|
|
208
|
+
return report_current_target_noop(target_version) if target_version == current_version
|
|
209
|
+
|
|
210
|
+
report_fix_results(fix_results(configuration, current_version, target_version))
|
|
222
211
|
end
|
|
223
212
|
|
|
224
213
|
##
|
|
225
|
-
# Checks
|
|
214
|
+
# Checks a single registered version check.
|
|
215
|
+
#
|
|
216
|
+
# @param [#findings] version_check
|
|
217
|
+
# @param [Rake::TaskArguments, nil] args
|
|
226
218
|
#
|
|
227
219
|
# @return [void]
|
|
228
|
-
def
|
|
220
|
+
def check_version_check(version_check, args = nil)
|
|
229
221
|
configuration, current_version = check_context
|
|
222
|
+
target_version = check_target_version(version_check, args, "semverve:check:#{version_check.task_name}")
|
|
230
223
|
report_findings(
|
|
231
|
-
[[
|
|
224
|
+
[[
|
|
225
|
+
version_check,
|
|
226
|
+
version_check.finding_label,
|
|
227
|
+
version_check.findings(
|
|
228
|
+
configuration,
|
|
229
|
+
current_version,
|
|
230
|
+
include_ignored: report_ignored?,
|
|
231
|
+
target_version: target_version
|
|
232
|
+
)
|
|
233
|
+
]],
|
|
232
234
|
current_version,
|
|
233
|
-
|
|
235
|
+
target_version: target_version,
|
|
236
|
+
fix_task_name: "semverve:fix:#{version_check.task_name}",
|
|
237
|
+
clean_message: version_check.clean_message
|
|
234
238
|
)
|
|
235
239
|
end
|
|
236
240
|
|
|
237
241
|
##
|
|
238
|
-
#
|
|
242
|
+
# Fixes a single registered version check.
|
|
243
|
+
#
|
|
244
|
+
# @param [#fix] version_check
|
|
245
|
+
# @param [Rake::TaskArguments, nil] args
|
|
239
246
|
#
|
|
240
247
|
# @return [void]
|
|
241
|
-
def
|
|
248
|
+
def fix_version_check(version_check, args = nil)
|
|
242
249
|
configuration, current_version = check_context
|
|
250
|
+
target_version = check_target_version(version_check, args, "semverve:fix:#{version_check.task_name}")
|
|
251
|
+
return report_current_target_noop(target_version) if target_version == current_version
|
|
252
|
+
|
|
243
253
|
report_fix_results(
|
|
244
|
-
[[
|
|
245
|
-
|
|
254
|
+
[[
|
|
255
|
+
version_check.fix_label,
|
|
256
|
+
version_check.fix(configuration, current_version, target_version: target_version)
|
|
257
|
+
]],
|
|
258
|
+
clean_message: version_check.clean_message
|
|
246
259
|
)
|
|
247
260
|
end
|
|
248
261
|
|
|
249
262
|
##
|
|
250
|
-
#
|
|
263
|
+
# Registered version checks available to tasks.
|
|
251
264
|
#
|
|
252
|
-
# @return [
|
|
253
|
-
def
|
|
254
|
-
|
|
255
|
-
report_findings(
|
|
256
|
-
[["code version literal", VersionCodeReferences.new(configuration, current_version, include_ignored: report_ignored?).findings]],
|
|
257
|
-
current_version,
|
|
258
|
-
clean_message: "Code version literals are current."
|
|
259
|
-
)
|
|
265
|
+
# @return [Array<#name>]
|
|
266
|
+
def version_checks
|
|
267
|
+
VersionChecks.all(extra_checks: Adapters.checks)
|
|
260
268
|
end
|
|
261
269
|
|
|
262
270
|
##
|
|
263
|
-
#
|
|
271
|
+
# Fetches a registered version check.
|
|
264
272
|
#
|
|
265
|
-
# @
|
|
266
|
-
def fix_code
|
|
267
|
-
configuration, current_version = check_context
|
|
268
|
-
report_fix_results(
|
|
269
|
-
[["code version literal", VersionCodeReferences.new(configuration, current_version).fix]],
|
|
270
|
-
clean_message: "Code version literals are current."
|
|
271
|
-
)
|
|
272
|
-
end
|
|
273
|
-
|
|
274
|
-
##
|
|
275
|
-
# Checks gem metadata for version mismatches.
|
|
273
|
+
# @param [Symbol, String] name
|
|
276
274
|
#
|
|
277
|
-
# @return [
|
|
278
|
-
def
|
|
279
|
-
|
|
280
|
-
report_findings(
|
|
281
|
-
[[nil, VersionMetadata.new(configuration, current_version).findings]],
|
|
282
|
-
current_version,
|
|
283
|
-
clean_message: "Version metadata is current."
|
|
284
|
-
)
|
|
275
|
+
# @return [#name]
|
|
276
|
+
def version_check(name)
|
|
277
|
+
VersionChecks.fetch(name, extra_checks: Adapters.checks)
|
|
285
278
|
end
|
|
286
279
|
|
|
287
280
|
##
|
|
@@ -309,18 +302,6 @@ module Semverve
|
|
|
309
302
|
puts "Release checks passed."
|
|
310
303
|
end
|
|
311
304
|
|
|
312
|
-
##
|
|
313
|
-
# Fixes safe gem metadata version mismatches.
|
|
314
|
-
#
|
|
315
|
-
# @return [void]
|
|
316
|
-
def fix_metadata
|
|
317
|
-
configuration, current_version = check_context
|
|
318
|
-
report_fix_results(
|
|
319
|
-
[["metadata version", VersionMetadata.new(configuration, current_version).fix]],
|
|
320
|
-
clean_message: "Version metadata is current."
|
|
321
|
-
)
|
|
322
|
-
end
|
|
323
|
-
|
|
324
305
|
##
|
|
325
306
|
# Resolved configuration and current version for check tasks.
|
|
326
307
|
#
|
|
@@ -336,19 +317,23 @@ module Semverve
|
|
|
336
317
|
# @param [Semverve::ResolvedConfiguration] configuration
|
|
337
318
|
# @param [Semverve::SemanticVersion] current_version
|
|
338
319
|
#
|
|
339
|
-
# @
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
320
|
+
# @param [Semverve::SemanticVersion, nil] target_version
|
|
321
|
+
#
|
|
322
|
+
# @return [Array<Array(#name, String, Array)>]
|
|
323
|
+
def check_groups(configuration, current_version, target_version = nil)
|
|
324
|
+
configuration.version_checks.map do |check_name|
|
|
325
|
+
version_check = version_check(check_name)
|
|
326
|
+
[
|
|
327
|
+
version_check,
|
|
328
|
+
version_check.finding_label,
|
|
329
|
+
version_check.findings(
|
|
330
|
+
configuration,
|
|
331
|
+
current_version,
|
|
332
|
+
include_ignored: report_ignored?,
|
|
333
|
+
target_version: target_version_for(version_check, target_version)
|
|
334
|
+
)
|
|
335
|
+
]
|
|
350
336
|
end
|
|
351
|
-
groups
|
|
352
337
|
end
|
|
353
338
|
|
|
354
339
|
##
|
|
@@ -412,25 +397,67 @@ module Semverve
|
|
|
412
397
|
version
|
|
413
398
|
end
|
|
414
399
|
|
|
400
|
+
##
|
|
401
|
+
# Optional exact version argument for check and fix tasks.
|
|
402
|
+
#
|
|
403
|
+
# @param [Rake::TaskArguments, nil] args
|
|
404
|
+
# @param [String] task_name
|
|
405
|
+
#
|
|
406
|
+
# @return [Semverve::SemanticVersion, nil]
|
|
407
|
+
def target_version_argument(args, task_name)
|
|
408
|
+
version = args&.[](:version)
|
|
409
|
+
return nil if version.nil? || version.empty?
|
|
410
|
+
|
|
411
|
+
SemanticVersion.parse(version)
|
|
412
|
+
rescue Error
|
|
413
|
+
raise Error, "Run rake '#{task_name}[MAJOR.MINOR.PATCH]'."
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
##
|
|
417
|
+
# Optional exact version argument for checks that support targeting.
|
|
418
|
+
#
|
|
419
|
+
# @param [#targetable?] version_check
|
|
420
|
+
# @param [Rake::TaskArguments, nil] args
|
|
421
|
+
# @param [String] task_name
|
|
422
|
+
#
|
|
423
|
+
# @return [Semverve::SemanticVersion, nil]
|
|
424
|
+
def check_target_version(version_check, args, task_name)
|
|
425
|
+
return nil unless version_check.targetable?
|
|
426
|
+
|
|
427
|
+
target_version_argument(args, task_name)
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
##
|
|
431
|
+
# Applies an umbrella target only to checks that support targeting.
|
|
432
|
+
#
|
|
433
|
+
# @param [#targetable?] version_check
|
|
434
|
+
# @param [Semverve::SemanticVersion, nil] target_version
|
|
435
|
+
#
|
|
436
|
+
# @return [Semverve::SemanticVersion, nil]
|
|
437
|
+
def target_version_for(version_check, target_version)
|
|
438
|
+
version_check.targetable? ? target_version : nil
|
|
439
|
+
end
|
|
440
|
+
|
|
415
441
|
##
|
|
416
442
|
# Fix results enabled for the umbrella fix task.
|
|
417
443
|
#
|
|
418
444
|
# @param [Semverve::ResolvedConfiguration] configuration
|
|
419
445
|
# @param [Semverve::SemanticVersion] current_version
|
|
446
|
+
# @param [Semverve::SemanticVersion, nil] target_version
|
|
420
447
|
#
|
|
421
448
|
# @return [Array<Array(String, #replacement_count, #changed_files)>]
|
|
422
|
-
def fix_results(configuration, current_version)
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
449
|
+
def fix_results(configuration, current_version, target_version = nil)
|
|
450
|
+
configuration.version_checks.map do |check_name|
|
|
451
|
+
version_check = version_check(check_name)
|
|
452
|
+
[
|
|
453
|
+
version_check.fix_label,
|
|
454
|
+
version_check.fix(
|
|
455
|
+
configuration,
|
|
456
|
+
current_version,
|
|
457
|
+
target_version: target_version_for(version_check, target_version)
|
|
458
|
+
)
|
|
459
|
+
]
|
|
429
460
|
end
|
|
430
|
-
if configuration.version_checks.include?(:metadata)
|
|
431
|
-
results << ["metadata version", VersionMetadata.new(configuration, current_version).fix]
|
|
432
|
-
end
|
|
433
|
-
results
|
|
434
461
|
end
|
|
435
462
|
|
|
436
463
|
##
|
|
@@ -438,12 +465,14 @@ module Semverve
|
|
|
438
465
|
#
|
|
439
466
|
# @param [Array<Array(String, Array)>] groups
|
|
440
467
|
# @param [Semverve::SemanticVersion] current_version
|
|
468
|
+
# @param [Semverve::SemanticVersion, nil] target_version
|
|
469
|
+
# @param [String, nil] fix_task_name
|
|
441
470
|
# @param [String] clean_message
|
|
442
471
|
#
|
|
443
472
|
# @return [void]
|
|
444
|
-
def report_findings(groups, current_version, clean_message:)
|
|
445
|
-
findings = groups.flat_map do |(label, group_findings)|
|
|
446
|
-
group_findings.map { |finding| [label || finding.label, finding] }
|
|
473
|
+
def report_findings(groups, current_version, clean_message:, target_version: nil, fix_task_name: nil)
|
|
474
|
+
findings = groups.flat_map do |(version_check, label, group_findings)|
|
|
475
|
+
group_findings.map { |finding| [version_check, label || finding.label, finding] }
|
|
447
476
|
end
|
|
448
477
|
|
|
449
478
|
if findings.empty?
|
|
@@ -451,14 +480,37 @@ module Semverve
|
|
|
451
480
|
return
|
|
452
481
|
end
|
|
453
482
|
|
|
454
|
-
findings.each do |(label, finding)|
|
|
483
|
+
findings.each do |(_version_check, label, finding)|
|
|
455
484
|
puts "#{finding.path}:#{finding.line}:#{finding.column}: #{label} #{finding.version} -> #{current_version}"
|
|
456
485
|
end
|
|
486
|
+
if target_version == current_version && fix_task_name && exact_target_fix_noop_findings?(findings)
|
|
487
|
+
puts "Target version #{target_version} is already current; #{fix_task_name}[#{target_version}] will not change these references."
|
|
488
|
+
end
|
|
457
489
|
|
|
458
490
|
issue = findings.one? ? "issue" : "issues"
|
|
459
491
|
raise Error, "Found #{findings.count} version check #{issue}."
|
|
460
492
|
end
|
|
461
493
|
|
|
494
|
+
##
|
|
495
|
+
# Prints a no-op message for exact fix requests targeting the current version.
|
|
496
|
+
#
|
|
497
|
+
# @param [Semverve::SemanticVersion, nil] target_version
|
|
498
|
+
#
|
|
499
|
+
# @return [void]
|
|
500
|
+
def report_current_target_noop(target_version)
|
|
501
|
+
puts "Target version #{target_version} is already current; nothing to fix."
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
##
|
|
505
|
+
# Whether findings include surfaces controlled by exact-target fixes.
|
|
506
|
+
#
|
|
507
|
+
# @param [Array<Array(#exact_target_fix_noop_notice?, String, Object)>] findings
|
|
508
|
+
#
|
|
509
|
+
# @return [Boolean]
|
|
510
|
+
def exact_target_fix_noop_findings?(findings)
|
|
511
|
+
findings.any? { |(version_check, _label, _finding)| version_check.exact_target_fix_noop_notice? }
|
|
512
|
+
end
|
|
513
|
+
|
|
462
514
|
##
|
|
463
515
|
# Prints fix results.
|
|
464
516
|
#
|
|
@@ -468,7 +520,7 @@ module Semverve
|
|
|
468
520
|
# @return [void]
|
|
469
521
|
def report_fix_results(results, clean_message: "Version checks passed.")
|
|
470
522
|
replacement_count = results.sum { |(_label, result)| result.replacement_count }
|
|
471
|
-
bundle_lock_ran = results.any? { |(_label, result)| result.
|
|
523
|
+
bundle_lock_ran = results.any? { |(_label, result)| result.bundle_lock_ran }
|
|
472
524
|
|
|
473
525
|
if replacement_count.zero? && !bundle_lock_ran
|
|
474
526
|
puts clean_message
|