strong_versions 0.4.0 → 0.4.1

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: f73f7623edb5e3a662b18ea78cd67822dfdbcc81bd6eb0e9332e80bd1eda57c6
4
- data.tar.gz: 9ed40edc5e76826e6458848fadd2b92a5b9f0985cefa0a3e56943c176e32edbb
3
+ metadata.gz: 3a6f079070e66cd3ed6ce44e528fac54f1c3c8b0d997b4bf4c8a7d91a0eddeb8
4
+ data.tar.gz: 2e013a9ff3016707b445a77b18a42f9e84c3b0f8f2235f2f6216ecd6fab0309e
5
5
  SHA512:
6
- metadata.gz: 17fc0b16150395edf3d57daed7893803fd012311620285ad3a57df5330cfb28b1c1eebde904ece4484c5651c203dc27eeeb34f4699d79e6d443954020da23f81
7
- data.tar.gz: 67d7d4dd885f70cf4877e72180311545606abc33d8191039c95c9afdcc2d2ef8a081222ab4fa56207e23e7830fa9adda0269444c093d8983e4c227119f9fe82a
6
+ metadata.gz: c067dd53846c4b49e7104c11744569703b20c26b50c1de29a2fb7810889945939fe5d70f869f480d52851c28ac1c821541ace4e03c57e6fb09eb0ae15c9a0a05
7
+ data.tar.gz: 07f2665d5a01d9cc0686f7faf4990536a1151f630dbaeadbbb029a73f3dad5d956c255370938640b2e69aeda4db03845640da0a7bb9b883578cc6a19d4d96d27
data/README.md CHANGED
@@ -28,7 +28,7 @@ The benefit of applying this standard is that, if all gems follow [Semantic Vers
28
28
  Add the gem to your `Gemfile`
29
29
 
30
30
  ```ruby
31
- gem 'strong_versions', '~> 0.4.0'
31
+ gem 'strong_versions', '~> 0.4.1'
32
32
  ```
33
33
 
34
34
  And rebuild your bundle:
@@ -39,7 +39,7 @@ $ bundle install
39
39
 
40
40
  Or install yourself:
41
41
  ```bash
42
- $ gem install strong_versions -v '0.4.0'
42
+ $ gem install strong_versions -v '0.4.1'
43
43
  ```
44
44
 
45
45
  ## Usage
@@ -10,8 +10,8 @@ require 'strong_versions/dependency'
10
10
  require 'strong_versions/dependency_finder'
11
11
  require 'strong_versions/dependencies'
12
12
  require 'strong_versions/errors'
13
- require 'strong_versions/suggestion'
14
13
  require 'strong_versions/terminal'
14
+ require 'strong_versions/gem_version'
15
15
  require 'strong_versions/version'
16
16
 
17
17
  module StrongVersions
@@ -21,25 +21,25 @@ module StrongVersions
21
21
  @errors.empty?
22
22
  end
23
23
 
24
- def suggestion
25
- Suggestion.new(lockfile_version)
24
+ def suggested_version
25
+ GemVersion.new(GemVersion.new(lockfile_version).version_string)
26
26
  end
27
27
 
28
28
  def suggested_definition
29
29
  guards = guard_versions.map { |op, version| "'#{op} #{version}'" }
30
- "gem '#{@name}', #{[suggestion, *guards].join(', ')}"
30
+ "gem '#{@name}', #{[suggested_version.suggestion, *guards].join(', ')}"
31
31
  end
32
32
 
33
33
  def definition
34
34
  versions.map do |operator, version|
35
- next t('version_not_specified') if operator == '>=' && version == '0'
35
+ next t('version_not_specified') if operator == '>=' && version.zero?
36
36
 
37
37
  "'#{operator} #{version}'"
38
38
  end.join(', ')
39
39
  end
40
40
 
41
41
  def updatable?
42
- gemfile && !suggestion.missing? && !path_source?
42
+ gemfile && !suggested_version.missing? && !path_source?
43
43
  end
44
44
 
45
45
  private
@@ -54,13 +54,13 @@ module StrongVersions
54
54
 
55
55
  def parse_version(requirement)
56
56
  operator, version_obj = Gem::Requirement.parse(requirement)
57
- [operator, version(version_obj)]
57
+ [operator, GemVersion.new(version_obj)]
58
58
  end
59
59
 
60
60
  def lockfile_version
61
61
  @lockfile_version ||= begin
62
62
  gem_spec = @lockfile.specs.find { |spec| spec.name == @name }
63
- gem_spec.nil? ? nil : version(gem_spec.version)
63
+ gem_spec.nil? ? nil : gem_spec.version
64
64
  end
65
65
  end
66
66
 
@@ -68,14 +68,6 @@ module StrongVersions
68
68
  Bundler::LockfileParser.new(Bundler.read_file(Bundler.default_lockfile))
69
69
  end
70
70
 
71
- def version(version_obj)
72
- # Ruby >= 2.3.0: `version_obj` is a `Gem::Version`
73
- return version_obj.version if version_obj.respond_to?(:version)
74
-
75
- # Ruby < 2.3.0: `version_obj` is a `String`
76
- version_obj
77
- end
78
-
79
71
  def validate_version(operator, version)
80
72
  return if path_source?
81
73
  return if any_valid?
@@ -91,41 +83,34 @@ module StrongVersions
91
83
  end
92
84
 
93
85
  def check_valid_version(version)
94
- return if valid_version?(version)
86
+ return if version.valid?
95
87
 
96
- value = version == '0' ? t('version_not_specified') : version
88
+ value = version.zero? ? t('version_not_specified') : version
97
89
  @errors << { type: :version, value: value }
98
90
  end
99
91
 
100
92
  def redundant?(operator, version)
101
- return false unless operator.start_with?('>') || pessimistic?(operator)
93
+ return true if pessimistic?(operator)
94
+ return false if guard_needed?(operator, version)
102
95
 
103
- multiply_version(version) <= multiply_version(suggestion.version)
96
+ true
104
97
  end
105
98
 
106
- def multiply_version(version)
107
- # Support extremely precise versions e.g. '1.2.3.4.5.6.7.8.9'
108
- components = version.split('.').map(&:to_i)
109
- components += [0] * (10 - components.size)
110
- components.reverse.each_with_index.map do |component, index|
111
- component * 10.pow(index + 1)
112
- end.sum
99
+ def guard_needed?(operator, version)
100
+ return false unless %w[< <= > >=].include?(operator)
101
+ return true if %(< <=).include?(operator) && suggested_version < version
102
+ return true if %(> >=).include?(operator) && suggested_version < version
103
+
104
+ false
113
105
  end
114
106
 
115
107
  def pessimistic?(operator)
116
108
  operator == '~>'
117
109
  end
118
110
 
119
- def valid_version?(version)
120
- return true if version =~ /^[1-9][0-9]*\.\d+$/ # major.minor, e.g. "2.5"
121
- return true if version =~ /^0\.\d+\.\d+$/ # 0.minor.patch, e.g. "0.1.8"
122
-
123
- false
124
- end
125
-
126
111
  def any_valid?
127
112
  versions.any? do |operator, version|
128
- pessimistic?(operator) && valid_version?(version)
113
+ pessimistic?(operator) && version.valid?
129
114
  end
130
115
  end
131
116
 
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module StrongVersions
4
+ class GemVersion
5
+ def initialize(version)
6
+ @version = normalize(version) || ''
7
+ @parts = @version&.split('.')
8
+ end
9
+
10
+ def to_s
11
+ @version
12
+ end
13
+
14
+ def zero?
15
+ @version == '0'
16
+ end
17
+
18
+ def suggestion
19
+ return '' if version_string.empty?
20
+
21
+ "'~> #{version_string}'"
22
+ end
23
+
24
+ def version_string
25
+ return '' unless standard?
26
+
27
+ major, minor, patch = @parts
28
+ return "#{major}.#{minor}" if stable?
29
+ return "#{major}.#{minor}.#{patch}" if unstable?
30
+
31
+ raise 'Unexpected condition met'
32
+ end
33
+
34
+ def <(other)
35
+ numeric < other.numeric
36
+ end
37
+
38
+ def <=(other)
39
+ numeric <= other.numeric
40
+ end
41
+
42
+ def >(other)
43
+ numeric > other.numeric
44
+ end
45
+
46
+ def >=(other)
47
+ numeric >= other.numeric
48
+ end
49
+
50
+ def numeric
51
+ # Support extremely precise versions e.g. '1.2.3.4.5.6.7.8.9'
52
+ components = @version.split('.').map(&:to_i)
53
+ components += [0] * (10 - components.size)
54
+ components.reverse.each_with_index.map do |component, index|
55
+ component * 10.pow(index + 1)
56
+ end.sum
57
+ end
58
+
59
+ def valid?
60
+ return true if @version =~ /^[1-9][0-9]*\.\d+$/ # major.minor, e.g. "2.5"
61
+ return true if @version =~ /^0\.\d+\.\d+$/ # 0.minor.patch, e.g. "0.1.8"
62
+
63
+ false
64
+ end
65
+
66
+ def missing?
67
+ return false if stable?
68
+ return false if unstable?
69
+
70
+ true
71
+ end
72
+
73
+ private
74
+
75
+ def normalize(version)
76
+ # Ruby >= 2.3.0: `version_obj` is a `Gem::Version`
77
+ return version.version.to_s if version.respond_to?(:version)
78
+
79
+ # Ruby < 2.3.0: `version_obj` is a `String`
80
+ version
81
+ end
82
+
83
+ def unstable?
84
+ standard? && @parts.first.to_i.zero?
85
+ end
86
+
87
+ def stable?
88
+ standard? && @parts.first.to_i >= 1
89
+ end
90
+
91
+ def standard?(parts = @parts)
92
+ return false if parts.nil?
93
+ return false unless numeric?
94
+ return true if [2, 3, 4].include?(parts.size)
95
+ return true if parts.size == 3
96
+
97
+ false
98
+ end
99
+
100
+ def numeric?
101
+ @parts.all? { |part| part =~ /\A[0-9]+\Z/ }
102
+ end
103
+ end
104
+ end
@@ -77,10 +77,9 @@ module StrongVersions
77
77
  type = t("errors.#{error[:type]}")
78
78
  color(
79
79
  ' %{type} %{example}, found: %{found}',
80
- :default,
81
- type: [type, :default],
82
- example: example(error[:type]),
83
- found: [error[:value], :red]
80
+ :default, type: [type, :default],
81
+ example: example(error[:type]),
82
+ found: [error[:value], :red]
84
83
  )
85
84
  end
86
85
  end
@@ -92,10 +91,11 @@ module StrongVersions
92
91
  end
93
92
 
94
93
  def suggestion_definition(gem)
95
- unidentified = gem.suggestion.to_s.empty?
94
+ version = gem.suggested_version.suggestion
95
+ unidentified = version.empty?
96
96
  return [t('no-suggestion'), :yellow] if unidentified
97
97
 
98
- [gem.suggestion.to_s, :green]
98
+ [version, :green]
99
99
  end
100
100
 
101
101
  def name_and_definition(gem)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StrongVersions
4
- VERSION = '0.4.0'
4
+ VERSION = '0.4.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: strong_versions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bob Farrell
@@ -171,7 +171,7 @@ files:
171
171
  - lib/strong_versions/dependency.rb
172
172
  - lib/strong_versions/dependency_finder.rb
173
173
  - lib/strong_versions/errors.rb
174
- - lib/strong_versions/suggestion.rb
174
+ - lib/strong_versions/gem_version.rb
175
175
  - lib/strong_versions/terminal.rb
176
176
  - lib/strong_versions/version.rb
177
177
  - strong_versions.gemspec
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module StrongVersions
4
- class Suggestion
5
- def initialize(version)
6
- return if version.nil?
7
-
8
- @parts = version.split('.')
9
- # Treat '4.3.2.1' as '4.3.2'
10
- @parts.pop if standard?(@parts.first(3)) && @parts.size == 4
11
- end
12
-
13
- def to_s
14
- return version.to_s if version.nil?
15
-
16
- "'~> #{version}'"
17
- end
18
-
19
- def version
20
- return nil unless standard?
21
-
22
- major, minor, patch = @parts
23
- return "#{major}.#{minor}" if stable?
24
- return "#{major}.#{minor}.#{patch}" if unstable?
25
-
26
- raise 'Unexpected condition met'
27
- end
28
-
29
- def missing?
30
- return false if stable?
31
- return false if unstable?
32
-
33
- true
34
- end
35
-
36
- private
37
-
38
- def unstable?
39
- standard? && @parts.first.to_i.zero?
40
- end
41
-
42
- def stable?
43
- standard? && @parts.first.to_i >= 1
44
- end
45
-
46
- def standard?(parts = @parts)
47
- return false if parts.nil?
48
- return false unless numeric?
49
- return true if [2, 3].include?(parts.size)
50
- return true if parts.size == 3 && unstable?
51
-
52
- false
53
- end
54
-
55
- def numeric?
56
- @parts.all? { |part| part =~ /\A[0-9]+\Z/ }
57
- end
58
- end
59
- end