travis_check_rubies 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.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZjA1NTQ3ZjAwMjE4YmI4MzBkZGE2MGMxOWZiZmY0MDZiNzA3YWNjZQ==
5
- data.tar.gz: !binary |-
6
- YzMyMGIwYzk2NzM4NzI3NjUxMGE0MmU0NmVkOTEzN2U3NmU4YzkwOQ==
2
+ SHA1:
3
+ metadata.gz: bfd262c7e986d7ca949f6811db98ef99f2aab55e
4
+ data.tar.gz: 65c395fa0c08ae67e8e0c35f526891091f02ab8d
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MTk2MDVjYTJmYjY0MDA2MzdiMDFjZTE3Nzc5NjI3MzA2ZWVkMzkwNjc2MzJj
10
- MTE3YmI3NjkxYzE2YjBlYzg5ZjFjYzQyZjVlZmJmYTViMGRiODUxNjg1MGRj
11
- YWQ4Mzk0YmFjNDgzMDZlMDAyOGUyZmZhNzEyMWQxMWYzMmY3OWU=
12
- data.tar.gz: !binary |-
13
- NWM2YzI5YTExMzdkZmEyM2Y4ZTdjOGY5NjBkZDk4Mzc0YzJhNGFhMjc5NzE1
14
- MmI4YTU2MTZjNGJmZDM5NDdhMWNiMGZmZGFjNTBjZjRhODQxOGVjNjI3YTNl
15
- NmVlNTEzMWQwMjBiNmY1MTIzMzk5NzJjNmViODhmMjdjNjdjOWY=
6
+ metadata.gz: 86c99d9aa7055c649b3611d29181429f25b4997c253504c4af5740973606f8838eeb466355d9cb961f07e1e79556d76ef6accb3bc2ad42abcd5767a2054a6b44
7
+ data.tar.gz: d71305cf683e36b261330a182b2c77de094e4f6be19b795aed62908091323abb8ad319b3dd37db1b09a9f0879f30d576787be107815fe6e0f9ffd50f2ba7a8f4
data/.travis.yml CHANGED
@@ -1,14 +1,20 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - '1.8.7-p371'
5
- - '1.9.3-p551'
6
4
  - '2.0.0-p648'
7
5
  - '2.1.10'
8
6
  - '2.2.6'
9
7
  - '2.3.3'
10
8
  - '2.4.0'
11
- - 'jruby-1.7.26'
12
9
  - 'jruby-9.0.5.0'
13
10
  - 'jruby-9.1.5.0'
14
- script: bundle exec travis_check_rubies
11
+ script:
12
+ - bundle exec rspec
13
+ - bundle exec travis_check_rubies
14
+ matrix:
15
+ allow_failures:
16
+ - rvm: 'jruby-9.0.5.0'
17
+ exclude:
18
+ - rvm: 'jruby-9.0.5.0'
19
+ include:
20
+ - rvm: 'jruby-9.0.5.0'
data/README.markdown CHANGED
@@ -29,7 +29,7 @@ Merge into your `.travis.yml`:
29
29
  matrix:
30
30
  include:
31
31
  - env: CHECK_RUBIES=✓
32
- rvm: '2'
32
+ rvm: '2.4.0'
33
33
  script: bundle exec travis_check_rubies
