zypper-upgraderepo 1.1.0 → 1.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 +4 -4
- data/Gemfile.lock +2 -2
- data/lib/zypper/upgraderepo.rb +48 -12
- data/lib/zypper/upgraderepo/cli.rb +27 -13
- data/lib/zypper/upgraderepo/os_release.rb +4 -1
- data/lib/zypper/upgraderepo/repository.rb +31 -112
- data/lib/zypper/upgraderepo/request.rb +196 -0
- data/lib/zypper/upgraderepo/utils.rb +13 -84
- data/lib/zypper/upgraderepo/version.rb +1 -1
- data/lib/zypper/upgraderepo/view.rb +126 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a427fb24de5056e9425117be69b150cd225a9cf649d93f0ee8c5425951021824
|
4
|
+
data.tar.gz: a317a3f790c16151bb08a9cdffddd8e813f325adf0f49f5a5aac9760a4b28aee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 256f4cf0b63242db412d27328bdc0599b583e20dfbc194941963d4676f025033defadaeab0bb1f6cf3cbeaf2c0ebe64cdc78e3460c9693ac53454768d810cf91
|
7
|
+
data.tar.gz: '0408b1a8169c94fa1115b1f9fda5ce411718cac4d8afeb149dbdb3b5f2a76a89a57c97ebca951a7c440ffc2c96929985e94f60d353fd5302517d9a8f9f2aa141'
|
data/Gemfile.lock
CHANGED
data/lib/zypper/upgraderepo.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
require 'zypper/upgraderepo/repository'
|
2
|
+
require 'zypper/upgraderepo/request'
|
2
3
|
require 'zypper/upgraderepo/os_release'
|
3
4
|
require 'zypper/upgraderepo/utils'
|
5
|
+
require 'zypper/upgraderepo/view'
|
6
|
+
require 'zlib'
|
7
|
+
require 'minitar'
|
4
8
|
|
5
9
|
|
6
10
|
module Zypper
|
@@ -11,12 +15,22 @@ module Zypper
|
|
11
15
|
@os_release = OsRelease.new(options)
|
12
16
|
@repos = RepositoryList.new(options)
|
13
17
|
@print_hint = options.hint
|
14
|
-
@view_class =
|
18
|
+
@view_class = Zypper::Upgraderepo::View.const_get options.view.to_s.capitalize
|
19
|
+
|
20
|
+
@overrides = options.overrides
|
21
|
+
@upgrade_options = { alias: options.alias, name: options.name }
|
22
|
+
|
23
|
+
@backup_path = options.backup_path
|
15
24
|
end
|
16
25
|
|
17
26
|
def backup
|
18
|
-
@repos.
|
19
|
-
|
27
|
+
filename = File.join(@backup_path, "repos-backup-#{Time.now.to_s.delete(': +-')[0..-5]}.tgz")
|
28
|
+
|
29
|
+
raise InvalidPermissions, filename unless File.writable? @backup_path
|
30
|
+
|
31
|
+
Minitar.pack(RepositoryList::REPOSITORY_PATH, Zlib::GzipWriter.new(File.open(filename, 'wb')))
|
32
|
+
|
33
|
+
Messages.ok "Backup file generated at #{filename.bold.green}"
|
20
34
|
end
|
21
35
|
|
22
36
|
def check_current
|
@@ -25,26 +39,23 @@ module Zypper
|
|
25
39
|
|
26
40
|
def check_next
|
27
41
|
raise AlreadyUpgraded, 'latest' if @os_release.last?
|
28
|
-
@repos.upgrade(@os_release.next)
|
42
|
+
@repos.each_with_index { |r, i| r.upgrade(@os_release.next, @upgrade_options.merge(url_override: @overrides[i.next])) }
|
29
43
|
check_repos(@os_release.next)
|
30
44
|
end
|
31
45
|
|
32
46
|
def check_to
|
33
|
-
@repos.upgrade(@os_release.custom)
|
47
|
+
@repos.each_with_index { |r, i| r.upgrade(@os_release.custom, @upgrade_options.merge(url_override: @overrides[i.next])) }
|
34
48
|
check_repos(@os_release.custom)
|
35
49
|
end
|
36
50
|
|
37
51
|
def upgrade
|
38
52
|
raise AlreadyUpgraded, 'latest' if @os_release.last?
|
39
|
-
|
40
|
-
@repos.save
|
41
|
-
Messages.ok 'Repositories upgraded!'
|
53
|
+
upgrade_repos(@os_release.next)
|
42
54
|
end
|
43
55
|
|
44
56
|
def upgrade_to
|
45
|
-
@
|
46
|
-
@
|
47
|
-
Messages.ok 'Repositories upgraded!'
|
57
|
+
raise AlreadyUpgraded, @os_release.custom if @os_release.current?(@os_release.custom)
|
58
|
+
upgrade_repos(@os_release.custom)
|
48
59
|
end
|
49
60
|
|
50
61
|
|
@@ -53,7 +64,8 @@ module Zypper
|
|
53
64
|
def check_repos(version)
|
54
65
|
@view_class.header(@repos.max_col)
|
55
66
|
|
56
|
-
@repos.
|
67
|
+
@repos.each_with_index do |r, i|
|
68
|
+
|
57
69
|
@view_class.separator
|
58
70
|
|
59
71
|
if r.available?
|
@@ -66,12 +78,36 @@ module Zypper
|
|
66
78
|
else
|
67
79
|
@view_class.not_found i.next, r, @repos.max_col
|
68
80
|
end
|
81
|
+
elsif r.timeout?
|
82
|
+
@view_class.timeout i.next, r, @repos.max_col
|
69
83
|
end
|
70
84
|
end
|
71
85
|
|
72
86
|
@view_class.footer
|
73
87
|
end
|
74
88
|
|
89
|
+
def upgrade_repos(version)
|
90
|
+
@view_class.header(@repos.max_col, true)
|
91
|
+
|
92
|
+
@repos.each_with_index do |repo, i|
|
93
|
+
|
94
|
+
@view_class.separator
|
95
|
+
|
96
|
+
repo.upgrade(version, @upgrade_options.merge(url_override: @overrides[i.next]))
|
97
|
+
|
98
|
+
if repo.upgraded?
|
99
|
+
@view_class.upgraded i.next, repo, @repos.max_col
|
100
|
+
else
|
101
|
+
@view_class.untouched i.next, repo, @repos.max_col
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
@view_class.separator
|
106
|
+
|
107
|
+
@repos.save
|
108
|
+
Messages.ok 'Repositories upgraded!'
|
109
|
+
end
|
110
|
+
|
75
111
|
end
|
76
112
|
|
77
113
|
end
|
@@ -21,7 +21,9 @@ module Zypper
|
|
21
21
|
options.version = nil
|
22
22
|
options.sort_by = :alias
|
23
23
|
options.view = :table
|
24
|
-
|
24
|
+
options.only_repo = nil
|
25
|
+
options.timeout = 10.0
|
26
|
+
|
25
27
|
opt_parser = OptionParser.new do |opt|
|
26
28
|
|
27
29
|
if ENV['ZYPPER_UPGRADEREPO']
|
@@ -64,26 +66,37 @@ module Zypper
|
|
64
66
|
opt.separator ''
|
65
67
|
opt.separator 'Options:'
|
66
68
|
|
67
|
-
opt.on('--
|
68
|
-
options.only_enabled =
|
69
|
+
opt.on('--only-enabled', 'Include only the enabled repositories') do |o|
|
70
|
+
options.only_enabled = true
|
71
|
+
end
|
72
|
+
|
73
|
+
opt.on('--only-repo <NUMBER>[,NUMBER2,...]', 'Include only the repositories specified by NUMBER') do |o|
|
74
|
+
options.only_repo = o.split(',').map(&:to_i)
|
69
75
|
end
|
70
76
|
|
71
|
-
opt.on('--
|
72
|
-
options.name =
|
77
|
+
opt.on('--no-name', 'Don\'t upgrade the name') do |o|
|
78
|
+
options.name = false
|
73
79
|
end
|
74
80
|
|
75
|
-
opt.on('--
|
76
|
-
options.alias =
|
81
|
+
opt.on('--no-alias', 'Don\'t upgrade the alias') do |o|
|
82
|
+
options.alias = false
|
77
83
|
end
|
78
84
|
|
79
|
-
opt.on('--
|
80
|
-
options.hint =
|
85
|
+
opt.on('--no-hint', 'Don\'t find a working url when the current is invalid') do |o|
|
86
|
+
options.hint = false
|
81
87
|
end
|
82
88
|
|
83
89
|
opt.on('--override-url <NUMBER>,<URL>', Array, 'Overwrite the repository\'s url NUMBER with URL') do |r|
|
84
|
-
options.overrides[r[0]] = r[1]
|
90
|
+
options.overrides[r[0].to_i] = r[1]
|
91
|
+
end
|
92
|
+
|
93
|
+
opt.on('--timeout <SECONDS>', "Adjust the waiting SECONDS used to catch an HTTP Timeout Error (Default: #{options.timeout})") do |o|
|
94
|
+
options.timeout = o.to_f
|
85
95
|
end
|
86
96
|
|
97
|
+
opt.separator ''
|
98
|
+
opt.separator 'View options:'
|
99
|
+
|
87
100
|
opt.on('--sort-by-alias', 'Sort repositories by alias (Default)') do |o|
|
88
101
|
options.sort_by = :alias
|
89
102
|
end
|
@@ -96,10 +109,11 @@ module Zypper
|
|
96
109
|
options.sort_by = :priority
|
97
110
|
end
|
98
111
|
|
99
|
-
opt.on('--report
|
112
|
+
opt.on('--report', 'View the data as report') do |o|
|
100
113
|
options.view = :report
|
101
114
|
end
|
102
115
|
|
116
|
+
|
103
117
|
unless ENV['ZYPPER_UPGRADEREPO']
|
104
118
|
opt.separator ''
|
105
119
|
opt.separator 'Other:'
|
@@ -116,7 +130,7 @@ module Zypper
|
|
116
130
|
end
|
117
131
|
|
118
132
|
end
|
119
|
-
|
133
|
+
|
120
134
|
if ARGV.empty?
|
121
135
|
puts opt_parser; exit
|
122
136
|
else
|
@@ -129,7 +143,7 @@ module Zypper
|
|
129
143
|
end
|
130
144
|
|
131
145
|
|
132
|
-
class CLI
|
146
|
+
class CLI
|
133
147
|
def self.start
|
134
148
|
begin
|
135
149
|
options = OptParseMain.parse(ARGV)
|
@@ -24,7 +24,6 @@ module Zypper
|
|
24
24
|
|
25
25
|
if options.version
|
26
26
|
raise InvalidVersion, options.version unless OS_VERSIONS.include?(options.version)
|
27
|
-
raise AlreadyUpgraded, options.version unless OS_VERSIONS.index(options.version) != @current_idx
|
28
27
|
@custom = options.version
|
29
28
|
end
|
30
29
|
end
|
@@ -60,6 +59,10 @@ module Zypper
|
|
60
59
|
def valid?(version)
|
61
60
|
OS_VERSIONS.include? version
|
62
61
|
end
|
62
|
+
|
63
|
+
def current?(version)
|
64
|
+
OS_VERSIONS.index(version) == @current_idx
|
65
|
+
end
|
63
66
|
end
|
64
67
|
|
65
68
|
|
@@ -1,24 +1,23 @@
|
|
1
1
|
require 'iniparse'
|
2
|
-
require 'net/http'
|
3
|
-
require 'zlib'
|
4
|
-
require 'minitar'
|
5
2
|
|
6
3
|
module Zypper
|
7
4
|
module Upgraderepo
|
8
5
|
|
9
6
|
|
10
7
|
class RepositoryList
|
8
|
+
|
9
|
+
REPOSITORY_PATH = '/etc/zypp/repos.d'
|
10
|
+
|
11
11
|
attr_reader :list, :max_col
|
12
12
|
|
13
13
|
def initialize(options)
|
14
14
|
@alias = options.alias
|
15
15
|
@name = options.name
|
16
|
-
@
|
16
|
+
@only_repo = options.only_repo
|
17
17
|
@list = []
|
18
|
-
@backup_path = options.backup_path
|
19
18
|
|
20
|
-
Dir.glob('
|
21
|
-
r = Repository.new(i)
|
19
|
+
Dir.glob(File.join(REPOSITORY_PATH, '*.repo')).each do |i|
|
20
|
+
r = RepositoryRequest.new(Repository.new(i), options.timeout)
|
22
21
|
next if options.only_enabled && (!r.enabled?)
|
23
22
|
@list << r
|
24
23
|
end
|
@@ -28,22 +27,11 @@ module Zypper
|
|
28
27
|
@list.sort_by! { |x| x.send(options.sort_by) } if options.sort_by != :alias
|
29
28
|
end
|
30
29
|
|
31
|
-
def
|
32
|
-
filename = File.join(@backup_path, "repos-backup-#{Time.now.to_s.delete(': +-')[0..-5]}.tgz")
|
33
|
-
raise InvalidPermissions, filename unless File.writable? @backup_path
|
34
|
-
Minitar.pack('/etc/zypp/repos.d',
|
35
|
-
Zlib::GzipWriter.new(File.open(filename, 'wb')))
|
36
|
-
end
|
37
|
-
|
38
|
-
def upgrade(version)
|
30
|
+
def each_with_index
|
39
31
|
@list.each_with_index do |repo, i|
|
40
|
-
if @
|
41
|
-
|
42
|
-
|
43
|
-
repo.url = repo.url.gsub(/\d\d\.\d/, version)
|
44
|
-
end
|
45
|
-
repo.alias = repo.alias.gsub(/\d\d\.\d/, version) if @alias
|
46
|
-
repo.name = repo.name.gsub(/\d\d\.\d/, version) if @name
|
32
|
+
next if @only_repo && !@only_repo.include?(i.next)
|
33
|
+
|
34
|
+
yield repo, i if block_given?
|
47
35
|
end
|
48
36
|
end
|
49
37
|
|
@@ -56,13 +44,15 @@ module Zypper
|
|
56
44
|
|
57
45
|
|
58
46
|
class Repository
|
59
|
-
attr_reader :filename
|
60
|
-
|
47
|
+
attr_reader :filename, :old_url, :old_alias, :old_name
|
48
|
+
|
61
49
|
def initialize(filename)
|
62
50
|
@filename = filename
|
63
51
|
@repo = IniParse.parse(File.read(filename))
|
64
|
-
@key = get_key
|
65
|
-
@
|
52
|
+
@key = get_key
|
53
|
+
@old_url = nil
|
54
|
+
@old_name = nil
|
55
|
+
@old_alias = nil
|
66
56
|
end
|
67
57
|
|
68
58
|
def enabled?
|
@@ -102,109 +92,38 @@ module Zypper
|
|
102
92
|
@key = get_key
|
103
93
|
end
|
104
94
|
|
105
|
-
def
|
106
|
-
|
107
|
-
|
95
|
+
def upgrade(version, args = {})
|
96
|
+
@old_url ||= self.url
|
97
|
+
@old_alias ||= self.alias
|
98
|
+
@old_name ||= self.name
|
108
99
|
|
109
|
-
|
110
|
-
|
111
|
-
|
100
|
+
if args[:url_override]
|
101
|
+
self.url = args[:url_override]
|
102
|
+
else
|
103
|
+
self.url = self.url.gsub(/\d\d\.\d/, version)
|
104
|
+
end
|
112
105
|
|
113
|
-
|
114
|
-
|
106
|
+
self.alias = self.alias.gsub(/\d\d\.\d/, version) if args[:alias]
|
107
|
+
self.name = self.name.gsub(/\d\d\.\d/, version) if args[:name]
|
115
108
|
end
|
116
109
|
|
117
|
-
def
|
118
|
-
|
110
|
+
def upgraded?(item = :url)
|
111
|
+
(!self.send("old_#{item}").nil?) && (self.send("old_#{item}") != self.send(item))
|
119
112
|
end
|
120
113
|
|
121
114
|
def save
|
122
115
|
raise InvalidPermissions, @filename unless File.writable? @filename
|
123
|
-
@repo.save(@filename)
|
116
|
+
@repo.save(@filename)
|
124
117
|
end
|
125
118
|
|
126
|
-
def evaluate_alternative(version)
|
127
|
-
if url =~ /dl\.google\.com/
|
128
|
-
return { url: '', message: 'Just Google security, use this repo anyway ;)'}
|
129
|
-
elsif not_found?
|
130
|
-
return traverse_url(URI(url.clone), version)
|
131
|
-
elsif redirected?
|
132
|
-
return { url: redirected_to, message: 'Redirected to:' }
|
133
|
-
end
|
134
|
-
end
|
135
119
|
|
136
120
|
private
|
137
121
|
|
138
|
-
def ping(uri = URI(url), force = false)
|
139
|
-
begin
|
140
|
-
@res = Net::HTTP.get_response(uri) if @res.nil? || force
|
141
|
-
rescue SocketError
|
142
|
-
raise NoConnection
|
143
|
-
end
|
144
|
-
@res
|
145
|
-
end
|
146
|
-
|
147
122
|
def get_key
|
148
123
|
@repo.to_hash.keys.delete_if {|k| k == '0'}.pop
|
149
124
|
end
|
150
|
-
|
151
|
-
def traverse_url(uri, version)
|
152
|
-
uri.path = File.dirname(uri.path)
|
153
|
-
|
154
|
-
return {url: '', message: 'None, try to find it manually'} if uri.path == '/'
|
155
|
-
|
156
|
-
uri.path += '/'
|
157
|
-
ping(uri, true)
|
158
|
-
|
159
|
-
if not_found?
|
160
|
-
return traverse_url(uri, version)
|
161
|
-
elsif available?
|
162
|
-
return {url: uri.to_s, message: 'Override with this one' } if uri.path =~ Regexp.new(version) && !search_repo(version).empty?
|
163
|
-
|
164
|
-
path = search_path(version)
|
165
|
-
if path.empty?
|
166
|
-
return traverse_url(uri, version)
|
167
|
-
else
|
168
|
-
return traverse_url_forward(uri, version) if search_repo(version).empty?
|
169
|
-
|
170
|
-
uri.path += extract_path(path)
|
171
|
-
return {url: uri.to_s, message: 'Override with this one' }
|
172
|
-
end
|
173
|
-
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
|
178
|
-
def traverse_url_forward(uri, version)
|
179
|
-
ping(uri, true)
|
180
|
-
|
181
|
-
if search_repo(version).empty?
|
182
|
-
|
183
|
-
path = search_path(version)
|
184
|
-
if path.empty?
|
185
|
-
return {url: '', message: 'Can\'t find anything similar, try manually!' }
|
186
|
-
else
|
187
|
-
uri.path += extract_path(path)
|
188
|
-
return traverse_url_forward(uri, version)
|
189
|
-
end
|
190
|
-
else
|
191
|
-
return {url: uri.to_s, message: 'Override with this one' }
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
def search_path(version)
|
196
|
-
ping.body.to_s.scan(Regexp.new("href=\"[^\"]*#{version}[^\"]*\"")).delete_if { |x| x =~ Regexp.new("\"#{URI(url).path}\"") }.uniq
|
197
|
-
end
|
198
|
-
|
199
|
-
def search_repo(version)
|
200
|
-
ping.body.to_s.scan(Regexp.new("href=\"[^\"]*#{version}[^\"]*\.repo\"|repodata/")).uniq
|
201
|
-
end
|
202
|
-
|
203
|
-
def extract_path(path)
|
204
|
-
"#{path.pop.scan(/href="(.*)"/).pop.pop}"
|
205
|
-
end
|
206
|
-
|
207
125
|
end
|
208
126
|
|
127
|
+
|
209
128
|
end
|
210
129
|
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module Zypper
|
5
|
+
module Upgraderepo
|
6
|
+
|
7
|
+
|
8
|
+
class PageRequest < SimpleDelegator
|
9
|
+
|
10
|
+
attr_reader :page
|
11
|
+
|
12
|
+
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:59.0) Gecko/20100101 Firefox/59.0'
|
13
|
+
|
14
|
+
def initialize(obj, timeout = 60)
|
15
|
+
super obj
|
16
|
+
@timeout = timeout
|
17
|
+
end
|
18
|
+
|
19
|
+
def available?
|
20
|
+
ping.is_a?(Net::HTTPSuccess)
|
21
|
+
end
|
22
|
+
|
23
|
+
def redirected?
|
24
|
+
ping.is_a?(Net::HTTPRedirection)
|
25
|
+
end
|
26
|
+
|
27
|
+
def redirected_to
|
28
|
+
ping['location']
|
29
|
+
end
|
30
|
+
|
31
|
+
def not_found?
|
32
|
+
ping.is_a?(Net::HTTPNotFound)
|
33
|
+
end
|
34
|
+
|
35
|
+
def forbidden?
|
36
|
+
ping.is_a?(Net::HTTPForbidden)
|
37
|
+
end
|
38
|
+
|
39
|
+
def timeout?
|
40
|
+
ping.is_a?(Net::HTTPRequestTimeOut)
|
41
|
+
end
|
42
|
+
|
43
|
+
def status
|
44
|
+
ping.class.to_s
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def get_request(uri, head)
|
51
|
+
uri ||= repodata_uri
|
52
|
+
|
53
|
+
if head
|
54
|
+
request = Net::HTTP::Head.new(uri.request_uri)
|
55
|
+
else
|
56
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
57
|
+
end
|
58
|
+
|
59
|
+
request['User-Agent'] = USER_AGENT
|
60
|
+
|
61
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
62
|
+
http.use_ssl = (uri.scheme == "https")
|
63
|
+
http.open_timeout = @timeout
|
64
|
+
|
65
|
+
http.request(request)
|
66
|
+
end
|
67
|
+
|
68
|
+
def ping(uri = nil, head = true)
|
69
|
+
begin
|
70
|
+
if @page.nil? || uri
|
71
|
+
@page = get_request(uri, head)
|
72
|
+
end
|
73
|
+
rescue SocketError
|
74
|
+
raise NoConnection
|
75
|
+
rescue Net::OpenTimeout
|
76
|
+
@page = Net::HTTPRequestTimeOut.new('1.1', '', '')
|
77
|
+
end
|
78
|
+
@page
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
class RepositoryRequest < PageRequest
|
85
|
+
|
86
|
+
def evaluate_alternative(version)
|
87
|
+
|
88
|
+
if not_found?
|
89
|
+
return traverse_url(URI(url), version)
|
90
|
+
elsif redirected?
|
91
|
+
return { url: redirected_to, message: 'Redirected to:' }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def traverse_url(uri, version)
|
99
|
+
ping(uri)
|
100
|
+
|
101
|
+
if forbidden?
|
102
|
+
res = { url: url, message: 'Can\'t navigate through the repository!' }
|
103
|
+
elsif available? && uri.to_s =~ /#{version}/
|
104
|
+
res = traverse_url_forward(uri, version)
|
105
|
+
else
|
106
|
+
res = traverse_url_backward(uri, version)
|
107
|
+
end
|
108
|
+
|
109
|
+
res || { url: '', message: 'Can\'t find a valid alternative, try manually!' }
|
110
|
+
end
|
111
|
+
|
112
|
+
def traverse_url_backward(uri, version)
|
113
|
+
uri.path = File.dirname(uri.path)
|
114
|
+
|
115
|
+
return nil if uri.path == '/' || uri.path == '.'
|
116
|
+
|
117
|
+
uri.path += '/' if uri.path[-1] != '/'
|
118
|
+
ping(uri, false)
|
119
|
+
|
120
|
+
if not_found?
|
121
|
+
return traverse_url_backward(uri, version)
|
122
|
+
elsif available?
|
123
|
+
|
124
|
+
if uri.path =~ /#{version}/ && repodata?
|
125
|
+
return {url: uri.to_s, message: 'Override with this one' }
|
126
|
+
elsif res = traverse_url_forward(uri, version, !(uri.path =~ /#{version}/))
|
127
|
+
return res
|
128
|
+
else
|
129
|
+
return traverse_url_backward(uri, version)
|
130
|
+
end
|
131
|
+
|
132
|
+
elsif forbidden?
|
133
|
+
return { url: uri.to_s, message: 'Try to replace with this one' } if repodata?(uri)
|
134
|
+
|
135
|
+
return traverse_url_backward(uri, version)
|
136
|
+
end
|
137
|
+
|
138
|
+
nil
|
139
|
+
end
|
140
|
+
|
141
|
+
def traverse_url_forward(uri, version, check_version = false)
|
142
|
+
uri.path += '/' if uri.path[-1] != '/'
|
143
|
+
ping(uri, false)
|
144
|
+
|
145
|
+
subfolders(version, check_version).each do |dir|
|
146
|
+
u = URI(uri.to_s)
|
147
|
+
u.path += dir
|
148
|
+
|
149
|
+
if repodata?(u)
|
150
|
+
return {url: u.to_s, message: 'Override with this one' }
|
151
|
+
else
|
152
|
+
res = traverse_url_forward(u, version)
|
153
|
+
return res if res.class == Hash
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
|
160
|
+
def repodata_uri(uri = nil)
|
161
|
+
if uri
|
162
|
+
uri = URI(uri.to_s)
|
163
|
+
else
|
164
|
+
uri = URI(url)
|
165
|
+
end
|
166
|
+
|
167
|
+
uri.path = uri.path.gsub(/\/$/, '') + '/repodata/repomd.xml'
|
168
|
+
|
169
|
+
uri
|
170
|
+
end
|
171
|
+
|
172
|
+
def repodata?(uri = nil)
|
173
|
+
if uri.nil?
|
174
|
+
return ping.body.to_s.scan(Regexp.new("href=\"repodata/")).empty?
|
175
|
+
else
|
176
|
+
ping(repodata_uri(uri))
|
177
|
+
return available?
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def subfolders(version, check_version)
|
182
|
+
res = ping.body.to_s.scan(Regexp.new('href=[\'\"][^\/\"]+\/[\'\"]')).delete_if do |x|
|
183
|
+
x =~ /^\// || x =~ /^\.\./ || x =~ /\:\/\// || x =~ /href=[\"\'](media\.1|boot|EFI)\/[\"\']/
|
184
|
+
end.uniq.map do |d|
|
185
|
+
d.scan(/href=[\"\']([^"]+)[\'\"]/).pop.pop
|
186
|
+
end
|
187
|
+
|
188
|
+
res = res.delete_if { |x| !(x =~ /#{version}/) } if check_version
|
189
|
+
|
190
|
+
res
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
@@ -31,6 +31,8 @@ module Zypper
|
|
31
31
|
def self.error(e)
|
32
32
|
if e.class == String
|
33
33
|
puts ' [E] '.bold.red + e
|
34
|
+
elsif e.class == Interruption
|
35
|
+
STDERR.puts e.message =~ /\(/ ? e.message.gsub(/.*\((.*)\).*/, '\1').green : e.message.green
|
34
36
|
else
|
35
37
|
STDERR.puts 'Error! '.bold.red + e.message
|
36
38
|
end
|
@@ -46,96 +48,13 @@ module Zypper
|
|
46
48
|
|
47
49
|
end
|
48
50
|
|
49
|
-
class TableView
|
50
|
-
|
51
|
-
def self.available(num, repo, max_col)
|
52
|
-
Messages.ok("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} |")
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.redirected(num, repo, max_col, redirected)
|
56
|
-
Messages.warning("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{'Redirection'.bold.yellow} of #{repo.url} ")
|
57
|
-
puts " #{' ' * 3} | #{' ' * 2} | #{ ' ' * max_col} | #{ ' ' * 3 } | #{'To:'.bold.yellow} #{redirected}"
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.not_found(num, repo, max_col)
|
61
|
-
Messages.error("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} |")
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.alternative(num, repo, max_col, alt)
|
65
|
-
Messages.error("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{alt[:message].bold.yellow}")
|
66
|
-
puts " #{' ' * 3} | #{' ' * 2} | #{' ' * max_col} | #{' ' * 3} | #{alt[:url]}" unless alt[:url].to_s.empty?
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.separator
|
70
|
-
puts '-' * 90
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.header(max_col)
|
74
|
-
puts " St. | # | #{'Name'.ljust(max_col, ' ')} | En. | Hint"
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.footer
|
78
|
-
self.separator
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
|
83
|
-
class ReportView
|
84
|
-
|
85
|
-
def self.available(num, repo, max_col)
|
86
|
-
puts " #{num.to_s.rjust(2).bold.green} | Status: #{'Ok'.bold.green}"
|
87
|
-
self.info(repo)
|
88
|
-
end
|
89
|
-
|
90
|
-
def self.redirected(num, repo, max_col, redirected)
|
91
|
-
puts " #{num.to_s.rjust(2).bold.yellow} | Status: #{'Redirected'.bold.yellow}"
|
92
|
-
puts " #{' ' * 2} | #{'To:'.bold.yellow} #{redirected}"
|
93
|
-
self.info(repo)
|
94
|
-
end
|
95
|
-
|
96
|
-
def self.not_found(num, repo, max_col)
|
97
|
-
puts " #{num.to_s.rjust(2).bold.red} | Status: #{'Not Found'.bold.red}"
|
98
|
-
self.info(repo)
|
99
|
-
end
|
100
|
-
|
101
|
-
def self.alternative(num, repo, max_col, alt)
|
102
|
-
puts " #{num.to_s.rjust(2).bold.red} | Status: #{'Not Found'.bold.red}"
|
103
|
-
puts " #{' ' * 2} | Hint: #{alt[:message].bold.yellow}"
|
104
|
-
puts " #{' ' * 2} | #{'Suggested:'.bold.yellow} #{alt[:url]}" unless alt[:url].to_s.empty?
|
105
|
-
self.info(repo)
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.separator
|
109
|
-
puts '-' * 90
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.header(max_col)
|
113
|
-
puts " # | Report"
|
114
|
-
end
|
115
|
-
|
116
|
-
def self.footer
|
117
|
-
self.separator
|
118
|
-
end
|
119
|
-
|
120
|
-
private
|
121
|
-
|
122
|
-
def self.info(repo)
|
123
|
-
puts " #{ ' ' * 2 } | Name: #{repo.name}"
|
124
|
-
puts " #{ ' ' * 2 } | Alias: #{repo.alias}"
|
125
|
-
puts " #{ ' ' * 2 } | Url: #{repo.url}"
|
126
|
-
puts " #{ ' ' * 2 } | Priority: #{repo.priority}"
|
127
|
-
puts " #{ ' ' * 2 } | #{repo.enabled? ? 'Enabled: Yes' : 'Enabled: No'.yellow}"
|
128
|
-
puts " #{ ' ' * 2 } | Filename: #{repo.filename}"
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
51
|
|
133
52
|
class ReleaseFileNotFound < StandardError
|
134
53
|
def initialize
|
135
54
|
super 'The release file is not found.'
|
136
55
|
end
|
137
56
|
end
|
138
|
-
|
57
|
+
|
139
58
|
class InvalidVersion < StandardError
|
140
59
|
def initialize(version)
|
141
60
|
super "The version #{version} is not valid"
|
@@ -159,5 +78,15 @@ module Zypper
|
|
159
78
|
super 'Internet connection has some trouble'
|
160
79
|
end
|
161
80
|
end
|
81
|
+
|
82
|
+
class Interruption < StandardError
|
83
|
+
def initialize
|
84
|
+
super 'Ok ok... Exiting!'
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
Signal.trap('INT') { raise Interruption }
|
89
|
+
|
90
|
+
Signal.trap('TERM') { raise Interruption }
|
162
91
|
end
|
163
92
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module Zypper
|
2
|
+
module Upgraderepo
|
3
|
+
|
4
|
+
module View
|
5
|
+
|
6
|
+
class Report
|
7
|
+
|
8
|
+
def self.available(num, repo, max_col)
|
9
|
+
puts " #{num.to_s.rjust(2).bold.green} | Status: #{'Ok'.bold.green}"
|
10
|
+
self.info(repo)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.redirected(num, repo, max_col, redirected)
|
14
|
+
puts " #{num.to_s.rjust(2).bold.yellow} | Status: #{'Redirected'.bold.yellow}"
|
15
|
+
puts " #{' ' * 2} | #{'To:'.bold.yellow} #{redirected}"
|
16
|
+
self.info(repo)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.not_found(num, repo, max_col)
|
20
|
+
puts " #{num.to_s.rjust(2).bold.red} | Status: #{'Not Found'.bold.red}"
|
21
|
+
self.info(repo)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.alternative(num, repo, max_col, alt)
|
25
|
+
puts " #{num.to_s.rjust(2).bold.red} | Status: #{'Not Found'.bold.red}"
|
26
|
+
puts " #{' ' * 2} | Hint: #{alt[:message].bold.yellow}"
|
27
|
+
puts " #{' ' * 2} | #{'Suggested:'.bold.yellow} #{alt[:url]}" unless alt[:url].to_s.empty?
|
28
|
+
self.info(repo)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.timeout(num, repo, max_col)
|
32
|
+
puts " #{num.to_s.rjust(2).bold.yellow} | Status: #{'Server Timeout'.bold.yellow}"
|
33
|
+
self.info(repo)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.upgraded(num, repo, max_col)
|
37
|
+
puts " #{num.to_s.rjust(2).bold.green} | #{'Upgraded'.bold.green}" #{'Upgraded from:'.bold.green} #{repo.old_url}"
|
38
|
+
#puts " #{' ' * 2} | Old Name: #{old_data[:name].yellow}" if old_data[:name] != repo.name
|
39
|
+
#puts " #{' ' * 2} | Old Alias: #{old_data[:alias].yellow}" if old_data[:alias] != repo.alias
|
40
|
+
|
41
|
+
#puts " #{' ' * 2} | Old URL: #{repo.old_url}"
|
42
|
+
self.info(repo)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.untouched(num, repo, max_col)
|
46
|
+
puts " #{num.to_s.rjust(2).bold.yellow} | #{'Untouched'.bold.yellow}"
|
47
|
+
self.info(repo)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.separator
|
51
|
+
puts '-' * 90
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.header(max_col)
|
55
|
+
puts " # | Report"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.footer
|
59
|
+
self.separator
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def self.info(repo)
|
66
|
+
puts " #{ ' ' * 2 } | Name: #{repo.name} #{repo.upgraded?(:name) ? '(' + repo.old_name.yellow + ')' : '' }"
|
67
|
+
puts " #{ ' ' * 2 } | Alias: #{repo.alias} #{repo.upgraded?(:alias) ? '(' + repo.old_alias.yellow + ')' : ''}"
|
68
|
+
puts " #{ ' ' * 2 } | Url: #{repo.url}"
|
69
|
+
puts " #{ ' ' * 2 } | (#{repo.old_url.yellow})" if repo.upgraded?
|
70
|
+
puts " #{ ' ' * 2 } | Priority: #{repo.priority}"
|
71
|
+
puts " #{ ' ' * 2 } | #{repo.enabled? ? 'Enabled: Yes' : 'Enabled: No'.yellow}"
|
72
|
+
puts " #{ ' ' * 2 } | Filename: #{repo.filename}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
class Table
|
78
|
+
|
79
|
+
def self.available(num, repo, max_col)
|
80
|
+
Messages.ok("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} |")
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.redirected(num, repo, max_col, redirected)
|
84
|
+
Messages.warning("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{'Redirection'.bold.yellow} of #{repo.url} ")
|
85
|
+
puts " #{' ' * 3} | #{' ' * 2} | #{ ' ' * max_col} | #{ ' ' * 3 } | #{'To:'.bold.yellow} #{redirected}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.not_found(num, repo, max_col)
|
89
|
+
Messages.error("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} |")
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.alternative(num, repo, max_col, alt)
|
93
|
+
Messages.error("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{alt[:message].bold.yellow}")
|
94
|
+
puts " #{' ' * 3} | #{' ' * 2} | #{' ' * max_col} | #{' ' * 3} | #{alt[:url]}" unless alt[:url].to_s.empty?
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.timeout(num, repo, max_col)
|
98
|
+
Messages.error("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{'Server Timeout'.bold.yellow}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.upgraded(num, repo, max_col) #, old_data)
|
102
|
+
Messages.ok("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{'From:'.bold.green} #{repo.old_url}")
|
103
|
+
puts " #{' ' * 3} | #{' ' * 2} | #{' ' * max_col} | #{' ' * 3} | #{'To:'.bold.green} #{repo.url}"
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.untouched(num, repo, max_col)
|
107
|
+
Messages.warning("| #{num.to_s.rjust(2)} | #{repo.name.ljust(max_col, ' ')} | #{repo.enabled? ? ' Y ' : ' N '.yellow} | #{'Untouched:'.bold.yellow} #{repo.old_url}")
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.separator
|
111
|
+
puts '-' * 90
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.header(max_col, upgrade = false)
|
115
|
+
puts " St. | # | #{'Name'.ljust(max_col, ' ')} | En. | #{upgrade ? 'Details' : 'Hint' }"
|
116
|
+
end
|
117
|
+
|
118
|
+
def self.footer
|
119
|
+
self.separator
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zypper-upgraderepo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fabio Mucciante
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -105,15 +105,17 @@ files:
|
|
105
105
|
- lib/zypper/upgraderepo/cli.rb
|
106
106
|
- lib/zypper/upgraderepo/os_release.rb
|
107
107
|
- lib/zypper/upgraderepo/repository.rb
|
108
|
+
- lib/zypper/upgraderepo/request.rb
|
108
109
|
- lib/zypper/upgraderepo/utils.rb
|
109
110
|
- lib/zypper/upgraderepo/version.rb
|
111
|
+
- lib/zypper/upgraderepo/view.rb
|
110
112
|
- zypper-upgraderepo.gemspec
|
111
113
|
homepage: https://github.com/fabiomux/zypper-upgraderepo
|
112
114
|
licenses:
|
113
115
|
- GPL-3.0
|
114
116
|
metadata:
|
115
117
|
bug_tracker_uri: https://github.com/fabiomux/zypper-upgraderepo/issues
|
116
|
-
documentation_uri: https://www.rubydoc.info/gems/zypper-upgraderepo/1.
|
118
|
+
documentation_uri: https://www.rubydoc.info/gems/zypper-upgraderepo/1.2.0
|
117
119
|
homepage_uri: https://github.com/fabiomux/zypper-upgraderepo
|
118
120
|
source_code_uri: https://github.com/fabiomux/zypper-upgraderepo
|
119
121
|
wiki_uri: https://github.com/fabiomux/zypper-upgraderepo/wiki
|