Class: Y2Packager::ZyppUrl

Inherits:
SimpleDelegator
  • Object
show all
Includes:
Yast::Logger
Defined in:
library/packages/src/lib/y2packager/zypp_url.rb

Overview

This class represents a libzypp URL

Libzypp URLs do not conform to rfc3986 because they can include the so-called Repository Variables. Those vars can have several formats like $variable, $variable, $variable-word or $variable+word. According to libzypp's documentation, the variables can appear in any component of the URL (host, path, port...) except in scheme, user or password. But, at the time of writing, zypper throws an "invalid port component" error when trying to use variables as part of the port, even with the most recent available version of libzypp.

See https://doc.opensuse.org/projects/libzypp/HEAD/zypp-repovars.html

The current implementation relies on SimpleDelegator to expose all the methods of an underlying URI object, so objects of this class can be used as a direct replacement in places that used to use URI, like Repository#raw_url

Constant Summary collapse

LOCAL_SCHEMES =
[:cd, :dvd, :dir, :hd, :iso, :file].freeze

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ ZyppUrl

Constructor

If the argument is a string with an invalid URL, an empty URL is created

Parameters:

  • url (String, ZyppUrl, URI::Generic)


47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 47

def initialize(url)
  super

  uri =
    begin
      URI(repovars_escape(url.to_s))
    rescue URI::InvalidURIError => e
      log.error "Failed to parse URL, considered as empty: #{e.inspect}"
      URI("")
    end

  __setobj__(uri)
end

Instance Method Details

#==(other) ⇒ Object Also known as: eql?

Compares two URLs

NOTE: this considers an URI::Generic object to be equal if it represents the same URL. That should increase a bit the robustness when a ZyppUrl object is introduced to replace an existing URI one.



147
148
149
150
151
152
153
154
155
156
157
158
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 147

def ==(other)
  if other.is_a?(URI::Generic)
    uri == other ||
      # zypp will normalize dir:///foo to dir:/foo
      # https://github.com/openSUSE/libzypp/issues/441
      uri == URI(other.to_s.sub(":///", ":/"))
  elsif other.class == self.class
    uri == other.uri
  else
    false
  end
end

#expandedZyppUrl

Expanded version of the URL in which the repository vars has been replaced by their value

Returns:

  • (ZyppUrl)

    an URL that is expected to conform to rfc3986



130
131
132
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 130

def expanded
  ZyppUrl.new(Yast::Pkg.ExpandedUrl(to_s))
end

#hostnameString

See URI::Generic#hostname

Returns:

  • (String)


78
79
80
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 78

def hostname
  repovars_unescape(uri.hostname)
end

#inspectString

String representation of the state of the object

Returns:

  • (String)


137
138
139
140
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 137

def inspect
  # Prevent SimpleDelegator from forwarding this to the wrapped URI object
  "#<#{self.class}:#{object_id} @uri=#{uri.inspect}>"
end

#local?Boolean

Whether the URL is local

Returns:

  • (Boolean)

    true if the URL is considered local; false otherwise



122
123
124
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 122

def local?
  LOCAL_SCHEMES.include?(scheme&.to_sym)
end

#pathString

See URI::Generic#path

Returns:

  • (String)


105
106
107
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 105

def path
  repovars_unescape(uri.path)
end

#portString

See URI::Generic#hostname

FIXME: escaping does not work here because the port wouldn't accept the escaped characters either. If we really want to support the usage of repository variables in the port, we would likely have to implement one of these solutions:

1) Modify the regexp used by URI to parse/validate the port, so it accepts the vars (escaped or not). That's not as easy as the documentation of the URI class suggests and may affect the reliability of the parsing. 2) Extract the port section before parsing the URL if it contains repovars, storing its value in a separate instance variable and restoring it on demand.

Anyways, using variables in the port of an URL doesn't seem to really work in libzypp, although it's documented to be valid.

Returns:

  • (String)


98
99
100
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 98

def port
  repovars_unescape(uri.port)
end

#queryString

See URI::Generic#path

Offered for completeness, even if the query component makes very little sense in a zypper URL.

Returns:

  • (String)


115
116
117
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 115

def query
  repovars_unescape(uri.query)
end

#to_sString

Constructs String from the URL

Returns:

  • (String)


71
72
73
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 71

def to_s
  repovars_unescape(uri.to_s)
end

#uriURI::Generic Also known as: to_uri

Returns:

  • (URI::Generic)


62
63
64
# File 'library/packages/src/lib/y2packager/zypp_url.rb', line 62

def uri
  __getobj__
end