diff --git a/src/lib/autoinstall/ask/runner.rb b/src/lib/autoinstall/ask/runner.rb index 945063297..865e76529 100644 --- a/src/lib/autoinstall/ask/runner.rb +++ b/src/lib/autoinstall/ask/runner.rb @@ -75,8 +75,8 @@ def run if result == :back current_dialog = go_back elsif result == :next - current_dialog.questions.each { |q| process_question(q) } - current_dialog = go_next + results = current_dialog.questions.map { |q| process_question(q) } + current_dialog = go_next unless results.any? { |r| r == :repeat } end end end @@ -179,6 +179,9 @@ def first? # 3. Runs the script # # @param question [Question] Question to process + # @return [Symbol] Action to perform depending on this question. + # :next to continue; :repeat to run the question (and the whole dialog) again. + # @see #run_script def process_question(question) update_profile(question) write_value(question) @@ -210,13 +213,19 @@ def write_value(question) # Runs the associated script if defined # + # If the script fails but the `rerun_on_error` attribute is set to true, + # the dialog should run again. + # # @param question [Question] + # @return [Symbol] Action to perform depending on this script. + # :next to continue; :repeat to run the question (and the whole dialog) again. def run_script(question) - return unless question.script + return :next unless question.script question.script.create_script_file env = question.script.environment ? { "VAL" => question.value } : {} - script_runner.run(question.script, env: env) + result = script_runner.run(question.script, env: env) + (result || !question.script.rerun_on_error) ? :next : :repeat end # Returns a ScriptRunner instance to run scripts diff --git a/src/lib/autoinstall/script.rb b/src/lib/autoinstall/script.rb index 67000067d..3fd08095f 100644 --- a/src/lib/autoinstall/script.rb +++ b/src/lib/autoinstall/script.rb @@ -422,7 +422,7 @@ def script_path # Scripts that are used when processing the section class AskScript < Y2Autoinstallation::ExecutedScript - attr_reader :environment + attr_reader :environment, :rerun_on_error def self.type "ask-scripts" @@ -431,6 +431,7 @@ def self.type def initialize(hash) super @environment = !!hash["environment"] + @rerun_on_error = !!hash["rerun_on_error"] end def to_hash diff --git a/src/lib/autoinstall/script_runner.rb b/src/lib/autoinstall/script_runner.rb index c983f1be9..c55e721f5 100644 --- a/src/lib/autoinstall/script_runner.rb +++ b/src/lib/autoinstall/script_runner.rb @@ -45,6 +45,7 @@ def run(script, env: {}) show_feedback(script) report_error(script) unless result + result end private diff --git a/test/lib/autoinstall/ask/runner_test.rb b/test/lib/autoinstall/ask/runner_test.rb index 165b28b66..9b6c36259 100644 --- a/test/lib/autoinstall/ask/runner_test.rb +++ b/test/lib/autoinstall/ask/runner_test.rb @@ -104,7 +104,10 @@ context "when a script is set" do let(:script) do - instance_double(Y2Autoinstallation::AskScript, environment: environment?) + instance_double( + Y2Autoinstallation::AskScript, + environment: environment?, rerun_on_error: rerun_on_error? + ) end let(:script_runner) do @@ -112,6 +115,7 @@ end let(:environment?) { false } + let(:rerun_on_error?) { false } let(:question1) do Y2Autoinstall::Ask::Question.new("Question 1").tap do |question| @@ -130,6 +134,36 @@ runner.run end + context "and if it fails but the 'rerun_on_error' is set to 'true'" do + let(:rerun_on_error?) { true } + + before do + allow(script).to receive(:create_script_file) + allow(script_runner).to receive(:run).with(script, env: {}) + .and_return(false, true) + end + + it "runs the dialog again" do + expect(ask_dialog1).to receive(:run).twice + runner.run + end + end + + context "and if it fails but the 'rerun_on_error' is set to 'true'" do + let(:rerun_on_error?) { false } + + before do + allow(script).to receive(:create_script_file) + allow(script_runner).to receive(:run).with(script, env: {}) + .and_return(false) + end + + it "runs the dialog again" do + expect(ask_dialog1).to receive(:run).once + runner.run + end + end + context "when the 'environment' attribute is set to 'true'" do let(:environment?) { true } diff --git a/test/lib/autoinstall/script_runner_test.rb b/test/lib/autoinstall/script_runner_test.rb index aa674091a..0db973a34 100644 --- a/test/lib/autoinstall/script_runner_test.rb +++ b/test/lib/autoinstall/script_runner_test.rb @@ -40,6 +40,10 @@ runner.run(script) end + it "returns true" do + expect(runner.run(script)).to eq(true) + end + context "when a notification is defined" do let(:spec) do { "notification" => "A script is running..." } @@ -111,6 +115,10 @@ .with(/User script/, any_args) runner.run(script) end + + it "returns false" do + expect(runner.run(script)).to eq(false) + end end end end