zypper-upgraderepo 1.8.0 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +79 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +50 -14
- data/README.md +7 -2
- data/Rakefile +7 -1
- data/lib/zypper/upgraderepo/cli.rb +85 -75
- data/lib/zypper/upgraderepo/os_release.rb +27 -29
- data/lib/zypper/upgraderepo/repository.rb +69 -71
- data/lib/zypper/upgraderepo/request.rb +16 -17
- data/lib/zypper/upgraderepo/requests/http.rb +52 -42
- data/lib/zypper/upgraderepo/requests/local.rb +28 -22
- data/lib/zypper/upgraderepo/traversable.rb +34 -32
- data/lib/zypper/upgraderepo/utils.rb +157 -44
- data/lib/zypper/upgraderepo/version.rb +3 -1
- data/lib/zypper/upgraderepo/view.rb +176 -159
- data/lib/zypper/upgraderepo.rb +32 -25
- data/zypper-upgraderepo.gemspec +25 -27
- metadata +10 -10
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "iniparse"
|
2
4
|
|
3
5
|
module Zypper
|
4
6
|
module Upgraderepo
|
5
|
-
|
6
|
-
|
7
|
+
#
|
8
|
+
# Handle the repository collection.
|
9
|
+
#
|
7
10
|
class RepositoryList
|
8
|
-
|
9
|
-
REPOSITORY_PATH = '/etc/zypp/repos.d'
|
11
|
+
REPOSITORY_PATH = "/etc/zypp/repos.d"
|
10
12
|
|
11
13
|
attr_reader :list, :max_col
|
12
14
|
|
@@ -18,19 +20,19 @@ module Zypper
|
|
18
20
|
@only_invalid = options.only_invalid
|
19
21
|
@only_protocols = options.only_protocols
|
20
22
|
@overrides = options.overrides
|
21
|
-
@upgrade_options = {alias: options.alias, name: options.name}
|
23
|
+
@upgrade_options = { alias: options.alias, name: options.name }
|
22
24
|
@list = []
|
23
|
-
@cpu_arch, @arch = `rpm --eval "%cpu_arch;%_arch"`.tr("\n",
|
25
|
+
@cpu_arch, @arch = `rpm --eval "%cpu_arch;%_arch"`.tr("\n", "").split(";")
|
24
26
|
|
25
|
-
Dir.glob(File.join(self.class::REPOSITORY_PATH,
|
27
|
+
Dir.glob(File.join(self.class::REPOSITORY_PATH, "*.repo")).each do |i|
|
26
28
|
r = Request.build(Repository.new(i), options.timeout)
|
27
29
|
@list << r
|
28
30
|
end
|
29
31
|
@max_col = @list.max_by { |r| r.name.length }.name.length
|
30
32
|
|
31
|
-
@list = @list.sort_by
|
33
|
+
@list = @list.sort_by(&:alias).map.with_index(1) { |r, i| { num: i, repo: r } }
|
32
34
|
|
33
|
-
@list.sort_by! { |x| x[:repo].send(options.
|
35
|
+
@list.sort_by! { |x| x[:repo].send(options.sorting_by) } if options.sorting_by != :alias
|
34
36
|
|
35
37
|
@only_repo = select_repos(@only_repo) unless @only_repo.nil?
|
36
38
|
|
@@ -58,7 +60,7 @@ module Zypper
|
|
58
60
|
next if only_repo && !only_repo.include?(x[:num])
|
59
61
|
next if only_enabled && !x[:repo].enabled?
|
60
62
|
next if only_invalid && x[:repo].available?
|
61
|
-
next if only_protocols &&
|
63
|
+
next if only_protocols && !only_protocols.include?(x[:repo].protocol)
|
62
64
|
|
63
65
|
yield x[:repo], x[:num] if block_given?
|
64
66
|
end
|
@@ -66,9 +68,7 @@ module Zypper
|
|
66
68
|
|
67
69
|
def resolve_variables!(version)
|
68
70
|
each_with_number do |r|
|
69
|
-
if r.url =~ /\$/
|
70
|
-
r.url = expand_variables(r.url, version)
|
71
|
-
end
|
71
|
+
r.url = expand_variables(r.url, version) if r.url =~ /\$/
|
72
72
|
r.name = expand_variables(r.name, version)
|
73
73
|
r.alias = expand_variables(r.alias, version)
|
74
74
|
end
|
@@ -82,36 +82,36 @@ module Zypper
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
|
-
|
86
85
|
private
|
87
86
|
|
88
87
|
def select_repos(repos)
|
89
88
|
res = []
|
90
89
|
repos.each do |r|
|
91
|
-
if r.to_i
|
90
|
+
if r.to_i.positive?
|
92
91
|
res.push r.to_i
|
93
92
|
elsif r =~ /^\ *@.*/
|
94
|
-
a = r.gsub(/@/,
|
95
|
-
@list.select { |x| x[:repo].alias.match?(Regexp.new(a,
|
93
|
+
a = r.gsub(/@/, "").strip
|
94
|
+
@list.select { |x| x[:repo].alias.match?(Regexp.new(a, "i")) }.each do |l|
|
96
95
|
res.push l[:num]
|
97
96
|
end
|
98
97
|
elsif r =~ /^\ *\#.*/
|
99
|
-
u = r.gsub(/\#/,
|
100
|
-
@list.select { |x| x[:repo].url.match?(Regexp.new(u,
|
98
|
+
u = r.gsub(/\#/, "").strip
|
99
|
+
@list.select { |x| x[:repo].url.match?(Regexp.new(u, "i")) }.each do |l|
|
101
100
|
res.push l[:num]
|
102
101
|
end
|
103
|
-
elsif r =~ /^\
|
104
|
-
s = r.gsub(
|
105
|
-
@list.select do |x|
|
106
|
-
x[:repo].alias.match?(Regexp.new(s,
|
107
|
-
|
108
|
-
|
109
|
-
end
|
102
|
+
elsif r =~ /^\ *&.*/
|
103
|
+
s = r.gsub(/&/, "").strip
|
104
|
+
sel = @list.select do |x|
|
105
|
+
x[:repo].alias.match?(Regexp.new(s, "i")) ||
|
106
|
+
x[:repo].name.match?(Regexp.new(s, "i")) ||
|
107
|
+
x[:repo].url.match?(Regexp.new(s, "i"))
|
108
|
+
end
|
109
|
+
sel.each do |l|
|
110
110
|
res.push l[:num]
|
111
111
|
end
|
112
112
|
else
|
113
113
|
n = r.strip
|
114
|
-
@list.select { |x| x[:repo].name.match?(Regexp.new(n,
|
114
|
+
@list.select { |x| x[:repo].name.match?(Regexp.new(n, "i")) }.each do |l|
|
115
115
|
res.push l[:num]
|
116
116
|
end
|
117
117
|
end
|
@@ -121,75 +121,78 @@ module Zypper
|
|
121
121
|
end
|
122
122
|
|
123
123
|
def expand_variables(str, version)
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
str.gsub(/\$releasever_major/, version.split(".")[0])
|
125
|
+
.gsub(/\$releasever_minor/, version.split(".")[1])
|
126
|
+
.gsub(/\$releasever/, version)
|
127
|
+
.gsub(/\$basearch/, @arch)
|
128
|
+
.gsub(/\$arch/, @cpu_arch)
|
129
129
|
end
|
130
130
|
|
131
131
|
def load_overrides(filename)
|
132
132
|
raise FileNotFound, filename unless File.exist?(filename)
|
133
|
+
|
133
134
|
ini = IniParse.parse(File.read(filename))
|
134
135
|
each_with_number(only_invalid: false) do |repo, num|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
136
|
+
next unless (x = ini["repository_#{num}"])
|
137
|
+
|
138
|
+
repo.enable!(x["enabled"])
|
139
|
+
raise UnmatchingOverrides, { num: num, ini: x, repo: repo } if repo.url != x["old_url"]
|
140
|
+
|
141
|
+
if only_enabled?
|
142
|
+
raise MissingOverride, { num: num, ini: x } unless x["url"] || x["enabled"] =~ /no|false|0/i
|
143
|
+
else
|
144
|
+
raise MissingOverride, { num: num, ini: x } unless x["url"]
|
144
145
|
end
|
146
|
+
@overrides[num] = x["url"] if x["url"]
|
145
147
|
end
|
146
148
|
end
|
147
|
-
|
148
149
|
end
|
149
150
|
|
150
|
-
|
151
|
+
#
|
152
|
+
# Single repository class.
|
153
|
+
#
|
151
154
|
class Repository
|
152
155
|
attr_reader :filename, :old_url, :old_alias, :old_name
|
153
156
|
|
154
157
|
def initialize(filename)
|
155
158
|
@filename = filename
|
156
159
|
@repo = IniParse.parse(File.read(filename))
|
157
|
-
@key =
|
160
|
+
@key = read_key
|
158
161
|
@old_url = nil
|
159
162
|
@old_name = nil
|
160
163
|
@old_alias = nil
|
161
164
|
end
|
162
165
|
|
163
166
|
def enabled?
|
164
|
-
@repo[@key][
|
167
|
+
@repo[@key]["enabled"].to_i == 1
|
165
168
|
end
|
166
169
|
|
167
|
-
def enable!(value =
|
168
|
-
@repo[@key][
|
170
|
+
def enable!(value = nil)
|
171
|
+
@repo[@key]["enabled"] = (value || true).to_s =~ /true|1|yes/i ? 1 : 0
|
169
172
|
end
|
170
173
|
|
171
174
|
def type
|
172
|
-
@repo[@key][
|
175
|
+
@repo[@key]["type"]
|
173
176
|
end
|
174
177
|
|
175
178
|
def name
|
176
|
-
@repo[@key][
|
179
|
+
@repo[@key]["name"] || @key
|
177
180
|
end
|
178
181
|
|
179
182
|
def name=(value)
|
180
|
-
@repo[@key][
|
183
|
+
@repo[@key]["name"] = value
|
181
184
|
end
|
182
185
|
|
183
186
|
def priority
|
184
|
-
@repo[@key][
|
187
|
+
@repo[@key]["priority"] || 99
|
185
188
|
end
|
186
189
|
|
187
190
|
def url
|
188
|
-
@repo[@key][
|
191
|
+
@repo[@key]["baseurl"]
|
189
192
|
end
|
190
193
|
|
191
194
|
def url=(value)
|
192
|
-
@repo[@key][
|
195
|
+
@repo[@key]["baseurl"] = value
|
193
196
|
end
|
194
197
|
|
195
198
|
def protocol
|
@@ -210,50 +213,45 @@ module Zypper
|
|
210
213
|
|
211
214
|
def alias=(value)
|
212
215
|
@repo = IniParse.parse(@repo.to_ini.sub(/\[[^\]]+\]/, "[#{value}]"))
|
213
|
-
@key =
|
216
|
+
@key = read_key
|
214
217
|
end
|
215
218
|
|
216
219
|
def upgrade!(version, args = {})
|
217
|
-
@old_url ||=
|
220
|
+
@old_url ||= url
|
218
221
|
@old_alias ||= self.alias
|
219
|
-
@old_name ||=
|
222
|
+
@old_name ||= name
|
220
223
|
|
221
|
-
|
222
|
-
self.url = args[:url_override]
|
223
|
-
else
|
224
|
-
self.url = self.url.gsub(/\d\d\.\d/, version)
|
225
|
-
end
|
224
|
+
self.url = (args[:url_override] || url.gsub(/\d\d\.\d/, version))
|
226
225
|
|
227
226
|
self.alias = self.alias.gsub(/\d\d\.\d/, version) if args[:alias]
|
228
|
-
self.name =
|
227
|
+
self.name = name.gsub(/\d\d\.\d/, version) if args[:name]
|
229
228
|
end
|
230
229
|
|
231
230
|
def upgraded?(item = :url)
|
232
|
-
|
231
|
+
!send("old_#{item}").nil? && (send("old_#{item}") != send(item))
|
233
232
|
end
|
234
233
|
|
235
234
|
def save
|
236
235
|
raise InvalidWritePermissions, @filename unless File.writable? @filename
|
236
|
+
|
237
237
|
process, pid = libzypp_process
|
238
238
|
raise SystemUpdateRunning, { pid: pid, process: process } if pid
|
239
|
+
|
239
240
|
@repo.save(@filename)
|
240
241
|
end
|
241
242
|
|
242
|
-
|
243
243
|
private
|
244
244
|
|
245
245
|
def libzypp_process
|
246
|
-
libpath = `ldd /usr/bin/zypper | grep "libzypp.so"`.split(
|
246
|
+
libpath = `ldd /usr/bin/zypper | grep "libzypp.so"`.split(" => ")[1].split.shift
|
247
247
|
process = `sudo lsof #{libpath} | tail -n 1`
|
248
|
-
process, pid = process.split
|
248
|
+
process, pid = process.split
|
249
249
|
[process, pid]
|
250
250
|
end
|
251
251
|
|
252
|
-
def
|
253
|
-
@repo.to_hash.keys.delete_if {|k| k ==
|
252
|
+
def read_key
|
253
|
+
@repo.to_hash.keys.delete_if { |k| k == "0" }.pop
|
254
254
|
end
|
255
255
|
end
|
256
|
-
|
257
|
-
|
258
256
|
end
|
259
257
|
end
|
@@ -1,27 +1,29 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
require_relative
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
require_relative "traversable"
|
5
|
+
require_relative "requests/local"
|
6
|
+
require_relative "requests/http"
|
5
7
|
|
6
8
|
module Zypper
|
7
9
|
module Upgraderepo
|
8
|
-
|
10
|
+
#
|
11
|
+
# Load the right class to handle the protool and
|
12
|
+
# achieve the request..
|
13
|
+
#
|
9
14
|
class Request
|
10
|
-
|
11
15
|
def self.build(repo, timeout)
|
12
|
-
@@registry ||=
|
16
|
+
@@registry ||= load_requests
|
13
17
|
|
14
18
|
raise InvalidProtocol, repo unless @@registry.include? repo.protocol
|
15
19
|
|
16
|
-
Object.const_get(
|
20
|
+
Object.const_get(find_class(repo)).new(repo, timeout)
|
17
21
|
end
|
18
22
|
|
19
23
|
def self.protocols
|
20
|
-
|
24
|
+
load_requests.keys
|
21
25
|
end
|
22
26
|
|
23
|
-
private
|
24
|
-
|
25
27
|
def self.load_requests
|
26
28
|
res = {}
|
27
29
|
Requests.constants.each do |klass|
|
@@ -38,13 +40,10 @@ module Zypper
|
|
38
40
|
def self.find_class(repo)
|
39
41
|
domain = URI(repo.url).hostname
|
40
42
|
|
41
|
-
if @@registry[repo.protocol].
|
42
|
-
|
43
|
-
|
44
|
-
return @@registry[repo.protocol]['default']
|
45
|
-
end
|
43
|
+
return @@registry[repo.protocol][domain] if @@registry[repo.protocol].key? domain
|
44
|
+
|
45
|
+
@@registry[repo.protocol]["default"]
|
46
46
|
end
|
47
47
|
end
|
48
|
-
|
49
48
|
end
|
50
49
|
end
|
@@ -1,14 +1,17 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
4
|
+
require "net/http"
|
3
5
|
|
4
6
|
module Zypper
|
5
7
|
module Upgraderepo
|
6
|
-
|
8
|
+
#
|
9
|
+
# Base class for a Web page request.
|
10
|
+
#
|
7
11
|
class PageRequest < SimpleDelegator
|
8
|
-
|
9
12
|
attr_reader :page
|
10
13
|
|
11
|
-
USER_AGENT =
|
14
|
+
USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0"
|
12
15
|
|
13
16
|
def initialize(obj, timeout = 60)
|
14
17
|
super obj
|
@@ -24,7 +27,7 @@ module Zypper
|
|
24
27
|
end
|
25
28
|
|
26
29
|
def redirected_to
|
27
|
-
ping[
|
30
|
+
ping["location"]
|
28
31
|
end
|
29
32
|
|
30
33
|
def not_found?
|
@@ -47,27 +50,25 @@ module Zypper
|
|
47
50
|
@page = nil
|
48
51
|
end
|
49
52
|
|
50
|
-
|
51
53
|
private
|
52
54
|
|
53
55
|
def get_request(uri, head)
|
56
|
+
request = if head
|
57
|
+
Net::HTTP::Head.new(uri.request_uri)
|
58
|
+
else
|
59
|
+
Net::HTTP::Get.new(uri.request_uri)
|
60
|
+
end
|
54
61
|
|
55
|
-
|
56
|
-
request = Net::HTTP::Head.new(uri.request_uri)
|
57
|
-
else
|
58
|
-
request = Net::HTTP::Get.new(uri.request_uri)
|
59
|
-
end
|
60
|
-
|
61
|
-
request['User-Agent'] = USER_AGENT
|
62
|
+
request["User-Agent"] = USER_AGENT
|
62
63
|
|
63
64
|
http = Net::HTTP.new(uri.host, uri.port)
|
64
|
-
http.use_ssl = (uri.scheme ==
|
65
|
+
http.use_ssl = (uri.scheme == "https")
|
65
66
|
http.open_timeout = @timeout
|
66
67
|
|
67
68
|
http.request(request)
|
68
69
|
end
|
69
70
|
|
70
|
-
def ping(uri = nil, head
|
71
|
+
def ping(uri = nil, head: true, cache: true)
|
71
72
|
begin
|
72
73
|
if @page.nil? || uri
|
73
74
|
if cache
|
@@ -79,69 +80,78 @@ module Zypper
|
|
79
80
|
rescue SocketError
|
80
81
|
raise NoConnection
|
81
82
|
rescue Net::OpenTimeout
|
82
|
-
@page = Net::HTTPRequestTimeOut.new(
|
83
|
+
@page = Net::HTTPRequestTimeOut.new("1.1", "", "")
|
83
84
|
end
|
84
85
|
cache ? @page : unpage
|
85
86
|
end
|
86
|
-
|
87
87
|
end
|
88
88
|
|
89
|
-
|
90
89
|
module Requests
|
91
|
-
|
90
|
+
#
|
91
|
+
# This is where the repository pages are scraped
|
92
|
+
# and analyzed to find newer versions.
|
93
|
+
#
|
92
94
|
class HttpRequest < PageRequest
|
93
|
-
|
94
95
|
include Traversable
|
95
96
|
|
96
|
-
def max_drop_back
|
97
|
+
def max_drop_back
|
98
|
+
0
|
99
|
+
end
|
97
100
|
|
98
|
-
def self.register_protocol
|
101
|
+
def self.register_protocol
|
102
|
+
%w[https http]
|
103
|
+
end
|
99
104
|
|
100
|
-
def self.domain
|
105
|
+
def self.domain
|
106
|
+
"default"
|
107
|
+
end
|
101
108
|
|
102
109
|
def evaluate_alternative(version)
|
103
110
|
if not_found?
|
104
|
-
|
111
|
+
traverse_url(URI(url), version)
|
105
112
|
elsif redirected?
|
106
|
-
|
113
|
+
{ url: redirected_to, message: "Redirected to:" }
|
107
114
|
end
|
108
115
|
end
|
109
116
|
|
110
|
-
|
111
117
|
private
|
112
118
|
|
113
119
|
def get_request(uri, head)
|
114
|
-
#super uri || URI(url), head
|
120
|
+
# super uri || URI(url), head
|
115
121
|
super uri || repodata_uri, head
|
116
122
|
end
|
117
123
|
|
118
|
-
def
|
119
|
-
ping(repodata_uri(uri), true, false).is_a?(Net::HTTPSuccess)
|
124
|
+
def repodata?(uri)
|
125
|
+
ping(repodata_uri(uri), head: true, cache: false).is_a?(Net::HTTPSuccess)
|
120
126
|
end
|
121
127
|
|
122
|
-
def subfolders(
|
123
|
-
ping.body.to_s.scan(Regexp.new('href=[\'\"][^\/\"]+\/[\'\"]')).delete_if do |x|
|
124
|
-
x =~
|
125
|
-
end
|
126
|
-
|
128
|
+
def subfolders(_uri)
|
129
|
+
subf = ping.body.to_s.scan(Regexp.new('href=[\'\"][^\/\"]+\/[\'\"]')).delete_if do |x|
|
130
|
+
x =~ %r{^/} || x =~ /^\.\./ || x =~ %r{://} || x =~ %r{href=["'](media\.1|boot|EFI)/["']}
|
131
|
+
end
|
132
|
+
subf.uniq.map do |d|
|
133
|
+
d.scan(/href=["']([^"]+)['"]/).pop.pop
|
127
134
|
end
|
128
135
|
end
|
129
136
|
end
|
130
137
|
|
138
|
+
#
|
139
|
+
# Custom scraping methods for the specific
|
140
|
+
# download.opensuse.org search engine.
|
141
|
+
#
|
131
142
|
class DownloadOpensuseOrgRequest < HttpRequest
|
132
|
-
|
133
|
-
|
143
|
+
def self.domain
|
144
|
+
"download.opensuse.org"
|
145
|
+
end
|
134
146
|
|
135
147
|
def subfolders(uri)
|
136
148
|
u = URI(uri.to_s)
|
137
149
|
u.path = "/download#{u.path}"
|
138
|
-
u.query =
|
139
|
-
require
|
140
|
-
JSON.parse(ping(u, false).body.to_s)["data"].map { |x| x["name"] }
|
150
|
+
u.query = "jsontable"
|
151
|
+
require "json"
|
152
|
+
JSON.parse(ping(u, head: false).body.to_s)["data"].map { |x| x["name"] }
|
141
153
|
end
|
142
154
|
end
|
143
|
-
|
144
155
|
end
|
145
|
-
|
146
156
|
end
|
147
157
|
end
|
@@ -1,14 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "delegate"
|
2
4
|
|
3
5
|
module Zypper
|
4
6
|
module Upgraderepo
|
5
|
-
|
6
|
-
|
7
|
+
#
|
8
|
+
# Base class for a local directory request.
|
9
|
+
#
|
7
10
|
class DirRequest < SimpleDelegator
|
8
|
-
|
9
11
|
attr_reader :dir_path
|
10
12
|
|
11
|
-
def initialize(obj,
|
13
|
+
def initialize(obj, _timeout)
|
12
14
|
super obj
|
13
15
|
end
|
14
16
|
|
@@ -44,53 +46,57 @@ module Zypper
|
|
44
46
|
@dir_path = nil
|
45
47
|
end
|
46
48
|
|
47
|
-
|
48
49
|
private
|
49
50
|
|
50
|
-
def ping(uri = nil, head
|
51
|
+
def ping(uri = nil, head: true)
|
51
52
|
@dir_path ||= URI(url).path
|
52
53
|
|
53
|
-
@dir_path = uri.to_s =~
|
54
|
+
@dir_path = uri.to_s =~ %r{^/} ? uri.to_s : URI(uri.to_s).path if uri
|
54
55
|
|
55
56
|
URI.unescape(@dir_path)
|
56
57
|
end
|
57
|
-
|
58
58
|
end
|
59
59
|
|
60
|
-
|
61
60
|
module Requests
|
62
|
-
|
61
|
+
#
|
62
|
+
# This is where the local repositories are
|
63
|
+
# analyzed to find newer versions.
|
64
|
+
#
|
63
65
|
class LocalRequest < DirRequest
|
64
|
-
|
65
66
|
include Traversable
|
66
67
|
|
67
|
-
def max_drop_back
|
68
|
+
def max_drop_back
|
69
|
+
1
|
70
|
+
end
|
68
71
|
|
69
|
-
def self.register_protocol
|
72
|
+
def self.register_protocol
|
73
|
+
["dir"]
|
74
|
+
end
|
70
75
|
|
71
|
-
def self.domain
|
76
|
+
def self.domain
|
77
|
+
"default"
|
78
|
+
end
|
72
79
|
|
73
80
|
def evaluate_alternative(version)
|
74
81
|
if not_found?
|
75
|
-
|
82
|
+
traverse_url(URI(url), version)
|
76
83
|
elsif redirected?
|
77
|
-
|
84
|
+
{ url: redirected_to, message: "Linked to" }
|
78
85
|
end
|
79
86
|
end
|
80
87
|
|
81
|
-
|
82
88
|
private
|
83
89
|
|
84
|
-
def
|
90
|
+
def repodata?(uri)
|
85
91
|
File.exist? URI.unescape(repodata_uri(uri).path)
|
86
92
|
end
|
87
93
|
|
88
94
|
def subfolders
|
89
|
-
Dir.glob(ping.gsub(
|
95
|
+
Dir.glob("#{ping.gsub(%r{/$}, "")}/*/").map do |x|
|
96
|
+
URI.escape(x.gsub(%r{/$}, "").gsub(ping, "").gsub(%r{^/}, ""))
|
97
|
+
end
|
90
98
|
end
|
91
99
|
end
|
92
|
-
|
93
100
|
end
|
94
|
-
|
95
101
|
end
|
96
102
|
end
|