zypper-upgraderepo 1.8.1 → 1.10.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 +80 -0
- data/Gemfile +13 -1
- data/Gemfile.lock +50 -14
- data/README.md +5 -0
- data/Rakefile +7 -1
- data/lib/zypper/upgraderepo/cli.rb +93 -75
- data/lib/zypper/upgraderepo/os_release.rb +27 -29
- data/lib/zypper/upgraderepo/repository.rb +106 -84
- 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 +161 -44
- data/lib/zypper/upgraderepo/version.rb +3 -1
- data/lib/zypper/upgraderepo/view.rb +269 -154
- data/lib/zypper/upgraderepo.rb +73 -26
- data/zypper-upgraderepo.gemspec +25 -27
- metadata +10 -10
@@ -1,16 +1,51 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "iniparse"
|
2
4
|
|
3
5
|
module Zypper
|
4
6
|
module Upgraderepo
|
7
|
+
#
|
8
|
+
# Calculate and apply the variables that can be
|
9
|
+
# declared within the repository metadata.
|
10
|
+
#
|
11
|
+
class RepositoryVariables
|
12
|
+
VARIABLE_PATH = "/etc/zypp/vars.d"
|
13
|
+
|
14
|
+
VAR_CPU_ARCH, VAR_ARCH = `rpm --eval "%cpu_arch;%_arch"`.tr("\n", "").split(";")
|
15
|
+
|
16
|
+
attr_reader :variables
|
17
|
+
|
18
|
+
def initialize(version)
|
19
|
+
@variables = {
|
20
|
+
releasever_major: version.split(".")[0],
|
21
|
+
releasever_minor: version.split(".")[1],
|
22
|
+
releasever: version,
|
23
|
+
basearch: VAR_ARCH,
|
24
|
+
arch: VAR_CPU_ARCH
|
25
|
+
}
|
26
|
+
|
27
|
+
Dir.glob(File.join(self.class::VARIABLE_PATH, "*")).each do |i|
|
28
|
+
@variables[File.basename(i).to_sym] = File.read(i).strip
|
29
|
+
end
|
30
|
+
end
|
5
31
|
|
32
|
+
def apply(str)
|
33
|
+
str.gsub(/\${?([a-zA-Z0-9_]+)}?/) do
|
34
|
+
last = Regexp.last_match(1)
|
35
|
+
@variables[last.to_sym] || "<Unknown var: $#{last}>"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
6
39
|
|
40
|
+
#
|
41
|
+
# Handle the repository collection.
|
42
|
+
#
|
7
43
|
class RepositoryList
|
8
|
-
|
9
|
-
REPOSITORY_PATH = '/etc/zypp/repos.d'
|
44
|
+
REPOSITORY_PATH = "/etc/zypp/repos.d"
|
10
45
|
|
11
46
|
attr_reader :list, :max_col
|
12
47
|
|
13
|
-
def initialize(options)
|
48
|
+
def initialize(options, variables)
|
14
49
|
@alias = options.alias
|
15
50
|
@name = options.name
|
16
51
|
@only_repo = options.only_repo
|
@@ -18,19 +53,19 @@ module Zypper
|
|
18
53
|
@only_invalid = options.only_invalid
|
19
54
|
@only_protocols = options.only_protocols
|
20
55
|
@overrides = options.overrides
|
21
|
-
@upgrade_options = {alias: options.alias, name: options.name}
|
56
|
+
@upgrade_options = { alias: options.alias, name: options.name }
|
22
57
|
@list = []
|
23
|
-
@cpu_arch, @arch = `rpm --eval "%cpu_arch;%_arch"`.tr("\n", '').split(';')
|
24
58
|
|
25
|
-
|
26
|
-
|
59
|
+
@variables = variables
|
60
|
+
Dir.glob(File.join(self.class::REPOSITORY_PATH, "*.repo")).each do |i|
|
61
|
+
r = Request.build(Repository.new(i, @variables), options.timeout)
|
27
62
|
@list << r
|
28
63
|
end
|
29
64
|
@max_col = @list.max_by { |r| r.name.length }.name.length
|
30
65
|
|
31
|
-
@list = @list.sort_by
|
66
|
+
@list = @list.sort_by(&:alias).map.with_index(1) { |r, i| { num: i, repo: r } }
|
32
67
|
|
33
|
-
@list.sort_by! { |x| x[:repo].send(options.
|
68
|
+
@list.sort_by! { |x| x[:repo].send(options.sorting_by) } if options.sorting_by != :alias
|
34
69
|
|
35
70
|
@only_repo = select_repos(@only_repo) unless @only_repo.nil?
|
36
71
|
|
@@ -58,60 +93,48 @@ module Zypper
|
|
58
93
|
next if only_repo && !only_repo.include?(x[:num])
|
59
94
|
next if only_enabled && !x[:repo].enabled?
|
60
95
|
next if only_invalid && x[:repo].available?
|
61
|
-
next if only_protocols &&
|
96
|
+
next if only_protocols && !only_protocols.include?(x[:repo].protocol)
|
62
97
|
|
63
98
|
yield x[:repo], x[:num] if block_given?
|
64
99
|
end
|
65
100
|
end
|
66
101
|
|
67
|
-
def resolve_variables!(version)
|
68
|
-
each_with_number do |r|
|
69
|
-
if r.url =~ /\$/
|
70
|
-
r.url = expand_variables(r.url, version)
|
71
|
-
end
|
72
|
-
r.name = expand_variables(r.name, version)
|
73
|
-
r.alias = expand_variables(r.alias, version)
|
74
|
-
end
|
75
|
-
|
76
|
-
self
|
77
|
-
end
|
78
|
-
|
79
102
|
def save
|
80
103
|
@list.each do |i|
|
81
104
|
i[:repo].save
|
82
105
|
end
|
83
106
|
end
|
84
107
|
|
85
|
-
|
86
108
|
private
|
87
109
|
|
88
110
|
def select_repos(repos)
|
89
111
|
res = []
|
90
112
|
repos.each do |r|
|
91
|
-
if r.to_i
|
113
|
+
if r.to_i.positive?
|
92
114
|
res.push r.to_i
|
93
115
|
elsif r =~ /^\ *@.*/
|
94
|
-
a = r.gsub(/@/,
|
95
|
-
@list.select { |x| x[:repo].alias.match?(Regexp.new(a,
|
116
|
+
a = r.gsub(/@/, "").strip
|
117
|
+
@list.select { |x| x[:repo].alias.match?(Regexp.new(a, "i")) }.each do |l|
|
96
118
|
res.push l[:num]
|
97
119
|
end
|
98
120
|
elsif r =~ /^\ *\#.*/
|
99
|
-
u = r.gsub(/\#/,
|
100
|
-
@list.select { |x| x[:repo].url.match?(Regexp.new(u,
|
121
|
+
u = r.gsub(/\#/, "").strip
|
122
|
+
@list.select { |x| x[:repo].url.match?(Regexp.new(u, "i")) }.each do |l|
|
101
123
|
res.push l[:num]
|
102
124
|
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
|
125
|
+
elsif r =~ /^\ *&.*/
|
126
|
+
s = r.gsub(/&/, "").strip
|
127
|
+
sel = @list.select do |x|
|
128
|
+
x[:repo].alias.match?(Regexp.new(s, "i")) ||
|
129
|
+
x[:repo].name.match?(Regexp.new(s, "i")) ||
|
130
|
+
x[:repo].url.match?(Regexp.new(s, "i"))
|
131
|
+
end
|
132
|
+
sel.each do |l|
|
110
133
|
res.push l[:num]
|
111
134
|
end
|
112
135
|
else
|
113
136
|
n = r.strip
|
114
|
-
@list.select { |x| x[:repo].name.match?(Regexp.new(n,
|
137
|
+
@list.select { |x| x[:repo].name.match?(Regexp.new(n, "i")) }.each do |l|
|
115
138
|
res.push l[:num]
|
116
139
|
end
|
117
140
|
end
|
@@ -120,76 +143,72 @@ module Zypper
|
|
120
143
|
res.uniq
|
121
144
|
end
|
122
145
|
|
123
|
-
def expand_variables(str, version)
|
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
|
-
end
|
130
|
-
|
131
146
|
def load_overrides(filename)
|
132
147
|
raise FileNotFound, filename unless File.exist?(filename)
|
148
|
+
|
133
149
|
ini = IniParse.parse(File.read(filename))
|
134
150
|
each_with_number(only_invalid: false) do |repo, num|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
151
|
+
next unless (x = ini["repository_#{num}"])
|
152
|
+
|
153
|
+
repo.enable!(x["enabled"])
|
154
|
+
raise UnmatchingOverrides, { num: num, ini: x, repo: repo } if repo.url != x["old_url"]
|
155
|
+
|
156
|
+
if only_enabled?
|
157
|
+
raise MissingOverride, { num: num, ini: x } unless x["url"] || x["enabled"] =~ /no|false|0/i
|
158
|
+
else
|
159
|
+
raise MissingOverride, { num: num, ini: x } unless x["url"]
|
144
160
|
end
|
161
|
+
@overrides[num] = x["url"] if x["url"]
|
145
162
|
end
|
146
163
|
end
|
147
|
-
|
148
164
|
end
|
149
165
|
|
150
|
-
|
166
|
+
#
|
167
|
+
# Single repository class.
|
168
|
+
#
|
151
169
|
class Repository
|
152
170
|
attr_reader :filename, :old_url, :old_alias, :old_name
|
153
171
|
|
154
|
-
def initialize(filename)
|
172
|
+
def initialize(filename, variables)
|
155
173
|
@filename = filename
|
156
174
|
@repo = IniParse.parse(File.read(filename))
|
157
|
-
@key =
|
175
|
+
@key = read_key
|
158
176
|
@old_url = nil
|
159
177
|
@old_name = nil
|
160
178
|
@old_alias = nil
|
179
|
+
resolve_variables!(variables)
|
161
180
|
end
|
162
181
|
|
163
182
|
def enabled?
|
164
|
-
@repo[@key][
|
183
|
+
@repo[@key]["enabled"].to_i == 1
|
165
184
|
end
|
166
185
|
|
167
|
-
def enable!(value =
|
168
|
-
@repo[@key][
|
186
|
+
def enable!(value = nil)
|
187
|
+
@repo[@key]["enabled"] = (value || true).to_s =~ /true|1|yes/i ? 1 : 0
|
169
188
|
end
|
170
189
|
|
171
190
|
def type
|
172
|
-
@repo[@key][
|
191
|
+
@repo[@key]["type"]
|
173
192
|
end
|
174
193
|
|
175
194
|
def name
|
176
|
-
@repo[@key][
|
195
|
+
@repo[@key]["name"] || @key
|
177
196
|
end
|
178
197
|
|
179
198
|
def name=(value)
|
180
|
-
@repo[@key][
|
199
|
+
@repo[@key]["name"] = value
|
181
200
|
end
|
182
201
|
|
183
202
|
def priority
|
184
|
-
@repo[@key][
|
203
|
+
@repo[@key]["priority"] || 99
|
185
204
|
end
|
186
205
|
|
187
206
|
def url
|
188
|
-
@repo[@key][
|
207
|
+
@repo[@key]["baseurl"]
|
189
208
|
end
|
190
209
|
|
191
210
|
def url=(value)
|
192
|
-
@repo[@key][
|
211
|
+
@repo[@key]["baseurl"] = value
|
193
212
|
end
|
194
213
|
|
195
214
|
def protocol
|
@@ -210,50 +229,53 @@ module Zypper
|
|
210
229
|
|
211
230
|
def alias=(value)
|
212
231
|
@repo = IniParse.parse(@repo.to_ini.sub(/\[[^\]]+\]/, "[#{value}]"))
|
213
|
-
@key =
|
232
|
+
@key = read_key
|
214
233
|
end
|
215
234
|
|
216
235
|
def upgrade!(version, args = {})
|
217
|
-
@old_url ||=
|
236
|
+
@old_url ||= url
|
218
237
|
@old_alias ||= self.alias
|
219
|
-
@old_name ||=
|
238
|
+
@old_name ||= name
|
220
239
|
|
221
|
-
|
222
|
-
self.url = args[:url_override]
|
223
|
-
else
|
224
|
-
self.url = self.url.gsub(/\d\d\.\d/, version)
|
225
|
-
end
|
240
|
+
self.url = (args[:url_override] || url.gsub(/\d\d\.\d/, version))
|
226
241
|
|
227
242
|
self.alias = self.alias.gsub(/\d\d\.\d/, version) if args[:alias]
|
228
|
-
self.name =
|
243
|
+
self.name = name.gsub(/\d\d\.\d/, version) if args[:name]
|
229
244
|
end
|
230
245
|
|
231
246
|
def upgraded?(item = :url)
|
232
|
-
|
247
|
+
!send("old_#{item}").nil? && (send("old_#{item}") != send(item))
|
233
248
|
end
|
234
249
|
|
235
250
|
def save
|
236
251
|
raise InvalidWritePermissions, @filename unless File.writable? @filename
|
252
|
+
|
237
253
|
process, pid = libzypp_process
|
238
254
|
raise SystemUpdateRunning, { pid: pid, process: process } if pid
|
255
|
+
|
239
256
|
@repo.save(@filename)
|
240
257
|
end
|
241
258
|
|
242
|
-
|
243
259
|
private
|
244
260
|
|
261
|
+
def resolve_variables!(variables)
|
262
|
+
self.url = variables.apply(url) if url =~ /\$/
|
263
|
+
self.name = variables.apply(name) if name =~ /\$/
|
264
|
+
self.alias = variables.apply(self.alias) if self.alias =~ /\$/
|
265
|
+
|
266
|
+
self
|
267
|
+
end
|
268
|
+
|
245
269
|
def libzypp_process
|
246
|
-
libpath = `ldd /usr/bin/zypper | grep "libzypp.so"`.split(
|
270
|
+
libpath = `ldd /usr/bin/zypper | grep "libzypp.so"`.split(" => ")[1].split.shift
|
247
271
|
process = `sudo lsof #{libpath} | tail -n 1`
|
248
|
-
process, pid = process.split
|
272
|
+
process, pid = process.split
|
249
273
|
[process, pid]
|
250
274
|
end
|
251
275
|
|
252
|
-
def
|
253
|
-
@repo.to_hash.keys.delete_if {|k| k ==
|
276
|
+
def read_key
|
277
|
+
@repo.to_hash.keys.delete_if { |k| k == "0" }.pop
|
254
278
|
end
|
255
279
|
end
|
256
|
-
|
257
|
-
|
258
280
|
end
|
259
281
|
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
|