Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions src/hermes/commands/harvest/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,19 @@ class ContributorData:
Stores contributor data information from Git history.
"""

def __init__(self, name: str | t.List[str], email: str | t.List[str], ts: str | t.List[str]):
def __init__(self, name: str | t.List[str], email: str | t.List[str], timestamp: str | t.List[str]):
"""
Initialize a new contributor dataset.

:param name: Name as returned by the `git log` command (i.e., with `.mailmap` applied).
:param email: Email address as returned by the `git log` command (also with `.mailmap` applied).
:param ts: Timestamp when the respective commit was done.
:param timestamp: Timestamp when the respective commit was done.
"""
self.name = []
self.email = []
self.ts = []
self.timestamp = []

self.update(name=name, email=email, ts=ts)
self.update(name=name, email=email, timestamp=timestamp)

def __str__(self):
parts = []
Expand All @@ -66,17 +66,17 @@ def _update_attr(self, target, value, unique=True):
case str() if not unique or value not in target:
target.append(value)

def update(self, name=None, email=None, ts=None):
def update(self, name=None, email=None, timestamp=None):
"""
Update the current contributor with the given data.

:param name: New name to assign (addtionally).
:param email: New email to assign (additionally).
:param ts: New timestamp to adapt time range.
:param timestamp: New timestamp to adapt time range.
"""
self._update_attr(self.name, name)
self._update_attr(self.email, email)
self._update_attr(self.ts, ts, unique=False)
self._update_attr(self.timestamp, timestamp, unique=False)

def merge(self, other: 'ContributorData'):
"""
Expand All @@ -88,7 +88,7 @@ def merge(self, other: 'ContributorData'):
"""
self.name += [n for n in other.name if n not in self.name]
self.email += [e for e in other.email if e not in self.email]
self.ts += other.ts
self.timestamp += other.timestamp

def to_codemeta(self) -> dict:
"""
Expand All @@ -110,10 +110,10 @@ def to_codemeta(self) -> dict:
if self.email:
res['contactPoint'] = [{'@type': 'ContactPoint', 'email': email} for email in self.email]

if self.ts:
ts_start, *_, ts_end = sorted(self.ts + [self.ts[0]])
res['startTime'] = ts_start
res['endTime'] = ts_end
if self.timestamp:
timestamp_start, *_, timestamp_end = sorted(self.timestamp + [self.timestamp[0]])
res['startTime'] = timestamp_start
res['endTime'] = timestamp_end

return res

Expand All @@ -127,8 +127,8 @@ def from_codemeta(cls, data) -> 'ContributorData':
"""
name = [data['name']] + data.get('alternateName', [])
email = [data['email']] + [contact['email'] for contact in data.get('contactPoint', [])]
ts = [data['startTime'], data['endTime']]
return cls(name, email, ts)
timestamp = [data['startTime'], data['endTime']]
return cls(name, email, timestamp)


class NodeRegister:
Expand Down Expand Up @@ -313,11 +313,11 @@ def harvest_git(click_ctx: click.Context, ctx: HermesHarvestContext):
log = p.stdout.decode(SHELL_ENCODING).split('\n')
for line in log:
try:
name, email, ts = line.split(_GIT_SEP)
name, email, timestamp = line.split(_GIT_SEP)
except ValueError:
continue

authors.update(email=email, name=name, ts=ts)
authors.update(email=email, name=name, timestamp=timestamp)

_audit_authors(authors, logging.getLogger('audit.git'))

Expand Down
20 changes: 10 additions & 10 deletions src/hermes/model/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,30 +195,30 @@ def update(self, _key: str, _value: t.Any, **kwargs: t.Any):
See :py:meth:`HermesContext.update` for more information.
"""

ts = kwargs.pop('ts', datetime.datetime.now().isoformat(timespec='seconds'))
ep = kwargs.pop('ep', self._ep.name)
timestamp = kwargs.pop('timestamp', datetime.datetime.now().isoformat(timespec='seconds'))
harvester = kwargs.pop('harvester', self._ep.name)

if _key not in self._data:
self._data[_key] = []

for entry in self._data[_key]:
value, tag = entry
tag_ts = tag.pop('ts')
tag_ep = tag.pop('ep')
tag_timestamp = tag.pop('timestamp')
tag_harvester = tag.pop('harvester')

