klauer / blark

Beckhoff TwinCAT ST (IEC 61131-3) code parsing in Python using Lark (Earley)
https://klauer.github.io/blark/
GNU General Public License v2.0
42 stars 5 forks source link

ENH: interface support #73

Closed klauer closed 1 year ago

klauer commented 1 year ago

Context

First pass at INTERFACE support.

Closes #16

It wasn't possible to parse TcIO files with pytmc previously, but now with our built-in solution parser of #64 we can move forward with supporting interface files directly from TwinCAT projects.

Some additional fixes made their way in here, too.

klauer commented 1 year ago

Does this work on any interface source code you might have, @engineerjoe440? (No rush in replying/testing of course)

engineerjoe440 commented 1 year ago

I just pulled this branch and then did a retroactive git clone --recursive (by using the git submodule update --init --recursive command), and I'm seeing failures and errors, now. ☹️

Here's the short test-summary:

======================================================================================== short test summary info ========================================================================================
FAILED blark/tests/test_dependency_store.py::test_load_project[LCLS_General-v2.8.1] - RuntimeError: No match for project LCLS_General version=v2.8.1
FAILED blark/tests/test_dependency_store.py::test_load_project[project_a-*] - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Documents\\Python%20RTAC%20Projects\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\ProjectA.plcproj'
FAILED blark/tests/test_dependency_store.py::test_load_project[project_b-*] - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Documents\\Python%20RTAC%20Projects\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB\\ProjectB.plc...
ERROR blark/tests/test_summary.py::test_project_a_summary - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Documents\\Python%20RTAC%20Projects\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\ProjectA.plcproj'
ERROR blark/tests/test_summary.py::test_project_b_summary - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Documents\\Python%20RTAC%20Projects\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB\\ProjectB.plc...
ERROR blark/tests/test_summary.py::test_twincat_general - ValueError: not enough values to unpack (expected 1, got 0)
ERROR blark/tests/test_summary.py::test_twincat_general_interface - ValueError: not enough values to unpack (expected 1, got 0)
========================================================================== 3 failed, 621 passed, 6 xfailed, 4 errors in 38.73s ==========================================================================

It looks like there's some little edge-cases with the testing, that's all. I do think that this is an awesome body of work! Looking forward to verifying it. 😄

klauer commented 1 year ago

Thanks for the reviews, @engineerjoe440 👍

Hmm, let's see - what did I mess up here with that test project submodule...

klauer commented 1 year ago

I think your submodule may still be behind somehow. Submodules are a pain in git, that's for sure. Would you mind trying the following:

git clone --branch=enh_interface --recursive https://github.com/klauer/blark
cd blark
pytest -v blark/tests/test_dependency_store.py blark/tests/test_summary.py

Or checking your existing checkout with git status to make sure twincat_root looks like it's at this commit - https://github.com/klauer/blark-twincat-root-example/commit/16191a36164ff215414a1b67f2d6f95eb5bd207b

engineerjoe440 commented 1 year ago

Ok... here's that response:

