diff options
-rw-r--r-- | gemato/find_top_level.py | 2 | ||||
-rw-r--r-- | gemato/manifest.py | 16 | ||||
-rw-r--r-- | gemato/recursiveloader.py | 123 | ||||
-rw-r--r-- | gemato/verify.py | 14 |
4 files changed, 74 insertions, 81 deletions
diff --git a/gemato/find_top_level.py b/gemato/find_top_level.py index 97cb26f..b70abdf 100644 --- a/gemato/find_top_level.py +++ b/gemato/find_top_level.py @@ -55,7 +55,7 @@ def find_top_level_manifest(path='.'): if relpath == '.': relpath = '' fe = m.find_path_entry(relpath) - if isinstance(fe, gemato.manifest.ManifestEntryIGNORE): + if fe is not None and fe.tag == 'IGNORE': return last_found last_found = m_path diff --git a/gemato/manifest.py b/gemato/manifest.py index 262c7f3..f0438e9 100644 --- a/gemato/manifest.py +++ b/gemato/manifest.py @@ -431,7 +431,7 @@ class ManifestFile(object): """ for e in self.entries: - if isinstance(e, ManifestEntryTIMESTAMP): + if e.tag == 'TIMESTAMP': return e return None @@ -442,15 +442,16 @@ class ManifestFile(object): """ for e in self.entries: - if isinstance(e, ManifestEntryIGNORE): + if e.tag == 'IGNORE': # ignore matches recursively, so we process it separately # py<3.5 does not have os.path.commonpath() if gemato.util.path_starts_with(path, e.path): return e - elif isinstance(e, ManifestEntryDIST): + elif e.tag in ('DIST', 'TIMESTAMP'): # distfiles are not local files, so skip them + # timestamp is not a file ;-) pass - elif isinstance(e, ManifestPathEntry): + else: if e.path == path: return e return None @@ -462,9 +463,8 @@ class ManifestFile(object): """ for e in self.entries: - if isinstance(e, ManifestEntryDIST): - if e.path == filename: - return e + if e.tag == 'DIST' and e.path == filename: + return e return None def find_manifests_for_path(self, path): @@ -475,7 +475,7 @@ class ManifestFile(object): """ for e in self.entries: - if isinstance(e, ManifestEntryMANIFEST): + if e.tag == 'MANIFEST': mdir = os.path.dirname(e.path) if gemato.util.path_inside_dir(path, mdir): yield e diff --git a/gemato/recursiveloader.py b/gemato/recursiveloader.py index 9333c15..9e1ac61 100644 --- a/gemato/recursiveloader.py +++ b/gemato/recursiveloader.py @@ -135,7 +135,7 @@ class ManifestRecursiveLoader(object): for curmpath, relpath, m in self._iter_manifests_for_path( path, recursive): for e in m.entries: - if not isinstance(e, gemato.manifest.ManifestEntryMANIFEST): + if e.tag != 'MANIFEST': continue mpath = os.path.join(relpath, e.path) if curmpath == mpath or mpath in self.loaded_manifests: @@ -159,7 +159,7 @@ class ManifestRecursiveLoader(object): self.load_manifests_for_path('') for mpath, p, m in self._iter_manifests_for_path(''): for e in m.entries: - if isinstance(e, gemato.manifest.ManifestEntryTIMESTAMP): + if e.tag == 'TIMESTAMP': return e return None @@ -172,16 +172,17 @@ class ManifestRecursiveLoader(object): self.load_manifests_for_path(path) for mpath, relpath, m in self._iter_manifests_for_path(path): for e in m.entries: - if isinstance(e, gemato.manifest.ManifestEntryIGNORE): + if e.tag == 'IGNORE': # 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 gemato.util.path_starts_with(path, fullpath): return e - elif isinstance(e, gemato.manifest.ManifestEntryDIST): + elif e.tag in ('DIST', 'TIMESTAMP'): # distfiles are not local files, so skip them + # timestamp is not a file ;-) pass - elif isinstance(e, gemato.manifest.ManifestPathEntry): + else: fullpath = os.path.join(relpath, e.path) if fullpath == path: return e @@ -222,9 +223,8 @@ class ManifestRecursiveLoader(object): self.load_manifests_for_path(relpath+'/') for mpath, 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 + if e.tag == 'DIST' and e.path == filename: + return e return None def get_file_entry_dict(self, path=''): @@ -239,26 +239,27 @@ class ManifestRecursiveLoader(object): for mpath, relpath, m in self._iter_manifests_for_path(path, recursive=True): for e in m.entries: - if isinstance(e, gemato.manifest.ManifestEntryDIST): + if e.tag in ('DIST', 'TIMESTAMP'): # distfiles are not local files, so skip them - pass - elif isinstance(e, gemato.manifest.ManifestPathEntry): - fullpath = os.path.join(relpath, e.path) - if gemato.util.path_starts_with(fullpath, path): - if fullpath in out: - # compare the two entries - ret, diff = gemato.verify.verify_entry_compatibility( - out[fullpath], e) - if not ret: - raise gemato.exceptions.ManifestIncompatibleEntry(out[fullpath], e, diff) - # we need to construct a single entry with both checksums - if diff: - new_checksums = dict(e.checksums) - for k, d1, d2 in diff: - if d2 is None: - new_checksums[k] = d1 - e = type(e)(e.path, e.size, new_checksums) - out[fullpath] = e + # timestamp is not a file ;-) + continue + + fullpath = os.path.join(relpath, e.path) + if gemato.util.path_starts_with(fullpath, path): + if fullpath in out: + # compare the two entries + ret, diff = gemato.verify.verify_entry_compatibility( + out[fullpath], e) + if not ret: + raise gemato.exceptions.ManifestIncompatibleEntry(out[fullpath], e, diff) + # we need to construct a single entry with both checksums + if diff: + new_checksums = dict(e.checksums) + for k, d1, d2 in diff: + if d2 is None: + new_checksums[k] = d1 + e = type(e)(e.path, e.size, new_checksums) + out[fullpath] = e return out def _verify_one_file(self, path, relpath, e, fail_handler, warn_handler): @@ -266,8 +267,7 @@ class ManifestRecursiveLoader(object): expected_dev=self.manifest_device) if not ret: - if (isinstance(e, gemato.manifest.ManifestEntryOPTIONAL) - or isinstance(e, gemato.manifest.ManifestEntryMISC)): + if e is not None and e.tag in ('MISC', 'OPTIONAL'): h = warn_handler else: h = fail_handler @@ -333,7 +333,7 @@ class ManifestRecursiveLoader(object): raise gemato.exceptions.ManifestCrossDevice(syspath) continue - if isinstance(de, gemato.manifest.ManifestEntryIGNORE): + if de.tag == 'IGNORE': skip_dirs.append(d) else: ret &= self._verify_one_file(os.path.join(dirpath, d), @@ -385,8 +385,7 @@ class ManifestRecursiveLoader(object): for mpath, relpath, m in self._iter_manifests_for_path('', recursive=True): for e in m.entries: - if not isinstance(e, gemato.manifest - .ManifestEntryMANIFEST): + if e.tag != 'MANIFEST': continue fullpath = os.path.join(relpath, e.path) @@ -460,20 +459,21 @@ class ManifestRecursiveLoader(object): for mpath, relpath, m in self._iter_manifests_for_path(path): entries_to_remove = [] for e in m.entries: - if isinstance(e, gemato.manifest.ManifestEntryIGNORE): + if e.tag == 'IGNORE': # ignore matches recursively, so we process it separately # py<3.5 does not have os.path.commonpath() fullpath = os.path.join(relpath, e.path) assert not gemato.util.path_starts_with(path, fullpath) - elif isinstance(e, gemato.manifest.ManifestEntryDIST): + elif e.tag in ('DIST', 'TIMESTAMP'): # distfiles are not local files, so skip them + # timestamp is not a file ;-) pass - elif isinstance(e, gemato.manifest.ManifestEntryOPTIONAL): + elif e.tag == 'OPTIONAL': # leave OPTIONAL entries as-is fullpath = os.path.join(relpath, e.path) if fullpath == path: had_entry = True - elif isinstance(e, gemato.manifest.ManifestPathEntry): + else: # we update either file at the specified path # or any relevant Manifests fullpath = os.path.join(relpath, e.path) @@ -559,27 +559,28 @@ class ManifestRecursiveLoader(object): recursive=True): entries_to_remove = [] for e in m.entries: - if isinstance(e, gemato.manifest.ManifestEntryDIST): + if e.tag in ('DIST', 'TIMESTAMP'): # distfiles are not local files, so skip them - pass - elif isinstance(e, gemato.manifest.ManifestPathEntry): - fullpath = os.path.join(relpath, e.path) - if gemato.util.path_starts_with(fullpath, path): - if fullpath in out: - # compare the two entries - ret, diff = gemato.verify.verify_entry_compatibility( - out[fullpath][1], e) - # if semantically incompatible, throw - if not ret and diff[0][0] == '__type__': - raise (gemato.exceptions - .ManifestIncompatibleEntry( - out[fullpath][1], e, diff)) - # otherwise, make sure we have all checksums - out[fullpath][1].checksums.update(e.checksums) - # and drop the duplicate - entries_to_remove.append(e) - else: - out[fullpath] = (mpath, e) + # timestamp is not a file ;-) + continue + + fullpath = os.path.join(relpath, e.path) + if gemato.util.path_starts_with(fullpath, path): + if fullpath in out: + # compare the two entries + ret, diff = gemato.verify.verify_entry_compatibility( + out[fullpath][1], e) + # if semantically incompatible, throw + if not ret and diff[0][0] == '__type__': + raise (gemato.exceptions + .ManifestIncompatibleEntry( + out[fullpath][1], e, diff)) + # otherwise, make sure we have all checksums + out[fullpath][1].checksums.update(e.checksums) + # and drop the duplicate + entries_to_remove.append(e) + else: + out[fullpath] = (mpath, e) if entries_to_remove: for e in entries_to_remove: @@ -637,7 +638,7 @@ class ManifestRecursiveLoader(object): raise gemato.exceptions.ManifestCrossDevice(syspath) continue - if isinstance(de, gemato.manifest.ManifestEntryIGNORE): + if de.tag == 'IGNORE': skip_dirs.append(d) else: # trigger the exception indirectly @@ -667,9 +668,7 @@ class ManifestRecursiveLoader(object): continue mpath, fe = entry_dict.pop(fpath, (None, None)) if fe is not None: - if isinstance(fe, gemato.manifest.ManifestEntryIGNORE): - continue - elif isinstance(fe, gemato.manifest.ManifestEntryOPTIONAL): + if fe.tag in ('IGNORE', 'OPTIONAL'): continue else: # find appropriate Manifest for this directory @@ -698,9 +697,7 @@ class ManifestRecursiveLoader(object): # check for removed files for relpath, me in entry_dict.items(): mpath, fe = me - if isinstance(fe, gemato.manifest.ManifestEntryIGNORE): - continue - elif isinstance(fe, gemato.manifest.ManifestEntryOPTIONAL): + if fe.tag in ('IGNORE', 'OPTIONAL'): continue self.loaded_manifests[mpath].entries.remove(fe) diff --git a/gemato/verify.py b/gemato/verify.py index 0b1097b..538c998 100644 --- a/gemato/verify.py +++ b/gemato/verify.py @@ -140,15 +140,15 @@ def verify_path(path, e, expected_dev=None): """ if e is not None: - assert isinstance(e, gemato.manifest.ManifestPathEntry) + assert e.tag != 'TIMESTAMP' # IGNORE entries cause verification to always succeed - if isinstance(e, gemato.manifest.ManifestEntryIGNORE): + if e.tag == 'IGNORE': return (True, []) # OPTIONAL does not contain checksums, and expects not to exist # same goes for None - if e is None or isinstance(e, gemato.manifest.ManifestEntryOPTIONAL): + if e is None or e.tag == 'OPTIONAL': expect_exist = False checksums = () else: @@ -218,9 +218,7 @@ def update_entry_for_path(path, e, hashes=None, expected_dev=None): the files do not cross filesystem boundaries. """ - assert isinstance(e, gemato.manifest.ManifestPathEntry) - assert not isinstance(e, gemato.manifest.ManifestEntryIGNORE) - assert not isinstance(e, gemato.manifest.ManifestEntryOPTIONAL) + assert e.tag not in ('IGNORE', 'OPTIONAL', 'TIMESTAMP') if hashes is None: hashes = list(e.checksums) @@ -272,12 +270,10 @@ def verify_entry_compatibility(e1, e2): hashes that are present only in one of the entries. """ - assert isinstance(e1, gemato.manifest.ManifestPathEntry) - assert isinstance(e2, gemato.manifest.ManifestPathEntry) - # 1. compare types t1 = e1.tag t2 = e2.tag + assert 'TIMESTAMP' not in (t1, t2) if t1 != t2: # all those tags have compatible semantics COMPATIBLE_TAGS = ('MANIFEST', 'DATA', 'EBUILD', 'AUX') |