Skip to content

Commit 32ad110

Browse files
committed
disable error raise on users without email in package.json
1 parent a400d97 commit 32ad110

3 files changed

Lines changed: 103 additions & 7 deletions

File tree

src/somesy/package_json/models.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
"""package.json validation models."""
22

33
import re
4+
from logging import getLogger
45
from typing import List, Optional, Union
56

67
from pydantic import BaseModel, EmailStr, Field, field_validator
78
from typing_extensions import Annotated
89

910
from somesy.core.types import HttpUrlStr
1011

12+
logger = getLogger("somesy")
13+
1114

1215
class PackageAuthor(BaseModel):
1316
"""Package author model."""
@@ -74,7 +77,7 @@ class PackageJsonConfig(BaseModel):
7477

7578
# convert package author to dict if it is a string
7679
@classmethod
77-
def convert_author(cls, author: str) -> PackageAuthor:
80+
def convert_author(cls, author: str) -> Optional[PackageAuthor]:
7881
"""Convert author string to PackageAuthor model."""
7982
# parse author string to "name <email> (url)" format with regex
8083
author_match = re.match(NPM_PKG_AUTHOR, author)
@@ -84,6 +87,8 @@ def convert_author(cls, author: str) -> PackageAuthor:
8487
author_email = author_match[2]
8588
author_url = author_match[3]
8689

90+
if author_email is None:
91+
return None
8792
return PackageAuthor(name=author_name, email=author_email, url=author_url)
8893

8994
@field_validator("name")
@@ -116,7 +121,17 @@ def validate_people(cls, v):
116121
people = []
117122
for p in v:
118123
if isinstance(p, str):
119-
people.append(cls.convert_author(p))
120-
else:
124+
author = cls.convert_author(p)
125+
if author is not None:
126+
people.append(cls.convert_author(p))
127+
else:
128+
logger.warning(
129+
f"Invalid email format for maintainer/contributor {p}, omitting."
130+
)
131+
elif p.email is not None:
121132
people.append(p)
133+
else:
134+
logger.warning(
135+
f"Invalid email format for maintainer/contributor {p}, omitting."
136+
)
122137
return people

src/somesy/package_json/writer.py

Lines changed: 52 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ def __init__(
3535
@property
3636
def authors(self):
3737
"""Return the only author of the package.json file as list."""
38+
# check if the author has the correct format
39+
if isinstance(author := self._get_property(self._get_key("authors")), str):
40+
author = PackageJsonConfig.convert_author(author)
41+
if author is None:
42+
return []
43+
3844
return [self._get_property(self._get_key("authors"))]
3945

4046
@authors.setter
@@ -43,10 +49,49 @@ def authors(self, authors: List[Person]) -> None:
4349
authors = self._from_person(authors[0])
4450
self._set_property(self._get_key("authors"), authors)
4551

52+
@property
53+
def maintainers(self):
54+
"""Return the maintainers of the package.json file."""
55+
# check if the maintainer has the correct format
56+
maintainers = self._get_property(self._get_key("maintainers"))
57+
# return empty list if maintainers is None
58+
if maintainers is None:
59+
return []
60+
61+
maintainers_valid = []
62+
63+
for maintainer in maintainers:
64+
if isinstance(maintainer, str):
65+
maintainer = PackageJsonConfig.convert_author(maintainer)
66+
if maintainer is None:
67+
continue
68+
maintainers_valid.append(maintainer)
69+
return maintainers_valid
70+
71+
@maintainers.setter
72+
def maintainers(self, maintainers: List[Person]) -> None:
73+
"""Set the maintainers of the project."""
74+
maintainers = [self._from_person(m) for m in maintainers]
75+
self._set_property(self._get_key("maintainers"), maintainers)
76+
4677
@property
4778
def contributors(self):
4879
"""Return the contributors of the package.json file."""
49-
return self._get_property(self._get_key("contributors"))
80+
# check if the contributor has the correct format
81+
contributors = self._get_property(self._get_key("contributors"))
82+
# return empty list if contributors is None
83+
if contributors is None:
84+
return []
85+
86+
contributors_valid = []
87+
88+
for contributor in contributors:
89+
if isinstance(contributor, str):
90+
contributor = PackageJsonConfig.convert_author(contributor)
91+
if contributor is None:
92+
continue
93+
contributors_valid.append(contributor)
94+
return contributors_valid
5095

5196
@contributors.setter
5297
def contributors(self, contributors: List[Person]) -> None:
@@ -91,9 +136,12 @@ def _to_person(person) -> Person:
91136
"""Convert package.json dict or str for person format to project metadata person object."""
92137
if isinstance(person, str):
93138
# parse from package.json format
94-
person = PackageJsonConfig.convert_author(person).model_dump(
95-
exclude_none=True
96-
)
139+
person = PackageJsonConfig.convert_author(person)
140+
141+
if person is None:
142+
return None
143+
144+
person = person.model_dump(exclude_none=True)
97145

98146
names = list(map(lambda s: s.strip(), person["name"].split()))
99147
person_obj = {

tests/output/test_package_json_writer.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,39 @@ def test_from_to_person(person: Person):
4848
assert p.email == person.email
4949
assert p.orcid == person.orcid
5050

51+
# without email
52+
p = PackageJSON._to_person("John Doe")
53+
assert p is None
54+
55+
56+
def test_only_name(package_json: PackageJSON, person: Person):
57+
package_json._data["author"] = "John Doe"
58+
package_json._data["maintainers"] = ["Jane Doe"]
59+
60+
assert len(package_json.authors) == 0
61+
assert len(package_json.maintainers) == 0
62+
63+
# merge and see if it works
64+
pm = ProjectMetadata(
65+
name="My awesome project",
66+
description="Project description",
67+
license=LicenseEnum.MIT,
68+
version="0.1.0",
69+
people=[
70+
person.model_copy(
71+
update=dict(author=True, publication_author=True, maintainer=True)
72+
)
73+
],
74+
)
75+
package_json.sync(pm)
76+
77+
assert len(package_json.authors) == 1
78+
assert len(package_json.maintainers) == 1
79+
80+
assert package_json.authors[0]["name"] == person.full_name
81+
assert package_json.authors[0]["email"] == person.email
82+
assert package_json.authors[0]["url"] == str(person.orcid)
83+
5184

5285
def test_person_merge(package_json_file, person: Person):
5386
pj = PackageJSON(package_json_file)

0 commit comments

Comments
 (0)