34
34
  ```
35
35
 
@@ -1,24 +1,36 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'travis_check_rubies/version'
3
+ require 'travis_check_rubies/travis_yml'
4
+ require 'optparse'
4
5
 
5
- matches = TravisCheckRubies::Version.matches
6
- if matches.values.any?
7
- ansi_red = `tput setaf 1 2>/dev/null`
8
- ansi_green = `tput setaf 2 2>/dev/null`
9
- ansi_reset = `tput sgr0 2>/dev/null`
10
- puts 'Suggested changes:'
11
- matches.each do |version, matched_versions|
12
- if !matched_versions || matched_versions.include?(version)
13
- puts " #{version}"
14
- else
15
- puts "#{ansi_red}-#{version}#{ansi_reset}"
16
- end
17
- if matched_versions
18
- (matched_versions - [version]).each do |matched_version|
19
- puts "#{ansi_green}+#{matched_version}#{ansi_reset}"
20
- end
21
- end
6
+ options = {}
7
+
8
+ op = OptionParser.new
9
+ op.on('--parts N|M..N', 'Match updates by how many parts (0..2 by default)') do |parts|
10
+ options[:parts] = case parts
11
+ when /\A\d+\z/
12
+ parts.to_i
13
+ when /\A(\d+)..(\d+)\z/
14
+ $1.to_i..$2.to_i
15
+ else
16
+ fail "Expected number N or range M..N, got #{parts}"
22
17
  end
23
- abort
24
18
  end
19
+ op.on('--[no-]allow-pre', 'Allow matching pre releases (false by default)') do |allow_pre|
20
+ options[:allow_pre] = allow_pre
21
+ end
22
+ op.on('--[no-]intermediary', 'Include all latest version distinct by maximum matchable '\
23
+ 'parts, like 2.3.X when current is 2.2.X and latest is 2.4.X (true by default)') do |intermediary|
24
+ options[:intermediary] = intermediary
25
+ end
26
+ op.on('--exclude V,V,V', Array, 'Exclude matching versions') do |exclude|
27
+ options[:exclude] = exclude
28
+ end
29
+ begin
30
+ op.parse!
31
+ rescue => e
32
+ abort "#{e}\n\n#{op.help}"
33
+ end
34
+
35
+ suggestions = TravisCheckRubies::TravisYml.new.suggestions(options)
36
+ abort suggestions if suggestions
@@ -0,0 +1,70 @@
1
+ require 'yaml'
2
+ require 'travis_check_rubies/version'
3
+
4
+ module TravisCheckRubies
5
+ class TravisYml
6
+ attr_reader :path
7
+ attr_reader :versions, :allow_failures_versions, :exclude_versions, :include_versions
8
+
9
+ def initialize(path = '.travis.yml')
10
+ @path = path
11
+
12
+ yaml = YAML.load_file(path)
13
+ @versions = Array(yaml['rvm']).map(&Version.method(:new))
14
+ @allow_failures_versions = matrix_versions(yaml, 'allow_failures')
15
+ @exclude_versions = matrix_versions(yaml, 'exclude')
16
+ @include_versions = matrix_versions(yaml, 'include')
17
+ end
18
+
19
+ def suggestions(options)
20
+ suggestions = Hash.new{ |h, k| h[k] = [] }
21
+
22
+ updates = Version.updates(versions, options)
23
+
24
+ versions.each do |version|
25
+ next unless (for_version = updates[version])
26
+ suggestions['rvm'] << "#{version} -> #{for_version.join(', ')}"
27
+ end
28
+
29
+ allow_failures_versions.each do |version|
30
+ next if versions.include?(version)
31
+ next if include_versions.include?(version)
32
+ suggestions['matrix.allow_failures'] << "#{version} in matrix.allow_failures is not in rvm or include list"
33
+ end
34
+
35
+ exclude_versions.each do |version|
36
+ next if versions.include?(version)
37
+ suggestions['matrix.exclude'] << "#{version} in matrix.exclude is not in rvm list"
38
+ end
39
+
40
+ {
41
+ 'matrix.allow_failures' => allow_failures_versions,
42
+ 'matrix.exclude' => exclude_versions,
43
+ }.each do |section, versions|
44
+ versions.each do |version|
45
+ next unless (for_version = updates[version])
46
+ suggestions[section] << "#{version} -> #{for_version.join(', ')}"
47
+ end
48
+ end
49
+
50
+ include_versions.each do |version|
51
+ next unless (for_version = Version.update(version, options))
52
+ next if for_version.include?(version)
53
+ suggestions['matrix.include'] << "#{version} -> #{for_version.join(', ')}"
54
+ end
55
+
56
+ return if suggestions.empty?
57
+ suggestions.map do |section, lines|
58
+ "#{section}:\n#{lines.map{ |line| " #{line}" }.join("\n")}"
59
+ end.join("\n")
60
+ end
61
+
62
+ private
63
+
64
+ def matrix_versions(yaml, key)
65
+ return [] unless (matrix = yaml['matrix'])
66
+ return [] unless (list = matrix[key])
67
+ Array(list).map{ |attrs| attrs['rvm'] }.compact.map(&Version.method(:new))
68
+ end
69
+ end
70
+ end
@@ -1,12 +1,17 @@
1
1
  require 'net/http'
2
+ require 'fspath'
2
3
  require 'set'
3
4
  require 'uri'
4
- require 'yaml'
5
5
 
6
6
  module TravisCheckRubies
7
7
  class Version
8
+ ROOT_URL = 'http://rubies.travis-ci.org/'
9
+ CACHE_TIME = 24 * 60 * 60
10
+
8
11
  class << self
9
- ROOT_URL = 'http://rubies.travis-ci.org/'
12
+ def convert(version_or_string)
13
+ version_or_string.is_a?(self) ? version_or_string : new(version_or_string)
14
+ end
10
15
 
11
16
  def available
12
17
  @available ||= begin
@@ -14,36 +19,81 @@ module TravisCheckRubies
14
19
  url.start_with?(base_url)
15
20
  end.map do |url|
16
21
  new(url[%r{([^/]+)\.tar\.(?:gz|bz2)$}, 1])
17
- end
22
+ end.sort
18
23
  end
19
24
  end
20
25
 
21
- def selected
22
- @selected ||= begin
23
- Array(YAML.load_file('.travis.yml')['rvm']).map do |string|
24
- new(string)
26
+ def update(version, parts: 0..2, allow_pre: false, intermediary: true, exclude: [])
27
+ version = convert(version)
28
+ return unless version.version_parts
29
+
30
+ parts = Array(parts)
31
+ exclude = exclude.map{ |ev| convert(ev) }
32
+ ordered = allow_pre ? available : available.partition(&:pre).inject(:+)
33
+ candidates = ordered.reverse.select do |v|
34
+ next unless v.version_parts
35
+ next unless v.match?(version, parts.min)
36
+ next unless v >= version
37
+ next if exclude.any?{ |ev| ev.match?(v, ev.version_parts.length) }
38
+ true
39
+ end
40
+
41
+ updates = if intermediary
42
+ candidates.group_by do |v|
43
+ v.version_parts.take(parts.max)
44
+ end.flat_map do |_, group|
45
+ parts.map do |n|
46
+ group.find{ |v| v.match?(version, n) }
47
+ end
48
+ end
49
+ else
50
+ parts.map do |n|
51
+ candidates.find{ |v| v.match?(version, n) }
25
52
  end
26
53
  end
54
+
55
+ updates.compact!
56
+ updates.uniq!
57
+ updates.sort!
58
+
59
+ updates unless [version] == updates
27
60
  end
28
61
 
29
- def matches
30
- matches = {}
31
- deduplicate = Set.new
32
- available_versioned = available.select(&:version_parts).sort.reverse
33
- selected.select(&:version_parts).sort.reverse.each do |version|
34
- matches[version] = (0..version.version_parts.length).map do |n|
35
- available_versioned.find{ |v| version.match?(v, n) }
36
- end.reverse.select{ |v| deduplicate.add?(v) }
62
+ def updates(versions, **options)
63
+ versions = versions.map{ |v| convert(v) }
64
+
65
+ updates = {}
66
+ has = Set.new
67
+ versions.uniq.sort.reverse_each do |version|
68
+ deduplicated = (update(version, options) || [version]).select{ |v| has.add?(v) }
69
+ updates[version] = [version] == deduplicated ? nil : deduplicated
37
70
  end
38
- Hash[selected.map do |v|
39
- [v, [v] == matches[v] ? nil : matches[v]]
40
- end]
71
+
72
+ Hash[versions.map{ |v| [v, updates[v]] }]
41
73
  end
42
74
 
43
75
  private
44
76
 
77
+ def cache_path
78
+ @cache_path ||= FSPath(ENV['XDG_CACHE_HOME'] || '~/.cache').expand_path / 'travis_check_rubies.txt'
79
+ end
80
+
45
81
  def index_urls
46
- @index_urls ||= Net::HTTP.get(URI(ROOT_URL + 'index.txt')).split("\n")
82
+ @index_urls ||= begin
83
+ if cache_path.size? && cache_path.mtime + CACHE_TIME > Time.now
84
+ cache_path.read
85
+ else
86
+ data = Net::HTTP.get(URI(ROOT_URL + 'index.txt'))
87
+
88
+ cache_path.dirname.mkpath
89
+ FSPath.temp_file('travis_check_rubies', cache_path.dirname) do |f|
90
+ f.write(data)
91
+ f.path.rename(cache_path)
92
+ end
93
+
94
+ data
95
+ end
96
+ end.split("\n")
47
97
  end
48
98
 
49
99
  def base_url
@@ -91,6 +141,10 @@ module TravisCheckRubies
91
141
  match_by(n) == other.match_by(n)
92
142
  end
93
143
 
144
+ def inspect
145
+ "#<#{self.class.name} #{str}>"
146
+ end
147
+
94
148
  protected
95
149
 
96
150
  def compare_by
@@ -103,7 +157,7 @@ module TravisCheckRubies
103
157
  end
104
158
 
105
159
  def match_by(n)
106
- [type, variant, version_parts.take(n)]
160
+ [type, variant, version_parts && version_parts.take(n)]
107
161
  end
108
162
  end
109
163
  end
@@ -0,0 +1,425 @@
1
+ require 'rspec'
2
+ require 'travis_check_rubies/version'
3
+
4
+ describe TravisCheckRubies::Version do
5
+ def v(str)
6
+ described_class.new(str)
7
+ end
8
+
9
+ def vs(strs)
10
+ strs.map{ |str| described_class.new(str) }
11
+ end
12
+
13
+ def cleanup_instance_variables(o)
14
+ o.instance_variables.each do |name|
15
+ o.remove_instance_variable(name)
16
+ end
17
+ end
18
+
19
+ describe 'parsing' do
20
+ {
21
+ '1.2.3-pre1' => {
22
+ version_parts: [1, 2, 3],
23
+ pre: 'pre1',
24
+ },
25
+ 'jruby' => {
26
+ type: 'jruby',
27
+ },
28
+ 'ruby-2.3.4.5-clang' => {
29
+ str: '2.3.4.5-clang',
30
+ version_parts: [2, 3, 4, 5],
31
+ variant: 'clang',
32
+ },
33
+ 'xrb-1000' => {
34
+ type: 'xrb',
35
+ version_parts: [1000],
36
+ },
37
+ '1.5' => {
38
+ version_parts: [1, 5],
39
+ },
40
+ '1.8.4-p616' => {
41
+ version_parts: [1, 8, 4, 616],
42
+ },
43
+ }.each do |version_string, defined_attributes|
44
+ context "of #{version_string}" do
45
+ subject{ v(version_string) }
46
+
47
+ let(:default_attributes) do
48
+ {
49
+ str: version_string,
50
+ type: 'ruby',
51
+ version_parts: nil,
52
+ pre: nil,
53
+ variant: nil,
54
+ }
55
+ end
56
+
57
+ it{ is_expected.to have_attributes(default_attributes.merge(defined_attributes)) }
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#eql?' do
63
+ it 'returns false for different version' do
64
+ expect(v('1.8')).not_to eql(v('1.9'))
65
+ end
66
+
67
+ it 'returns true for equal versions' do
68
+ expect(v('1.8')).to eql(v('1.8'))
69
+ end
70
+
71
+ it 'returns true for same version in different format' do
72
+ expect(v('1.8')).to eql(v('ruby-1.8'))
73
+ end
74
+
75
+ it 'returns true for same version string' do
76
+ expect(v('1.8')).to eql('1.8')
77
+ end
78
+ end
79
+
80
+ describe '#<=>' do
81
+ let(:versions) do
82
+ vs(%w[
83
+ jruby-head
84
+ jruby-1.7.7
85
+ jruby-1.7.26
86
+ jruby-9.0.0.0.pre1
87
+ jruby-9.0.0.0.pre2
88
+ jruby-9.0.0.0
89
+ ruby-1.8.7
90
+ ruby-1.8.7-p371
91
+ ruby-2.0.0-p645
92
+ ruby-2.0.0-p647
93
+ ruby-2.0.0-p647-clang
94
+ ])
95
+ end
96
+
97
+ it 'oders versions using all parts' do
98
+ expect(versions.reverse.sort).to eq(versions)
99
+ end
100
+ end
101
+
102
+ describe '#match?' do
103
+ subject{ v('ruby-1.7.7') }
104
+
105
+ context 'for same version' do
106
+ let(:version){ v('ruby-1.7.7') }
107
+
108
+ it 'matches with any number of parts' do
109
+ (0..4).each{ |n| is_expected.to be_match(version, n) }
110
+ end
111
+ end
112
+
113
+ context 'for different patch version' do
114
+ let(:version){ v('ruby-1.7.8') }
115
+
116
+ it 'matches with 0..2 parts' do
117
+ (0..2).each{ |n| is_expected.to be_match(version, n) }
118
+ end
119
+
120
+ it 'does not match with more parts' do
121
+ (3..4).each{ |n| is_expected.not_to be_match(version, n) }
122
+ end
123
+ end
124
+
125
+ context 'for different minor version' do
126
+ let(:version){ v('ruby-1.8.7') }
127
+
128
+ it 'matches with 0..1 parts' do
129
+ (0..1).each{ |n| is_expected.to be_match(version, n) }
130
+ end
131
+
132
+ it 'does not match with more parts' do
133
+ (2..4).each{ |n| is_expected.not_to be_match(version, n) }
134
+ end
135
+ end
136
+
137
+ context 'for different major version' do
138
+ let(:version){ v('ruby-2.7.7') }
139
+
140
+ it 'matches with 0 parts' do
141
+ is_expected.to be_match(version, 0)
142
+ end
143
+
144
+ it 'does not match with more parts' do
145
+ (1..4).each{ |n| is_expected.not_to be_match(version, n) }
146
+ end
147
+ end
148
+
149
+ context 'for version with additional part' do
150
+ let(:version){ v('ruby-1.7.7.1') }
151
+
152
+ it 'matches with 0..3 parts' do
153
+ (0..3).each{ |n| is_expected.to be_match(version, n) }
154
+ end
155
+
156
+ it 'does not match with more parts' do
157
+ is_expected.not_to be_match(version, 4)
158
+ end
159
+ end
160
+
161
+ context 'for pre release of same version' do
162
+ let(:version){ v('ruby-1.7.7-pre1') }
163
+
164
+ it 'matches with any number of parts' do
165
+ (0..4).each{ |n| is_expected.to be_match(version, n) }
166
+ end
167
+ end
168
+
169
+ context 'for different type of same version' do
170
+ let(:version){ v('jruby-1.7.7') }
171
+
172
+ it 'does not match' do
173
+ (0..4).each{ |n| is_expected.not_to be_match(version, n) }
174
+ end
175
+ end
176
+
177
+ context 'for different variant of same version' do
178
+ let(:version){ v('ruby-1.7.7-clang') }
179
+
180
+ it 'does not match' do
181
+ (0..4).each{ |n| is_expected.not_to be_match(version, n) }
182
+ end
183
+ end
184
+
185
+ context 'for version without version parts' do
186
+ let(:version){ v('ruby') }
187
+
188
+ it 'does not match' do
189
+ (0..4).each{ |n| is_expected.not_to be_match(version, n) }
190
+ end
191
+ end
192
+ end
193
+
194
+ describe '#inspect' do
195
+ {
196
+ '1.2.3-pre1' => '#<TravisCheckRubies::Version 1.2.3-pre1>',
197
+ 'jruby' => '#<TravisCheckRubies::Version jruby>',
198
+ }.each do |version_string, inspect|
199
+ context "for #{version_string}" do
200
+ it{ expect(v(version_string).inspect).to eq(inspect) }
201
+ end
202
+ end
203
+ end
204
+
205
+ describe '.index_urls' do
206
+ let(:cache_path){ FSPath.temp_file_path }
207
+
208
+ before do
209
+ cleanup_instance_variables(described_class)
210
+ allow(described_class).to receive(:cache_path).and_return(cache_path)
211
+ end
212
+
213
+ it 'returns urls from text index of rubies.travis-ci.org' do
214
+ allow(Net::HTTP).to receive(:get).with(URI('http://rubies.travis-ci.org/index.txt')).
215
+ and_return("one\ntwo\nthree")
216
+
217
+ expect(described_class.send(:index_urls)).to eq(%w[one two three])
218
+ end
219
+
220
+ it 'caches result' do
221
+ allow(Net::HTTP).to receive(:get).with(URI('http://rubies.travis-ci.org/index.txt')).
222
+ once.and_return("a\nb\nc")
223
+
224
+ 3.times{ expect(described_class.send(:index_urls)).to eq(%w[a b c]) }
225
+ end
226
+
227
+ it 'reads cache from file if it is new' do
228
+ allow(cache_path).to receive(:size?).and_return(616)
229
+ allow(cache_path).to receive(:mtime).and_return(Time.now - described_class::CACHE_TIME / 2)
230
+ allow(cache_path).to receive(:read).and_return("foo\nbar")
231
+
232
+ expect(Net::HTTP).not_to receive(:get)
233
+ expect(described_class.send(:index_urls)).to eq(%w[foo bar])
234
+ end
235
+
236
+ it 'writes cache file if it is stale' do
237
+ allow(cache_path).to receive(:size?).and_return(616)
238
+ allow(cache_path).to receive(:mtime).and_return(Time.now - described_class::CACHE_TIME * 2)
239
+ allow(Net::HTTP).to receive(:get).with(URI('http://rubies.travis-ci.org/index.txt')).
240
+ once.and_return("brave\nnew\nworld")
241
+
242
+ expect(described_class.send(:index_urls)).to eq(%w[brave new world])
243
+ expect(cache_path.read).to eq("brave\nnew\nworld")
244
+ end
245
+ end
246
+
247
+ describe '.base_url' do
248
+ before do
249
+ cleanup_instance_variables(described_class)
250
+ allow(ENV).to receive(:[]).with('TRAVIS').and_return(env_travis)
251
+ end
252
+
253
+ context 'when env variable TRAVIS is set' do
254
+ let(:env_travis){ 'true' }
255
+
256
+ it 'gets base_url from rvm debug' do
257
+ allow(described_class).to receive(:`).with('rvm debug').
258
+ and_return(%Q{ foo: "xxx" \n system: "XXX/YYY" \n bar: "yyy" })
259
+
260
+ expect(described_class.send(:base_url)).to eq('http://rubies.travis-ci.org/XXX/YYY/')
261
+ end
262
+ end
263
+
264
+ context 'when env variable TRAVIS is not set' do
265
+ let(:env_travis){ nil }
266
+
267
+ it 'gets base_url from first ubuntu url in index' do
268
+ allow(described_class).to receive(:index_urls).and_return(%w[
269
+ http://rubies.travis-ci.org/osx/AAA/1.tar.gz
270
+ http://rubies.travis-ci.org/ubuntu/ZZZ/2.tar.gz
271
+ http://rubies.travis-ci.org/ubuntu/BBB/3.tar.gz
272
+ ])
273
+
274
+ expect(described_class.send(:base_url)).to eq('http://rubies.travis-ci.org/ubuntu/BBB/')
275
+ end
276
+ end
277
+ end
278
+
279
+ describe '.available' do
280
+ before do
281
+ cleanup_instance_variables(described_class)
282
+ end
283
+
284
+ it 'gets sorted versions from index urls matching base_url' do
285
+ allow(described_class).to receive(:index_urls).and_return(%w[
286
+ http://rubies.travis-ci.org/osx/AAA/1.tar.gz
287
+ http://rubies.travis-ci.org/ubuntu/ZZZ/2.tar.gz
288
+ http://rubies.travis-ci.org/ubuntu/BBB/4.tar.gz
289
+ http://rubies.travis-ci.org/ubuntu/BBB/3.tar.bz2
290
+ ])
291
+ allow(described_class).to receive(:base_url).and_return('http://rubies.travis-ci.org/ubuntu/BBB/')
292
+
293
+ expect(described_class.available).to eq([v('3'), v('4')])
294
+ end
295
+
296
+ it 'caches result' do
297
+ allow(described_class).to receive(:index_urls).once.and_return(%w[
298
+ http://rubies.travis-ci.org/ubuntu/CCC/a.tar.gz
299
+ http://rubies.travis-ci.org/ubuntu/CCC/b.tar.bz2
300
+ ])
301
+ allow(described_class).to receive(:base_url).and_return('http://rubies.travis-ci.org/ubuntu/CCC/')
302
+
303
+ 3.times{ expect(described_class.available).to eq([v('a'), v('b')]) }
304
+ end
305
+ end
306
+
307
+ describe '.update' do
308
+ before do
309
+ allow(described_class).to receive(:available).and_return(vs(available_strs).sort)
310
+ end
311
+
312
+ context 'for version without version parts' do
313
+ let(:available_strs){ %w[ruby 1.2.3 2.3.4] }
314
+
315
+ it{ expect(described_class.update(v('ruby'))).to eq nil }
316
+ end
317
+
318
+ context 'when there are no updates' do
319
+ let(:available_strs){ %w[ruby 1.2.3 2.3.4] }
320
+
321
+ it{ expect(described_class.update(v('2.3.4'))).to eq nil }
322
+ end
323
+
324
+ context 'when version is not present' do
325
+ let(:available_strs){ %w[ruby 1.2.3 2.3.4] }
326
+
327
+ it{ expect(described_class.update(v('3.4.5'))).to eq [] }
328
+ end
329
+
330
+ describe 'parts and intermediary' do
331
+ let(:version){ v('1.7.1') }
332
+
333
+ let(:available_strs){ %w[
334
+ 1.7.1 1.7.2 1.8.6 1.8.7 1.9.2 1.9.3
335
+ 2.0.8 2.0.9 2.1.6 2.1.7 2.2.4 2.2.5
336
+ 3.0.4 3.0.5 3.1.2 3.1.3 3.2.0 3.2.1
337
+ ] }
338
+
339
+ context 'when intermediary is true' do
340
+ it 'returns all latest with distinct 0..2 (by default) matching version parts' do
341
+ expect(described_class.update(version)).to eq vs(%w[1.7.2 1.8.7 1.9.3 2.0.9 2.1.7 2.2.5 3.0.5 3.1.3 3.2.1])
342
+ end
343
+
344
+ {
345
+ 0 => %w[3.2.1],
346
+ 0..1 => %w[1.9.3 2.2.5 3.2.1],
347
+ 0..2 => %w[1.7.2 1.8.7 1.9.3 2.0.9 2.1.7 2.2.5 3.0.5 3.1.3 3.2.1],
348
+ 1..2 => %w[1.7.2 1.8.7 1.9.3],
349
+ 2 => %w[1.7.2],
350
+ }.each do |parts, expected|
351
+ it "returns all latest with distinct #{parts} matching version parts" do
352
+ expect(described_class.update(version, parts: parts)).to eq vs(expected)
353
+ end
354
+ end
355
+ end
356
+
357
+ context 'when intermediary is false' do
358
+ it 'returns latest for each 0..2 (by default) matching version parts' do
359
+ expect(described_class.update(version, intermediary: false)).to eq vs(%w[1.7.2 1.9.3 3.2.1])
360
+ end
361
+
362
+ {
363
+ 0 => %w[3.2.1],
364
+ 0..1 => %w[1.9.3 3.2.1],
365
+ 0..2 => %w[1.7.2 1.9.3 3.2.1],
366
+ 1..2 => %w[1.7.2 1.9.3],
367
+ 2 => %w[1.7.2],
368
+ }.each do |parts, expected|
369
+ it "returns latest for each #{parts} matching version parts" do
370
+ expect(described_class.update(version, parts: parts, intermediary: false)).to eq vs(expected)
371
+ end
372
+ end
373
+ end
374
+ end
375
+
376
+ describe 'pre releases' do
377
+ let(:available_strs){ %w[2.4.0-pre 2.4.0 2.4.1 2.4.2-pre1 2.4.2-pre2] }
378
+
379
+ context 'when for pre release there is only newer pre release' do
380
+ it 'returns next pre release' do
381
+ expect(described_class.update(v('2.4.2-pre1'))).to eq [v('2.4.2-pre2')]
382
+ end
383
+ end
384
+
385
+ context 'when there is a newer release and even newer pre release' do
386
+ context 'for release' do
387
+ it 'returns newer release when allow_pre is false' do
388
+ expect(described_class.update(v('2.4.0'))).to eq [v('2.4.1')]
389
+ end
390
+
391
+ it 'returns even newer pre release when allow_pre is true' do
392
+ expect(described_class.update(v('2.4.0'), allow_pre: true)).to eq [v('2.4.2-pre2')]
393
+ end
394
+ end
395
+
396
+ context 'for pre release' do
397
+ it 'returns release when allow_pre is false' do
398
+ expect(described_class.update(v('2.4.0-pre'))).to eq [v('2.4.1')]
399
+ end
400
+
401
+ it 'returns even newer pre release when allow_pre is true' do
402
+ expect(described_class.update(v('2.4.0-pre'), allow_pre: true)).to eq [v('2.4.2-pre2')]
403
+ end
404
+ end
405
+ end
406
+ end
407
+ end
408
+
409
+ describe '.updates' do
410
+ before do
411
+ allow(described_class).to receive(:available).
412
+ and_return(vs(%w[1.8.7 1.9.3 2.0.9 2.1.7]).sort)
413
+ end
414
+
415
+ it 'returns a hash with updates for higher versions removed from updates for lower versions' do
416
+ expect(described_class.updates(vs(%w[2.0.8 2.1.7 1.8.6 1.9.3])).to_a).
417
+ to eq({
418
+ v('2.0.8') => vs(%w[2.0.9]),
419
+ v('2.1.7') => nil,
420
+ v('1.8.6') => vs(%w[1.8.7]),
421
+ v('1.9.3') => nil,
422
+ }.to_a)
423
+ end
424
+ end
425
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'travis_check_rubies'
5
- s.version = '0.1.0'
5
+ s.version = '0.2.0'
6
6
  s.summary = 'Are you using the latest rubies in .travis.yml?'
