Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package yast2 for openSUSE:Factory checked in at 2021-12-18 20:29:43 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2 (Old) and /work/SRC/openSUSE:Factory/.yast2.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2" Sat Dec 18 20:29:43 2021 rev:520 rq:940886 version:4.4.30 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2/yast2.changes 2021-12-03 20:35:43.824150355 +0100 +++ /work/SRC/openSUSE:Factory/.yast2.new.2520/yast2.changes 2021-12-18 20:30:03.642236368 +0100 @@ -1,0 +2,21 @@ +Thu Dec 16 08:39:01 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Fixed RelURL to work properly with the FTP URLs (related to + jsc#SLE-22669) +- 4.4.30 + +------------------------------------------------------------------- +Wed Dec 15 13:21:31 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Fixed RelURL unit test randomly crashing (related to + jsc#SLE-22669) +- 4.4.29 + +------------------------------------------------------------------- +Tue Dec 14 16:24:00 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Added RelURL class for working with relative URLs ("relurl://") + (jsc#SLE-22669) +- 4.4.28 + +------------------------------------------------------------------- Old: ---- yast2-4.4.27.tar.bz2 New: ---- yast2-4.4.30.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2.spec ++++++ --- /var/tmp/diff_new_pack.MlZjXh/_old 2021-12-18 20:30:04.494236841 +0100 +++ /var/tmp/diff_new_pack.MlZjXh/_new 2021-12-18 20:30:04.514236852 +0100 @@ -17,7 +17,7 @@ Name: yast2 -Version: 4.4.27 +Version: 4.4.30 Release: 0 Summary: YaST2 Main Package License: GPL-2.0-only ++++++ yast2-4.4.27.tar.bz2 -> yast2-4.4.30.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/library/general/src/lib/yast2/rel_url.rb new/yast2-4.4.30/library/general/src/lib/yast2/rel_url.rb --- old/yast2-4.4.27/library/general/src/lib/yast2/rel_url.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-4.4.30/library/general/src/lib/yast2/rel_url.rb 2021-12-16 13:24:53.000000000 +0100 @@ -0,0 +1,135 @@ +# Copyright (c) [2021] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require "yast" +require "uri" + +module Yast2 + # Class for working with relative URLs ("relurl://") + class RelURL + # @return [URI] the input base URL + attr_reader :base + + # @return [URI] the input relative URL + attr_reader :relative + + # Is the URL a relative URL? + # + # @param url [String, URI] the URL + # @return [Boolean] `true` if the URL uses the "relurl" schema, otherwise `false` + def self.relurl?(url) + URI(url).scheme == "relurl" + end + + # Create RelURL object with URL relative to the installation repository + # + # @param rel_url [String, URI] the relative URL, if non-relative URL is used + # then the result is this URL + # @return [RelURL] + # + # @note Works properly only during installation/upgrade, do not use + # in an installed system. + def self.from_installation_repository(rel_url) + Yast.import "InstURL" + base_url = Yast::InstURL.installInf2Url("") + new(base_url, rel_url) + end + + # Constructor + # + # @param base_url [String,URI] the base URL + # @param rel_url [String,URI] the relative URL, it should use the "relurl://" + # schema otherwise the base URL is ignored + def initialize(base_url, rel_url) + @base = URI(base_url).dup + @relative = URI(rel_url).dup + + preprocess_url(base) + preprocess_url(relative) + end + + # Build an absolute URL + # + # @param path [String,nil] optional URL subpath + # @return [URI] the absolute URL + # + # @note It internally uses the Ruby `File.expand_path` function which + # also evaluates the parent directory path ("../") so it is possible + # to go up in the tree using the "relurl://../foo" or the "../foo" path + # parameter. + def absolute_url(path = nil) + if (!relative.to_s.empty? && !RelURL.relurl?(relative)) || base.to_s.empty? + ret = relative.dup + relative_url = URI("") + else + ret = base.dup + relative_url = relative.dup + end + + relative_path = relative_url.path + relative_path = File.join(relative_path, path) if path && !path.empty? + + base_path = ret.path + if !base_path.empty? || !relative_path.empty? + # the path would be expanded from the current working directory + # by File.expand_path if the base path is not absolute + base_path.prepend("/") if !base_path.start_with?("/") + + # escape the "~" character, it is treated as a home directory name by File.expand_path, + # moreover it raises ArgumentError if that user does not exist in the system + relative_path.gsub!("~", "%7E") + # the relative path really needs to be relative, remove the leading slash(es) + relative_path.sub!(/\A\/+/, "") + + absolute_path = File.expand_path(relative_path, base_path) + # URI::FTP escapes the initial "/" to "%2F" which we do not want here + absolute_path.sub!(/\A\/+/, "") if ret.scheme == "ftp" + + ret.path = absolute_path + end + + postprocess_url(ret) + ret + end + + private + + # a helper method which fixes the URL path for the "file://" and "relurl://" URLs + def preprocess_url(url) + # move the host part to the path part for some URL types + return unless ["file", "relurl"].include?(url.scheme) && url.host + + # URI requires absolute path + url.path = File.join("/", url.host, url.path) + url.host = nil + end + + # a reverse method to "preprocess_url", fix the URL if it is a "file://" URL + def postprocess_url(url) + return if url.scheme != "file" && !url.host.nil? && !url.host.empty? + + path = url.path.sub(/\A\/+/, "").split("/") + url.host = path.shift + + rest = File.join(path) + rest.prepend("/") unless rest.empty? + url.path = rest + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/library/general/test/yast2/rel_url_test.rb new/yast2-4.4.30/library/general/test/yast2/rel_url_test.rb --- old/yast2-4.4.27/library/general/test/yast2/rel_url_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-4.4.30/library/general/test/yast2/rel_url_test.rb 2021-12-16 13:24:53.000000000 +0100 @@ -0,0 +1,260 @@ +require_relative "../test_helper" +require "yast2/rel_url" + +describe Yast2::RelURL do + describe ".is_relurl?" do + it "raises ArgumentError for nil" do + expect { Yast2::RelURL.relurl?(nil) }.to raise_error(ArgumentError) + end + + it "raises ArgumentError for invalid parameter" do + expect { Yast2::RelURL.relurl?(42) }.to raise_error(ArgumentError) + end + + it "raises URI::InvalidURIError for invalid URL" do + expect { Yast2::RelURL.relurl?("!@#$^") }.to raise_error(URI::InvalidURIError) + end + + it "returns false for empty string" do + expect(Yast2::RelURL.relurl?("")).to be false + end + + it "returns false for HTTP String URL" do + expect(Yast2::RelURL.relurl?("http://example.com")).to be false + end + + it "returns false for HTTP URI URL" do + expect(Yast2::RelURL.relurl?(URI("http://example.com"))).to be false + end + + it "returns true for relative String URL" do + expect(Yast2::RelURL.relurl?("relurl://test/test")).to be true + end + + it "returns true for relative URI URL" do + expect(Yast2::RelURL.relurl?(URI("relurl://test/test"))).to be true + end + + it "returns true for upper case URL" do + expect(Yast2::RelURL.relurl?("RELURL://test/test")).to be true + end + + it "returns true for mixed case URL" do + expect(Yast2::RelURL.relurl?("RELurl://test/test")).to be true + end + end + + describe "#initialize" do + it "raises ArgumentError for invalid parameter" do + expect { Yast2::RelURL.new(42, 42) }.to raise_error(ArgumentError) + end + + it "raises URI::InvalidURIError for invalid URL" do + expect { Yast2::RelURL.new("@#$%^&*", "@#$%^&*") }.to raise_error(URI::InvalidURIError) + end + end + + describe "#absolute_url" do + # empty URLs should not be used, just make sure it does not crash + # and returns sane values + it "returns the base URL if the relative URL is empty" do + relurl = Yast2::RelURL.new("http://example.com", "") + expect(relurl.absolute_url.to_s).to eq("http://example.com") + end + + it "returns the relative URL if the base URL is empty" do + relurl = Yast2::RelURL.new("", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("relurl://test") + end + + it "returns empty URL if both relative and base URLs are empty" do + relurl = Yast2::RelURL.new("", "") + expect(relurl.absolute_url.to_s).to eq("") + end + + it "returns the original relative URL if it does not use the relurl:// schema" do + relurl = Yast2::RelURL.new("http://example.com", "http://example2.com") + expect(relurl.absolute_url.to_s).to eq("http://example2.com") + end + + it "returns the relative URL" do + relurl = Yast2::RelURL.new("http://example.com", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test") + end + + it "returns relative URL with full path" do + relurl = Yast2::RelURL.new("http://example.com", "relurl://test/test2/test3") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test/test2/test3") + end + + it "returns relative URL with base path" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test") + end + + it "treats the hostname in the relative URL as a path" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl://example.com/test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/example.com/test") + end + + it "treats absolute_url path as relative in the relative URL" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl:///test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test") + end + + # this is rather a side effect of the used library function and not an intended + # behavior, but as ~ is used very rarely in path names (needs shell escaping) + # let's consider it as an acceptable behavior, the escaped character in URL is equal + # to unescaped one so there is no functional difference, only visual + it "escapes ~ character in the relative URL path" do + relurl = Yast2::RelURL.new("http://example.com/~base", "relurl://~test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/~base/%7Etest") + end + + it "allows going up in the tree using ../" do + relurl = Yast2::RelURL.new("http://example.com/base/dir", "relurl://../test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test") + end + + it "allows going up in the tree using ../.." do + relurl = Yast2::RelURL.new("http://example.com/base/dir", "relurl://../../test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test") + end + + it "cannot go up beyond the root dir" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl://../../../../test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test") + end + + it "removes single dot item from relative path" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl://./test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test") + end + + it "removes multiple dot items from relative path" do + relurl = Yast2::RelURL.new("http://example.com/base", "relurl://././test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test") + end + + # again, this is rather a side effect of the used library, but as single dots + # do not make much sense in a path then just accept that + it "removes single dot path from base path" do + relurl = Yast2::RelURL.new("http://example.com/base/./dir", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/dir/test") + end + + # same as above + it "removes single dot paths from base path" do + relurl = Yast2::RelURL.new("http://example.com/base/././dir", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/dir/test") + end + + it "ignores query parameters in the relative URL" do + relurl = Yast2::RelURL.new("http://example.com", "relurl://test?foo=bar") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test") + end + + it "keeps the query parameters in the base URL" do + relurl = Yast2::RelURL.new("http://example.com?foo=bar", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/test?foo=bar") + end + + it "keeps the query parameters in the base URL when going up" do + relurl = Yast2::RelURL.new("http://example.com/base/dir?foo=bar", "relurl://../test") + expect(relurl.absolute_url.to_s).to eq("http://example.com/base/test?foo=bar") + end + + it "keeps the port parameter in the base URL" do + relurl = Yast2::RelURL.new("http://example.com:8080", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://example.com:8080/test") + end + + it "keeps the user and password parameters in the base URL" do + relurl = Yast2::RelURL.new("http://user:passw...@example.com", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("http://user:passw...@example.com/test") + end + + it "works with ftp:// URL" do + relurl = Yast2::RelURL.new("ftp://example.com", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("ftp://example.com/test") + end + + it "works with cd:// URL" do + relurl = Yast2::RelURL.new("cd://", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("cd://test") + end + + it "works with cifs:// URL" do + relurl = Yast2::RelURL.new("cifs://server/share/path", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("cifs://server/share/path/test") + end + + it "works with nfs:// URL" do + relurl = Yast2::RelURL.new("nfs://server/export/path", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("nfs://server/export/path/test") + end + + it "works with file:// base URL" do + relurl = Yast2::RelURL.new("file://foo/bar", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("file://foo/bar/test") + end + + it "works with file:/// base URL" do + relurl = Yast2::RelURL.new("file:///", "relurl://test") + expect(relurl.absolute_url.to_s).to eq("file://test") + end + + it "goes up with file:// base URL properly" do + relurl = Yast2::RelURL.new("file://foo/bar", "relurl://../../test") + expect(relurl.absolute_url.to_s).to eq("file://test") + end + + it "adds the requested path to the absolute URL" do + relurl = Yast2::RelURL.new("http://example.com/foo", "relurl://test") + expect(relurl.absolute_url("path").to_s).to eq("http://example.com/foo/test/path") + end + + it "allow the requested path to go up in the relative path" do + relurl = Yast2::RelURL.new("http://example.com/foo", "relurl://test") + expect(relurl.absolute_url("../path").to_s).to eq("http://example.com/foo/path") + end + + it "allows the requested path to go up in the path even to the base URL" do + relurl = Yast2::RelURL.new("http://example.com/foo", "relurl://test") + expect(relurl.absolute_url("../../path").to_s).to eq("http://example.com/path") + end + + it "returns the path if both relative and base URLs are empty" do + relurl = Yast2::RelURL.new("", "") + # might not be exactly what you would expect as the result but this is a corner + # case, do not overengineer the code, the most important fact is that it does + # not crash and the result is a valid file path + expect(relurl.absolute_url("foo/bar").to_s).to eq("//foo/bar") + end + end + + describe ".from_installation_repository" do + before do + allow(Yast::InstURL).to receive(:installInf2Url).and_return(inst_url) + end + + let(:rel_url) { "relurl://test" } + subject { Yast2::RelURL.from_installation_repository(rel_url) } + + context "during installation" do + let(:inst_url) { "http://example.com/repo" } + + it "returns URL relative to the installation repository" do + expect(subject.absolute_url.to_s).to eq("http://example.com/repo/test") + end + end + + context "in an installed system" do + let(:inst_url) { "" } + + it "returns the original relative URL" do + expect(subject.absolute_url.to_s).to eq(rel_url) + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/library/packages/test/test_helper.rb new/yast2-4.4.30/library/packages/test/test_helper.rb --- old/yast2-4.4.27/library/packages/test/test_helper.rb 2021-12-02 22:40:47.000000000 +0100 +++ new/yast2-4.4.30/library/packages/test/test_helper.rb 2021-12-16 13:24:53.000000000 +0100 @@ -2,15 +2,3 @@ require "pathname" PACKAGES_FIXTURES_PATH = Pathname.new(File.dirname(__FILE__)).join("data") - -# mock missing YaST modules -module Yast - # we cannot depend on this module (circular dependency) - class InstURLClass - def installInf2Url(_extra_dir = "") - "" - end - end - - InstURL = InstURLClass.new -end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/package/yast2.changes new/yast2-4.4.30/package/yast2.changes --- old/yast2-4.4.27/package/yast2.changes 2021-12-02 22:40:47.000000000 +0100 +++ new/yast2-4.4.30/package/yast2.changes 2021-12-16 13:24:53.000000000 +0100 @@ -1,4 +1,25 @@ ------------------------------------------------------------------- +Thu Dec 16 08:39:01 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Fixed RelURL to work properly with the FTP URLs (related to + jsc#SLE-22669) +- 4.4.30 + +------------------------------------------------------------------- +Wed Dec 15 13:21:31 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Fixed RelURL unit test randomly crashing (related to + jsc#SLE-22669) +- 4.4.29 + +------------------------------------------------------------------- +Tue Dec 14 16:24:00 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> + +- Added RelURL class for working with relative URLs ("relurl://") + (jsc#SLE-22669) +- 4.4.28 + +------------------------------------------------------------------- Thu Dec 2 17:13:37 UTC 2021 - Ladislav Slez??k <lsle...@suse.cz> - Drop support for subscription-tools, that package is not present diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/package/yast2.spec new/yast2-4.4.30/package/yast2.spec --- old/yast2-4.4.27/package/yast2.spec 2021-12-02 22:40:47.000000000 +0100 +++ new/yast2-4.4.30/package/yast2.spec 2021-12-16 13:24:53.000000000 +0100 @@ -17,7 +17,7 @@ Name: yast2 -Version: 4.4.27 +Version: 4.4.30 Release: 0 Summary: YaST2 Main Package License: GPL-2.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-4.4.27/test/test_helper.rb new/yast2-4.4.30/test/test_helper.rb --- old/yast2-4.4.27/test/test_helper.rb 2021-12-02 22:40:47.000000000 +0100 +++ new/yast2-4.4.30/test/test_helper.rb 2021-12-16 13:24:53.000000000 +0100 @@ -57,3 +57,22 @@ ] end end + +# mock missing YaST modules +begin + # try loading the Yast::InstURL module, we cannot depend on it (because of + # circular build dependency), but it is present when running the tests + # locally or in GitHub Actions + Yast.import "InstURL" +rescue NameError + # if it is missing then mock it + module Yast + class InstURLClass + def installInf2Url(_extra_dir = "") + "" + end + end + + InstURL = InstURLClass.new + end +end