Hello community,

here is the log from the commit of package yast2 for openSUSE:Factory checked 
in at 2020-01-24 14:10:54
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2 (Old)
 and      /work/SRC/openSUSE:Factory/.yast2.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2"

Fri Jan 24 14:10:54 2020 rev:471 rq:766631 version:4.2.59

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2/yast2.changes      2020-01-17 
16:03:42.120392215 +0100
+++ /work/SRC/openSUSE:Factory/.yast2.new.26092/yast2.changes   2020-01-24 
14:11:02.122406867 +0100
@@ -1,0 +2,27 @@
+Thu Jan 23 14:29:49 UTC 2020 - Imobach Gonzalez Sosa <[email protected]>
+
+- Add an option to enable the online search in the package
+  selector (jsc#SLE-9109).
+- 4.2.59
+
+-------------------------------------------------------------------
+Thu Jan 23 13:22:10 UTC 2020 - Steffen Winterfeldt <[email protected]>
+
+- don't use /bin/systemd compat symlink (bsc#1160890)
+- 4.2.58
+
+-------------------------------------------------------------------
+Wed Jan 22 15:27:15 UTC 2020 - Josef Reidinger <[email protected]>
+
+- CommandLine: Add ability to actions to skip writing.
+  Useful for more CLI bug fixes e.g. bsc#1160928
+- 4.2.57
+
+-------------------------------------------------------------------
+Wed Jan 22 11:44:01 CET 2020 - [email protected]
+
+- Evaluating system release/version in an more understandable form
+  for the user e.g. "15-SP2" (improvement for fate#325834).
+- 4.2.56
+
+-------------------------------------------------------------------

Old:
----
  yast2-4.2.55.tar.bz2

New:
----
  yast2-4.2.59.tar.bz2

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

Other differences:
------------------
++++++ yast2.spec ++++++
--- /var/tmp/diff_new_pack.MOQx7W/_old  2020-01-24 14:11:04.030407513 +0100
+++ /var/tmp/diff_new_pack.MOQx7W/_new  2020-01-24 14:11:04.030407513 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2
-Version:        4.2.55
+Version:        4.2.59
 Release:        0
 Summary:        YaST2 Main Package
 License:        GPL-2.0-only

++++++ yast2-4.2.55.tar.bz2 -> yast2-4.2.59.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/library/commandline/MAINTAINER 
new/yast2-4.2.59/library/commandline/MAINTAINER
--- old/yast2-4.2.55/library/commandline/MAINTAINER     2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/commandline/MAINTAINER     1970-01-01 
01:00:00.000000000 +0100
@@ -1 +0,0 @@
-Ladislav Slezak <[email protected]>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/commandline/doc/CommandLine-section.xml 
new/yast2-4.2.59/library/commandline/doc/CommandLine-section.xml
--- old/yast2-4.2.55/library/commandline/doc/CommandLine-section.xml    
2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/commandline/doc/CommandLine-section.xml    
1970-01-01 01:00:00.000000000 +0100
@@ -1,450 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE section PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN" 
"/usr/share/xml/docbook/schema/dtd/4.2/docbookx.dtd">
-
-
-<!-- $Id$ -->
-<section id="Commandline-library">
-<title>Advanced YaST2 command line parsing</title>
-<!-- 
-Authors:
-Stanislav Visnovsky <[email protected]>
-Michal Svec <[email protected]> - original proposal
--->
-
-<section>
-    <title>Important features</title>
-    <itemizedlist>
-        <listitem><para>simple specification in the YaST 
module</para></listitem>
-        <listitem><para>automatic help</para></listitem>
-        <listitem><para>automatic checking of arguments (types, 
format)</para></listitem>
-        <listitem><para>interactive session without UI</para></listitem>
-    </itemizedlist>
-</section>
-<section>
-    <title>Basic usage of module CommandLine</title>
-    <para>
-The aim of the module is to provide as automatic interface as
-possible for controlling the module. To support interactive
-sessions, the YaST module needs to provide command-handling loop
-similar to concept of event-handling in GUIs.</para>
-<para>
-If the module does not need to do any special handling of the actions,
-it can use the "commandline" include (a wrapper for CommandLine). The
-include defines a single function "CommandLineRun()", which implements
-a standard event-loop and returns true on success. The module just
-needs to specify handlers for actions, user-interface, initialization
-and finishing.
-</para>
-
-<example>
-    <title>Simple CommandLine definition</title>
-    <programlisting>
-{
-
-define void deleteHandler( map options ) ``{
-    string dev = options["device"]:"";
-    <link 
linkend="Module_CommandLine_Print">CommandLine::Print</link>("Deleting: "+dev);
-
-    if(Lan::Delete(dev) &amp;&amp; Lan::Commit())
-       <link 
linkend="Module_CommandLine_Print">CommandLine::Print</link>("Success");
-    else
-       <link 
linkend="Module_CommandLine_Print">CommandLine::Print</link>("Error");
-}
-
-...
-
-map cmdline = $[
-    "help"     : "Configuration of network cards",
-    "id"       : "lan",
-    "guihandler": ``(LanSequence()),
-    "initialize": ``(Lan::Read()),
-    "finish"   : ``(Lan::Finish()),
-
-    "actions"  : $[
-       "list" : $[
-           "help"      : "display configuration summary",
-           "example"   : "lan list configured",
-           "handler"   : ``(listHandler())
-       ],
-       "add" : $[
-           "help"      : "add a network card",
-           "handler"   : ``(addHandler())
-       ],
-       "delete" : $[
-           "help"      : "delete a network card",
-           "handler"   : ``(deleteHandler())
-       ]
-    ],
-    ...
-];
-
-import "Lan";
-include "commandline/commandline.ycp";
-
-CommandLineRun(cmdline);
-
-/* EOF */
-}
-    </programlisting>
-
-</example>
-<para>
-The UI handler is specified in the "guihandler" key of the command
-line description map. It must take no arguments and return boolean,
-true on success.</para>
-<para>
-The initialize resp. finish handler is specified by the
-"initialize" resp. "finish" key of the description map. They
-do not take any arguments and must return boolean, true on success. Notice 
-that "initialize" and "finish" handlers are not used if a user
-asked for GUI (guihandler is used instead and therefore it must
-do initializing and finishing on its own).
-The handler for an action is specified in the "handler" key of the
-action description map. Each handler must take a single argument
-containing the options entered by the user and return a boolean, true on
-success. If the handler returns "false", the command line 
-will abort for non-interactive handling. This is useful for
-handling error states. However, a handler must use
-CommandLine::Abort()
-to stop event-handling in the interactive mode.
-</para>
-<para>
-
-The CommandLine module is stateful, i.e., it contains a current state
-of command line parsing/interactive console control of a YaST module.
-Therefore, the CommandLineRun() handles the commands as follows:</para>
-<orderedlist>
-    <listitem><para>standard UI start of a module - <link 
linkend="Module_CommandLine_StartGUI">CommandLine::StartGUI</link> will return 
true in this case</para></listitem>
-    <listitem><para>command given as an argument - the inner while loop will 
be done only once</para></listitem>
-    <listitem><para>interactive controling of a module - the while loop will 
be done as long as the user does not enter
-            "exit" or "quit"</para></listitem>
-</orderedlist>
-
-</section>
-<section>
-    <title>Internally handled commands</title>
-
-    <variablelist>
-        <varlistentry>
-            <term>help</term>
-            <listitem>
-                <para>shows the help text for the command</para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term>interactive</term>
-            <listitem>
-                <para>starts interactive session without UI</para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term>&lt;command&gt; help</term>
-            <listitem>
-                <para> shows the command-specific help</para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term>&lt;command&gt; quiet</term>
-            <listitem>
-                <para>option to supress the progress messages</para>
-            </listitem>
-        </varlistentry>
-    </variablelist>
-
-<para>These are available in interactive mode only:</para>
-
-    <variablelist>
-        <varlistentry>
-            <term>quit</term>
-            <listitem id="Module_CommandLine_Aborted">
-                <para>quits interactive session, sets
-                CommandLine::Aborted() flag to true</para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term>exit</term>
-            <listitem id="Module_CommandLine_Aborted">
-                <para>exits interactive
-                session, sets CommandLine::Aborted() flag to false</para>
-            </listitem>
-        </varlistentry>
-    </variablelist>
-</section>
-
-<section>
-    <title>Specification of the supported commands in YaST module</title>
-
-    <note><para>
-If the map does not follow the following rules, an error
-will be emitted into log.</para></note>
-
-<para>
-The map describing the command line interface of a module must contain
-"id" entry containing the name of the module. The map can contain
-global help text, a list of actions, a list of options and a list for 
-mapping of options to actions (which optionscan be used for which 
-actions). Each action and option must have its help text.
-</para>
-<para>
-Actions is a map with the action name as a key. For each
-action, it isnecessary to provide the help text. Optionally, action
-can have defined an example of usage.
-</para>
-<para>
-A list of flags can be specified to change the default behavior of
-the parameter checker. It is a list with key "options". Currently known flags:
-</para>
-
-    <variablelist>
-        <varlistentry>
-            <term>non_strict</term>
-            <listitem>
-                <para>for unknown parameters, do not check their validity
-                               can be used for passing unknown options into 
the handler</para>
-            </listitem>
-        </varlistentry>
-    </variablelist>
-
-    <example>
-       <title>Actions map definition</title>
-        <programlisting>
-       "actions"       : $[
-                       "list"  : $[
-                               "help": "display configuration summary",
-                               "example": "lan list configured",
-                               "options": [ "non_strict" ]
-                       ],
-                       "add"   : $[
-                               "help": "add a network card" ],
-                       ...
-                        ],
-        </programlisting>
-    </example>
-        <para>
-
-Options is a map with the option name as a key. For each
-option, it is necessary to provide a description text in "help" key,
-and a "type" key (for options with arguments only). Optionally, an
-option can contain an example.
-</para>
-<para>
-There are two kinds of options: flags and options, which require an
-argument.For flags ommit type key, or specify type as "". A type is a
-string describing the type.basic types supported are string, boolean,
-integer.
-</para>
-
-    <variablelist>
-        <title>Special types:</title>
-        <varlistentry>
-            <term>regex</term>
-            <listitem>
-                <para>In this case, you need to specify "typespec" key 
containing
-                        the regular expression the argument should be matched 
against.</para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term>enum</term>
-            <listitem>
-                <para>
-                    In this case, the typespec key must contain a list of 
possible
-                            values as strings
-                </para>
-            </listitem>
-        </varlistentry>
-    </variablelist>
-    <example>
-       <title>Options map definition</title>
-        <programlisting>
-       "options"       : $[
-                       "propose" : $[
-                               "help": "propose a configuration",
-                               "example": "lan add propose",
-                               "type": ""
-                       ],
-                       "device": $[
-                               "help": "device ID",
-                               "type": "string",
-                               "example": "lan add device=eth0"
-                       ],
-                       "blem"  : $[
-                               "help": "other argument (without spaces)",
-                               "type": "regex",
-                               "typespec": "^[^ ]+$"
-                       ],
-                       "atboot": $[
-                               "help": "should be brought up at boot?",
-                               "type": "enum",
-                               "typespec": ["yes","no"]
-                                }
-
-                            </programlisting>
-                        </example>
-
-                        <para>
-The actions and options are grouped together using mappings.
-Currently, you can mapan action to a set of options. You can't specify
-required/optional options, all ofthem are optional.
-</para>
-
-<example>
-    <title>Mappings between actions and their options</title>
-    <programlisting>
-       "mappings"      $[
-                       "list"  : [ "configured", "unconfigured" ],
-                       "add"   : [ "device", "ip", "netmask", "blem" ],
-                       "delete": [ "device" ]
-                        ]
-
-        </programlisting>
-    </example>
-
-</section>
-<section><title>Advanced API</title>
-    <para>
-If you need to write your own event loop, this is a part of the
-CommandLine API useful for this:</para>
-    <variablelist>
-        <varlistentry>
-            <term id="Module_CommandLine_StartGUI">boolean 
CommandLine::StartGUI()</term>
-            <listitem>
-                <para>
-                    returns true, if the user asked to start up the
-                            module GUI
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Scan">list CommandLine::Scan()</term>
-            <listitem>
-                <para>
-                    reads a new command line in interactive mode, splits the 
arguments into a list
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Command">map 
CommandLine::Command()</term>
-            <listitem>
-                <para>
-                    parse (and scan if needed) next command and return its map
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Parse">map CommandLine::Parse( list 
commandline )</term>
-            <listitem>
-                <para>
-                    lower-level function to parse the command line, check the 
validity
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Done">boolean 
CommandLine::Done()</term>
-            <listitem>
-                <para>
-                    returns true, if the last command was already returned
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Aborted">boolean 
CommandLine::Aborted()</term>
-            <listitem>
-                <para>
-                    returns true, if the user asked to cancel the changes
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Error">void 
CommandLine::Error(string)</term>
-            <listitem>
-                <para>
-                    prints the string and then a message how to
-                            obtain the help
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_Print">void 
CommandLine::Print(string)</term>
-            <listitem>
-                <para>
-                    prints the string
-                </para>
-            </listitem>
-        </varlistentry>
-        <varlistentry>
-            <term id="Module_CommandLine_PrintVerbose">void 
CommandLine::PrintVerbose(string)</term>
-            <listitem>
-                <para>
-                    same as CommandLine::Print, but the string is printed only 
in verbose mode
-                </para>
-            </listitem>
-        </varlistentry>
-    </variablelist>
-
-
-    <example><title>Example of an event-loop</title>
-        <programlisting>
-
-       import "CommandLine";
-
-       if( ! <link linkend="Module_CommandLine_Init">CommandLine::Init</link>( 
description_of_commands, Args() ) ) return;
-
-       if( <link 
linkend="Module_CommandLine_StartGUI">CommandLine::StartGUI</link>() ) {
-
-               &lt;do standard GUI module&gt;
-
-               return;
-       }
-       
-       &lt;initialize call&gt;
-
-       while( ! <link 
linkend="Module_CommandLine_Done">CommandLine::Done</link>() )
-       {
-               map command = <link 
linkend="Module_CommandLine_Command">CommandLine::Command</link>();
-
-               &lt;handle commands here&gt;
-       }
-       
-       &lt;finish call&gt;
-    </programlisting>
-</example>
-
-<para id="Module_CommandLine_Init">
-The CommandLine::Init() returns boolean whether the module has
-something to do. If the user only requested help or the arguments
-passed were not correct, the module should stop processing.
-</para>
-
-<para id="Module_CommandLine_Command">
-The CommandLine::Command() will do the user interaction if necessary.
-Also, it will handle all supported"system" commands, like "help",
-"exit" and "quit".
-</para>
-
-<note>
-    <para>
-In interactive mode, the communication uses /dev/tty. In non-interactive 
commandline
-mode it prints everything to standard error output.</para>
-</note>
-</section>
-<section>
-    <title>Example usage in YaST module</title>
-    
-    <para>For an example without using the event-loop provided by the
-        CommandLine module, see <filename>lan-simple.ycp</filename>.</para>
-<informalexample>
-    <programlisting><xi:include href="lan-simple.ycp" parse="text"
-                          
xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
-</informalexample>
-
-    <para> For an example with the standard event-loop provided by the
-        commandline.ycp include, see 
<filename>lan-simpler.ycp</filename>.</para>
-<informalexample>
-    <programlisting><xi:include href="lan-simpler.ycp" parse="text"
-                          
xmlns:xi="http://www.w3.org/2001/XInclude"/></programlisting>
-</informalexample>
-</section>
-
-
-
-</section>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/library/commandline/doc/CommandLine.txt 
new/yast2-4.2.59/library/commandline/doc/CommandLine.txt
--- old/yast2-4.2.55/library/commandline/doc/CommandLine.txt    2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/commandline/doc/CommandLine.txt    2020-01-23 
15:43:03.000000000 +0100
@@ -22,76 +22,28 @@
 similar to concept of event-handling in GUIs.
 
 If the module does not need to do any special handling of the actions,
-it can use the "commandline" include (a wrapper for CommandLine). The
-include defines a single function "CommandLineRun()", which implements
-a standard event-loop and returns true on success. The module just
+it can use the Run method of CommandLine module. The module just
 needs to specify handlers for actions, user-interface, initialization
 and finishing.
 
-Example:
-
-{
-
-define void deleteHandler( map options ) ``{
-    string dev = options["device"]:"";
-    CommandLine::Print("Deleting: "+dev);
-
-    if(Lan::Delete(dev) && Lan::Commit())
-       CommandLine::Print("Success");
-    else
-       CommandLine::Print("Error");
-}
-
-...
-
-map cmdline = $[
-    "help"     : "Configuration of network cards",
-    "id"       : "lan",
-    "guihandler": ``(LanSequence()),
-    "initialize": ``(Lan::Read()),
-    "finish"   : ``(Lan::Finish()),
-
-    "actions"  : $[
-       "list" : $[
-           "help"      : "display configuration summary",
-           "example"   : "lan list configured",
-           "handler"   : ``(listHandler())
-       ],
-       "add" : $[
-           "help"      : "add a network card",
-           "handler"   : ``(addHandler())
-       ],
-       "delete" : $[
-           "help"      : "delete a network card",
-           "handler"   : ``(deleteHandler())
-       ]
-    ],
-    ...
-];
-
-import "Lan";
-include "commandline/commandline.ycp";
-
-CommandLineRun(cmdline);
-
-/* EOF */
-}
+For example see yardoc for {CommandLineClass#Run}
 
 The UI handler is specified in the "guihandler" key of the command
 line description map. It must take no arguments and return boolean,
 true on success.
 The initialize resp. finish handler is specified by the
 "initialize" resp. "finish" key of the description map. They
-do not take any arguments and must return boolean, true on success. Notice 
+do not take any arguments and must return boolean, true on success. Notice
 that "initialize" and "finish" handlers are not used if a user
 asked for GUI (guihandler is used instead and therefore it must
-do initializing and finishing on its own).
+do initializing and finishing on its own). Also finish is skipped if all
+actions that user perform is read only.
 The handler for an action is specified in the "handler" key of the
 action description map. Each handler must take a single argument
 containing the options entered by the user and return a boolean, true on
-success. If the handler returns "false", the command line 
+success. If the handler returns "false", the command line
 will abort for non-interactive handling. This is useful for
-handling error states. However, a handler must use CommandLine::Abort() 
+handling error states. However, a handler must use CommandLine::Abort()
 to stop event-handling in the interactive mode.
 
 The CommandLine module is stateful, i.e., it contains a current state
@@ -114,12 +66,14 @@
 "interactive"    starts interactive session without UI
 "<command> help" shows the command-specific help
 "<command> quiet" option to supress the progress messages
+"<command> verbose" option to print additional output
 
 These are available in interactive mode only:
 
 "quit"           quits interactive session, sets
-CommandLine::Aborted() flag to true"exit"           exits interactive
-session, sets CommandLine::Aborted() flag to false
+                 CommandLine::Aborted() flag to true
+"exit"           exits interactive
+                 session, sets CommandLine::Aborted() flag to false
 
 Specification of the supported commands in YaST module
 ======================================================
@@ -129,24 +83,26 @@
 
 The map describing the command line interface of a module must contain
 "id" entry containing the name of the module. The map can contain
-global help text, a list of actions, a list of options and a list for 
-mapping of options to actions (which optionscan be used for which 
+global help text, a list of actions, a list of options and a list for
+mapping of options to actions (which optionscan be used for which
 actions). Each action and option must have its help text.
 
 Actions is a map with the action name as a key. For each
 action, it isnecessary to provide the help text. Optionally, action
-can have defined an example of usage.
+can have defined an example of usage. Optionally, action can be also
+defined as readonly.
 A list of flags can be specified to change the default behavior of
 the parameter checker. It is a list with key "options". Currently known flags:
 - non_strict - for unknown parameters, do not check their validity
                can be used for passing unknown options into the handler
 
-Example:       "actions"       : $[
-                       "list"  : $[
-                               // help can be single string or list of strings
-                               "help": "display configuration summary",
-                               "example": "lan list configured",
-                               "options": [ "non_strict" ]
+Example:       "actions"       => {
+                       "list"  => {
+                               # help can be single string or list of strings
+                               "help" => "display configuration summary",
+                               "example" => "lan list configured",
+                               "readonly" => true,
+                               "options" => [ "non_strict" ]
                        ],
                        "add"   : $[
                                "help": "add a network card" ],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/commandline/src/modules/CommandLine.rb 
new/yast2-4.2.59/library/commandline/src/modules/CommandLine.rb
--- old/yast2-4.2.55/library/commandline/src/modules/CommandLine.rb     
2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/commandline/src/modules/CommandLine.rb     
2020-01-23 15:43:03.000000000 +0100
@@ -29,6 +29,8 @@
 
 module Yast
   class CommandLineClass < Module
+    include Yast::Logger
+
     def main
       Yast.import "Directory"
       Yast.import "Mode"
@@ -49,39 +51,47 @@
         "actions"  => {
           "help"        => {
             # translators: help for 'help' option on command line
-            "help" => _(
+            "help"     => _(
               "Print the help for this module"
-            )
+            ),
+            "readonly" => true
           },
           "longhelp"    => {
             # translators: help for 'longhelp' option on command line
-            "help" => _(
+            "help"     => _(
               "Print a long version of help for this module"
-            )
+            ),
+            "readonly" => true
           },
           "xmlhelp"     => {
             # translators: help for 'xmlhelp' option on command line
-            "help" => _(
+            "help"     => _(
               "Print a long version of help for this module in XML format"
-            )
+            ),
+            "readonly" => true
           },
           "interactive" => {
             # translators: help for 'interactive' option on command line
-            "help" => _(
+            "help"     => _(
               "Start interactive shell to control the module"
-            )
+            ),
+            # interactive mode itself does not mean that write is needed.
+            # The first action that is not readonly will switch flag.
+            "readonly" => true
           },
           "exit"        => {
             # translators: help for 'exit' command line interactive mode
-            "help" => _(
+            "help"     => _(
               "Exit interactive mode and save the changes"
-            )
+            ),
+            "readonly" => true
           },
           "abort"       => {
             # translators: help for 'abort' command line interactive mode
-            "help" => _(
+            "help"     => _(
               "Abort interactive mode without saving the changes"
-            )
+            ),
+            "readonly" => true
           }
         },
         "options"  => {
@@ -150,6 +160,7 @@
     #  Suppress printing if there are no commands to be handled (starting GUI)
     #
     #  @param [String] string to be printed
+    #  @param [Boolean] newline if newline character should be added or not
     def PrintInternal(string, newline)
       return if !Mode.commandline
 
@@ -337,14 +348,12 @@
     #  @return [Hash{String => Object}]  containing the command and it's 
option. In case of
     #        error it is an empty map.
     def Parse(arguments)
-      arguments = deep_copy(arguments)
       args = deep_copy(arguments)
       return {} if Ops.less_than(Builtins.size(args), 1)
 
       # Parse command
-      command = Ops.get_string(args, 0, "")
+      command = args.shift
       Builtins.y2debug("command=%1", command)
-      args = Builtins.remove(args, 0)
       Builtins.y2debug("args=%1", args)
 
       if command == ""
@@ -557,17 +566,10 @@
         _("YaST Configuration Module %1\n"),
         Ops.get_string(@modulecommands, "id", "YaST")
       )
-      headlen = Builtins.size(head)
-      i = 0
-      while Ops.less_than(i, headlen)
-        head = Ops.add(head, "-")
-        i = Ops.add(i, 1)
-      end
+      head += "-" * (head.size - 1) # -1 to remove newline char from count
       head = Ops.add(Ops.add("\n", head), "\n")
 
       Print(head)
-
-      nil
     end
 
     # Print a help text for a given action.
@@ -1391,69 +1393,34 @@
     # @param [Array] unique_options  list of mutually exclusive options to 
check against
     # @return  nil if there is a problem, otherwise the unique option found
     def UniqueOption(options, unique_options)
-      options = deep_copy(options)
-      unique_options = deep_copy(unique_options)
+      return nil if options.nil? || unique_options.nil?
+
       # sanity check
-      if Builtins.size(unique_options) == 0
-        Builtins.y2error(
-          "Unique test of options required, but the list of the possible 
options is empty"
-        )
+      if unique_options.empty?
+        log.error "Unique list of options required, but the list of the 
possible options is empty"
         return nil
       end
 
       # first do a filtering, then convert to a list of keys
-      cmds = Builtins.maplist(Builtins.filter(options) do |opt, _value|
-        Builtins.contains(unique_options, opt)
-      end) { |key, _value| key }
+      cmds = unique_options & options.keys
 
       # if it is OK, quickly return
-      return Ops.get_string(cmds, 0) if Builtins.size(cmds) == 1
-
-      # something is wrong, prepare the error report
-      i = 0
-      opt_list = ""
-      while Ops.less_than(i, Ops.subtract(Builtins.size(unique_options), 1))
-        opt_list = Ops.add(
-          opt_list,
-          Builtins.sformat("'%1', ", Ops.get(unique_options, i))
-        )
-        i = Ops.add(i, 1)
-      end
-
-      # translators: the last command %1 in a list of unique commands
-      opt_list = Ops.add(
-        opt_list,
-        Builtins.sformat(_("or '%1'"), Ops.get(unique_options, i))
-      )
+      return cmds.first if cmds.size == 1
 
-      if Builtins.size(cmds) == 0
-        if Builtins.size(unique_options) == 1
+      msg = if cmds.empty?
+        if unique_options.size == 1
           # translators: error message - missing unique command for command 
line execution
-          Report.Error(
-            Builtins.sformat(
-              _("Specify the command '%1'."),
-              Ops.get(unique_options, 0)
-            )
-          )
+          Builtins.sformat(_("Specify the command '%1'."), 
unique_options.first)
         else
           # translators: error message - missing unique command for command 
line execution
-          Report.Error(
-            Builtins.sformat(_("Specify one of the commands: %1."), opt_list)
-          )
+          Builtins.sformat(_("Specify one of the commands: %1."), 
format_list(unique_options))
         end
-        return nil
-      end
-
-      if Builtins.size(cmds) != 1
-        # size( unique_options ) == 1 here does not make sense
-
-        Report.Error(
-          Builtins.sformat(_("Specify only one of the commands: %1."), 
opt_list)
-        )
-        return nil
+      else
+        Builtins.sformat(_("Specify only one of the commands: %1."), 
format_list(cmds))
       end
 
-      Ops.get_string(cmds, 0)
+      Report.Error(msg)
+      nil
     end
 
     # Parse the Command Line
@@ -1463,9 +1430,90 @@
     #
     # @param [Hash] commandline  a map used in the CommandLine module with 
information
     #                      about the handlers for GUI and commands.
-    # @return [Object]    false if there was an error or no changes to be 
written (for example "help").
+    # @option commandline [String] "help" global help text.
+    #   Help for options and actions are separated. Mandatory if module 
support command line.
+    # @option commandline [String] "id" module id. Mandatory if module support 
command line.
+    # @option commandline [Yast::FunRef("symbol ()")|Yast::FunRef("boolean 
()")] "guihandler"
+    #   function to be called when gui requested. Mandatory for modules with 
GUI.
+    # @option commandline [Yast::FunRef("boolean ()")] "initialize" function 
that is called before
+    #   any action handler is called. Usually module initialization happens 
there.
+    # @option commandline [Yast::FunRef("boolean ()")] "finish" function that 
is called after
+    #   all action handlers are called. Usually writing of changes happens 
there. NOTE: calling
+    #   is skipped if all called handlers are readonly.
+    # @option commandline [Hash<String, Object>] "actions" definition of 
actions. Hash has action
+    #   name as key and value is hash with following keys:
+    #
+    #      - **"help"** _String|Array<String>_ mandatory action specific help 
text.
+    #        Options help text is defined separately. If array is passed it 
will be
+    #        printed indended on multiple lines.
+    #      - **"handler"** _Yast::FunRef("boolean (map <string, string>)")_ 
handler when action is
+    #        specified. Parameter is passed options. Mandatory.
+    #      - **"example"** _String_ optional example of action invocation.
+    #        By default no example is provided.
+    #      - **"options"** _Array<String>_ optional list of flags. So far only 
`"non_strict"`
+    #        supported. Useful when action arguments is not well defined, so 
unknown option does
+    #        not finish with error. By default it is empty array.
+    #      - **"readonly"** _Boolean_ optional flag that if it is set to true 
then
+    #        invoking action is not reason to run finish handler, but if 
another
+    #        action without readonly is called, it will run finish handler.
+    #        Default value is `false`.
+    #
+    # @option commandline [Hash<String, Object>] "options" definition of 
options. Hash has action
+    #   name as key and value is hash with following keys:
+    #
+    #      - **"help"** _String|Array<String>_ mandatory action specific help 
text.
+    #        If array is passed it will be printed indended on multiple lines.
+    #      - **"type"** _String_ optional type check for option parameter. By 
default no
+    #        type checking is done. It aborts if no checking is done and a 
value is passed on CLI.
+    #        Possible values are ycp types and additionally enum and regex. 
For enum additional
+    #        key **"typespec"** with array of values have to be specified. For 
regex additional
+    #        key **"typespec"** with string containing ycp regexp is required. 
For integer it
+    #        does conversion of a string value to an integer value.
+    #      - **"typespec"** _Object_ additional type specification. See 
**"type"** for details.
+    #
+    # @option commandline [Hash<String, Array<String>>] "mappings" defines 
connection between
+    #   **"actions"** and its **"options"**. The key is action and the value 
is a list of options it
+    #   supports.
+    # @return [Object] false if there was an error or there are no changes to 
be written (for example "help").
     #      true if the changes should be written, or a value returned by the
-    #      handler
+    #      handler. Actions that are read-only return also true on success 
even if there is nothing to write.
+    #
+    # @example Complete CLI support. Methods definition are skipped for 
simplicity.
+    #   Yast::CommandLine.Run(
+    #     "help"       => _("Foo Configuration"),
+    #     "id"         => "foo",
+    #     "guihandler" => fun_ref(method(:FooSequence), "symbol ()"),
+    #     "initialize" => fun_ref(Foo.method(:ReadNoGUI), "boolean ()"),
+    #     "finish"     => fun_ref(Foo.method(:WriteNoGUI), "boolean ()"),
+    #     "actions"    => {
+    #       "list"   => {
+    #         "help"     => _(
+    #           "Display configuration summary"
+    #           ),
+    #         "example"  => "foo list configured",
+    #         "readonly" => true,
+    #         "handler"  => fun_ref(
+    #           method(:ListHandler),
+    #           "boolean (map <string, string>)"
+    #         )
+    #       },
+    #       "edit"   => {
+    #         "help"    => _("Change existing configuration"),
+    #         "handler" => fun_ref(
+    #           method(:EditHandler),
+    #           "boolean (map <string, string>)"
+    #         )
+    #       },
+    #     },
+    #     "options"    => {
+    #       "configured"   => {
+    #         "help" => _("List only configured foo fighters")
+    #       }
+    #     },
+    #     "mappings"   => {
+    #       "list"   => ["configured"]
+    #     }
+    #   )
     def Run(commandline)
       commandline = deep_copy(commandline)
       # The main ()
@@ -1477,6 +1525,8 @@
       return !Aborted() if !Init(commandline, WFM.Args)
 
       ret = true
+      # no action is readonly, but the first module without "readonly" will 
switch the flag to `false`
+      read_only = true
 
       initialized = false
       if Ops.get(commandline, "initialize").nil?
@@ -1556,6 +1606,8 @@
           # there is a handler, execute the action
           if !exec.nil?
             res = exec.call(options)
+            # unless an action explicitly mentions that it is read-only it 
will run the finish handler
+            read_only = false unless 
commandline["actions"][command]["readonly"]
 
             # if it is not interactive, abort on errors
             Abort() if !Interactive() && res == false
@@ -1568,7 +1620,7 @@
         ret = !Aborted()
       end
 
-      if ret && Ops.get(commandline, "finish") && initialized
+      if ret && Ops.get(commandline, "finish") && initialized && !read_only
         # translators: Progress message - the command line interface is about 
to finish
         PrintVerbose(_("Finishing"))
         ret = commandline["finish"].call
@@ -1653,6 +1705,14 @@
     publish function: :Run, type: "any (map)"
     publish function: :YesNo, type: "boolean ()"
     publish function: :Verbose, type: "boolean ()"
+
+  private
+
+    def format_list(list)
+      # translators: the last entry in output of list
+      list[0..-2].map { |l| "'#{l}'" }.join(", ") + " " +
+        Builtins.sformat(_("or '%1'"), list[-1])
+    end
   end
 
   CommandLine = CommandLineClass.new
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/commandline/test/commandline_test.rb 
new/yast2-4.2.59/library/commandline/test/commandline_test.rb
--- old/yast2-4.2.55/library/commandline/test/commandline_test.rb       
2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/commandline/test/commandline_test.rb       
2020-01-23 15:43:03.000000000 +0100
@@ -19,7 +19,10 @@
     Yast::Mode.SetUI(orig_ui)
   end
 
+  subject { Yast::CommandLine }
+
   before do
+    subject.main # reset
     allow(Yast::Debugger).to receive(:installed?).and_return(false)
   end
 
@@ -37,16 +40,73 @@
 
   it "displays errors and aborts" do
     expect($stdout).to receive(:puts).with("Initialize called").ordered
-    expect(Yast::CommandLine).to receive(:Print).with(/I crashed/).ordered
+    expect(subject).to receive(:Print).with(/I crashed/).ordered
     expect($stdout).to_not receive(:puts).with("Finish called")
 
     Yast::WFM.CallFunction("dummy_cmdline", ["crash"])
   end
 
   it "complains about unknown commands and returns false" do
-    expect(Yast::CommandLine).to receive(:Print).with(/Unknown Command:/)
-    expect(Yast::CommandLine).to receive(:Print).with(/Use.*help.*available 
commands/)
+    expect(subject).to receive(:Print).with(/Unknown Command:/)
+    expect(subject).to receive(:Print).with(/Use.*help.*available commands/)
 
     expect(Yast::WFM.CallFunction("dummy_cmdline", ["unknowncommand"])).to eq 
false
   end
+
+  describe ".PrintHead" do
+    it "prints header with underscore" do
+      # \n is needed due to autocorrect from rubocop in heredoc
+      expect(subject).to receive(:Print).with("\n" + <<~OUTPUT
+        YaST Configuration Module YaST
+        ------------------------------
+      OUTPUT
+                                             )
+
+      subject.PrintHead
+    end
+  end
+
+  describe ".UniqueOption" do
+    context "in options is only one of the options mentioned in 
unique_options" do
+      it "returns string" do
+        expect(subject.UniqueOption({ "c" => "v" }, ["c", "d", "e"])).to eq "c"
+      end
+    end
+
+    context "in options is none of the options mentioned in unique_options" do
+      it "returns nil" do
+        expect(subject.UniqueOption({}, ["c", "d", "e"])).to eq nil
+      end
+
+      it "reports error mentioning to specify one of the option if there are 
more in unique options" do
+        expect(Yast::Report).to receive(:Error).with("Specify one of the 
commands: 'c', 'd' or 'e'.")
+
+        subject.UniqueOption({}, ["c", "d", "e"])
+      end
+
+      it "reports error mentioning to specify one the option if there is only 
one in unique options" do
+        expect(Yast::Report).to receive(:Error).with("Specify the command 
'c'.")
+
+        subject.UniqueOption({}, ["c"])
+      end
+    end
+
+    context "in options is more then one of the options mentioned in 
unique_options" do
+      it "returns nil" do
+        expect(subject.UniqueOption({ "a" => "v", "b" => "v2" }, ["a", "b", 
"e"])).to eq nil
+      end
+
+      it "reports error" do
+        expect(Yast::Report).to receive(:Error).with("Specify only one of the 
commands: 'a' or 'b'.")
+
+        subject.UniqueOption({ "a" => "v", "b" => "v2" }, ["a", "b", "e"])
+      end
+    end
+
+    context "unique_options is empty" do
+      it "returns nil" do
+        expect(subject.UniqueOption({ "a" => "v" }, [])).to eq nil
+      end
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/general/src/modules/OSRelease.rb 
new/yast2-4.2.59/library/general/src/modules/OSRelease.rb
--- old/yast2-4.2.55/library/general/src/modules/OSRelease.rb   2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/general/src/modules/OSRelease.rb   2020-01-23 
15:43:03.000000000 +0100
@@ -71,13 +71,20 @@
       Misc.CustomSysconfigRead("NAME", "SUSE Linux", File.join(directory, 
OS_RELEASE_PATH))
     end
 
-    # Get information about the OS version
+    # Get information about the OS version (technical). E.g. 15.2
     # Is limited for the currently running product
     # @return [String] the release information
     def ReleaseVersion(directory = "/")
       Misc.CustomSysconfigRead("VERSION_ID", "", File.join(directory, 
OS_RELEASE_PATH))
     end
 
+    # Get information about the OS version (human readable). E.g. 15-SP2
+    # Is limited for the currently running product
+    # @return [String] the release information
+    def ReleaseVersionHumanReadable(directory = "/")
+      Misc.CustomSysconfigRead("VERSION", "", File.join(directory, 
OS_RELEASE_PATH))
+    end
+
     # Get information about OS ID
     # Is limited for the currently running product
     # @return [String] the OS identifier (sles, opensuse, etc.)
@@ -98,6 +105,7 @@
     publish function: :ReleaseInformation, type: "string (string)"
     publish function: :ReleaseName, type: "string ()"
     publish function: :ReleaseVersion, type: "string ()"
+    publish function: :ReleaseVersionHumanReadable, type: "string ()"
 
   private
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/general/test/data/os-release-SLES-15-SP2 
new/yast2-4.2.59/library/general/test/data/os-release-SLES-15-SP2
--- old/yast2-4.2.55/library/general/test/data/os-release-SLES-15-SP2   
1970-01-01 01:00:00.000000000 +0100
+++ new/yast2-4.2.59/library/general/test/data/os-release-SLES-15-SP2   
2020-01-23 15:43:03.000000000 +0100
@@ -0,0 +1,8 @@
+NAME="SLE"
+VERSION="15-SP2"
+VERSION_ID="15.2"
+PRETTY_NAME="SUSE Linux Enterprise 15 SP2"
+ID="sle"
+ID_LIKE="suse"
+ANSI_COLOR="0;32"
+CPE_NAME="cpe:/o:suse:sle:15:sp2"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/library/general/test/os_release_test.rb 
new/yast2-4.2.59/library/general/test/os_release_test.rb
--- old/yast2-4.2.55/library/general/test/os_release_test.rb    2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/general/test/os_release_test.rb    2020-01-23 
15:43:03.000000000 +0100
@@ -59,6 +59,13 @@
     end
   end
 
+  describe "#ReleaseVersionHumanReadable" do
+    it "returns a release version in a human readable format" do
+      stub_const("Yast::OSReleaseClass::OS_RELEASE_PATH", 
"os-release-SLES-15-SP2")
+      expect(Yast::OSRelease.ReleaseVersionHumanReadable(DATA_DIR)).to 
eq("15-SP2")
+    end
+  end
+
   describe "#id" do
     it "returns an OS identifier" do
       stub_const("Yast::OSReleaseClass::OS_RELEASE_PATH", 
"os-release_SLES_12_Beta5")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/packages/src/lib/y2packager/product.rb 
new/yast2-4.2.59/library/packages/src/lib/y2packager/product.rb
--- old/yast2-4.2.55/library/packages/src/lib/y2packager/product.rb     
2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/packages/src/lib/y2packager/product.rb     
2020-01-23 15:43:03.000000000 +0100
@@ -304,5 +304,12 @@
     def resolvable_properties
       @resolvable_properties ||= Y2Packager::Resolvable.find(kind: :product, 
name: name, version: version).first
     end
+
+    # Returns the version number (without the release part)
+    #
+    # @return [String] Version number
+    def version_version
+      version.split("-").first
+    end
   end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/packages/src/modules/PackagesUI.rb 
new/yast2-4.2.59/library/packages/src/modules/PackagesUI.rb
--- old/yast2-4.2.55/library/packages/src/modules/PackagesUI.rb 2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/packages/src/modules/PackagesUI.rb 2020-01-23 
15:43:03.000000000 +0100
@@ -254,6 +254,7 @@
     # if an option is missing or is nil the default value will be used. All 
options:
     # $[ "enable_repo_mgr" : boolean // display the repository management menu,
     #      // default: false (disabled)
+    #    "enable_online_search": boolean // enable the online search feature
     #    "display_support_status" : boolean // display the support status 
summary dialog,
     #      // default: depends on the Product Feature "software", 
"display_support_status"
     #    "mode" : symbol // package selector mode, no default value, supported 
values:
@@ -299,6 +300,8 @@
 
       widget_options = Builtins.add(widget_options, :confirmUnsupported) if 
!display_support_status.nil? && display_support_status
 
+      widget_options = Builtins.add(widget_options, :onlineSearch) if 
options["enable_online_search"]
+
       Builtins.y2milestone(
         "Options for the package selector widget: %1",
         widget_options
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-4.2.55/library/packages/test/y2packager/product_test.rb 
new/yast2-4.2.59/library/packages/test/y2packager/product_test.rb
--- old/yast2-4.2.55/library/packages/test/y2packager/product_test.rb   
2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/packages/test/y2packager/product_test.rb   
2020-01-23 15:43:03.000000000 +0100
@@ -502,4 +502,12 @@
       end
     end
   end
+
+  describe "#version_version" do
+    subject(:product) { Y2Packager::Product.new(name: "SLES", version: 
"15.2-0", arch: "x86_64") }
+
+    it "returns the version omitting the release part" do
+      expect(product.version_version).to eq("15.2")
+    end
+  end
 end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/library/systemd/src/modules/Systemd.rb 
new/yast2-4.2.59/library/systemd/src/modules/Systemd.rb
--- old/yast2-4.2.55/library/systemd/src/modules/Systemd.rb     2020-01-17 
09:40:03.000000000 +0100
+++ new/yast2-4.2.59/library/systemd/src/modules/Systemd.rb     2020-01-23 
15:43:03.000000000 +0100
@@ -35,7 +35,7 @@
     def main
       Yast.import "FileUtils"
 
-      @systemd_path = "/bin/systemd"
+      @systemd_path = "/usr/lib/systemd/systemd"
       @default_target_symlink = "/etc/systemd/system/default.target"
       @systemd_targets_dir = "/usr/lib/systemd/system"
       @systemd_mountdir = "/sys/fs/cgroup/systemd"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/package/yast2.changes 
new/yast2-4.2.59/package/yast2.changes
--- old/yast2-4.2.55/package/yast2.changes      2020-01-17 09:40:03.000000000 
+0100
+++ new/yast2-4.2.59/package/yast2.changes      2020-01-23 15:43:03.000000000 
+0100
@@ -1,4 +1,31 @@
 -------------------------------------------------------------------
+Thu Jan 23 14:29:49 UTC 2020 - Imobach Gonzalez Sosa <[email protected]>
+
+- Add an option to enable the online search in the package
+  selector (jsc#SLE-9109).
+- 4.2.59
+
+-------------------------------------------------------------------
+Thu Jan 23 13:22:10 UTC 2020 - Steffen Winterfeldt <[email protected]>
+
+- don't use /bin/systemd compat symlink (bsc#1160890)
+- 4.2.58
+
+-------------------------------------------------------------------
+Wed Jan 22 15:27:15 UTC 2020 - Josef Reidinger <[email protected]>
+
+- CommandLine: Add ability to actions to skip writing.
+  Useful for more CLI bug fixes e.g. bsc#1160928
+- 4.2.57
+
+-------------------------------------------------------------------
+Wed Jan 22 11:44:01 CET 2020 - [email protected]
+
+- Evaluating system release/version in an more understandable form
+  for the user e.g. "15-SP2" (improvement for fate#325834).
+- 4.2.56
+
+-------------------------------------------------------------------
 Tue Jan 14 16:38:43 UTC 2020 - David Diaz <[email protected]>
 
 - Add a text helper to strip HTML tags (related bsc#1157780)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-4.2.55/package/yast2.spec 
new/yast2-4.2.59/package/yast2.spec
--- old/yast2-4.2.55/package/yast2.spec 2020-01-17 09:40:03.000000000 +0100
+++ new/yast2-4.2.59/package/yast2.spec 2020-01-23 15:43:03.000000000 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           yast2
-Version:        4.2.55
+Version:        4.2.59
 Release:        0
 Summary:        YaST2 Main Package
 License:        GPL-2.0-only


Reply via email to