Changeset View
Changeset View
Standalone View
Standalone View
swh/loader/cvs/rlog.py
Show All 39 Lines | |||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
import calendar | import calendar | ||||
from collections import defaultdict | |||||
import re | import re | ||||
import string | import string | ||||
import time | import time | ||||
from typing import BinaryIO, Dict, List, NamedTuple, Optional, Tuple | from typing import BinaryIO, Dict, List, NamedTuple, Optional, Tuple | ||||
from swh.loader.cvs.cvs2gitdump.cvs2gitdump import ChangeSetKey | from swh.loader.cvs.cvs2gitdump.cvs2gitdump import ChangeSetKey | ||||
Show All 18 Lines | class RlogConv: | ||||
def _process_rlog_revisions( | def _process_rlog_revisions( | ||||
self, | self, | ||||
path: bytes, | path: bytes, | ||||
taginfo: Dict[bytes, bytes], | taginfo: Dict[bytes, bytes], | ||||
revisions: Dict[str, revtuple], | revisions: Dict[str, revtuple], | ||||
logmsgs: Dict[str, Optional[bytes]], | logmsgs: Dict[str, Optional[bytes]], | ||||
) -> None: | ) -> None: | ||||
"""Convert RCS revision history of a file into self.changesets items""" | """Convert RCS revision history of a file into self.changesets items""" | ||||
rtags: Dict[str, List[str]] = dict() | rtags: Dict[str, List[str]] = defaultdict(list) | ||||
# RCS and CVS represent branches by adding digits to revision numbers. | # RCS and CVS represent branches by adding digits to revision numbers. | ||||
# And CVS assigns special meaning to certain revision number ranges. | # And CVS assigns special meaning to certain revision number ranges. | ||||
# | # | ||||
# Revision numbers on the main branch have only two digits: | # Revision numbers on the main branch have only two digits: | ||||
# | # | ||||
# 1.1, 1.2, 1.3, ... | # 1.1, 1.2, 1.3, ... | ||||
# | # | ||||
# Branches created with 'cvs tag -b' use even numbers for | # Branches created with 'cvs tag -b' use even numbers for | ||||
Show All 25 Lines | ) -> None: | ||||
# | # | ||||
# 1.1, 1.2, 1.3, ... main branch history of the file | # 1.1, 1.2, 1.3, ... main branch history of the file | ||||
# | | # | | ||||
# 1.1.2.0.1 magic branch (2) | # 1.1.2.0.1 magic branch (2) | ||||
# | # | ||||
# This allows CVS to store information about a branch's existence | # This allows CVS to store information about a branch's existence | ||||
# before any files on this branch have been modified. | # before any files on this branch have been modified. | ||||
# Even-numbered branch revisions appear once the file is modified. | # Even-numbered branch revisions appear once the file is modified. | ||||
branches = {"1": "HEAD", "1.1.1": "VENDOR"} | branches = {"1": "HEAD", "1.1.1": "VENDOR"} | ||||
k: str | for k_, v_ in taginfo.items(): | ||||
v_: str | v_str = v_.decode() | ||||
ardumont: not on you but i have a hard time reading the what the `k` and `v_` variables stand for... | |||||
Done Inline ActionsI thought about renaming these loop variables (plus the two others in other loop below) but I wanted to keep that diff small and readable. anlambert: I thought about renaming these loop variables (plus the two others in other loop below) but I… | |||||
for k, v_ in list(taginfo.items()): # type: ignore # FIXME, inconsistent types | r = v_str.split(".") | ||||
r = v_.split(".") | |||||
if len(r) == 3: | if len(r) == 3: | ||||
# vendor branch number | # vendor branch number | ||||
branches[v_] = "VENDOR" | branches[v_str] = "VENDOR" | ||||
elif len(r) >= 3 and r[-2] == "0": | elif len(r) >= 3 and r[-2] == "0": | ||||
# magic branch number | # magic branch number | ||||
branches[".".join(r[:-2] + r[-1:])] = k | branches[".".join(r[:-2] + r[-1:])] = k_.decode() | ||||
if len(r) == 2 and branches[r[0]] == "HEAD": | elif len(r) == 2 and branches.get(r[0]) == "HEAD": | ||||
# main branch number | # main branch number | ||||
if v_ not in rtags: | rtags[v_str].append(k_.decode()) | ||||
rtags[v_] = list() | |||||
rtags[v_].append(k) | |||||
revs: List[Tuple[str, revtuple]] = list(revisions.items()) | revs: List[Tuple[str, revtuple]] = list(revisions.items()) | ||||
# sort by revision descending to priorize 1.1.1.1 than 1.1 | # sort by revision descending to priorize 1.1.1.1 than 1.1 | ||||
revs.sort(key=lambda a: a[1][0], reverse=True) | revs.sort(key=lambda a: a[1][0], reverse=True) | ||||
# sort by time | # sort by time | ||||
revs.sort(key=lambda a: a[1][1]) | revs.sort(key=lambda a: a[1][1]) | ||||
novendor = False | novendor = False | ||||
have_initial_revision = False | have_initial_revision = False | ||||
Show All 13 Lines | ) -> None: | ||||
continue | continue | ||||
last_vendor_status = v[3] | last_vendor_status = v[3] | ||||
have_initial_revision = True | have_initial_revision = True | ||||
elif len(r) == 4 and r[0] == "1" and r[1] == "1" and r[2] == "1": | elif len(r) == 4 and r[0] == "1" and r[1] == "1" and r[2] == "1": | ||||
if novendor: | if novendor: | ||||
continue | continue | ||||
last_vendor_status = v[3] | last_vendor_status = v[3] | ||||
elif len(r) == 2: | elif len(r) == 2: | ||||
# ensure revision targets head branch | |||||
branches[r[0]] = "HEAD" | |||||
if r[0] == "1" and r[1] == "1": | if r[0] == "1" and r[1] == "1": | ||||
if have_initial_revision: | if have_initial_revision: | ||||
continue | continue | ||||
if v[3] == "dead": | if v[3] == "dead": | ||||
continue | continue | ||||
have_initial_revision = True | have_initial_revision = True | ||||
elif r[0] == "1" and r[1] != "1": | elif r[0] == "1" and r[1] != "1": | ||||
novendor = True | novendor = True | ||||
▲ Show 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | ]: | ||||
while 1: | while 1: | ||||
line = fp.readline() | line = fp.readline() | ||||
if not line: | if not line: | ||||
# the true end-of-file | # the true end-of-file | ||||
eof = _EOF_LOG | eof = _EOF_LOG | ||||
break | break | ||||
if state == 1: | if state == 1: | ||||
if line[0] == b"\t": | if line.startswith(b"\t"): | ||||
[tag, rev] = [x.strip() for x in line.split(b":")] | [tag, rev] = [x.strip() for x in line.split(b":")] | ||||
taginfo[tag] = rev | taginfo[tag] = rev | ||||
else: | else: | ||||
# oops. this line isn't tag info. stop parsing tags. | # oops. this line isn't tag info. stop parsing tags. | ||||
state = 0 | state = 0 | ||||
if state == 2: | if state == 2: | ||||
if line[0] == b"\t": | if line.startswith(b"\t"): | ||||
Not Done Inline Actionsare those last 2 changes the same as before though? ardumont: are those last 2 changes the same as before though? | |||||
Done Inline ActionsThey are related yes, I found that issue while discovering the taginfo dict in the code above was always empty even for repositories with tags. anlambert: They are related yes, I found that issue while discovering the `taginfo` dict in the code above… | |||||
[locker, rev] = [x.strip() for x in line.split(b":")] | [locker, rev] = [x.strip() for x in line.split(b":")] | ||||
lockinfo[rev] = locker | lockinfo[rev] = locker | ||||
else: | else: | ||||
# oops. this line isn't lock info. stop parsing tags. | # oops. this line isn't lock info. stop parsing tags. | ||||
state = 0 | state = 0 | ||||
if state == 0: | if state == 0: | ||||
if line == "\n": | if line == "\n": | ||||
▲ Show 20 Lines • Show All 170 Lines • Show Last 20 Lines |
not on you but i have a hard time reading the what the k and v_ variables stand for...