Class: UI::Sequence

Inherits:
Object
  • Object
show all
Includes:
Yast::I18n
Defined in:
library/sequencer/src/lib/ui/sequence.rb

Overview

A Sequence is an object-oriented interface for the good old Yast::Sequencer. In the simple case it runs a sequence of dialogs connected by Back and Next buttons.

Examples:

simple two steps sequence

class SimpleSequence < UI::Sequence
  SEQUENCE_HASH = {
    START   => "step1",
    "step1" => { next: "step2" },
    "step2" => { next: :finish }
  }

  def step1
    # cool stuff
    :next
  end

  def step2
    # cool stuff
    :next
  end

  def run
    super(sequence: SEQUENCE_HASH)
  end
end

complex sequence with branching and auto steps that are skipped when going back

class ComplexSequence < UI::Sequence
  SEQUENCE_HASH = {
    START   => "step1",
    "step1" => { next: "auto_step" },
    "auto_step" => {
      next: "finish_step",
      alternative: "alternative_finish"
    },
    "finish_step" => { next: :finish },
    "alternative_finish" => { next: :finish }
  }

  def step1
    # cool stuff
    :next
  end

  skip_stack :auto_step
  def auto_step
    # cool stuff
    rand(2) == 0 ? :next : :alternative
  end

  def finish_step
    # cool stuff
    :next
  end

  def alternative_finish
    # cool stuff
    :back
  end

  def run
    super(sequence: SEQUENCE_HASH)
  end
end

Constant Summary collapse

START =

A reserved name in the sequence hash to mark the graph entry point.

"ws_start".freeze

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.run(aliases, sequence) ⇒ Object

A drop-in replacement for Yast::Sequencer.Run



80
81
82
# File 'library/sequencer/src/lib/ui/sequence.rb', line 80

def self.run(aliases, sequence)
  Yast::Sequencer.Run(aliases, sequence)
end

.skip_stack(name) ⇒ Object

Declare that a method is skipped when going :back, useful for noninteractive steps. (also see Yast::SequencerClass#WS_special)

Parameters:

  • name (Symbol, String)

    method name



152
153
154
155
# File 'library/sequencer/src/lib/ui/sequence.rb', line 152

def skip_stack(name)
  @skip_stack ||= {}
  @skip_stack[name.to_sym] = true
end

.skip_stack?(name) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Parameters:

  • name (Symbol, String)

    method name

Returns:

  • (Boolean)


160
161
162
163
# File 'library/sequencer/src/lib/ui/sequence.rb', line 160

def skip_stack?(name)
  @skip_stack ||= {}
  @skip_stack[name.to_sym]
end

Instance Method Details

#abortable(sequence_hash) ⇒ Object

Add {abort: :abort} transitions if missing (an :abort from a dialog should :abort the whole sequence)

Examples:

output

input = {
  START => "step1",
  "step1" => { next: "step2" },
  "step2" => { next: :finish }
}
output = {
  START => "step1",
  "step1" => { next: "step2", abort: :abort },
  "step2" => { next: :finish, abort: :abort }
}
abortable(input) == output # => true


122
123
124
125
126
127
128
129
130
# File 'library/sequencer/src/lib/ui/sequence.rb', line 122

def abortable(sequence_hash)
  sequence_hash.map do |name, destination|
    if name == START
      [name, destination]
    else
      [name, { abort: :abort }.merge(destination)]
    end
  end.to_h
end

#from_methods(sequence_hash) ⇒ Hash{String => Proc}

Make aliases from sequence_hash assuming there is a method for each alias.

Returns:

  • (Hash{String => Proc})

    aliases



135
136
137
138
139
140
141
142
143
144
145
# File 'library/sequencer/src/lib/ui/sequence.rb', line 135

def from_methods(sequence_hash)
  sequence_hash.keys.map do |name|
    next nil if name == START

    if self.class.skip_stack?(name)
      [name, [method(name), true]]
    else
      [name, method(name)]
    end
  end.compact.to_h
end

#run(sequence:, aliases: nil) ⇒ Object

A replacement for Yast::Sequencer.Run but smarter:

Examples:

sequence with branching with child having methods step1 and step2, where step 1 can finish sequence or run step 2

run(sequence: {
  START   => "step1",
  "step1" => {
    next:  :finish,
    step2: "step2",
  },
  "step2" => {
    next:  :finish
  }
})


102
103
104
105
# File 'library/sequencer/src/lib/ui/sequence.rb', line 102

def run(sequence:, aliases: nil)
  aliases ||= from_methods(sequence)
  self.class.run(aliases, abortable(sequence))
end