Hello community,

here is the log from the commit of package yast2-ruby-bindings for 
openSUSE:Factory checked in at 2016-06-02 12:49:38
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-ruby-bindings (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-ruby-bindings.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-ruby-bindings"

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-ruby-bindings/yast2-ruby-bindings.changes  
2016-01-13 22:43:13.000000000 +0100
+++ 
/work/SRC/openSUSE:Factory/.yast2-ruby-bindings.new/yast2-ruby-bindings.changes 
    2016-06-02 12:49:39.000000000 +0200
@@ -1,0 +2,21 @@
+Mon May 30 14:38:02 UTC 2016 - [email protected]
+
+- Improve the debugger support - use the same code also at run
+  time, allow using `Y2DEBUGGER` also in installed system
+  (FATE#318421)
+- 3.1.48
+
+-------------------------------------------------------------------
+Mon May 23 12:30:17 UTC 2016 - [email protected]
+
+- Added support for running the Ruby debugger (FATE#318421)
+- Allow running the Ruby debugger from the generic crash handler
+  if the debugger is installed
+- 3.1.47
+
+-------------------------------------------------------------------
+Mon Mar  7 16:12:00 UTC 2016 - [email protected]
+
+- update code according to updated yast ruby style guide
+
+-------------------------------------------------------------------

Old:
----
  yast2-ruby-bindings-3.1.46.tar.bz2

New:
----
  yast2-ruby-bindings-3.1.48.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-ruby-bindings.spec ++++++
--- /var/tmp/diff_new_pack.JBC3zK/_old  2016-06-02 12:49:40.000000000 +0200
+++ /var/tmp/diff_new_pack.JBC3zK/_new  2016-06-02 12:49:40.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-ruby-bindings
-Version:        3.1.46
+Version:        3.1.48
 Release:        0
 Url:            https://github.com/yast/yast-ruby-bindings
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -47,6 +47,17 @@
 BuildRequires:  libyui-ncurses >= 2.47.3
 # The mentioned test requires screen in order to be executed in headless 
systems
 BuildRequires:  screen
+
+# only a soft dependency, the Ruby debugger is optional
+Suggests:       rubygem(%{rb_default_ruby_abi}:byebug)
+
+# Unfortunately we cannot move this to macros.yast,
+# bcond within macros are ignored by osc/OBS.
+%bcond_with yast_run_ci_tests
+%if %{with yast_run_ci_tests}
+BuildRequires:  rubygem(yast-rake-ci)
+%endif
+
 Requires:       ruby
 Summary:        Ruby bindings for the YaST platform
 License:        GPL-2.0
@@ -80,6 +91,11 @@
 make test ARGS=-V
 cd -
 
+# run extra CI checks (in Jenkins)
+%if %{with yast_run_ci_tests}
+%yast_ci_check
+%endif
+
 %files
 %defattr (-, root, root)
 %{_libdir}/YaST2/plugin/libpy2lang_ruby.so

++++++ yast2-ruby-bindings-3.1.46.tar.bz2 -> yast2-ruby-bindings-3.1.48.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/.rubocop.yml 
new/yast2-ruby-bindings-3.1.48/.rubocop.yml
--- old/yast2-ruby-bindings-3.1.46/.rubocop.yml 2016-01-13 11:00:12.000000000 
+0100
+++ new/yast2-ruby-bindings-3.1.48/.rubocop.yml 2016-05-31 09:44:05.000000000 
+0200
@@ -46,20 +46,6 @@
 Style/Documentation:
   Enabled: false
 
-# Offense count: 1
-Style/DoubleNegation:
-  Enabled: false
-
-# Offense count: 3
-# Configuration parameters: MinBodyLength.
-Style/GuardClause:
-  Enabled: false
-
-# Offense count: 10
-# Configuration parameters: MaxLineLength.
-Style/IfUnlessModifier:
-  Enabled: false
-
 # Yast API: WFM.SetLanguage, SCR.Read
 # i18n: N_, Nn_
 Style/MethodName:
@@ -81,3 +67,8 @@
 # Offense count: 1 (@__last_exception)
 Style/TrivialAccessors:
   Enabled: false
+
+# the debugger invocation is deliberate here, it's not a forgotten leftover...
+Lint/Debugger:
+  Exclude:
+    - src/ruby/yast/debugger.rb
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/README.md 
new/yast2-ruby-bindings-3.1.48/README.md
--- old/yast2-ruby-bindings-3.1.46/README.md    2016-01-13 11:00:12.000000000 
+0100
+++ new/yast2-ruby-bindings-3.1.48/README.md    2016-05-31 09:44:05.000000000 
+0200
@@ -1,7 +1,7 @@
 # Yast2-ruby-bindings
 
-Travis:  [![Build 
Status](https://travis-ci.org/yast/yast-ruby-bindings.svg?branch=master)](https://travis-ci.org/yast/yast-ruby-bindings)
-Jenkins: [![Jenkins 
Build](http://img.shields.io/jenkins/s/https/ci.opensuse.org/yast-ruby-bindings-master.svg)](https://ci.opensuse.org/view/Yast/job/yast-ruby-bindings-master/)
+[![Travis Build 
Status](https://travis-ci.org/yast/yast-ruby-bindings.svg?branch=master)](https://travis-ci.org/yast/yast-ruby-bindings)
+[![Jenkins Build 
Status](http://ci.opensuse.org/buildStatus/icon?job=yast-ruby-bindings-master)](http://ci.opensuse.org/view/Yast/job/yast-ruby-bindings-master/)
 
 It is part of [YaST](http://yast.github.io) where you can find more information
 about YaST and its component system. The Ruby bindings cover only the 
connection to
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ruby-bindings-3.1.46/package/yast2-ruby-bindings.changes 
new/yast2-ruby-bindings-3.1.48/package/yast2-ruby-bindings.changes
--- old/yast2-ruby-bindings-3.1.46/package/yast2-ruby-bindings.changes  
2016-01-13 11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/package/yast2-ruby-bindings.changes  
2016-05-31 09:44:05.000000000 +0200
@@ -1,4 +1,25 @@
 -------------------------------------------------------------------
+Mon May 30 14:38:02 UTC 2016 - [email protected]
+
+- Improve the debugger support - use the same code also at run
+  time, allow using `Y2DEBUGGER` also in installed system
+  (FATE#318421)
+- 3.1.48
+
+-------------------------------------------------------------------
+Mon May 23 12:30:17 UTC 2016 - [email protected]
+
+- Added support for running the Ruby debugger (FATE#318421)
+- Allow running the Ruby debugger from the generic crash handler
+  if the debugger is installed
+- 3.1.47
+
+-------------------------------------------------------------------
+Mon Mar  7 16:12:00 UTC 2016 - [email protected]
+
+- update code according to updated yast ruby style guide
+
+-------------------------------------------------------------------
 Wed Jan 13 09:36:59 UTC 2016 - [email protected]
 
 - Move transdb initialization to C part to keep it together with
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ruby-bindings-3.1.46/package/yast2-ruby-bindings.spec 
new/yast2-ruby-bindings-3.1.48/package/yast2-ruby-bindings.spec
--- old/yast2-ruby-bindings-3.1.46/package/yast2-ruby-bindings.spec     
2016-01-13 11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/package/yast2-ruby-bindings.spec     
2016-05-31 09:44:05.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-ruby-bindings
-Version:        3.1.46
+Version:        3.1.48
 Url:            https://github.com/yast/yast-ruby-bindings
 Release:        0
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
@@ -47,6 +47,17 @@
 BuildRequires:  libyui-ncurses >= 2.47.3
 # The mentioned test requires screen in order to be executed in headless 
systems
 BuildRequires:  screen
+
+# only a soft dependency, the Ruby debugger is optional
+Suggests:       rubygem(%{rb_default_ruby_abi}:byebug)
+
+# Unfortunately we cannot move this to macros.yast,
+# bcond within macros are ignored by osc/OBS.
+%bcond_with yast_run_ci_tests
+%if %{with yast_run_ci_tests}
+BuildRequires: rubygem(yast-rake-ci)
+%endif
+
 Requires:       ruby
 Summary:        Ruby bindings for the YaST platform
 License:        GPL-2.0
@@ -80,6 +91,11 @@
 make test ARGS=-V
 cd -
 
+# run extra CI checks (in Jenkins)
+%if %{with yast_run_ci_tests}
+%yast_ci_check
+%endif
+
 %files
 %defattr (-, root, root)
 %{_libdir}/YaST2/plugin/libpy2lang_ruby.so
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/binary/Builtin.cc 
new/yast2-ruby-bindings-3.1.48/src/binary/Builtin.cc
--- old/yast2-ruby-bindings-3.1.46/src/binary/Builtin.cc        2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/binary/Builtin.cc        2016-05-31 
09:44:05.000000000 +0200
@@ -514,29 +514,10 @@
     return list;
   }
 
-
+  // documented in builtins.rb
   static VALUE
   regexpsub (VALUE o, VALUE i, VALUE p, VALUE m)
   {
-      /**
-       * @builtin regexpsub
-       * @short Regex Substitution
-       * @param string INPUT
-       * @param string PATTERN
-       * @param string OUTPUT
-       * @return string
-       *
-       * @description
-       * Searches a string for a POSIX Extended Regular Expression match
-       * and returns <i>OUTPUT</i> with the matched subexpressions
-       * substituted or <b>nil</b> if no match was found.
-       *
-       * @see regex(7)
-       *
-       * @usage regexpsub ("aaabbb", "(.*ab)", "s_\\1_e") -> "s_aaab_e"
-       * @usage regexpsub ("aaabbb", "(.*ba)", "s_\\1_e") -> nil
-       */
-
     if (NIL_P(i) || NIL_P(p))
       return Qnil;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/builtins.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/builtins.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/builtins.rb    2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/builtins.rb    2016-05-31 
09:44:05.000000000 +0200
@@ -146,9 +146,20 @@
       end
     end
 
-    # - Removes element from a list
-    # - Remove key/value pair from a map
-    # - Remove item from term
+    # Remove *element* from a **copy** of *object*.
+    #
+    # @param object [::Hash,::Array,Yast::Term,nil] a container
+    # @param element [Object,Integer,nil]
+    #   Any key for Hash;
+    #   Integer for Array and Term (negative means out of bounds!);
+    #   terms are indexed from 1 (**one**)
+    # @return [Object,nil]
+    #   Always returns a **copy** of *object*.
+    #   The copy is unchanged if either *object* or *element* is
+    #   `nil`, or if an Integer *element* is out of bounds.
+    #   otherwise the key/index *element* is removed from the copy.
+    # @raise [RuntimeError] if *object* has an unexpected type
+    #
     # @deprecated use native ruby method {::Hash#delete}, {::Array#delete_at}
     #   or {Yast::Term#params} (call delete_at on term params)
     def self.remove(object, element)
@@ -366,13 +377,11 @@
         return Yast.deep_copy(list) if offset1 < 0 || offset2 >= list.size || 
(offset1 > offset2)
 
         res = []
-        if offset1 > 0
-          res.concat list[0..offset1 - 1]
-        end
-        res.concat list[offset1..offset2].reverse!
-        if offset2 < list.size - 1
-          res.concat list[offset2 + 1..-1]
-        end
+
+        res.concat(list[0..offset1 - 1]) if offset1 > 0
+        res.concat(list[offset1..offset2].reverse!)
+        res.concat(list[offset2 + 1..-1]) if offset2 < list.size - 1
+
         Yast.deep_copy(res)
       end
     end
@@ -571,9 +580,7 @@
     # Yast compatible way how to format string with type conversion
     # see tostring for type conversion
     def self.sformat(format, *args)
-      if format.nil? || !format.is_a?(::String)
-        return nil
-      end
+      return nil if format.nil? || !format.is_a?(::String)
 
       return format if args.empty?
 
@@ -1033,6 +1040,29 @@
     #
     # In a condition, use `string =~ pattern` which returns integer or nil.
 
+    # @method self.regexpsub(input, pattern, output)
+    #
+    # @param input       [String] a string to search
+    # @param pattern     [String] a regex in the C(!) syntax
+    # @param output      [String] a template for what to return
+    # @return [String, nil] replacement, or no match
+    # @see regexpmatch notes about regex syntax
+    #
+    # Searches a string for a POSIX Extended Regular Expression match
+    # and returns *output* with the matched subexpressions
+    # substituted or `nil` if no match was found.
+    #
+    # If *string* or *pattern* is `nil`, or
+    # if pattern is an invalid regex, `nil` is returned.
+    # If *output* is `nil` or any other non-String, an Exception is raised.
+    #
+    # @example Usage
+    #   Builtins.regexpsub("lose", "(.*)s(.*)", "\\1v\\2")   # -> "love"
+    # @example Usage misunderstood
+    #   Builtins.regexpsub("lose", "s", "v")                 # -> "v"
+    # @example No match
+    #   Builtins.regexpsub("team", "I", "profit")            # -> nil
+
     ###########################################################
     # Yast Term Builtins
     ###########################################################
@@ -1120,12 +1150,10 @@
             raise "unknown value from comparison #{i1 <=> u2}"
           end
         end
-        unless ss1.empty?
-          res += ss1.reverse
-        end
-        unless ss2.empty?
-          res += ss2.reverse
-        end
+
+        res += ss1.reverse unless ss1.empty?
+        res += ss2.reverse unless ss2.empty?
+
         Yast.deep_copy(res.reverse)
       end
 
@@ -1177,12 +1205,8 @@
           end
         end
 
-        unless ss1.empty?
-          res += ss1.reverse
-        end
-        unless ss2.empty?
-          res += ss2.reverse
-        end
+        res += ss1.reverse unless ss1.empty?
+        res += ss2.reverse unless ss2.empty?
 
         Yast.deep_copy(res.reverse)
       end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/debugger.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/debugger.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/debugger.rb    1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/debugger.rb    2016-05-31 
09:44:05.000000000 +0200
@@ -0,0 +1,208 @@
+
+require "yast"
+
+module Yast
+  class Debugger
+    class << self
+      include Yast::Logger
+      include Yast::UIShortcuts
+
+      # Start the Ruby debugger. It handles the current UI mode and displays
+      # an user request if the debugger front-end needs to be started manually.
+      # @param [Boolean] remote if set to true the server is accesible from 
network.
+      #   By default the debugger can connect only from the local machine, not 
from
+      #   the network. If you need remote debugging then enable it.
+      #   WARNING: There is no authentication, everybody can connect to
+      #   the debugger! Use only in a trusted network as this is actually
+      #   a backdoor to the system! For secure connection use SSH and start
+      #   the debugger locally after connecting via SSH.
+      # @param [Fixnum] port the port number where the debugger server will
+      #   listen to
+      # @param [Boolean] start_client autostart the debugger client
+      #   (ignored in remote debugging)
+      # @example Start the debugger with default settings:
+      #   require "yast/debugger"
+      #   Yast::Debugger.start
+      # @example When using the debugger temporary you can use just simple:
+      #   require "byebug"
+      #   byebug
+      def start(remote: false, port: 3344, start_client: true)
+        return unless load_debugger
+
+        # do not start the server if it is already running
+        if Byebug.started?
+          log.warn "The debugger is already running at port 
#{Byebug.actual_port}"
+          log.warn "Skipping the server setup"
+        else
+          Yast.import "UI"
+          if UI.TextMode || remote || !start_client
+            # in textmode or in remote mode ask the user to start
+            # the debugger client manually
+            UI.OpenDialog(Label(debugger_message(remote, port)))
+            popup = true
+          else
+            # in GUI open an xterm session with the debugger
+            start_gui_session(port)
+          end
+
+          # start the server and wait for connection, add an extra delay
+          # if we start the front end automatically to get the server ready
+          # (to avoid "Broken pipe" error)
+          # FIXME: looks like a race condition inside byebug itself...
+          start_server(remote, port, delay: !popup)
+
+          UI.CloseDialog if popup
+        end
+
+        # start the debugger session
+        byebug
+        # Now you can inspect the current state in the debugger,
+        # or use "next" to continue.
+        # Use "help" command to see the available commands, see more at
+        # https://github.com/deivid-rodriguez/byebug/blob/master/GUIDE.md
+      end
+
+      # start the Ruby debugger if "Y2DEBUGGER" environment
+      # variable is set to "1", "remote" or "manual" (the test is case
+      # insensitive, "y2debugger" variable can be also used)
+      def start_from_env
+        # do not evaluate the debugger request again for each client started,
+        # run the debugger evaluation only once
+        return if @debugger_handled
+        @debugger_handled = true
+
+        debug = env_value
+        return if debug != "1" && debug != "remote" && debug != "manual"
+
+        # FIXME: the UI.TextMode call is used here just to force the UI
+        # initialization, if it is initialized inside the start method the
+        # ncurses UI segfaults :-(
+        # interestengly, the Qt UI works correctly...
+        Yast.import "UI"
+        log.info "text mode: #{UI.TextMode}"
+
+        log.info "Debugger set to: #{debug}"
+        start(remote: debug == "remote", start_client: debug != "manual")
+      end
+
+      # is the Ruby debugger installed and can be loaded?
+      # @return [Boolean] true if the debugger is present
+      def installed?
+        require "byebug"
+        true
+      rescue LoadError
+        false
+      end
+
+    private
+
+      # read the debugger value from Y2DEBUGGER environment variable,
+      # do case insensitive match
+      # @return [String,nil] environment value or nil if not defined
+      def env_value
+        # sort the keys to have a deterministic behavior and to prefer 
Y2DEBUGGER
+        # over the other variants, then do a case insensitive search
+        key = ENV.keys.sort.find { |k| k.match(/\AY2DEBUGGER\z/i) }
+        log.debug "Found debugger key: #{key.inspect}"
+        key ? ENV[key] : nil
+      end
+
+      # load the Ruby debugger, report an error on failure
+      # @return [Boolean] true if the debugger was loaded successfuly,
+      #   false on error
+      def load_debugger
+        require "byebug"
+        require "byebug/core"
+        true
+      rescue LoadError
+        # catch loading error, the debugger is optional (might not be present)
+        Yast.import "Report"
+        Report.Error(format("Cannot load the Ruby debugger.\n" \
+          "Make sure '%s' Ruby gem is installed.", "byebug"))
+        false
+      end
+
+      # starts the debugger server and waits for a client connection
+      # @param [Boolean] remote if set to true the server is accesible from 
network
+      # @param [Fixnum] port the port number used by the server
+      # @param [Boolean] delay add extra delay after starting the server
+      def start_server(remote, port, delay: false)
+        Byebug.wait_connection = true
+        host = remote ? "0.0.0.0" : "localhost"
+        log.info "Starting debugger server (#{host}:#{port}), waiting for 
connection..."
+        Byebug.start_server(host, port)
+        # extra delay if needed
+        sleep(3) if delay
+      end
+
+      # starts a debugger session in xterm
+      # @param [Fixnum] port the port number to connect to
+      def start_gui_session(port)
+        job = fork do
+          # wait until the main thread starts the debugger and opens the port
+          # for listening
+          loop do
+            break if port_open?(port)
+            sleep(1)
+          end
+
+          # start the debugger client in an xterm session
+          exec "xterm", "-e", "byebug", "-R", "#{port}"
+        end
+
+        # detach the process, we do not wait for it so avoid zombies
+        Process.detach(job)
+      end
+
+      # compose the popup message describing how to manually connect to
+      # the running debugger
+      # @param [Boolean] remote boolean flag indicating whether the debugger
+      #   can be accessed remotely
+      # @param [Fixnum] port the port number used by the debugger
+      # @return [String] text
+      def debugger_message(remote, port)
+        if remote
+          # get the local IP addresses
+          require "socket"
+          remote_ips = Socket.ip_address_list.select { |a| a.ipv4? && 
!a.ipv4_loopback? }
+          cmd = remote_ips.map { |a| debugger_cmd(a.ip_address, port) 
}.join("\n")
+
+          if remote_ips.size > 1
+            prefix = "To connect to the debugger from a remote machine use one 
of these commands:"
+          else
+            prefix = "To connect to the debugger from a remote machine use 
this command:"
+          end
+        else
+          prefix = "To start the debugger switch to another console and run:"
+          cmd = debugger_cmd(nil, port)
+        end
+
+        "#{prefix}\n\n#{cmd}\n\nWaiting for the connection..."
+      end
+
+      # construct a debugger command displayed to user in a popup
+      # @param [String,nil] host the machine host name or IP address, nil if
+      #   the debugger can be accessed only locally
+      # @param [Fixnum] port the port number used by the debugger
+      # @return [String] byebug command label
+      def debugger_cmd(host, port)
+        host_param = host ? "#{host}:" : ""
+        "    byebug -R #{host_param}#{port}"
+      end
+
+      # is the target port open?
+      # @param [Fixnum] port the port number
+      # @return [Boolean] true if the port is open, false otherwise
+      def port_open?(port)
+        require "socket"
+
+        begin
+          TCPSocket.new("localhost", port).close
+          true
+        rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
+          false
+        end
+      end
+    end
+  end
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/i18n.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/i18n.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/i18n.rb        2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/i18n.rb        2016-05-31 
09:44:05.000000000 +0200
@@ -113,7 +113,7 @@
       FastGettext::Translation.n_(singular, plural, num)
     end
 
-    private
+  private
 
     def available_locales
       # the first item is used as the fallback
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/logger.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/logger.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/logger.rb      2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/logger.rb      2016-05-31 
09:44:05.000000000 +0200
@@ -37,11 +37,11 @@
     caller[caller_frame] =~ /(.+):(\d+):in `([^']+)'/
     y2_logger(level, "Ruby", Regexp.last_match(1), Regexp.last_match(2).to_i, 
Regexp.last_match(3), res)
 
-    if backtrace
-      y2_logger_helper(level, [2, "------------- Backtrace begin 
-------------"])
-      caller(3).each { |frame| y2_logger_helper(level, [4, frame]) }
-      y2_logger_helper(level, [2, "------------- Backtrace end 
---------------"])
-    end
+    return unless backtrace
+
+    y2_logger_helper(level, [2, "------------- Backtrace begin -------------"])
+    caller(3).each { |frame| y2_logger_helper(level, [4, frame]) }
+    y2_logger_helper(level, [2, "------------- Backtrace end ---------------"])
   end
 
   # write to log debug message with arguments formated by 
{Yast::Builtins.sformat}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/ops.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/ops.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/ops.rb 2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/ops.rb 2016-05-31 
09:44:05.000000000 +0200
@@ -443,9 +443,8 @@
           # stupid nil handling
           fval = @value[i]
           sval = other[i]
-          if sval.nil? && !fval.nil?
-            return 1
-          end
+
+          return 1 if sval.nil? && !fval.nil?
 
           # we need to use out builtin, but also we need to
           res = Ops.comparable_object(fval, @localized) <=> sval
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/path.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/path.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/path.rb        2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/path.rb        2016-05-31 
09:44:05.000000000 +0200
@@ -55,7 +55,7 @@
       size <=> other.size
     end
 
-    private
+  private
 
     attr_reader :components
     COMPLEX_CHAR_REGEX = /[^a-zA-Z0-9_-]/
@@ -110,11 +110,11 @@
         end
       end
 
-      unless buffer.empty?
-        return if invalid_buffer?(buffer)
+      return if buffer.empty?
 
-        @components << modify_buffer(buffer)
-      end
+      return if invalid_buffer?(buffer)
+
+      @components << modify_buffer(buffer)
     end
 
     def invalid_buffer?(buffer)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ruby-bindings-3.1.46/src/ruby/yast/rspec/scr.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/rspec/scr.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/rspec/scr.rb   2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/rspec/scr.rb   2016-05-31 
09:44:05.000000000 +0200
@@ -63,12 +63,12 @@
         end
         Yast::WFM.SCRSetDefault(@scr_handle)
 
-        if block_given?
-          begin
-            yield
-          ensure
-            reset_scr_root
-          end
+        return unless block_given?
+
+        begin
+          yield
+        ensure
+          reset_scr_root
         end
       end
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/wfm.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/wfm.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/wfm.rb 2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/wfm.rb 2016-05-31 
09:44:05.000000000 +0200
@@ -1,6 +1,7 @@
 require "yast/builtinx"
 require "yast/builtins"
 require "yast/ops"
+require "yast/debugger"
 
 # @private we need it as clients is called in global contenxt
 GLOBAL_WFM_CONTEXT = proc {}
@@ -8,6 +9,8 @@
   # Wrapper class for WFM component in Yast
   # See yast documentation for WFM
   module WFM
+    extend Yast::Logger
+
     # Returns list of arguments passed to client or element at given index
     #
     # @example Get all args
@@ -181,11 +184,26 @@
       call_builtin(Regexp.last_match(1), Regexp.last_match(2).to_i, *args)
     end
 
+    def self.ask_to_run_debugger?
+      Yast.import "Mode"
+
+      !Mode.auto && Debugger.installed?
+    end
+
+    # @param [Exception] e the caught exception
+    # @return [String] human readable exception description
+    def self.internal_error_msg(e)
+      "Internal error. Please report a bug report with logs.\n" \
+        "Details: #{e.message}\n" \
+        "Caller:  #{e.backtrace.first}"
+    end
+
     # @private wrapper to run client in ruby
     def self.run_client(client)
       Builtins.y2milestone "Call client %1", client
       code = File.read client
       begin
+        Debugger.start_from_env
         result = eval(code, GLOBAL_WFM_CONTEXT.binding, client)
 
         allowed_types = Ops::TYPES_MAP.values.flatten
@@ -203,10 +221,26 @@
             e.message,
             e.backtrace
           )
-          Yast.import "Report"
-          Report.Error "Internal error. Please report a bug report with 
logs.\n" \
-            "Details: #{e.message}\n" \
-            "Caller:  #{e.backtrace.first}"
+
+          msg = internal_error_msg(e)
+
+          if ask_to_run_debugger?
+            Yast.import "Popup"
+            Yast.import "Label"
+            msg += "\n\nStart the Ruby debugger now and debug the issue?" \
+              " (Experts only!)"
+
+            if Popup.YesNoHeadline(Label.ErrorMsg, msg)
+              Debugger.start
+              # Now you can restart the client and watch it step-by-step with
+              # "next"/"step" commands or you can add some breakpoints into
+              # the code and use "continue".
+              retry
+            end
+          else
+            Yast.import "Report"
+            Report.Error(msg)
+          end
         rescue Exception => e
           Builtins.y2internal("Error reporting failed with '%1' and backtrace 
%2",
             e.message,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast/yast.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast/yast.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast/yast.rb        2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast/yast.rb        2016-05-31 
09:44:05.000000000 +0200
@@ -120,9 +120,7 @@
     mod = Yast.const_get module_name
 
     # if never included, then include
-    if !target.class.include? mod
-      target.class.send(:include, mod)
-    end
+    target.class.send(:include, mod) unless target.class.include?(mod)
 
     encoded_name = path_without_suffix.gsub(/[-.\/]/, "_")
     initialized_variable = "@" + encoded_name + "initialized"
@@ -189,8 +187,7 @@
             return Yast::call_yast_function("#{mname}", :#{sname}, $1, 
$2.to_i, *args)
           end
         END
-      end
-      if stype == :variable
+      elsif stype == :variable
         m.module_eval <<-"END"
           def self.#{sname}
             return Yast::call_yast_function("#{mname}", :#{sname})
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-ruby-bindings-3.1.46/src/ruby/yast.rb 
new/yast2-ruby-bindings-3.1.48/src/ruby/yast.rb
--- old/yast2-ruby-bindings-3.1.46/src/ruby/yast.rb     2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/src/ruby/yast.rb     2016-05-31 
09:44:05.000000000 +0200
@@ -49,7 +49,6 @@
 # unshift it in reverse order to keep precedence
 Yast.y2paths.reverse.each do |p|
   dir_path = File.join(p, "lib")
-  if File.exist? dir_path
-    $LOAD_PATH.unshift dir_path
-  end
+
+  $LOAD_PATH.unshift dir_path if File.exist? dir_path
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ruby-bindings-3.1.46/tests/ruby/builtins_regexps_spec.rb 
new/yast2-ruby-bindings-3.1.48/tests/ruby/builtins_regexps_spec.rb
--- old/yast2-ruby-bindings-3.1.46/tests/ruby/builtins_regexps_spec.rb  
2016-01-13 11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/tests/ruby/builtins_regexps_spec.rb  
2016-05-31 09:44:05.000000000 +0200
@@ -35,7 +35,34 @@
   end
 
   describe ".regexpsub" do
-    it "works as expected" do
+    def regexpsub(input, pattern, output)
+      Yast::Builtins.regexpsub(input, pattern, output)
+    end
+
+    it "handles nil in INPUT or PATTERN, returning nil" do
+      expect(regexpsub(nil, "I", "profit")).to eq(nil)
+      expect(regexpsub(nil, "I", nil)).to eq(nil)
+      expect(regexpsub("team", nil, "profit")).to eq(nil)
+      expect(regexpsub("team", nil, nil)).to eq(nil)
+    end
+
+    it "raises TypeError if OUTPUT is nil" do
+      expect { regexpsub("team", "I", nil) }.to raise_error(TypeError)
+    end
+
+    it "returns nil if there's no match" do
+      expect(regexpsub("team", "I", "profit")).to eq(nil)
+    end
+
+    it "returns OUTPUT (not INPUT!) if there is a match" do
+      expect(regexpsub("lose", "s", "v")).to eq("v")
+    end
+
+    it "substitutes match groups in OUTPUT" do
+      expect(regexpsub("lose", "(.*)s(.*)", "\\1v\\2")).to eq("love")
+    end
+
+    it "works on legacy tests" do
       expect(Yast::Builtins.regexpsub(nil, nil, nil)).to eq(nil)
 
       # from Yast documentation
@@ -43,11 +70,11 @@
       expect(Yast::Builtins.regexpsub("aaabbb", "(.*ba)", "s_\\1_e")).to 
eq(nil)
 
       # from sysconfig remove whitespaces
-      expect(Yast::Builtins.regexpsub(" lest test\tsrst\t",
-        "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ \t]*$",
-        "\\1")).to eq("lest test\tsrst")
-      expect(Yast::Builtins.regexpsub("", "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ 
\t]*$", "\\1")).to eq("")
-      expect(Yast::Builtins.regexpsub("  \t  ", "^[ \t]*(([^ \t]*[ \t]*[^ 
\t]+)*)[ \t]*$", "\\1")).to eq("")
+      pattern = "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ \t]*$"
+      expect(Yast::Builtins.regexpsub(" lest test\tsrst\t", pattern, "\\1"))
+        .to eq("lest test\tsrst")
+      expect(Yast::Builtins.regexpsub("", pattern, "\\1")).to eq("")
+      expect(Yast::Builtins.regexpsub("  \t  ", pattern, "\\1")).to eq("")
 
       # the result must be UTF-8 string
       expect(Yast::Builtins.regexpsub("aaabbb", "(.*ab)", 
"s_\\1_e").encoding).to eq(Encoding::UTF_8)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-ruby-bindings-3.1.46/tests/ruby/y2logger_spec.rb 
new/yast2-ruby-bindings-3.1.48/tests/ruby/y2logger_spec.rb
--- old/yast2-ruby-bindings-3.1.46/tests/ruby/y2logger_spec.rb  2016-01-13 
11:00:12.000000000 +0100
+++ new/yast2-ruby-bindings-3.1.48/tests/ruby/y2logger_spec.rb  2016-05-31 
09:44:05.000000000 +0200
@@ -44,15 +44,16 @@
 
     it "does not crash when logging an invalid UTF-8 string" do
       # do not process this string otherwise you'll get an exception :-)
-      invalid_utf8 = "invalid sequence: \xE3\x80"
-      # just make sure it is really an UTF-8 string
-      expect(invalid_utf8.encoding).to eq(Encoding::UTF_8)
+      invalid_utf8 = "invalid sequence: " + 0xE3.chr + 0x80.chr
+      # just make sure it is really an invalid UTF-8 string
+      invalid_utf8.force_encoding(Encoding::UTF_8)
+      expect(invalid_utf8.valid_encoding?).to eq(false)
       expect { Yast.y2milestone(invalid_utf8) }.not_to raise_error
     end
 
     it "does not crash when logging ASCII string with invalid UTF-8" do
       # do not process this string otherwise you'll get an exception :-)
-      invalid_ascii = "invalid sequence: \xE3\x80"
+      invalid_ascii = "invalid sequence: " + 0xE3.chr + 0x80.chr
       invalid_ascii.force_encoding(Encoding::ASCII)
       expect { Yast.y2milestone(invalid_ascii) }.not_to raise_error
     end


Reply via email to