diff --git a/requirements.txt b/requirements.txt --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ python-dateutil subvertpy >= 0.9.4 typing-extensions +pytest-postgresql < 4.0.0 diff --git a/swh/loader/svn/ra.py b/swh/loader/svn/ra.py --- a/swh/loader/svn/ra.py +++ b/swh/loader/svn/ra.py @@ -11,7 +11,7 @@ import os import shutil import tempfile -from typing import Dict, List, Tuple +from typing import List, Optional, Tuple import click from subvertpy import delta, properties @@ -122,19 +122,27 @@ SVN_PROPERTY_EOL = "svn:eol-style" -# EOL state check mess -EOL_STYLE = {} - class FileEditor: """File Editor in charge of updating file on disk and memory objects. """ - __slots__ = ["directory", "path", "fullpath", "executable", "link"] + __slots__ = [ + "directory", + "path", + "fullpath", + "executable", + "link", + "eol_style", + "svn_special_path_non_link_data", + ] + + eol_style: Optional[str] + """EOL state check mess""" - # keep track of non link file content with svn:special property set - svn_special_path_non_link_data: Dict[str, bytes] = {} + svn_special_path_non_link_data: bytes + """keep track of non link file content with svn:special property set""" def __init__(self, directory, rootpath, path): self.directory = directory @@ -143,6 +151,8 @@ self.executable = DEFAULT_FLAG self.link = None self.fullpath = os.path.join(rootpath, path) + self.eol_style = None + self.svn_special_path_non_link_data = None def change_prop(self, key, value): if key == properties.PROP_EXECUTABLE: @@ -156,7 +166,7 @@ self.link = value is not None elif key == SVN_PROPERTY_EOL: # backup end of line style for file - EOL_STYLE[self.fullpath] = value + self.eol_style = value def __make_symlink(self, src): """Convert the svnlink to a symlink on disk. @@ -242,18 +252,18 @@ if exported_data != content: # keep track of original file content in order to restore # it if the svn:special property gets unset in another revision - self.svn_special_path_non_link_data[self.fullpath] = content + self.svn_special_path_non_link_data = content f.write(exported_data) elif os.path.islink(self.fullpath): # path was a symbolic link in previous revision but got the property # svn:special unset in current one, revert its content to svn link format self.__make_svnlink() - elif self.fullpath in self.svn_special_path_non_link_data: + elif self.svn_special_path_non_link_data is not None: # path was a non link file with the svn:special property previously set # and got truncated on export, restore its original content with open(self.fullpath, "wb") as f: - f.write(self.svn_special_path_non_link_data[self.fullpath]) - del self.svn_special_path_non_link_data[self.fullpath] + f.write(self.svn_special_path_non_link_data) + self.svn_special_path_non_link_data = None if not is_link: # if a link, do nothing regarding flag if self.executable == EXEC_FLAG: @@ -262,14 +272,13 @@ os.chmod(self.fullpath, 0o644) # And now compute file's checksums - eol_style = EOL_STYLE.get(self.fullpath, None) - if eol_style and not is_link: + if self.eol_style and not is_link: # ensure to normalize line endings as defined by svn:eol-style # property to get the same file checksum as after an export # or checkout operation with subversion with open(self.fullpath, "rb") as f: data = f.read() - data = _normalize_line_endings(data, eol_style) + data = _normalize_line_endings(data, self.eol_style) mode = os.lstat(self.fullpath).st_mode self.directory[self.path] = from_disk.Content.from_bytes( mode=mode, data=data @@ -330,14 +339,6 @@ else: os.remove(fpath) - # when deleting a directory ensure to remove any eol style setting for the - # file it contains as they can be added again later in another revision - # without the svn:eol-style property set - fullpath = os.path.join(self.rootpath, path) - for eol_path in list(EOL_STYLE): - if eol_path.startswith(fullpath): - del EOL_STYLE[eol_path] - def update_checksum(self): raise NotImplementedError("This should be implemented.")