Hello community, here is the log from the commit of package yast2-update for openSUSE:Factory checked in at 2016-08-18 10:18:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-update (Old) and /work/SRC/openSUSE:Factory/.yast2-update.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-update" Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-update/yast2-update.changes 2016-06-09 15:56:25.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-update.new/yast2-update.changes 2016-08-18 10:18:16.000000000 +0200 @@ -1,0 +2,7 @@ +Fri Aug 5 08:55:42 UTC 2016 - [email protected] + +- Remember selected target/partitions after an installer update. + (bsc#988287) +- 3.1.41 + +------------------------------------------------------------------- Old: ---- yast2-update-3.1.40.tar.bz2 New: ---- yast2-update-3.1.41.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-update.spec ++++++ --- /var/tmp/diff_new_pack.SGPQof/_old 2016-08-18 10:18:17.000000000 +0200 +++ /var/tmp/diff_new_pack.SGPQof/_new 2016-08-18 10:18:17.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-update -Version: 3.1.40 +Version: 3.1.41 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -117,6 +117,9 @@ %dir %{yast_yncludedir} %{yast_yncludedir}/update %{yast_yncludedir}/update/rootpart.rb +%{yast_libdir}/update/ +%{yast_libdir}/update/clients +%{yast_libdir}/update/clients/inst_update_partition_auto.rb %doc %{yast_docdir} ++++++ yast2-update-3.1.40.tar.bz2 -> yast2-update-3.1.41.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/package/yast2-update.changes new/yast2-update-3.1.41/package/yast2-update.changes --- old/yast2-update-3.1.40/package/yast2-update.changes 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/package/yast2-update.changes 2016-08-09 12:24:39.000000000 +0200 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Fri Aug 5 08:55:42 UTC 2016 - [email protected] + +- Remember selected target/partitions after an installer update. + (bsc#988287) +- 3.1.41 + +------------------------------------------------------------------- Mon Jun 6 08:19:06 UTC 2016 - [email protected] - Stop generating autodocs (fate#320356) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/package/yast2-update.spec new/yast2-update-3.1.41/package/yast2-update.spec --- old/yast2-update-3.1.40/package/yast2-update.spec 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/package/yast2-update.spec 2016-08-09 12:24:39.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-update -Version: 3.1.40 +Version: 3.1.41 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build @@ -117,6 +117,9 @@ %dir %{yast_yncludedir} %{yast_yncludedir}/update %{yast_yncludedir}/update/rootpart.rb +%{yast_libdir}/update/ +%{yast_libdir}/update/clients +%{yast_libdir}/update/clients/inst_update_partition_auto.rb %doc %{yast_docdir} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/src/Makefile.am new/yast2-update-3.1.41/src/Makefile.am --- old/yast2-update-3.1.40/src/Makefile.am 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/src/Makefile.am 2016-08-09 12:24:39.000000000 +0200 @@ -30,6 +30,10 @@ desktop_DATA = \ desktop/update.desktop -EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(ybin_SCRIPTS) $(desktop_DATA) +ylibclientdir = "${yast2dir}/lib/update/clients" +ylibclient_DATA = \ + lib/update/clients/inst_update_partition_auto.rb -include $(top_srcdir)/Makefile.am.common \ No newline at end of file +EXTRA_DIST = $(module_DATA) $(client_DATA) $(ynclude_DATA) $(ybin_SCRIPTS) $(desktop_DATA) $(ylibclient_DATA) + +include $(top_srcdir)/Makefile.am.common diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/src/clients/inst_update_partition_auto.rb new/yast2-update-3.1.41/src/clients/inst_update_partition_auto.rb --- old/yast2-update-3.1.40/src/clients/inst_update_partition_auto.rb 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/src/clients/inst_update_partition_auto.rb 2016-08-09 12:24:39.000000000 +0200 @@ -29,75 +29,7 @@ # calling this module. # # $Id:$ -module Yast - class InstUpdatePartitionAutoClient < Client - def main - Yast.import "Pkg" - Yast.import "UI" - textdomain "update" - - Yast.import "ProductControl" - Yast.import "RootPart" - - Yast.include self, "update/rootpart.rb" - - if RootPart.Mounted - Update.Detach - RootPart.UnmountPartitions(false) - end - - RootPart.Detect - # if there is only one suitable partition which can be mounted, use it without asking - @target_system = "" - - - @partitions = Builtins.filter(RootPart.rootPartitions) do |name, p| - @target_system = name if Ops.get_boolean(p, :valid, false) - Ops.get_boolean(p, :valid, false) - end - - # allow to specicfy the target on cmdline (e.g. if there are multiple systems) - # ptoptions=TargetRoot target_root=<device> (bnc#875031) - install_inf_target_system = Linuxrc.InstallInf("TargetRoot") - if install_inf_target_system - @target_system = install_inf_target_system - @partitions = { @target_system => { :valid => true } } - Builtins.y2milestone("Selecting system %1 specified in install.inf", @target_system); - end - - if Builtins.size(@partitions) == 1 - Builtins.y2milestone( - "Auto-mounting system located at %1", - @target_system - ) - RootPart.selectedRootPartition = @target_system - RootPart.targetOk = RootPart.mount_target - - # Not mounted correctly - if !RootPart.targetOk - # error report - Report.Error(_("Failed to mount target system")) - UmountMountedPartition() - # Correctly mounted but incomplete installation found - elsif RootPart.IncompleteInstallationDetected(Installation.destdir) - Report.Error( - _("A possibly incomplete installation has been detected.") - ) - UmountMountedPartition() - elsif !(Pkg.TargetInitializeOptions(Installation.destdir, - "target_distro" => target_distribution) && Pkg.TargetLoad) - Report.Error("Initializing the target system failed") - UmountMountedPartition() - Pkg.TargetFinish - else - return :next - end - end - @ret = RootPartitionDialog(:update_dialog) - - @ret - end - end -end +require "yaml" +require "update/clients/inst_update_partition_auto" Yast::InstUpdatePartitionAutoClient.new.main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/src/lib/update/clients/inst_update_partition_auto.rb new/yast2-update-3.1.41/src/lib/update/clients/inst_update_partition_auto.rb --- old/yast2-update-3.1.40/src/lib/update/clients/inst_update_partition_auto.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-update-3.1.41/src/lib/update/clients/inst_update_partition_auto.rb 2016-08-09 12:24:39.000000000 +0200 @@ -0,0 +1,152 @@ +# encoding: utf-8 + +# ------------------------------------------------------------------------------ +# Copyright (c) 2016 SUSE LLC, All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of version 2 of the GNU General Public License as published by the +# Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# ------------------------------------------------------------------------------ +# +# Authors: Stefan Schubert <[email protected]> +# Arvin Schnell <[email protected]> +# +# Purpose: Select root partition for update or booting. +# RootPart::rootPartitions must be filled before +# calling this module. +# +# $Id:$ + +require "yaml" + +module Yast + class InstUpdatePartitionAutoClient < Client + include Logger + + DATA_PATH = "/var/lib/YaST2/update_partition_auto.yaml".freeze + + def main + Yast.import "Pkg" + Yast.import "UI" + + textdomain "update" + + Yast.import "ProductControl" + Yast.import "RootPart" + + Yast.include self, "update/rootpart.rb" + + # In case of restarting after a installer update, we restore previous + # data if exists (bsc#988287) + load_data if Installation.restarting? && data_stored? + + if RootPart.Mounted + log.debug("RootPart is mounted, detaching Update & unmounting partitions") + Update.Detach + RootPart.UnmountPartitions(false) + end + + RootPart.Detect + + # if there is only one suitable partition which can be mounted, use it without asking + @target_system = target_system_candidate if @target_system.to_s.empty? + + if @target_system + log.info("Auto-mounting system located at #{@target_system}") + + RootPart.selectedRootPartition = @target_system + RootPart.targetOk = RootPart.mount_target + + # Not mounted correctly + if !RootPart.targetOk + # error report + Report.Error(_("Failed to mount target system")) + UmountMountedPartition() + # Correctly mounted but incomplete installation found + elsif RootPart.IncompleteInstallationDetected(Installation.destdir) + Report.Error( + _("A possibly incomplete installation has been detected.") + ) + UmountMountedPartition() + elsif !(Pkg.TargetInitializeOptions(Installation.destdir, + "target_distro" => target_distribution) && Pkg.TargetLoad) + + Report.Error("Initializing the target system failed") + UmountMountedPartition() + Pkg.TargetFinish + else + store_data + + return :next + end + end + + @ret = RootPartitionDialog(:update_dialog) + + store_data if @ret == :next + + @ret + end + + private + + # @return [Boolean] true if dumped file data exists. + def data_stored? + ::File.exist?(DATA_PATH) + end + + # Save some important RootPart attributes into a yaml file. + def store_data + data = { + "activated" => RootPart.GetActivated, + "selected" => RootPart.selectedRootPartition, + "previous" => RootPart.previousRootPartition, + "partitions" => RootPart.rootPartitions + } + + File.write(DATA_PATH, data.to_yaml) + end + + # Loads RootPart data from a dump yaml file and delete the file after that. + # It also remember the current root selection as the target_system + def load_data + data = YAML.load(File.read(DATA_PATH)) + + log.debug("Loading data from dump file: #{data}") + RootPart.load_saved(data) + + root_target = RootPart.selectedRootPartition || "" + + @target_system = root_target unless root_target.empty? + + ::FileUtils.rm_rf(DATA_PATH) + end + + # Obtains the target system from the install.inf file or use the current + # partitions if there is only 1 valid. + # + # @return [String, nil] target root or nil + def target_system_candidate + # allow to specicfy the target on cmdline (e.g. if there are multiple systems) + # ptoptions=TargetRoot target_root=<device> (bnc#875031) + target_root = Linuxrc.InstallInf("TargetRoot") + if target_root + log.info("Selecting system #{target_root} specified in install.inf") + + return target_root + end + + partitions = RootPart.rootPartitions.select do |name, partition| + target_root = name if partition[:valid] + partition[:valid] + end + + partitions.size == 1 ? target_root : nil + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/src/modules/RootPart.rb new/yast2-update-3.1.41/src/modules/RootPart.rb --- old/yast2-update-3.1.40/src/modules/RootPart.rb 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/src/modules/RootPart.rb 2016-08-09 12:24:39.000000000 +0200 @@ -32,6 +32,7 @@ module Yast class RootPartClass < Module + include Logger NON_MODULAR_FS = ["proc", "sysfs"] def main @@ -1899,6 +1900,7 @@ mount_type = Ops.get(mt_map, p_detect_fs, "") error_message = nil + log.debug("Running RunFSCKonJFS with mount_type: #{mount_type} and device: #{p_dev}") if !( error_message_ref = arg_ref(error_message); _RunFSCKonJFS_result = RunFSCKonJFS( @@ -1910,23 +1912,31 @@ _RunFSCKonJFS_result ) Ops.set(freshman, :valid, false) + log.debug("Returning not valid partition: #{freshman}") return deep_copy(freshman) end # mustn't be empty and must be modular if mount_type != "" && !NON_MODULAR_FS.include?(mount_type) + log.debug("Calling modprobe #{mount_type}") SCR.Execute(path(".target.modprobe"), mount_type, "") end - # mount (read-only) partition to Installation::destdir + + log.debug("Removing #{p_dev}") Storage.RemoveDmMapsTo(p_dev) - if Convert.to_boolean( - SCR.Execute( - path(".target.mount"), - [p_dev, Installation.destdir, Installation.mountlog], - "-o ro" - ) + + # mount (read-only) partition to Installation::destdir + log.debug("Mounting #{[p_dev, Installation.destdir, Installation.mountlog].inspect}") + mount = + SCR.Execute( + path(".target.mount"), + [p_dev, Installation.destdir, Installation.mountlog], + "-o ro" ) + + if Convert.to_boolean(mount) # Is this a root partition, does /etc/fstab exists? + log.debug("Checking /etc/fstab in #{Installation.destdir}") if Ops.greater_than( SCR.Read( path(".target.size"), @@ -1983,6 +1993,7 @@ Ops.get_string(fstab, [0, "spec"], "") ) end + if Mode.autoinst # we dont care about the other checks in autoinstallation SCR.Execute(path(".target.umount"), Installation.destdir) @@ -2006,7 +2017,7 @@ # installed /bin/bash and the one from inst-sys are matching if Ops.get_string(freshman, :arch, "unknown") == instsys_arch Builtins.y2milestone("Architecture (%1) is valid", instsys_arch) - Ops.set(freshman, :arch_valid, true) + Ops.set(freshman, :arch_valid, true) # both are PPC, bugzilla #249791 elsif Builtins.contains( @@ -2020,7 +2031,7 @@ Ops.get_string(freshman, :arch, "unknown"), instsys_arch ) - Ops.set(freshman, :arch_valid, true) + Ops.set(freshman, :arch_valid, true) # Architecture is not matching else @@ -2060,7 +2071,7 @@ end end - Builtins.y2milestone("%1 %2", partition, freshman) + log.info("#{partition} #{freshman}") deep_copy(freshman) end @@ -2071,6 +2082,8 @@ # Loads a bunch of kernel modules. # @return [void] def FindRootPartitions + log.debug("Finding root partitions") + return if @didSearchForRootPartitions modules_to_load = { @@ -2088,6 +2101,7 @@ "dm-mod" => "DM", "dm-snapshot" => "DM Snapshot", } + modules_to_load.each do |module_to_load, show_name| ModuleLoading.Load(module_to_load, "", "Linux", show_name, Linuxrc.manual, true) end @@ -2104,7 +2118,8 @@ # Storage::ActivateEvms(); target_map = Storage.GetOndiskTarget - Builtins.y2milestone("target_map: %1", target_map) + + log.info("target_map: #{target_map}") # prepare progress-bar if UI.WidgetExists(Id("search_progress")) @@ -2155,6 +2170,7 @@ :label => "Label" } else + log.debug("Checking partition: #{partition}") freshman = CheckPartition(partition) end @@ -2237,6 +2253,16 @@ elements.join(",") end + # Load saved data from given Hash + # + # @param [Hash<String => Object>] + def load_saved(data) + @activated = data["activated"] || [] + @selectedRootPartition = data["selected"] || "" + @previousRootPartition = data["previous"] || "" + @rootPartitions = data["partitions"] || {} + end + publish :variable => :selectedRootPartition, :type => "string" publish :variable => :previousRootPartition, :type => "string" publish :variable => :rootPartitions, :type => "map <string, map>" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/test/Makefile.am new/yast2-update-3.1.41/test/Makefile.am --- old/yast2-update-3.1.40/test/Makefile.am 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/test/Makefile.am 2016-08-09 12:24:39.000000000 +0200 @@ -1,6 +1,7 @@ TESTS = \ root_part_test.rb \ suse_release_test.rb \ + inst_update_partition_auto_test.rb \ update_test.rb TEST_EXTENSIONS = .rb diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/test/helpers.rb new/yast2-update-3.1.41/test/helpers.rb --- old/yast2-update-3.1.40/test/helpers.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-update-3.1.41/test/helpers.rb 2016-08-09 12:24:39.000000000 +0200 @@ -0,0 +1,20 @@ +module Helpers + def stub_root_part + allow(Yast::RootPart).to receive(:Detect) + allow(Yast::RootPart).to receive(:Mounted) + allow(Yast::RootPart).to receive(:UnmountPartitions) + allow(Yast::RootPart).to receive(:rootPartitions).and_return({}) + allow(Yast::RootPart).to receive(:mount_target) + allow(Yast::RootPart).to receive(:IncompleteInstallationDetected) + end + + def stub_subject(subject) + allow(subject).to receive(:target_system_candidate).and_return(nil) + allow(subject).to receive(:RootPartitionDialog).and_return(:cancel) + allow(subject).to receive(:UmountMountedPartition) + allow(subject).to receive(:target_distribution).and_return("sle-12-x86_64") + allow(subject).to receive(:initialize_update_rootpart) + allow(subject).to receive(:load_data) + allow(subject).to receive(:store_data) + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/test/inst_update_partition_auto_test.rb new/yast2-update-3.1.41/test/inst_update_partition_auto_test.rb --- old/yast2-update-3.1.40/test/inst_update_partition_auto_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-update-3.1.41/test/inst_update_partition_auto_test.rb 2016-08-09 12:24:39.000000000 +0200 @@ -0,0 +1,211 @@ +#!/usr/bin/env rspec + +require_relative "test_helper" +require "update/clients/inst_update_partition_auto" + +Yast.import "RootPart" +Yast.import "Update" +Yast.import "Installation" + +describe Yast::InstUpdatePartitionAutoClient do + + describe "#main" do + let(:restarting) { false } + + before do + stub_root_part + stub_const("Yast::FileSystems", double) + allow(Yast::Update) + allow(Yast::Installation).to receive(:restarting?) { restarting } + allow(Yast::Installation).to receive(:destdir).and_return("/mnt") + allow(Yast::Report).to receive(:error) + allow(Yast::Pkg).to receive(:TargetInitializeOptions) + allow(Yast::Pkg).to receive(:TargetFinish) + allow(Yast::Pkg).to receive(:TargetLoad).and_return(true) + stub_subject(subject) + end + + context "when installation is restarting" do + let(:restarting) { true } + + it "loads data if it was stored" do + expect(subject).to receive(:data_stored?).and_return(true) + expect(subject).to receive(:load_data) + + subject.main + end + end + + context "when root partition is mounted" do + before do + allow(Yast::RootPart).to receive(:Mounted).and_return(true) + allow(Yast::RootPart).to receive(:UnmountPartitions) + end + + it "detachs update" do + expect(Yast::Update).to receive(:Detach) + + subject.main + end + + it "unmounts all the root partitions" do + expect(Yast::RootPart).to receive(:UnmountPartitions).with(false) + + subject.main + end + end + + it "obtains the current target system" do + expect(subject).to receive(:target_system_candidate).once + + subject.main + end + + context "when a target system can't be obtained" do + before do + allow(subject).to receive(:target_system_candidate).and_return(nil) + end + + it "shows the partition dialog" do + expect(subject).to receive(:RootPartitionDialog) + + subject.main + end + end + + context "when a target system can be obtained" do + before do + allow(subject).to receive(:target_system_candidate).and_return("/dev/whatever") + end + + it "sets the RootPart.selectedRootPartition with its value" do + expect(Yast::RootPart).to receive(:selectedRootPartition=).with("/dev/whatever") + + subject.main + end + + it "tries to mount the target" do + expect(Yast::RootPart).to receive(:mount_target) + + subject.main + end + + context "when the target system is not mounted" do + before do + allow(Yast::RootPart).to receive(:mount_target).and_return(false) + end + + it "reports and Error" do + expect(Yast::Report).to receive(:Error).with(_("Failed to mount target system")) + + subject.main + end + + it "unmount all the partitions" do + expect(subject).to receive(:UmountMountedPartition).once + + subject.main + end + + it "shows the partition dialog" do + expect(subject).to receive(:RootPartitionDialog) + + subject.main + end + end + + context "when the target system is mounted successfully" do + before do + allow(Yast::RootPart).to receive(:mount_target).and_return(true) + allow(subject).to receive(:store_data) + end + + context "when it detects an incomplete installation" do + before do + allow(Yast::RootPart).to receive(:IncompleteInstallationDetected).and_return(true) + end + + it "reports an error" do + expect(Yast::Report).to receive(:Error).with("A possibly incomplete installation has been detected.") + + subject.main + end + + it "unmounts mounted partitions" do + expect(subject).to receive(:UmountMountedPartition).once + + subject.main + end + + it "shows the partition dialog" do + expect(subject).to receive(:RootPartitionDialog) + + subject.main + end + end + + context "when Pkg initialization fails in the target" do + before do + allow(Yast::Pkg).to receive(:TargetLoad).and_return(false) + end + + it "reports and error" do + expect(Yast::Report).to receive(:Error).with("Initializing the target system failed") + + subject.main + end + + it "unmounts mounted partitions" do + expect(subject).to receive(:UmountMountedPartition).once + + subject.main + end + + it "finishes Pkg in the target" do + expect(Yast::Pkg).to receive(:TargetFinish) + + subject.main + end + end + + context "when all checks are fine" do + before do + allow(Yast::RootPart).to receive(:IncompleteInstallationDetected).and_return(false) + allow(Yast::Pkg).to receive(:TargetInitializeOptions).and_return(true) + end + + it "saves current data" do + expect(subject).not_to receive(:RootPartitionDialog) + expect(subject).to receive(:store_data) + + subject.main + end + + it "returns :next without shown selection dialog" do + expect(subject).not_to receive(:RootPartitionDialog) + + expect(subject.main).to eql(:next) + end + end + end + + end + + context "when a selection in the root partition dialog is done successfully" do + before do + allow(subject).to receive(:RootPartitionDialog).and_return(:next) + allow(subject).to receive(:target_system_candidate).and_return(nil) + end + + it "stores current data" do + expect(subject).to receive(:store_data) + + subject.main + end + + it "returns :next" do + expect(subject.main).to eql(:next) + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-update-3.1.40/test/test_helper.rb new/yast2-update-3.1.41/test/test_helper.rb --- old/yast2-update-3.1.40/test/test_helper.rb 2016-06-06 10:51:46.000000000 +0200 +++ new/yast2-update-3.1.41/test/test_helper.rb 2016-08-09 12:24:39.000000000 +0200 @@ -2,3 +2,10 @@ require "yast" require "yast/rspec" +require_relative "helpers" + +RSpec.configure do |config| + config.extend Yast::I18n # available in context/describe + config.include Yast::I18n # available in it/let/before + config.include Helpers +end
