Skip to content

Commit

Permalink
Merge pull request #1548 from dmach/xml-edit-comments
Browse files Browse the repository at this point in the history
Add comments with attributes/elements to edited XML
  • Loading branch information
dmach committed May 9, 2024
2 parents fe1fe52 + 7a67786 commit 798af31
Showing 1 changed file with 33 additions and 9 deletions.
42 changes: 33 additions & 9 deletions osc/util/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ class XmlModel(BaseModel):
default=FromParent("_apiurl", fallback=None),
)

def to_xml(self) -> ET.Element:
def to_xml(self, *, with_comments: bool = False) -> ET.Element:
xml_tag = None

# check if there's a special field that sets the tag
Expand All @@ -489,6 +489,17 @@ def to_xml(self) -> ET.Element:
assert xml_tag is not None
root = ET.Element(xml_tag)

if with_comments:
comment = [
"",
"The commented attributes and elements only provide hints on the XML structure.",
"See OBS documentation such as XML schema files for more details:",
"https://github.com/openSUSE/open-build-service/tree/master/docs/api/api",
"",
]
comment_node = ET.Comment(text="\n".join(comment))
root.append(comment_node)

for field_name, field in self.__fields__.items():
if field.exclude:
continue
Expand All @@ -503,6 +514,15 @@ def to_xml(self) -> ET.Element:
# a special case when the field determines the top-level tag name
continue

if with_comments:
if xml_attribute:
comment = f'{xml_name}=""'
else:
comment = f"<{xml_name}></{xml_name}>"

comment_node = ET.Comment(text=f" {comment} ")
root.append(comment_node)

value = getattr(self, field_name)
if value is None:
# skip fields that are not set
Expand Down Expand Up @@ -558,25 +578,25 @@ def from_file(cls, file: Union[str, typing.IO], *, apiurl: Optional[str] = None)
root = ET.parse(file).getroot()
return cls.from_xml(root, apiurl=apiurl)

def to_bytes(self) -> bytes:
def to_bytes(self, *, with_comments: bool = False) -> bytes:
"""
Serialize the object as XML and return it as utf-8 encoded bytes.
"""
root = self.to_xml()
root = self.to_xml(with_comments=with_comments)
xml.xml_indent(root)
return ET.tostring(root, encoding="utf-8")

def to_string(self) -> str:
def to_string(self, *, with_comments: bool = False) -> str:
"""
Serialize the object as XML and return it as a string.
"""
return self.to_bytes().decode("utf-8")
return self.to_bytes(with_comments=with_comments).decode("utf-8")

def to_file(self, file: Union[str, typing.IO]) -> None:
def to_file(self, file: Union[str, typing.IO], *, with_comments: bool = False) -> None:
"""
Serialize the object as XML and save it to an utf-8 encoded file.
"""
root = self.to_xml()
root = self.to_xml(with_comments=with_comments)
xml.xml_indent(root)
return ET.ElementTree(root).write(file, encoding="utf-8")

Expand Down Expand Up @@ -798,7 +818,8 @@ def write_file(f, data):

with tempfile.NamedTemporaryFile(mode="w+", encoding="utf-8", prefix="obs_xml_", suffix=".xml") as f:
original_data = self.to_string()
write_file(f, original_data)
original_data_with_comments = self.to_string(with_comments=True)
write_file(f, original_data_with_comments)

while True:
run_editor(f.name)
Expand All @@ -821,7 +842,10 @@ def write_file(f, data):
elif reply == "e":
continue
elif reply == "u":
write_file(f, original_data)
write_file(f, original_data_with_comments)
continue

# strip comments, we don't need to increase traffic to the server
edited_data = edited_obj.to_string()

return original_data, edited_data, edited_obj

0 comments on commit 798af31

Please sign in to comment.