From 62bf675736cb5f13d9395d229f9a76299104a64e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sybren=20A=2E=20St=C3=BCvel?= <sybren@stuvel.eu> Date: Fri, 27 Jan 2017 12:57:31 +0100 Subject: [PATCH] Worker: move_out_of_way cmd now handles existing destination dirs When 'src' needs to be moved to 'dst', but 'dst' already exists, the command finds a suffix that doesn't exist yet. --- .../flamenco_worker/runner.py | 15 +++++++ .../tests/test_runner_move_out_of_way.py | 42 +++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/packages/flamenco-worker-python/flamenco_worker/runner.py b/packages/flamenco-worker-python/flamenco_worker/runner.py index 194a152b..5c5bd549 100644 --- a/packages/flamenco-worker-python/flamenco_worker/runner.py +++ b/packages/flamenco-worker-python/flamenco_worker/runner.py @@ -274,6 +274,21 @@ class MoveOutOfWayCommand(AbstractCommand): mdatetime = datetime.fromtimestamp(mtime) dst = src.with_name('%s-%s' % (src.name, mdatetime.isoformat())) + if dst.exists(): + self._log.debug('Destination %s exists, finding one that does not', dst) + # See which suffixes are in use + max_nr = 0 + for path in dst.parent.glob(dst.name + '*'): + suffix = path.name.split('-')[-1] + try: + suffix = int(suffix) + except ValueError: + continue + self._log.debug('Found suffix %r', suffix) + max_nr = max(max_nr, suffix) + dst = dst.with_name(dst.name + '-%i' % (max_nr + 1)) + self._log.debug('New destination is %s', dst) + self._log.info('Moving %s to %s', src, dst) await self.worker.register_log('%s: Moving %s to %s', self.command_name, src, dst) src.rename(dst) diff --git a/packages/flamenco-worker-python/tests/test_runner_move_out_of_way.py b/packages/flamenco-worker-python/tests/test_runner_move_out_of_way.py index 59cba3f5..9b2d4ed6 100644 --- a/packages/flamenco-worker-python/tests/test_runner_move_out_of_way.py +++ b/packages/flamenco-worker-python/tests/test_runner_move_out_of_way.py @@ -34,6 +34,8 @@ class MoveOutOfWayTest(AbstractCommandTest): src = Path(self.tmpdir.name) / 'existing-dir' src.mkdir() + (src / 'src-contents').touch() + os.utime(str(src), (1330712280, 1330712292)) # fixed (atime, mtime) for testing task = self.cmd.run({'src': str(src)}) @@ -60,3 +62,43 @@ class MoveOutOfWayTest(AbstractCommandTest): self.assertTrue(dst.exists()) self.assertTrue(dst.is_file()) self.assertFalse(src.exists()) + + def test_existing_source_and_dest(self): + from pathlib import Path + import os + + src = Path(self.tmpdir.name) / 'existing-dir' + src.mkdir() + (src / 'src-contents').touch() + os.utime(str(src), (1330712280, 1330712292)) # fixed (atime, mtime) for testing + + existing_dst = src.with_name('existing-dir-2012-03-02T19:18:12') + existing_dst.mkdir() + (existing_dst / 'dst-existing-contents').touch() + + existing_dst2 = src.with_name('existing-dir-2012-03-02T19:18:12-2') + existing_dst2.mkdir() + (existing_dst2 / 'dst2-existing-contents').touch() + + existing_dst4 = src.with_name('existing-dir-2012-03-02T19:18:12-4') + existing_dst4.mkdir() + (existing_dst4 / 'dst4-existing-contents').touch() + + task = self.cmd.run({'src': str(src)}) + ok = self.loop.run_until_complete(task) + self.assertTrue(ok) + + # The existing destination directories should not have been touched. + self.assertTrue(existing_dst.exists()) + self.assertTrue(existing_dst2.exists()) + self.assertTrue(existing_dst4.exists()) + self.assertTrue((existing_dst / 'dst-existing-contents').exists()) + self.assertTrue((existing_dst2 / 'dst2-existing-contents').exists()) + self.assertTrue((existing_dst4 / 'dst4-existing-contents').exists()) + + # The source should have been moved to the new destination. + new_dst = existing_dst.with_name('existing-dir-2012-03-02T19:18:12-5') + self.assertTrue(new_dst.exists()) + self.assertTrue((new_dst / 'src-contents').exists()) + + self.assertFalse(src.exists()) -- GitLab