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 +5 -13
- data/.travis.yml +10 -4
- data/README.markdown +1 -1
- data/bin/travis_check_rubies +31 -19
- data/lib/travis_check_rubies/travis_yml.rb +70 -0
- data/lib/travis_check_rubies/version.rb +74 -20
- data/spec/travis_check_rubies/version_spec.rb +425 -0
- data/travis_check_rubies.gemspec +7 -1
- metadata +41 -11
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
YzMyMGIwYzk2NzM4NzI3NjUxMGE0MmU0NmVkOTEzN2U3NmU4YzkwOQ==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bfd262c7e986d7ca949f6811db98ef99f2aab55e
|
4
|
+
data.tar.gz: 65c395fa0c08ae67e8e0c35f526891091f02ab8d
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
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:
|
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
data/bin/travis_check_rubies
CHANGED
@@ -1,24 +1,36 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
require 'travis_check_rubies/
|
3
|
+
require 'travis_check_rubies/travis_yml'
|
4
|
+
require 'optparse'
|
4
5
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
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
|
-
|
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
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
39
|
-
|
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 ||=
|
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
|
data/travis_check_rubies.gemspec
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'travis_check_rubies'
|
5
|
-
s.version = '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.
|
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-
|
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:
|
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.
|
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
|
-
|
84
|
+
test_files:
|
85
|
+
- spec/travis_check_rubies/version_spec.rb
|