Skip to content

Commit 3e1a543

Browse files
authored
Merge pull request #81 from klauer/fix_global_text_list
FIX: ignore global text list project files
2 parents f7e0ecf + d89aa43 commit 3e1a543

File tree

3 files changed

+66
-24
lines changed

3 files changed

+66
-24
lines changed

blark/solution.py

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,26 @@
7373
]
7474

7575

76+
class SolutionLoaderError(Exception):
77+
"""Solution loader-related exception base class."""
78+
79+
80+
class UnsupportedSourceFileError(SolutionLoaderError):
81+
"""
82+
Unsupported project file.
83+
84+
blark does not support loading of these compilable items:
85+
1. GlobalTextList
86+
2. Any other non-structured text source code files
87+
"""
88+
89+
type: Optional[str] = None
90+
91+
def __init__(self, msg: str, type: Optional[str] = None):
92+
self.type = type
93+
super().__init__(msg)
94+
95+
7696
@functools.lru_cache(maxsize=2048)
7797
def strip_xml_namespace(tag: str) -> str:
7898
"""Strip off {{namespace}} from: {{namespace}}tag."""
@@ -439,19 +459,29 @@ def from_xml(
439459
xml: lxml.etree.Element,
440460
filename: Optional[pathlib.Path] = None,
441461
parent: Optional[TwincatSourceCodeItem] = None,
442-
) -> Optional[Union[TcDUT, TcTTO, TcPOU, TcIO, TcGVL]]:
462+
) -> Union[TcDUT, TcTTO, TcPOU, TcIO, TcGVL]:
443463
tcplc_object = get_tcplc_from_xml(xml)
444464
if tcplc_object is None:
445-
return None
465+
plc_attribs = {}
466+
else:
467+
plc_attribs = tcplc_object.attrib
468+
446469
source_cls, item = get_code_object_from_xml(xml)
447470
if source_cls is None or item is None:
448-
raise RuntimeError(
449-
f"Unsupported xml type for TcSource: {xml}"
471+
try:
472+
child_type = xml.getchildren()[0].tag
473+
except Exception:
474+
child_type = "unknown"
475+
raise UnsupportedSourceFileError(
476+
f"Unsupported xml type for TcSource in "
477+
f"{filename_from_xml(xml)}: {xml.tag}/{child_type} "
478+
f"(parent={parent})",
479+
type=child_type,
450480
)
451481

452482
metadata = dict(item.attrib)
453-
metadata["version"] = tcplc_object.attrib.get("Version", "")
454-
metadata["product_version"] = tcplc_object.attrib.get("ProductVersion", "")
483+
metadata["version"] = plc_attribs.get("Version", "")
484+
metadata["product_version"] = plc_attribs.get("ProductVersion", "")
455485

456486
decl = TcDeclImpl.from_xml(
457487
item,
@@ -481,15 +511,19 @@ def from_contents(
481511
contents: bytes,
482512
filename: Optional[pathlib.Path] = None,
483513
parent: Optional[TcSource] = None,
484-
) -> Optional[Union[TcDUT, TcPOU, TcIO, TcTTO, TcGVL]]:
485-
return cls.from_xml(parse_xml_contents(contents), filename=filename, parent=parent)
514+
) -> Union[TcDUT, TcPOU, TcIO, TcTTO, TcGVL]:
515+
return cls.from_xml(
516+
parse_xml_contents(contents),
517+
filename=filename,
518+
parent=parent,
519+
)
486520

487521
@classmethod
488522
def from_filename(
489523
cls: type[Self],
490524
filename: AnyPath,
491525
parent: Optional[TcSource] = None,
492-
) -> Optional[Union[TcDUT, TcPOU, TcIO, TcTTO, TcGVL]]:
526+
) -> Union[TcDUT, TcPOU, TcIO, TcTTO, TcGVL]:
493527
with open(filename, "rb") as fp:
494528
raw_contents = fp.read()
495529
return cls.from_contents(raw_contents, filename=pathlib.Path(filename), parent=parent)
@@ -995,6 +1029,9 @@ class TcUnknownXml:
9951029
xml: lxml.etree.Element
9961030
parent: TcSource
9971031

1032+
def to_blark(self) -> list[BlarkSourceItem]:
1033+
return []
1034+
9981035

9991036
@dataclasses.dataclass
10001037
class TwincatSourceCodeItem:
@@ -1015,12 +1052,12 @@ class TwincatSourceCodeItem:
10151052
subtype: Optional[str]
10161053
#: Link always set?
10171054
link_always: bool
1055+
#: Raw file contents.
1056+
raw_contents: bytes
1057+
#: Contents loaded into a type-specific class.
1058+
contents: Union[TcDUT, TcPOU, TcIO, TcGVL, TcTTO]
10181059
#: The globally unique identifier for the source code item.
10191060
guid: Optional[str] = None
1020-
#: Raw file contents.
1021-
raw_contents: bytes = b''
1022-
#: Raw contents loaded into a type-specific class.
1023-
contents: Optional[Union[TcDUT, TcPOU, TcIO, TcGVL, TcTTO]] = None
10241061
#: The parent project, if applicable.
10251062
parent: Optional[TwincatPlcProject] = None
10261063

@@ -1064,11 +1101,19 @@ def from_compile_xml(
10641101
else:
10651102
with open(local_path, "rb") as fp:
10661103
raw_contents = fp.read()
1067-
contents = TcSource.from_contents(
1068-
raw_contents,
1069-
filename=local_path,
1070-
parent=None,
1071-
)
1104+
try:
1105+
contents = TcSource.from_contents(
1106+
raw_contents,
1107+
filename=local_path,
1108+
parent=None,
1109+
)
1110+
except UnsupportedSourceFileError:
1111+
logger.debug(
1112+
"Unsupported source code file not loaded: %s",
1113+
local_path,
1114+
exc_info=True,
1115+
)
1116+
return None
10721117

10731118
namespaces = {"msbuild": xml.xpath("namespace-uri()")}
10741119
subtype = get_child_text(
@@ -1647,10 +1692,6 @@ def twincat_file_loader(
16471692
return project_loader(filename)
16481693

16491694
source = TcSource.from_filename(filename)
1650-
if source is None:
1651-
logger.warning("No source found in file %s (is this in error?)", filename)
1652-
return []
1653-
16541695
return source.to_blark()
16551696

16561697

blark/tests/test_dependency_store.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
if not conftest.DS_CONFIG.exists():
99
pytest.skip(
1010
"twincat_root directory not found! Did you recursively clone the "
11-
"repository? (git clone --recursive ...)"
11+
"repository? (git clone --recursive ...)",
12+
allow_module_level=True,
1213
)
1314

1415

0 commit comments

Comments
 (0)