diff --git a/README.rst b/README.rst index 4f87493..7056fbb 100644 --- a/README.rst +++ b/README.rst @@ -126,9 +126,14 @@ Options used: * ``wrapper`` (required) with ``cd32`` as an value * ``wrapper_archive`` (required) path to the archive with CD32 iso/cue/wav -* ``wrapper_archiver`` (required) archiver to use for storage save state +* ``wrapper_archiver`` (conditionally required) archiver to use for storage + save state * ``wrapper_gui_msg`` (optional) if set to "1", will display a graphical message during extracting files +* ``wrapper_save_state`` (optional) if set to "1", will load/archive save state + directory, defined as ``$CONFIG/[save-state-dir-name]`` using provided + ``wrapper_archiver`` archiver. If this option is enabled, + ``wrapper_archiver`` will be required. Let's see some sample config for a game, which is saved as ``ChaosEngine.fs-uae``: @@ -166,14 +171,15 @@ Now, there several thing will happen: - Archive with game assists will be extracted in that directory - Configuration file will be copied into that directory, and renamed to ``Config.fs-uae`` -- If there is saved state, it also would be extracted there +- If ``wrapper_save_state`` is set, and there is saved state archive, it also + would be extracted there - ``fs-uae`` will be launched inside that directory Next, after ``fs-uae`` quit, there will: -- Create archive containing save state with name like the configuration file - with additional ``_save`` suffix. In this example it would be - ``ChaosEngine_save.7z``. +- Optionally create archive containing save state with name like the + configuration file with additional ``_save`` suffix. In this example it would + be ``ChaosEngine_save.7z``. - Wipe out temporary directory archive @@ -181,14 +187,19 @@ archive Options used: -* ``wrapper`` (required) with ``cd32`` as an value +* ``wrapper`` (required) with ``archive`` as an value * ``wrapper_archive`` (required) path to the archive with assets (usually means -* ``wrapper_archiver`` (required) archiver to use for storage save state whole system directories, floppies or hard disk images) +* ``wrapper_archiver`` (conditionally required) archiver to use for storage + save state * ``wrapper_gui_msg`` (optional) if set to "1", will display a graphical message during extracting files * ``wrapper_persist_data`` (optional) if set to "1", will compress (possibly changed) data, replacing original archive +* ``wrapper_save_state`` (optional) if set to "1", will archive save state + directory, defined as ``$CONFIG/[save-state-dir-name]`` using provided + ``wrapper_archiver`` archiver. If this option is enabled, + ``wrapper_archiver`` will be required. Example configuration: @@ -201,7 +212,7 @@ Example configuration: wrapper_archiver = lha wrapper_gui_msg = 1 wrapper_persist_data = 1 - + wrapper_save_state = 1 ... And execution is as usual: @@ -214,11 +225,12 @@ This module will do several steps (similar as with ``cd32`` wrapper): - create temporary directory - extract provided in configuration archive -- extract save state (if exists) +- extract save state (if ``wrapper_save_state`` is set to ``1`` and archive + with save exists) - copy configuration under name ``Config.fs-uae`` - run the fs-uae emulator -- create archive with save state (if save state directory place is *not* a - global one) +- optionally create archive with save state (if save state directory place is + *not* a global one) - optionally create new archive under the same name as the original one and replace it with original one. diff --git a/fs_uae_wrapper/archive.py b/fs_uae_wrapper/archive.py index f15bf72..d70b975 100644 --- a/fs_uae_wrapper/archive.py +++ b/fs_uae_wrapper/archive.py @@ -65,9 +65,6 @@ class Archive(base.Base): validation_result = super(Archive, self)._validate_options() - if not super(Archive, self)._validate_options(): - validation_result = False - if 'wrapper_archive' not in self.all_options: sys.stderr.write("Configuration lacks of required " "`wrapper_archive' option.\n") diff --git a/fs_uae_wrapper/base.py b/fs_uae_wrapper/base.py index 55d4b09..5dc44d8 100644 --- a/fs_uae_wrapper/base.py +++ b/fs_uae_wrapper/base.py @@ -147,6 +147,9 @@ class Base(object): """ Get the saves from emulator and store it where configuration is placed """ + if self.all_options.get('wrapper_save_state', '0') != '1': + return True + os.chdir(self.dir) save_path = self._get_saves_dir() if not save_path: @@ -169,6 +172,9 @@ class Base(object): """ Put the saves (if exists) to the temp directory. """ + if self.all_options.get('wrapper_save_state', '0') != '1': + return True + if not os.path.exists(self.save_filename): return True @@ -212,6 +218,9 @@ class Base(object): "`wrapper' option.\n") return False + if self.all_options.get('wrapper_save_state', '0') == '0': + return True + if 'wrapper_archiver' not in self.all_options: sys.stderr.write("Configuration lacks of required " "`wrapper_archiver' option.\n") diff --git a/fs_uae_wrapper/cd32.py b/fs_uae_wrapper/cd32.py index db66841..62e8a91 100644 --- a/fs_uae_wrapper/cd32.py +++ b/fs_uae_wrapper/cd32.py @@ -45,7 +45,10 @@ class CD32(base.Base): if kick_opts: self.fsuae_options.update(kick_opts) - if self._run_emulator(self.fsuae_options.list()): + if not self._run_emulator(self.fsuae_options.list()): + return False + + if self._get_saves_dir(): return self._save_save() return True diff --git a/tests/test_archive.py b/tests/test_archive.py index 2afdb8c..736e572 100644 --- a/tests/test_archive.py +++ b/tests/test_archive.py @@ -28,40 +28,40 @@ class TestArchive(TestCase): @mock.patch('fs_uae_wrapper.path.which') def test_validate_options(self, which): - which.return_value = None + which.return_value = 'unrar' arch = archive.Archive('Config.fs-uae', utils.CmdOption(), {}) self.assertFalse(arch._validate_options()) + arch.all_options = {'wrapper': 'archive'} arch.all_options['wrapper'] = 'archive' self.assertFalse(arch._validate_options()) - arch.all_options['wrapper_archive'] = 'fake.tgz' - self.assertFalse(arch._validate_options()) - - arch.all_options['wrapper_archiver'] = 'rar' - self.assertFalse(arch._validate_options()) - - which.return_value = 'unrar' - arch.all_options['wrapper_archiver'] = 'rar' + arch.all_options['wrapper_archive'] = 'rar' self.assertTrue(arch._validate_options()) @mock.patch('tempfile.mkdtemp') @mock.patch('fs_uae_wrapper.path.which') @mock.patch('fs_uae_wrapper.archive.Archive._make_archive') + @mock.patch('fs_uae_wrapper.base.Base._save_save') + @mock.patch('fs_uae_wrapper.base.Base._get_saves_dir') @mock.patch('fs_uae_wrapper.base.Base._run_emulator') @mock.patch('fs_uae_wrapper.base.Base._kickstart_option') @mock.patch('fs_uae_wrapper.base.Base._copy_conf') @mock.patch('fs_uae_wrapper.base.Base._load_save') @mock.patch('fs_uae_wrapper.base.Base._extract') - def test_run(self, extr, load, copy, kick, run, march, which, mkdtemp): + def test_run(self, extract, load_save, copy_conf, kick_option, + run_emulator, get_save_dir, save_state, make_arch, which, + mkdtemp): - extr.return_value = False - load.return_value = False - copy.return_value = False - kick.return_value = False - run.return_value = False - march.return_value = False + extract.return_value = False + load_save.return_value = False + copy_conf.return_value = False + kick_option.return_value = False + run_emulator.return_value = False + get_save_dir.return_value = False + save_state.return_value = False + make_arch.return_value = False which.return_value = 'rar' arch = archive.Archive('Config.fs-uae', utils.CmdOption(), {}) @@ -73,23 +73,29 @@ class TestArchive(TestCase): self.assertFalse(arch.run()) - extr.return_value = True + extract.return_value = True self.assertFalse(arch.run()) - load.return_value = True + load_save.return_value = True self.assertFalse(arch.run()) - copy.return_value = True + copy_conf.return_value = True self.assertFalse(arch.run()) - kick.return_value = {'foo': 'bar'} + kick_option.return_value = {'foo': 'bar'} self.assertFalse(arch.run()) self.assertDictEqual(arch.fsuae_options, {'foo': 'bar'}) - run.return_value = True + run_emulator.return_value = True self.assertFalse(arch.run()) - march.return_value = True + get_save_dir.return_value = True + self.assertFalse(arch.run()) + + save_state.return_value = True + self.assertFalse(arch.run()) + + make_arch.return_value = True self.assertTrue(arch.run()) @mock.patch('os.rename') diff --git a/tests/test_base.py b/tests/test_base.py index 0cf3d6c..ce2346e 100644 --- a/tests/test_base.py +++ b/tests/test_base.py @@ -155,14 +155,18 @@ class TestBase(TestCase): saves_dir.return_value = None carch.return_value = True - self.assertTrue(bobj._save_save()) + self.assertTrue(bobj._save_save(), + 'there is assumption, that wrapper_save_state is' + ' false by default. Here it was true.') + + bobj.all_options['wrapper_save_state'] = '1' + self.assertTrue(bobj._save_save(), + 'unexpected save_state directory found') saves_dir.return_value = bobj.save_filename with open(bobj.save_filename, 'w') as fobj: fobj.write('asd') - self.assertTrue(bobj._save_save()) - os.mkdir(os.path.join(self.dirname, 'fs-uae-save')) self.assertTrue(bobj._save_save()) @@ -177,6 +181,12 @@ class TestBase(TestCase): bobj.save_filename = "foobar_save.7z" earch.return_value = 0 + # By default there would be no save state persistence + self.assertTrue(bobj._load_save()) + + # set wrapper_save_state option, so we can proceed with test + bobj.all_options['wrapper_save_state'] = '1' + # fail to load save is not fatal self.assertTrue(bobj._load_save()) @@ -234,14 +244,24 @@ class TestBase(TestCase): self.assertFalse(bobj._validate_options()) bobj.all_options = {'wrapper': 'dummy'} - self.assertFalse(bobj._validate_options()) + self.assertTrue(bobj._validate_options()) bobj.all_options = {'wrapper': 'dummy', 'wrapper_archiver': 'myarchiver'} + self.assertTrue(bobj._validate_options()) + + bobj.all_options = {'wrapper': 'dummy', + 'wrapper_save_state': '1', + 'wrapper_archiver': 'myarchiver'} self.assertFalse(bobj._validate_options()) which.return_value = '7z' bobj.all_options = {'wrapper': 'dummy', + 'wrapper_save_state': '1'} + self.assertFalse(bobj._validate_options()) + + bobj.all_options = {'wrapper': 'dummy', + 'wrapper_save_state': '1', 'wrapper_archiver': '7z'} self.assertTrue(bobj._validate_options()) diff --git a/tests/test_cd32.py b/tests/test_cd32.py index 4909c4d..c9b90bb 100644 --- a/tests/test_cd32.py +++ b/tests/test_cd32.py @@ -14,7 +14,7 @@ class TestCD32(TestCase): @mock.patch('fs_uae_wrapper.path.which') def test_validate_options(self, which): - which.return_value = None + which.return_value = 'rar' acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) self.assertFalse(acd32._validate_options()) @@ -23,32 +23,27 @@ class TestCD32(TestCase): self.assertFalse(acd32._validate_options()) acd32.all_options['wrapper_archive'] = 'fake.tgz' - self.assertFalse(acd32._validate_options()) - - acd32.all_options['wrapper_archiver'] = 'rar' - self.assertFalse(acd32._validate_options()) - - which.return_value = 'unrar' - acd32.all_options['wrapper_archiver'] = 'rar' self.assertTrue(acd32._validate_options()) @mock.patch('tempfile.mkdtemp') @mock.patch('fs_uae_wrapper.path.which') @mock.patch('fs_uae_wrapper.base.Base._save_save') + @mock.patch('fs_uae_wrapper.base.Base._get_saves_dir') @mock.patch('fs_uae_wrapper.base.Base._run_emulator') @mock.patch('fs_uae_wrapper.base.Base._kickstart_option') - @mock.patch('fs_uae_wrapper.base.Base._load_save') @mock.patch('fs_uae_wrapper.base.Base._copy_conf') + @mock.patch('fs_uae_wrapper.base.Base._load_save') @mock.patch('fs_uae_wrapper.base.Base._extract') - def test_run(self, extr, cconf, lsave, kick, runemul, ssave, which, - mkdtemp): + def test_run(self, extract, load_save, copy_conf, kick_option, + run_emulator, get_save_dir, save_state, which, mkdtemp): - extr.return_value = False - cconf.return_value = False - lsave.return_value = False - kick.return_value = {} - runemul.return_value = False - ssave.return_value = False + extract.return_value = False + copy_conf.return_value = False + load_save.return_value = False + kick_option.return_value = {} + run_emulator.return_value = False + get_save_dir.return_value = False + save_state.return_value = False which.return_value = 'unrar' acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) @@ -60,21 +55,24 @@ class TestCD32(TestCase): self.assertFalse(acd32.run()) - extr.return_value = True + extract.return_value = True self.assertFalse(acd32.run()) - cconf.return_value = True + copy_conf.return_value = True self.assertFalse(acd32.run()) - lsave.return_value = True - self.assertTrue(acd32.run()) + load_save.return_value = True + self.assertFalse(acd32.run()) - kick.return_value = {'foo': 'bar'} - self.assertTrue(acd32.run()) + kick_option.return_value = {'foo': 'bar'} + self.assertFalse(acd32.run()) self.assertDictEqual(acd32.fsuae_options, {'foo': 'bar'}) - runemul.return_value = True + run_emulator.return_value = True + self.assertTrue(acd32.run()) + + get_save_dir.return_value = True self.assertFalse(acd32.run()) - ssave.return_value = True + save_state.return_value = True self.assertTrue(acd32.run())