Method: Yast::CommandLineClass#Run

Defined in:
library/commandline/src/modules/CommandLine.rb

#Run(commandline) ⇒ Object

Parse the Command Line

Function to parse the command line, start a GUI or handle interactive and command line actions as supported by the Yast::CommandLine module.

Examples:

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"]
  }
)

Options Hash (commandline):

  • "help" (String)

    global help text. Help for options and actions are separated. Mandatory if module support command line.

  • "id" (String)

    module id. Mandatory if module support command line.

  • "guihandler" (Yast::FunRef("symbol ()")|Yast::FunRef("boolean ()"))

    function to be called when gui requested. Mandatory for modules with GUI.

  • "initialize" (Yast::FunRef("boolean ()"))

    function that is called before any action handler is called. Usually module initialization happens there.

  • "finish" (Yast::FunRef("boolean ()"))

    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.

  • "actions" (Hash<String, Object>)

    definition of actions. Hash has action name as key and value is hash with following keys:

    • "help" String|Array 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 )") 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 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.
  • "options" (Hash<String, Object>)

    definition of options. Hash has action name as key and value is hash with following keys:

    • "help" String|Array 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.
  • "mappings" (Hash<String, Array<String>>)

    defines connection between "actions" and its "options". The key is action and the value is a list of options it supports.



1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
# File 'library/commandline/src/modules/CommandLine.rb', line 1530

def Run(commandline)
  commandline = deep_copy(commandline)
  # The main ()
  Builtins.y2milestone("----------------------------------------")
  Builtins.y2milestone("Command line interface started")

  # Initialize the arguments
  @done = false
  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?
    # no initialization routine
    # set initialized state to true => call finish handler at the end in command line mode
    initialized = true
  end

  # Start GUI
  if StartGUI()
    if !Builtins.haskey(commandline, "guihandler")
      Builtins.y2error(
        "Missing GUI handler for %1",
        Ops.get_string(commandline, "id", "<unknown>")
      )
      # translators: error message - the module does not provide command line interface
      Error(_("There is no user interface available for this module."))
      return false
    end

    if Ops.is(Ops.get(commandline, "guihandler"), "symbol ()")
      exec = Convert.convert(
        Ops.get(commandline, "guihandler"),
        from: "any",
        to:   "symbol ()"
      )
      symbol_ret = exec.call
      Builtins.y2debug("GUI handler ret=%1", symbol_ret)
      return symbol_ret
    else
      exec = Convert.convert(
        Ops.get(
          commandline,
          "guihandler",
          fun_ref(method(:fake_false), "boolean ()")
        ),
        from: "any",
        to:   "boolean ()"
      )
      ret = exec.call
      Builtins.y2debug("GUI handler ret=%1", ret)
      return ret
    end
  else
    # translators: progress message - command line interface ready
    PrintVerbose(_("Ready"))

    until Done()
      m = Command()
      command = Ops.get_string(m, "command", "exit")
      options = Ops.get_map(m, "options", {})

      # start initialization code if it wasn't already used
      if !initialized && (Builtins.haskey(Ops.get_map(commandline, "actions", {}), command) &&
            Ops.get(commandline, "initialize"))
        # non-GUI handling
        PrintVerbose(_("Initializing"))
        ret2 = commandline["initialize"].call
        if ret2
          initialized = true
        else
          Builtins.y2milestone("Module initialization failed")
          return false
        end
      end

      exec = Convert.convert(
        Ops.get(commandline, ["actions", command, "handler"]),
        from: "any",
        to:   "boolean (map <string, string>)"
      )

      # 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
      elsif !Done()
        Builtins.y2error("Unknown command '%1' from CommandLine", command)
        next
      end
    end

    ret = !Aborted()
  end

  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
    if !ret
      Builtins.y2milestone("Module finishing failed")
      return false
    end
    # translators: The command line interface is finished
    PrintVerbose(_("Done"))
  else
    # translators: The command line interface is finished without writing the changes
    PrintVerbose(_("Quitting (without changes)"))
  end

  Builtins.y2milestone("Commandline interface finished")
  Builtins.y2milestone("----------------------------------------")

  ret
end