7
7
  s.description = 'Check if `.travis.yml` specifies latest available rubies from listed on http://rubies.travis-ci.org and propose changes'
8
8
  s.homepage = "http://github.com/toy/#{s.name}"
@@ -13,4 +13,10 @@ Gem::Specification.new do |s|
13
13
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
14
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
15
  s.require_paths = %w[lib]
16
+
17
+ s.required_ruby_version = '>= 2.0.0'
18
+
19
+ s.add_runtime_dependency 'fspath', '~> 3.0'
20
+
21
+ s.add_development_dependency 'rspec', '~> 3.0'
16
22
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: travis_check_rubies
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ivan Kuchin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-22 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2017-03-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fspath
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
13
41
  description: Check if `.travis.yml` specifies latest available rubies from listed
14
42
  on http://rubies.travis-ci.org and propose changes
15
43
  email:
@@ -18,14 +46,16 @@ executables:
18
46
  extensions: []
19
47
  extra_rdoc_files: []
20
48
  files:
21
- - .gitignore
22
- - .travis.yml
49
+ - ".gitignore"
50
+ - ".travis.yml"
23
51
  - Gemfile
24
52
  - LICENSE.txt
25
53
  - README.markdown
26
54
  - bin/travis_check_rubies
27
55
  - lib/travis_check_rubies.rb
