From f5adf65a3b1c81d09aee58a17816c762ccc84a0b Mon Sep 17 00:00:00 2001 From: Michał Górny Date: Mon, 23 Oct 2017 21:27:39 +0200 Subject: recursiveloader: Support finding file & dist entries --- gemato/recursiveloader.py | 53 +++++++++++++++++++++++++++++++ tests/test_recursiveloader.py | 74 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 120 insertions(+), 7 deletions(-) diff --git a/gemato/recursiveloader.py b/gemato/recursiveloader.py index 5198ba5..9b72c0c 100644 --- a/gemato/recursiveloader.py +++ b/gemato/recursiveloader.py @@ -72,3 +72,56 @@ class ManifestRecursiveLoader(object): break for mpath, e in to_load: self.load_manifest(mpath, e) + + def find_timestamp(self): + """ + Find a timestamp entry and return it. Returns None if there + is no timestamp. + """ + + self.load_manifests_for_path('') + for p, m in self._iter_manifests_for_path(''): + for e in m.entries: + if isinstance(e, gemato.manifest.ManifestEntryTIMESTAMP): + return e + return None + + def find_path_entry(self, path): + """ + Find a matching entry for path @path and return it. Returns + None when no path matches. DIST entries are not included. + """ + + self.load_manifests_for_path(path) + for relpath, m in self._iter_manifests_for_path(path): + for e in m.entries: + if isinstance(e, gemato.manifest.ManifestEntryIGNORE): + # ignore matches recursively, so we process it separately + # py<3.5 does not have os.path.commonpath() + fullpath = os.path.join(relpath, e.path) + if (path + '/').startswith(fullpath + '/'): + return e + elif isinstance(e, gemato.manifest.ManifestEntryDIST): + # distfiles are not local files, so skip them + pass + elif isinstance(e, gemato.manifest.ManifestPathEntry): + fullpath = os.path.join(relpath, e.path) + if fullpath == path: + return e + return None + + def find_dist_entry(self, filename, relpath=''): + """ + Find a matching entry for distfile @filename and return it. + If @relpath is provided, loads all Manifests up to @relpath + (which can be e.g. a relevant package directory). + Returns None when no DIST entry matches. + """ + + self.load_manifests_for_path(relpath+'/') + for p, m in self._iter_manifests_for_path(relpath+'/'): + for e in m.entries: + if isinstance(e, gemato.manifest.ManifestEntryDIST): + if e.path == filename: + return e + return None diff --git a/tests/test_recursiveloader.py b/tests/test_recursiveloader.py index 6bbc7bd..b60c44c 100644 --- a/tests/test_recursiveloader.py +++ b/tests/test_recursiveloader.py @@ -3,6 +3,7 @@ # (c) 2017 Michał Górny # Licensed under the terms of 2-clause BSD license +import datetime import io import os import tempfile @@ -15,12 +16,17 @@ class BasicNestingTest(unittest.TestCase): DIRS = ['sub', 'sub/deeper'] FILES = { 'Manifest': u''' -MANIFEST sub/Manifest 65 MD5 6af76e314820a44aba2b4bd3e6280c20 +TIMESTAMP 2017-01-01T01:01:01Z +MANIFEST sub/Manifest 128 MD5 30fd28b98a23031c72793908dd35c530 +DIST topdistfile-1.txt 0 MD5 d41d8cd98f00b204e9800998ecf8427e ''', 'sub/Manifest': u''' -MANIFEST deeper/Manifest 0 MD5 d41d8cd98f00b204e9800998ecf8427e +MANIFEST deeper/Manifest 50 MD5 0f7cd9ed779a4844f98d28315dd9176a +DIST subdistfile-1.txt 0 MD5 d41d8cd98f00b204e9800998ecf8427e +''', + 'sub/deeper/Manifest': u''' +DATA test 0 MD5 d41d8cd98f00b204e9800998ecf8427e ''', - 'sub/deeper/Manifest': u'', } def setUp(self): @@ -62,16 +68,55 @@ MANIFEST deeper/Manifest 0 MD5 d41d8cd98f00b204e9800998ecf8427e self.assertIn('sub/Manifest', m.loaded_manifests) self.assertIn('sub/deeper/Manifest', m.loaded_manifests) + def test_find_timestamp(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_timestamp().ts, + datetime.datetime(2017, 1, 1, 1, 1, 1)) + + def test_find_path_entry(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertIsNone(m.find_path_entry('test')) + self.assertIsNone(m.find_path_entry('sub/test')) + self.assertEqual(m.find_path_entry('sub/deeper/test').path, 'test') + + def test_find_top_dist_entry(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_dist_entry('topdistfile-1.txt').path, 'topdistfile-1.txt') + self.assertIsNone(m.find_dist_entry('subdistfile-1.txt')) + + def test_find_sub_dist_entry(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_dist_entry('topdistfile-1.txt', 'sub').path, 'topdistfile-1.txt') + self.assertEqual(m.find_dist_entry('subdistfile-1.txt', 'sub').path, 'subdistfile-1.txt') + + def test_find_sub_dist_entry_with_slash_path(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_dist_entry('topdistfile-1.txt', 'sub/').path, 'topdistfile-1.txt') + self.assertEqual(m.find_dist_entry('subdistfile-1.txt', 'sub/').path, 'subdistfile-1.txt') + + def test_find_sub_dist_entry_with_file_path(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_dist_entry('topdistfile-1.txt', 'sub/file').path, 'topdistfile-1.txt') + self.assertEqual(m.find_dist_entry('subdistfile-1.txt', 'sub/file').path, 'subdistfile-1.txt') + class MultipleManifestTest(unittest.TestCase): DIRS = ['sub'] FILES = { 'Manifest': u''' MANIFEST sub/Manifest.a 0 MD5 d41d8cd98f00b204e9800998ecf8427e -MANIFEST sub/Manifest.b 0 MD5 d41d8cd98f00b204e9800998ecf8427e +MANIFEST sub/Manifest.b 32 MD5 95737355786df5760d6369a80935cf8a ''', 'sub/Manifest.a': u'', - 'sub/Manifest.b': u'', + 'sub/Manifest.b': u''' +TIMESTAMP 2017-01-01T01:01:01Z +''', } def setUp(self): @@ -98,15 +143,24 @@ MANIFEST sub/Manifest.b 0 MD5 d41d8cd98f00b204e9800998ecf8427e self.assertIn('sub/Manifest.a', m.loaded_manifests) self.assertIn('sub/Manifest.b', m.loaded_manifests) + def test_find_timestamp(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + # here it is expected to fail since TIMESTAMP is supposed + # to be top-level + self.assertIsNone(m.find_timestamp()) + class MultipleTopLevelManifestTest(unittest.TestCase): FILES = { 'Manifest': u''' MANIFEST Manifest.a 0 MD5 d41d8cd98f00b204e9800998ecf8427e -MANIFEST Manifest.b 0 MD5 d41d8cd98f00b204e9800998ecf8427e +MANIFEST Manifest.b 32 MD5 95737355786df5760d6369a80935cf8a ''', 'Manifest.a': u'', - 'Manifest.b': u'', + 'Manifest.b': u''' +TIMESTAMP 2017-01-01T01:01:01Z +''', } def setUp(self): @@ -126,3 +180,9 @@ MANIFEST Manifest.b 0 MD5 d41d8cd98f00b204e9800998ecf8427e m.load_manifests_for_path('') self.assertIn('Manifest.a', m.loaded_manifests) self.assertIn('Manifest.b', m.loaded_manifests) + + def test_find_timestamp(self): + m = gemato.recursiveloader.ManifestRecursiveLoader( + os.path.join(self.dir, 'Manifest')) + self.assertEqual(m.find_timestamp().ts, + datetime.datetime(2017, 1, 1, 1, 1, 1)) -- cgit v1.2.3