Skip to content

Commit

Permalink
#32 #34 reactivated iec-checker
Browse files Browse the repository at this point in the history
  • Loading branch information
marwern committed Jul 30, 2023
1 parent 6e4c025 commit 3029ab3
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 30 deletions.
72 changes: 45 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
[![made-with-python](https://img.shields.io/badge/Made%20with-Python-1f425f.svg)](https://www.python.org/)
[![Tests](https://img.shields.io/badge/Tests-passed-<COLOR>.svg)](https://shields.io/)
[![Coverage](https://img.shields.io/badge/coverage-98%25-<COLOR>.svg)](https://shields.io/)
[![Coverage](https://img.shields.io/badge/coverage-99%25-<COLOR>.svg)](https://shields.io/)
[![GPLv3 license](https://img.shields.io/badge/License-GPLv3-blue.svg)](http://perso.crans.org/besson/LICENSE.html)

PLCreX is a modular command-line interface (CLI) application tailored for IEC 61131-3 Programmable Logic Controllers ([PLCs](https://en.wikipedia.org/wiki/Programmable_logic_controller)). It's designed with a focus on issues such as **re**view, **re**design, **re**use, and **re**liability, among others. This project is driven by our ongoing research and we're committed to progressively integrating new features. PLCreX serves as a comprehensive suite of analysis and reuse capabilities for existing IEC 61131-3 Program Organization Units ([POUs](https://en.wikipedia.org/wiki/IEC_61131-3#Program_organization_unit_(POU))) implemented in Function Block Diagrams (FBDs) or Structured Text (ST).

![diagram-20230726](https://github.com/marwern/PLCreX/assets/92115516/9ddd4a76-3afd-4fa7-a384-4c83a59ca1da)
![diagram-20230730](https://github.com/marwern/PLCreX/assets/92115516/05e44b6c-d023-48f8-b6fa-2a18ccfcea06)

## Quick links

Expand All @@ -26,6 +26,7 @@ PLCreX is a modular command-line interface (CLI) application tailored for IEC 61
### Prerequisites
* [Python](https://www.python.org/downloads/): 3.11
* Operating System: Windows
* [optional] Download iec-checker (Static analysis of IEC 61131-3 programs) 🔗 [.releases](https://github.com/jubnzv/iec-checker/releases/tag/v0.4)

### Installation via PyPI
Run ``pip install plcrex`` to get PLCreX using PyPI
Expand All @@ -36,31 +37,35 @@ Run ``pip install plcrex`` to get PLCreX using PyPI
3. [optional] Run ``coverage run -m pytest ./tests/ --verbose`` for local tests
4. [optional] Run ``coverage report -m`` to check test results

Name Stmts Miss Cover Missing
------------------------------------------------------------------
plcrex\__init__.py 4 0 100%
plcrex\cli.py 57 3 95% 33-34, 96
plcrex\tools\__init__.py 0 0 100%
plcrex\tools\ds2ts\__init__.py 0 0 100%
plcrex\tools\ds2ts\_ds2ts.py 3 1 67% 22
plcrex\tools\ds2ts\lib\__init__.py 0 0 100%
plcrex\tools\fbd2ia\__init__.py 0 0 100%
plcrex\tools\fbd2ia\_fbd2ia.py 4 0 100%
plcrex\tools\fbd2st\__init__.py 0 0 100%
plcrex\tools\fbd2st\_fbd2st.py 4 0 100%
plcrex\tools\st2ast\__init__.py 0 0 100%
plcrex\tools\st2ast\_st2ast.py 17 0 100%
plcrex\tools\xmlval\__init__.py 0 0 100%
plcrex\tools\xmlval\_xmlval.py 7 0 100%
tests\__init__.py 0 0 100%
tests\test_fbd2st.py 69 0 100%
tests\test_fbd_io_checker.py 7 0 100%
tests\test_help.py 6 0 100%
tests\test_st2tree.py 25 0 100%
tests\test_version.py 12 0 100%
tests\test_xml_checker.py 19 0 100%
------------------------------------------------------------------
TOTAL 234 4 98%
Name Stmts Miss Cover Missing
------------------------------------------------------------------------
plcrex\__init__.py 4 0 100%
plcrex\cli.py 73 1 99% 122
plcrex\tools\__init__.py 0 0 100%
plcrex\tools\ds2ts\__init__.py 0 0 100%
plcrex\tools\ds2ts\_ds2ts.py 3 0 100%
plcrex\tools\fbd2ia\__init__.py 0 0 100%
plcrex\tools\fbd2ia\_fbd2ia.py 4 0 100%
plcrex\tools\fbd2st\__init__.py 0 0 100%
plcrex\tools\fbd2st\_fbd2st.py 4 0 100%
plcrex\tools\iec_checker\__init__.py 0 0 100%
plcrex\tools\iec_checker\_iec_checker.py 4 0 100%
plcrex\tools\st2ast\__init__.py 0 0 100%
plcrex\tools\st2ast\_st2ast.py 34 0 100%
plcrex\tools\xmlval\__init__.py 0 0 100%
plcrex\tools\xmlval\_xmlval.py 16 0 100%
tests\__init__.py 0 0 100%
tests\test_ds2ts.py 10 0 100%
tests\test_fbd2st.py 69 0 100%
tests\test_fbd_io_checker.py 7 0 100%
tests\test_help.py 6 0 100%
tests\test_iec_checker.py 32 0 100%
tests\test_st2tree.py 25 0 100%
tests\test_version.py 12 0 100%
tests\test_xml_checker.py 19 0 100%
------------------------------------------------------------------------
TOTAL 322 1 99%



# 💻 Commands
Expand All @@ -85,6 +90,7 @@ Usage: ``python -m plcrex PLCreX [OPTIONS] COMMAND [ARGS]``
--st2ast: call ST-Parser<br>
--ds2ts: call Test-Case-Generator<br>
--xml-val: call XML-Validator<br>
--iec-checker: call iec-checker<br>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -135,6 +141,18 @@ Usage: ``python -m plcrex PLCreX [OPTIONS] COMMAND [ARGS]``
SRC: source path<br>
</td>
</tr>
<tr>
<td>
python -m plcrex iec-checker [OPTIONS] SRC EXE</td>
<td>
--help_iec_checker: call iec-checker help <br>
--help: show details<br><br>
</td>
<td>
SRC: source path<br>
EXE: iec-checker path (*.exe)
</td>
</tr>
</table>

# 📜 Publications
Expand Down
26 changes: 26 additions & 0 deletions plcrex/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,37 @@
from plcrex.tools.ds2ts import _ds2ts
from plcrex.tools.st2ast import _st2ast
from plcrex.tools.xmlval import _xmlval
from plcrex.tools.iec_checker import _iec_checker
from pathlib import Path
from plcrex import __app_name__, __version__

app = typer.Typer()



@app.command("iec-checker")
def iec_checker(
src: Path,
exe: Path,
verbose: bool = typer.Option(False, help="print full log"),
help_: bool = typer.Option(False, "--help_iec_checker", help="call iec-checker help")):
if src.is_file():
if exe.is_file():
if src.suffix == '.st' or src.suffix == '.xml':
# call iec-checker with ONE supported OPTIONS (only a subset is covered)
if help_:
_iec_checker.execution(src, exe, '--help')
elif not verbose:
_iec_checker.execution(src, exe, '--quiet')
elif verbose:
_iec_checker.execution(src, exe, '--verbose')
typer.echo("\n" + typer.style("Success!", fg=typer.colors.GREEN, bold=True))
else:
raise RuntimeError("no ST/xml file found")
else:
raise RuntimeError(rf"no .exe found at {exe}")
raise typer.Exit()

@app.command("ds2ts")
def ds2ts(formula: str):
_ds2ts.create(formula)
Expand Down
17 changes: 17 additions & 0 deletions plcrex/tools/iec_checker/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# This file is part of PLCreX (https://github.com/marwern/PLCreX).
#
# Copyright (c) 2022-2023 Marcel Werner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
23 changes: 23 additions & 0 deletions plcrex/tools/iec_checker/_iec_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# This file is part of PLCreX (https://github.com/marwern/PLCreX).
#
# Copyright (c) 2022-2023 Marcel Werner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from pathlib import Path
from subprocess import call

def execution(src: Path, exe: Path, option: str):
call([rf'{exe}', src, option])
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"

[project]
name = "plcrex"
version = "1.0.0"
version = "1.1.0-rc1"
requires-python = ">=3.11"
authors = [
{ name="Marcel Werner", email="plcrex.info@gmail.com" },
Expand All @@ -21,7 +21,6 @@ dependencies = [
"coverage==6.5.0",
"coverage-badge==1.1.0",
"colorama==0.4.5",
"configparser==5.3.0",
"dicttoxml2==2.1.0",
"lark==1.1.4",
"pydot==1.4.2",
Expand Down
1 change: 0 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
coverage==6.5.0
coverage-badge==v1.1.0
colorama==0.4.5
configparser==5.3.0
dicttoxml2==2.1.0
lark==1.1.4
pydot==1.4.2
Expand Down
34 changes: 34 additions & 0 deletions tests/test_ds2ts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# This file is part of PLCreX (https://github.com/marwern/PLCreX).
#
# Copyright (c) 2022-2023 Marcel Werner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from typer.testing import CliRunner

from plcrex import cli

runner = CliRunner()


def test_help():
result = runner.invoke(cli.app, ["ds2ts", "--help"])
assert result.exit_code == 0


def test_ds2ts_001():
result = runner.invoke(cli.app, ["ds2ts", "a&b"])
assert result.exit_code == 0
assert f"Success!" in result.stdout
67 changes: 67 additions & 0 deletions tests/test_iec_checker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#
# This file is part of PLCreX (https://github.com/marwern/PLCreX).
#
# Copyright (c) 2022-2023 Marcel Werner.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

from typer.testing import CliRunner

from plcrex import cli

runner = CliRunner()


def test_help():
result = runner.invoke(cli.app, ["iec-checker", "--help"])
assert result.exit_code == 0


def test_help_iec_checker():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\st_examples\TC001.st", r".\bin\iec_checker_Windows_x86_64_v0.4.exe", "--help_iec_checker"])
assert result.exit_code == 0
assert f"Success!" in result.stdout


def test_verbose_st():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\st_examples\TC001.st", r".\bin\iec_checker_Windows_x86_64_v0.4.exe", "--verbose"])
assert result.exit_code == 0
assert f"Success!" in result.stdout


def test_quiet_st():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\st_examples\TC001.st", r".\bin\iec_checker_Windows_x86_64_v0.4.exe"])
assert result.exit_code == 0
assert f"Success!" in result.stdout


def test_wrong_file():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\other_examples\TC001_wrong_file.txt", r".\bin\iec_checker_Windows_x86_64_v0.4.exe"])
assert result.exit_code == 1


def test_verbose_xml():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\plcopen_examples\TC001.xml", r".\bin\iec_checker_Windows_x86_64_v0.4.exe", "--verbose"])
assert result.exit_code == 0
assert f"Success!" in result.stdout


def test_quiet_xml():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\plcopen_examples\TC001.xml", r".\bin\iec_checker_Windows_x86_64_v0.4.exe"])
assert result.exit_code == 0
assert f"Success!" in result.stdout

def test_wrong_exe():
result = runner.invoke(cli.app, ["iec-checker", r".\tests\plcopen_examples\TC001.xml", r".\bin\_.exe"])
assert result.exit_code == 1
2 changes: 2 additions & 0 deletions tests/test_xml_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def test_v201_failed():
result = runner.invoke(cli.app, ["xml-val", "--v201", r".\tests\plcopen_examples\TC001_failed.xml"])
assert result.exit_code == 1

#TODO
#def test_v10_passed():

def test_v10_failed():
result = runner.invoke(cli.app, ["xml-val", r".\tests\plcopen_examples\TC001.xml"])
Expand Down

0 comments on commit 3029ab3

Please sign in to comment.