Skip to content

Commit

Permalink
Merge pull request #62 from AllSpiceIO/su/bom-newline-regex
Browse files Browse the repository at this point in the history
Broaden newline regex in Alitum BOM generation
  • Loading branch information
shrik450 authored Jan 30, 2024
2 parents 8517755 + 2f8cef9 commit 827eb55
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 6 deletions.
2 changes: 1 addition & 1 deletion __init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ruff: noqa: F401

from .allspice import (
from allspice import (
AllSpice,
User,
Organization,
Expand Down
10 changes: 8 additions & 2 deletions allspice/apiobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,10 +513,16 @@ def get_branch(self, name: str) -> 'Branch':
)
return Branch.parse_response(self.allspice_client, result)

def add_branch(self, create_from: Branch, newname: str) -> "Branch":
def add_branch(self, create_from: Ref, newname: str) -> "Branch":
"""Add a branch to the repository"""
# Note: will only work with gitea 1.13 or higher!
data = {"new_branch_name": newname, "old_branch_name": create_from.name}

ref_name = Util.data_params_for_ref(create_from)
if "ref" not in ref_name:
raise ValueError("create_from must be a Branch, Commit or string")
ref_name = ref_name["ref"]

data = {"new_branch_name": newname, "old_ref_name": ref_name}
result = self.allspice_client.requests_post(
Repository.REPO_BRANCHES % (self.owner.username, self.name), data=data
)
Expand Down
7 changes: 5 additions & 2 deletions allspice/utils/bom_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from ..apiobject import Content, Ref, Repository
from ..exceptions import NotYetGeneratedException

PRJPCB_SCHDOC_REGEX = re.compile(r"DocumentPath=(.*?SchDoc)(\r\n|\n\r|\n)")


@dataclass
class SchematicComponent:
Expand Down Expand Up @@ -183,8 +185,9 @@ def _extract_schdoc_list_from_prjpcb(prjpcb_file_content) -> list[str]:
Get a list of SchDoc files from a PrjPcb file.
"""

pattern = re.compile(r"DocumentPath=(.*?SchDoc)\r\n")
return [match.group(1) for match in pattern.finditer(prjpcb_file_content)]
# Sometimes the SchDoc file can use \n\r instead of CRLF line endings.
# Unfortunately, it looks like $ even with re.M doesn't(?) match \n\r.
return [match.group(1) for match in PRJPCB_SCHDOC_REGEX.finditer(prjpcb_file_content)]


def _schdoc_component_from_attributes(
Expand Down
11 changes: 11 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,17 @@ def test_create_branch(instance):
assert len(branches) == number_of_branches + 1


def test_create_branch_from_str_ref(instance):
org = Organization.request(instance, test_org)
repo = org.get_repository(test_repo)
branches = repo.get_branches()
number_of_branches = len(branches)
new_branch_name = "branch-" + uuid.uuid4().hex[:8]
repo.add_branch("master", new_branch_name)
branches = repo.get_branches()
assert len(branches) == number_of_branches + 1


def test_create_team(instance):
org = Organization.request(instance, test_org)
team = instance.create_team(org, test_team, "descr")
Expand Down
67 changes: 66 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import base64
import csv
import dataclasses
import uuid

import pytest

from allspice import AllSpice
from allspice.utils.bom_generation import AttributesMapping, generate_bom_for_altium
from allspice.utils.bom_generation import AttributesMapping, generate_bom_for_altium, _get_file_content
from allspice.utils.netlist_generation import generate_netlist

test_repo = "repo_" + uuid.uuid4().hex[:8]
test_branch = "branch_" + uuid.uuid4().hex[:8]


@pytest.fixture(scope="session")
Expand Down Expand Up @@ -86,6 +88,69 @@ def test_bom_generation(request, instance):
assert row == expected_row


def test_bom_generation_with_odd_line_endings(request, instance):
_setup_for_generation(instance, request.node.name)
repo = instance.get_repository(instance.get_user().username,
"-".join([test_repo, request.node.name]))
# We hard-code a ref so that this test is reproducible.
ref = "95719adde8107958bf40467ee092c45b6ddaba00"
attributes_mapping = AttributesMapping(
description=["PART DESCRIPTION"],
designator=["Designator"],
manufacturer=["Manufacturer", "MANUFACTURER"],
part_number=["PART", "MANUFACTURER #"],
)

new_branch_name = "-".join([test_branch, request.node.name])
repo.add_branch(ref, new_branch_name)
ref = new_branch_name

files_in_repo = repo.get_git_content(ref=ref)
prjpcb_file = next((x for x in files_in_repo if x.path == "Archimajor.PrjPcb"), None)
assert prjpcb_file is not None

original_prjpcb_sha = prjpcb_file.sha
encoded_content = repo.get_file_content(prjpcb_file, ref=ref)
prjpcb_content = base64.b64decode(encoded_content).decode("utf-8")
new_prjpcb_content = prjpcb_content.replace("\r\n", "\n\r")
new_content_econded = base64.b64encode(new_prjpcb_content.encode("utf-8")).decode("utf-8")
repo.change_file(
"Archimajor.PrjPcb",
original_prjpcb_sha,
new_content_econded,
{"branch": ref}
)

# Sanity check that the file was changed.
prjpcb_content_now = _get_file_content(repo, "Archimajor.PrjPcb", ref)
assert prjpcb_content_now != prjpcb_content

bom = generate_bom_for_altium(
instance,
repo,
"Archimajor.PrjPcb",
"Archimajor.PcbDoc",
attributes_mapping,
# Note that ref here is the branch, not a commit sha as in the previous
# test.
ref=ref,
)
assert len(bom) == 107

bom_as_dicts = []
# We have to do this manually because of how csv.DictWriter works.
for item in bom:
entry_as_dict = {}
for (key, value) in dataclasses.asdict(item).items():
entry_as_dict[key] = str(value) if value is not None else ""
bom_as_dicts.append(entry_as_dict)

with open("tests/data/archimajor_bom_expected.csv", "r") as f:
reader = csv.DictReader(f)
for row, expected_row in zip(reader, bom_as_dicts):
assert row == expected_row


def test_netlist_generation(request, instance):
_setup_for_generation(instance, request.node.name)
repo = instance.get_repository(instance.get_user().username,
Expand Down

0 comments on commit 827eb55

Please sign in to comment.