if tag == kwargs:
self._log.debug("Update %s: %s -> %s (%s)", _key, str(value), _value, str(tag))
entry[0] = _value
tag['ts'] = ts
tag['ep'] = ep
tag['timestamp'] = timestamp
tag['harvester'] = harvester
break

tag['ts'] = tag_ts
tag['ep'] = tag_ep
tag['timestamp'] = tag_timestamp
tag['harvester'] = tag_harvester

else:
kwargs['ts'] = ts
kwargs['ep'] = ep
kwargs['timestamp'] = timestamp
kwargs['harvester'] = harvester
self._data[_key].append([_value, kwargs])

def _update_key_from(self, _key: ContextPath, _value: t.Any, **kwargs):
Expand Down
60 changes: 36 additions & 24 deletions test/hermes_test/model/test_harvest_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ def test_context_default(harvest_ctx):
harvest_ctx.update('spam', 'eggs', test=True)

assert harvest_ctx._data['spam'] == [
['eggs', {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_default'}]
['eggs', {'test': True,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_default'}]
]


Expand All @@ -35,9 +37,11 @@ def test_context_update_append(harvest_ctx):

assert harvest_ctx._data['spam'] == [
['noodles', {'index': 0,
'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_update_append'}],
['eggs', {'index': 1, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_update_append'}]
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_update_append'}],
['eggs', {'index': 1,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_update_append'}]
]


Expand All @@ -47,8 +51,8 @@ def test_context_update_replace(harvest_ctx):

assert harvest_ctx._data['spam'] == [
['eggs', {'test': True,
'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_update_replace'}]
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_update_replace'}]
]


Expand All @@ -59,10 +63,14 @@ def test_context_bulk_flat(harvest_ctx):
}, test=True)

assert harvest_ctx._data['ans'] == [
[42, {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_bulk_flat'}]
[42, {'test': True,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_flat'}]
]
assert harvest_ctx._data['spam'] == [
['eggs', {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_bulk_flat'}]
['eggs', {'test': True,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_flat'}]
]


Expand All @@ -76,20 +84,22 @@ def test_context_bulk_complex(harvest_ctx):
}, test=True)

assert harvest_ctx._data['ans'] == [
[42, {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_bulk_complex'}]
[42, {'test': True,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_complex'}]
]
assert harvest_ctx._data['author[0].name'] == [
['Monty Python', {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_complex'}]
['Monty Python', {'test': True, 'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_complex'}]
]
assert harvest_ctx._data['author[0].email'] == [
['eggs@spam.io', {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_complex'}]
['eggs@spam.io', {'test': True, 'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_complex'}]
]
assert harvest_ctx._data['author[1].name'] == [
['Herr Mes', {'test': True,
'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_complex'}]
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_complex'}]
]


Expand All @@ -99,12 +109,12 @@ def test_context_bulk_replace(harvest_ctx):

assert harvest_ctx._data['author[0].name'] == [
['Herr Mes', {'test': True,
'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_replace'}]
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_replace'}]
]
assert harvest_ctx._data['author[0].email'] == [
['eggs@spam.io', {'test': True, 'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_replace'}]
['eggs@spam.io', {'test': True, 'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_replace'}]
]


Expand All @@ -113,11 +123,13 @@ def test_context_bulk_append(harvest_ctx):
harvest_ctx.update_from({'author': [{'name': 'Herr Mes', 'email': 'eggs@spam.io'}]}, index=1)

assert harvest_ctx._data['author[0].name'] == [
['Monty Python', {'index': 0, 'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_append'}],
['Herr Mes', {'index': 1, 'ts': datetime.now().isoformat(timespec='seconds'), 'ep': 'test_context_bulk_append'}]
['Monty Python', {'index': 0, 'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_append'}],
['Herr Mes', {'index': 1,
'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_append'}]
]
assert harvest_ctx._data['author[0].email'] == [
['eggs@spam.io', {'index': 1, 'ts': datetime.now().isoformat(timespec='seconds'),
'ep': 'test_context_bulk_append'}]
['eggs@spam.io', {'index': 1, 'timestamp': datetime.now().isoformat(timespec='seconds'),
'harvester': 'test_context_bulk_append'}]
]