56
+ - lib/travis_check_rubies/travis_yml.rb
28
57
  - lib/travis_check_rubies/version.rb
58
+ - spec/travis_check_rubies/version_spec.rb
29
59
  - travis_check_rubies.gemspec
30
60
  homepage: http://github.com/toy/travis_check_rubies
31
61
  licenses:
@@ -37,19 +67,19 @@ require_paths:
37
67
  - lib
38
68
  required_ruby_version: !ruby/object:Gem::Requirement
39
69
  requirements:
40
- - - ! '>='
70
+ - - ">="
41
71
  - !ruby/object:Gem::Version
42
- version: '0'
72
+ version: 2.0.0
43
73
  required_rubygems_version: !ruby/object:Gem::Requirement
44
74
  requirements:
45
- - - ! '>='
75
+ - - ">="
46
76
  - !ruby/object:Gem::Version
47
77
  version: '0'
48
78
  requirements: []
49
79
  rubyforge_project:
50
- rubygems_version: 2.6.4
80
+ rubygems_version: 2.6.10
51
81
  signing_key:
52
82
  specification_version: 4
53
83
  summary: Are you using the latest rubies in .travis.yml?
54
- test_files: []
55
- has_rdoc:
84
+ test_files:
85
+ - spec/travis_check_rubies/version_spec.rb