C:\Users\joestan\Downloads\New folder
λ git clone --branch=enh_interface --recursive https://github.com/klauer/blark
Cloning into 'blark'...
remote: Enumerating objects: 2048, done.
remote: Counting objects: 100% (635/635), done.
remote: Compressing objects: 100% (217/217), done.
remote: Total 2048 (delta 439), reused 424 (delta 418), pack-reused 1413
Receiving objects: 100% (2048/2048), 544.54 KiB | 30.25 MiB/s, done.
Resolving deltas: 100% (1509/1509), done.
Submodule 'blark/tests/blark-twincat-root-example' (https://github.com/klauer/blark-twincat-root-example) registered for path 'blark/tests/twincat_root'
Cloning into 'C:/Users/joestan/Downloads/New folder/blark/blark/tests/twincat_root'...
remote: Enumerating objects: 97, done.
remote: Counting objects: 100% (97/97), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 97 (delta 29), reused 95 (delta 27), pack-reused 0
Receiving objects: 100% (97/97), 25.29 KiB | 12.64 MiB/s, done.
Resolving deltas: 100% (29/29), done.
Submodule path 'blark/tests/twincat_root': checked out '16191a36164ff215414a1b67f2d6f95eb5bd207b'

C:\Users\joestan\Downloads\New folder
λ cd blark\

C:\Users\joestan\Downloads\New folder\blark(enh_interface -> origin)
λ pytest -v blark/tests/test_dependency_store.py blark/tests/test_summary.py
============================================================================= test session starts ============================================================================= platform win32 -- Python 3.11.4, pytest-7.4.0, pluggy-1.0.0 -- C:\Python311\python.exe
cachedir: .pytest_cache
rootdir: C:\Users\joestan\Downloads\New folder\blark
plugins: anyio-3.6.2, cov-4.1.0, markdown-docs-0.4.1, xdoctest-1.1.0
collected 7 items

blark/tests/test_dependency_store.py::test_load_project[LCLS_General-v2.8.1] FAILED                                                                                      [ 14%] blark/tests/test_dependency_store.py::test_load_project[project_a-*] FAILED                                                                                              [ 28%] blark/tests/test_dependency_store.py::test_load_project[project_b-*] FAILED                                                                                              [ 42%] blark/tests/test_summary.py::test_project_a_summary ERROR                                                                                                                [ 57%] blark/tests/test_summary.py::test_project_b_summary ERROR                                                                                                                [ 71%] blark/tests/test_summary.py::test_twincat_general ERROR                                                                                                                  [ 85%] blark/tests/test_summary.py::test_twincat_general_interface ERROR                                                                                                        [100%]

=================================================================================== ERRORS ==================================================================================== __________________________________________________________________ ERROR at setup of test_project_a_summary ___________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x0000026437956A10>

    @pytest.fixture
    def project_a(store: DependencyStore) -> PlcProjectMetadata:
        # This is project a from the git submodule included with the blark test
        # suite
>       proj, = store.get_dependency("project_a")

blark\tests\test_summary.py:63:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ blark\dependency_store.py:217: in get_dependency
    return list(
blark\dependency_store.py:353: in from_project_filename
    plc_md = cls.from_plcproject(
blark\dependency_store.py:281: in from_plcproject
    loaded_files[filename] = util.get_file_sha256(filename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

filename = WindowsPath('C:Users/joestan/Downloads/New%20folder/blark/blark/tests/twincat_root/project_a/project_a/ProjectA/ProjectA.plcproj')

    def get_file_sha256(filename: AnyPath) -> str:
        """Hash a file's contents with the SHA-256 algorithm."""
>       with open(filename, "rb") as fp:
E       FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\ProjectA.plcproj'

blark\util.py:487: FileNotFoundError
__________________________________________________________________ ERROR at setup of test_project_b_summary ___________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x0000026438F4CDD0>

    @pytest.fixture
    def project_b(store: DependencyStore) -> PlcProjectMetadata:
        # This is project b from the git submodule included with the blark test
        # suite
>       proj, = store.get_dependency("project_b")

blark\tests\test_summary.py:96:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ blark\dependency_store.py:217: in get_dependency
    return list(
blark\dependency_store.py:353: in from_project_filename
    plc_md = cls.from_plcproject(
blark\dependency_store.py:281: in from_plcproject
    loaded_files[filename] = util.get_file_sha256(filename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

filename = WindowsPath('C:Users/joestan/Downloads/New%20folder/blark/blark/tests/twincat_root/project_b/v1.0/project_b/ProjectB/ProjectB.plcproj')

    def get_file_sha256(filename: AnyPath) -> str:
        """Hash a file's contents with the SHA-256 algorithm."""
>       with open(filename, "rb") as fp:
E       FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB\\ProjectB.plcproj'

blark\util.py:487: FileNotFoundError
___________________________________________________________________ ERROR at setup of test_twincat_general ____________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x00000264399615D0>

    @pytest.fixture
    def twincat_general_281(store: DependencyStore) -> PlcProjectMetadata:
        # This is project lcls-twincat-general v2.8.1 from the git submodule
        # included with the blark test suite.
        # This is *not* the full version from pcdshub/lcls-twincat-general, but
        # rather a part of it for the purposes of the blark test suite.
>       proj, = store.get_dependency("LCLS_General", "v2.8.1")
E       ValueError: not enough values to unpack (expected 1, got 0)

blark\tests\test_summary.py:124: ValueError
----------------------------------------------------------------------------- Captured log setup ------------------------------------------------------------------------------ ERROR    blark.dependency_store:dependency_store.py:345 Failed to load project LCLSGeneral
Traceback (most recent call last):
  File "C:\Users\joestan\Downloads\New folder\blark\blark\dependency_store.py", line 343, in from_project_filename
    parsed_tsproj = tsproj_project.load()
                    ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1549, in load
    self.loaded = TwincatTsProject.from_filename(self.local_path)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1480, in from_filename
    return cls.from_xml(tsproj, filename=filename, root=root)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1453, in from_xml
    plcs = [
           ^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1454, in <listcomp>
    TwincatPlcProject.from_project_xml(plc_project, root=root)
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1357, in from_project_xml
    plcproj_path = util.fix_case_insensitive_path(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\util.py", line 524, in fix_case_insensitive_path
    raise FileNotFoundError(
FileNotFoundError: Path does not exist:
C:\Users\joestan\Downloads\New folder\blark\Users\joestan\Downloads\New%20folder\blark\blark\tests\twincat_root\lcls-twincat-general\v2.8.1\LCLSGeneral\LCLSGeneral\LCLSGeneral.plcproj
C:\Users\joestan\Downloads\New folder\blark/Users missing
______________________________________________________________ ERROR at setup of test_twincat_general_interface _______________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x0000026439875690>

    @pytest.fixture
    def twincat_general_281(store: DependencyStore) -> PlcProjectMetadata:
        # This is project lcls-twincat-general v2.8.1 from the git submodule
        # included with the blark test suite.
        # This is *not* the full version from pcdshub/lcls-twincat-general, but
        # rather a part of it for the purposes of the blark test suite.
>       proj, = store.get_dependency("LCLS_General", "v2.8.1")
E       ValueError: not enough values to unpack (expected 1, got 0)

blark\tests\test_summary.py:124: ValueError
----------------------------------------------------------------------------- Captured log setup ------------------------------------------------------------------------------ ERROR    blark.dependency_store:dependency_store.py:345 Failed to load project LCLSGeneral
Traceback (most recent call last):
  File "C:\Users\joestan\Downloads\New folder\blark\blark\dependency_store.py", line 343, in from_project_filename
    parsed_tsproj = tsproj_project.load()
                    ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1549, in load
    self.loaded = TwincatTsProject.from_filename(self.local_path)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1480, in from_filename
    return cls.from_xml(tsproj, filename=filename, root=root)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1453, in from_xml
    plcs = [
           ^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1454, in <listcomp>
    TwincatPlcProject.from_project_xml(plc_project, root=root)
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1357, in from_project_xml
    plcproj_path = util.fix_case_insensitive_path(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\util.py", line 524, in fix_case_insensitive_path
    raise FileNotFoundError(
FileNotFoundError: Path does not exist:
C:\Users\joestan\Downloads\New folder\blark\Users\joestan\Downloads\New%20folder\blark\blark\tests\twincat_root\lcls-twincat-general\v2.8.1\LCLSGeneral\LCLSGeneral\LCLSGeneral.plcproj
C:\Users\joestan\Downloads\New folder\blark/Users missing
================================================================================== FAILURES =================================================================================== ___________________________________________________________________ test_load_project[LCLS_General-v2.8.1] ____________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x00000264399629D0>, project_name = 'LCLS_General', version = 'v2.8.1'

    @pytest.mark.parametrize(
        "project_name, version",
        [
            ("LCLS_General", "v2.8.1"),
            ("project_a", "*"),
            ("project_b", "*"),
        ]
    )
    def test_load_project(
        store: DependencyStore,
        project_name: str,
        version: Optional[str],
    ):
        assert project_name in store.config.libraries
        matches = store.get_dependency(project_name, version)
        try:
>           match, = matches
E           ValueError: not enough values to unpack (expected 1, got 0)

blark\tests\test_dependency_store.py:31: ValueError

During handling of the above exception, another exception occurred:

store = <blark.dependency_store.DependencyStore object at 0x00000264399629D0>, project_name = 'LCLS_General', version = 'v2.8.1'

    @pytest.mark.parametrize(
        "project_name, version",
        [
            ("LCLS_General", "v2.8.1"),
            ("project_a", "*"),
            ("project_b", "*"),
        ]
    )
    def test_load_project(
        store: DependencyStore,
        project_name: str,
        version: Optional[str],
    ):
        assert project_name in store.config.libraries
        matches = store.get_dependency(project_name, version)
        try:
            match, = matches
        except ValueError:
>           raise RuntimeError(f"No match for project {project_name} version={version}")
E           RuntimeError: No match for project LCLS_General version=v2.8.1

blark\tests\test_dependency_store.py:33: RuntimeError
------------------------------------------------------------------------------ Captured log call ------------------------------------------------------------------------------ ERROR    blark.dependency_store:dependency_store.py:345 Failed to load project LCLSGeneral
Traceback (most recent call last):
  File "C:\Users\joestan\Downloads\New folder\blark\blark\dependency_store.py", line 343, in from_project_filename
    parsed_tsproj = tsproj_project.load()
                    ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1549, in load
    self.loaded = TwincatTsProject.from_filename(self.local_path)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1480, in from_filename
    return cls.from_xml(tsproj, filename=filename, root=root)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1453, in from_xml
    plcs = [
           ^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1454, in <listcomp>
    TwincatPlcProject.from_project_xml(plc_project, root=root)
  File "C:\Users\joestan\Downloads\New folder\blark\blark\solution.py", line 1357, in from_project_xml
    plcproj_path = util.fix_case_insensitive_path(
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Downloads\New folder\blark\blark\util.py", line 524, in fix_case_insensitive_path
    raise FileNotFoundError(
FileNotFoundError: Path does not exist:
C:\Users\joestan\Downloads\New folder\blark\Users\joestan\Downloads\New%20folder\blark\blark\tests\twincat_root\lcls-twincat-general\v2.8.1\LCLSGeneral\LCLSGeneral\LCLSGeneral.plcproj
C:\Users\joestan\Downloads\New folder\blark/Users missing
_______________________________________________________________________ test_load_project[project_a-*] ________________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x0000026439947AD0>, project_name = 'project_a', version = '*'

    @pytest.mark.parametrize(
        "project_name, version",
        [
            ("LCLS_General", "v2.8.1"),
            ("project_a", "*"),
            ("project_b", "*"),
        ]
    )
    def test_load_project(
        store: DependencyStore,
        project_name: str,
        version: Optional[str],
    ):
        assert project_name in store.config.libraries
>       matches = store.get_dependency(project_name, version)

blark\tests\test_dependency_store.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ blark\dependency_store.py:217: in get_dependency
    return list(
blark\dependency_store.py:353: in from_project_filename
    plc_md = cls.from_plcproject(
blark\dependency_store.py:281: in from_plcproject
    loaded_files[filename] = util.get_file_sha256(filename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

filename = WindowsPath('C:Users/joestan/Downloads/New%20folder/blark/blark/tests/twincat_root/project_a/project_a/ProjectA/ProjectA.plcproj')

    def get_file_sha256(filename: AnyPath) -> str:
        """Hash a file's contents with the SHA-256 algorithm."""
>       with open(filename, "rb") as fp:
E       FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\ProjectA.plcproj'

blark\util.py:487: FileNotFoundError
_______________________________________________________________________ test_load_project[project_b-*] ________________________________________________________________________

store = <blark.dependency_store.DependencyStore object at 0x0000026439880A90>, project_name = 'project_b', version = '*'

    @pytest.mark.parametrize(
        "project_name, version",
        [
            ("LCLS_General", "v2.8.1"),
            ("project_a", "*"),
            ("project_b", "*"),
        ]
    )
    def test_load_project(
        store: DependencyStore,
        project_name: str,
        version: Optional[str],
    ):
        assert project_name in store.config.libraries
>       matches = store.get_dependency(project_name, version)

blark\tests\test_dependency_store.py:29:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ blark\dependency_store.py:217: in get_dependency
    return list(
blark\dependency_store.py:353: in from_project_filename
    plc_md = cls.from_plcproject(
blark\dependency_store.py:281: in from_plcproject
    loaded_files[filename] = util.get_file_sha256(filename)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

filename = WindowsPath('C:Users/joestan/Downloads/New%20folder/blark/blark/tests/twincat_root/project_b/v1.0/project_b/ProjectB/ProjectB.plcproj')

    def get_file_sha256(filename: AnyPath) -> str:
        """Hash a file's contents with the SHA-256 algorithm."""
>       with open(filename, "rb") as fp:
E       FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB\\ProjectB.plcproj'

blark\util.py:487: FileNotFoundError
=========================================================================== short test summary info =========================================================================== FAILED blark/tests/test_dependency_store.py::test_load_project[LCLS_General-v2.8.1] - RuntimeError: No match for project LCLS_General version=v2.8.1
FAILED blark/tests/test_dependency_store.py::test_load_project[project_a-*] - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\Proj...
FAILED blark/tests/test_dependency_store.py::test_load_project[project_b-*] - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB...
ERROR blark/tests/test_summary.py::test_project_a_summary - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_a\\project_a\\ProjectA\\Proj...
ERROR blark/tests/test_summary.py::test_project_b_summary - FileNotFoundError: [Errno 2] No such file or directory: 'C:Users\\joestan\\Downloads\\New%20folder\\blark\\blark\\tests\\twincat_root\\project_b\\v1.0\\project_b\\ProjectB...
ERROR blark/tests/test_summary.py::test_twincat_general - ValueError: not enough values to unpack (expected 1, got 0)
ERROR blark/tests/test_summary.py::test_twincat_general_interface - ValueError: not enough values to unpack (expected 1, got 0)
========================================================================= 3 failed, 4 errors in 0.34s =========================================================================

It does look like that's the correct commit for the submodule, so I'm not sure what's happened, there.

klauer commented 1 year ago

Huh, OK - I've only tested on MacOS (locally) and Linux (via CI) so far, so I guess there's some work to be done on the dependency store with respect to Windows.

I'll see what I can do about getting to the bottom of that locally... Thanks for the tracebacks!

(Also: TODO - add Windows CI jobs here)

engineerjoe440 commented 1 year ago

That makes a lot of sense... Leave it to Windows to make some of this stuff monumentally annoying. 😆

THANK YOU!

I'll see if I can poke around with some of this with production 61131, tomorrow.

codecov-commenter commented 1 year ago

Codecov Report

Merging #73 (4b096b6) into master (2bd8165) will increase coverage by 1.0%. The diff coverage is 86.3%.

Additional details and impacted files [![Impacted file tree graph](https://app.codecov.io/gh/klauer/blark/pull/73/graphs/tree.svg?width=650&height=150&src=pr&token=QZDTKF30TH&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer)](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer) ```diff @@ Coverage Diff @@ ## master #73 +/- ## ======================================== + Coverage 78.5% 79.6% +1.0% ======================================== Files 26 26 Lines 5339 5463 +124 ======================================== + Hits 4195 4350 +155 + Misses 1144 1113 -31 ``` | [Files Changed](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer) | Coverage Δ | | |---|---|---| | [blark/util.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-YmxhcmsvdXRpbC5weQ==) | `83.9% <ø> (ø)` | | | [blark/solution.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-Ymxhcmsvc29sdXRpb24ucHk=) | `78.8% <76.4%> (+2.2%)` | :arrow_up: | | [blark/summary.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-Ymxhcmsvc3VtbWFyeS5weQ==) | `74.0% <80.2%> (+4.7%)` | :arrow_up: | | [blark/parse.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-YmxhcmsvcGFyc2UucHk=) | `79.3% <100.0%> (+<0.1%)` | :arrow_up: | | [blark/tests/test\_summary.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-YmxhcmsvdGVzdHMvdGVzdF9zdW1tYXJ5LnB5) | `98.3% <100.0%> (+0.4%)` | :arrow_up: | | [blark/tests/test\_transformer.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-YmxhcmsvdGVzdHMvdGVzdF90cmFuc2Zvcm1lci5weQ==) | `93.3% <100.0%> (+0.1%)` | :arrow_up: | | [blark/transform.py](https://app.codecov.io/gh/klauer/blark/pull/73?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer#diff-YmxhcmsvdHJhbnNmb3JtLnB5) | `98.9% <100.0%> (+<0.1%)` | :arrow_up: | ... and [1 file with indirect coverage changes](https://app.codecov.io/gh/klauer/blark/pull/73/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=K+Lauer)
engineerjoe440 commented 1 year ago

Well... so much for actually getting any testing done, today. I'll have to test next week. 😞

Thank you for being so perpetually patient!

klauer commented 1 year ago

No worries - and no rush. We'll get this fixed up and then maybe look toward tagging a new version.

klauer commented 1 year ago

Thanks to your testing I found the bug with Windows and we have functional CI for that platform, too.

lxml was behaving differently and - only on Windows - returning a file:/ prefix (URL scheme that is). Linux/macOS returned just a simple filename. I just quickly patched over that part in 024550e, though it may not necessarily be the best solution.

engineerjoe440 commented 1 year ago

Ok, so I finally tested on a plain system (without interfaces, yet), and my existing logic is throwing some new errors. I'm gonna start working through that to rectify those problems.

λ selint
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Python311\Scripts\selint.exe\__main__.py", line 7, in <module>
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\__init__.py", line 187, in main
    run_selint( selint.cliparser.parse_selint_arguments() )
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\__init__.py", line 133, in run_selint
    analysis = _set_analyzer(config=config)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\__init__.py", line 82, in _set_analyzer
    analysis.load_files(
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 442, in load_files
    self.objects[file_name] = PouXmlAnalyzer(
                              ^^^^^^^^^^^^^^^
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 367, in __init__
    super().__init__(
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 332, in __init__
    self.load_file()
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 350, in load_file
    self.root_st_object = STNode(
                          ^^^^^^^
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 117, in __init__
    self._examine(element, parent_name)
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 168, in _examine
    self._parse(parent_name=parent_name)
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 176, in _parse
    self._parse_source_code(self.source)
  File "C:\Users\joestan\Documents\Python RTAC Projects\selint\selint\core\__init__.py", line 272, in _parse_source_code
    self.source_tree = self.__parser.parse(processed_source)
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\lark.py", line 652, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parser_frontends.py", line 98, in parse
    chosen_start = self._verify_start(start)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Python311\Lib\site-packages\lark\parser_frontends.py", line 87, in _verify_start
    raise ConfigurationError("Lark initialized with more than 1 possible start rule. Must specify which start rule to parse", start_decls)
lark.exceptions.ConfigurationError: ('Lark initialized with more than 1 possible start rule. Must specify which start rule to parse', ['iec_source', 'action', 'data_type_declaration', 'function_block_method_declaration', 'function_block_property_declaration', 'function_block_type_declaration', 'function_declaration', 'global_var_declarations', 'interface_declaration', 'program_declaration', 'statement_list'])

If you recognize this quickly, though, I wouldn't mind the pointer! 😛

klauer commented 1 year ago

There's a little section in the updated readme from the solution parser refactor - https://github.com/klauer/blark/#sample-runs

The gist is that blark is a little bit more flexible in the set of "top-level grammar" entries for the default/shared parser returned by blark.get_parser(). If you're not using the parse_source_code function you'll have to replicate it yourself: https://github.com/klauer/blark/blob/2bd8165d1f60ec7d35ad93d217f201d388b85d71/blark/parse.py#L204C29-L204C29 - in parse() you have to say which starting rule you want. "iec_source" is the most generic, allowing you to load any arbitrary top-level IEC element / library declaration (https://github.com/klauer/blark/blob/2bd8165d1f60ec7d35ad93d217f201d388b85d71/blark/iec.lark#L24-L31)

engineerjoe440 commented 1 year ago

Awesome! Thank you for that pointer! I got that change working. Marvelous!!!

engineerjoe440 commented 1 year ago

I keep telling myself that I'm going to get this tested with some of my Interfaces, and I keep not getting there. This looks very good, and I think it's ready to move forward. From my testing, it seems that everything is in a satisfactory state. We might find more to improve/enhance on the Interfaces side of things, but I think it's good to go!

klauer commented 1 year ago

Thanks, Joe - let me know if you get around to it. We'll merge and move forward in the meantime.