Skip to content

writer

package.json parser and saver.

PackageJSON

Bases: ProjectMetadataWriter

package.json parser and saver.

Source code in src/somesy/package_json/writer.py
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
class PackageJSON(ProjectMetadataWriter):
    """package.json parser and saver."""

    def __init__(
        self,
        path: Path,
    ):
        """package.json parser.

        See [somesy.core.writer.ProjectMetadataWriter.__init__][].
        """
        mappings: FieldKeyMapping = {
            "authors": ["author"],
            "documentation": IgnoreKey(),
        }
        super().__init__(path, create_if_not_exists=False, direct_mappings=mappings)

    @property
    def authors(self):
        """Return the only author of the package.json file as list."""
        return [self._get_property(self._get_key("authors"))]

    @authors.setter
    def authors(self, authors: List[Person]) -> None:
        """Set the authors of the project."""
        authors = self._from_person(authors[0])
        self._set_property(self._get_key("authors"), authors)

    @property
    def contributors(self):
        """Return the contributors of the package.json file."""
        return self._get_property(self._get_key("contributors"))

    @contributors.setter
    def contributors(self, contributors: List[Person]) -> None:
        """Set the contributors of the project."""
        contributors = [self._from_person(c) for c in contributors]
        self._set_property(self._get_key("contributors"), contributors)

    def _load(self) -> None:
        """Load package.json file."""
        with self.path.open() as f:
            self._data = json.load(f, object_pairs_hook=OrderedDict)

    def _validate(self) -> None:
        """Validate package.json content using pydantic class."""
        config = dict(self._get_property([]))
        logger.debug(
            f"Validating config using {PackageJsonConfig.__name__}: {pretty_repr(config)}"
        )
        PackageJsonConfig(**config)

    def save(self, path: Optional[Path] = None) -> None:
        """Save the package.json file."""
        path = path or self.path
        logger.debug(f"Saving package.json to {path}")

        with path.open("w") as f:
            # package.json indentation is 2 spaces
            json.dump(self._data, f)

    @staticmethod
    def _from_person(person: Person):
        """Convert project metadata person object to package.json dict for person format."""
        person_dict = {"name": person.full_name}
        if person.email:
            person_dict["email"] = person.email
        if person.orcid:
            person_dict["url"] = str(person.orcid)
        return person_dict

    @staticmethod
    def _to_person(person) -> Person:
        """Convert package.json dict or str for person format to project metadata person object."""
        if isinstance(person, str):
            # parse from package.json format
            person = PackageJsonConfig.convert_author(person).model_dump(
                exclude_none=True
            )

        names = list(map(lambda s: s.strip(), person["name"].split()))
        person_obj = {
            "given-names": " ".join(names[:-1]),
            "family-names": names[-1],
        }
        if "email" in person:
            person_obj["email"] = person["email"].strip()
        if "url" in person:
            person_obj["orcid"] = person["url"].strip()
        return Person(**person_obj)

    def sync(self, metadata: ProjectMetadata) -> None:
        """Sync package.json with project metadata.

        Use existing sync function from ProjectMetadataWriter but update repository and contributors.
        """
        super().sync(metadata)
        self.contributors = self._sync_person_list(self.contributors, metadata.people)

    @property
    def repository(self) -> Optional[Union[str, Dict]]:
        """Return the repository url of the project."""
        if repo := super().repository:
            if isinstance(repo, str):
                return repo
            else:
                return repo.get("url")
        else:
            return None

    @repository.setter
    def repository(self, value: Optional[Union[str, Dict]]) -> None:
        """Set the repository url of the project."""
        self._set_property(self._get_key("repository"), dict(type="git", url=value))

authors property writable

authors

Return the only author of the package.json file as list.

contributors property writable

contributors

Return the contributors of the package.json file.

repository property writable

repository: Optional[Union[str, Dict]]

Return the repository url of the project.

__init__

__init__(path: Path)

package.json parser.

See somesy.core.writer.ProjectMetadataWriter.init.

Source code in src/somesy/package_json/writer.py
20
21
22
23
24
25
26
27
28
29
30
31
32
def __init__(
    self,
    path: Path,
):
    """package.json parser.

    See [somesy.core.writer.ProjectMetadataWriter.__init__][].
    """
    mappings: FieldKeyMapping = {
        "authors": ["author"],
        "documentation": IgnoreKey(),
    }
    super().__init__(path, create_if_not_exists=False, direct_mappings=mappings)

save

save(path: Optional[Path] = None) -> None

Save the package.json file.

Source code in src/somesy/package_json/writer.py
69
70
71
72
73
74
75
76
def save(self, path: Optional[Path] = None) -> None:
    """Save the package.json file."""
    path = path or self.path
    logger.debug(f"Saving package.json to {path}")

    with path.open("w") as f:
        # package.json indentation is 2 spaces
        json.dump(self._data, f)

sync

sync(metadata: ProjectMetadata) -> None

Sync package.json with project metadata.

Use existing sync function from ProjectMetadataWriter but update repository and contributors.

Source code in src/somesy/package_json/writer.py
108
109
110
111
112
113
114
def sync(self, metadata: ProjectMetadata) -> None:
    """Sync package.json with project metadata.

    Use existing sync function from ProjectMetadataWriter but update repository and contributors.
    """
    super().sync(metadata)
    self.contributors = self._sync_person_list(self.contributors, metadata.people)