Skip to content

Commit

Permalink
Merge pull request #29 from rruiter87/tc-version-check
Browse files Browse the repository at this point in the history
Tc version check
  • Loading branch information
ZLLentz authored Jul 2, 2024
2 parents 57ebc7e + 8375035 commit eecdf9a
Show file tree
Hide file tree
Showing 14 changed files with 17,116 additions and 11 deletions.
8 changes: 8 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,11 @@
entry: minimize-id-changes
language: python
files: .*\.plcproj$
- id: check-twincat-versions
name: Check if all TwinCAT versions match
description: Checks if TwinCAT versions match in different tsproj files, or if it matches the targeted one.
entry: check-twincat-versions
# All files need to be passed at once, else not all files are compared to eachother
require_serial: true
language: python
files: .*\.tsproj$
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ repos:
files: \.(TcPOU|TcDUT|TcGVL)$

- repo: https://github.com/pcdshub/pre-commit-hooks.git
rev: v1.6.0
rev: v1.7.0
hooks:
- id: twincat-leading-tabs-remover
- id: twincat-lineids-remover
Expand All @@ -36,6 +36,15 @@ repos:
# Check if minimize id changes is selected in the plc project file.
# See https://www.youtube.com/watch?v=KKpBtaYjfWo&t=935s why to do this.
- id: minimize-id-changes
# Checks if TwinCAT versions match in different tsproj files, or if it matches the targeted one.
- id: check-twincat-versions
# Possible optional arguments
# --target-version: Set a version that you want the tsproj file to have
# --fix: Fix the version numbers if a target version is set
# --reason: Add a reason to the error message in case of a non-matching version.
# --pinned: Require the TwinCAT version to be pinned. Apply pinning if combined with --fix.
# --no-pinned: Require the TwinCAT version to not be pinned. Remove pinning if combined with --fix.
args: [--target-version=3.1.4024.20, --pinned, --fix, --reason="This version has a crucial new feature"]
# Optional, if you use pytmc to generate EPICS IOCs:
# - id: pytmc-pragma-linter
```
Expand Down
11 changes: 10 additions & 1 deletion forTwinCatRepos/.pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ repos:
files: \.(TcPOU|TcDUT|TcGVL)$

- repo: https://github.com/pcdshub/pre-commit-hooks.git
rev: v1.5.0
rev: v1.7.0
hooks:
- id: twincat-leading-tabs-remover
- id: twincat-lineids-remover
Expand All @@ -20,5 +20,14 @@ repos:
# Check if minimize id changes is selected in the plc project file.
# See https://www.youtube.com/watch?v=KKpBtaYjfWo&t=935s why to do this.
- id: minimize-id-changes
# Checks if TwinCAT versions match in different tsproj files, or if it matches the targeted one.
- id: check-twincat-versions
# Possible optional arguments
# --target-version: Set a version that you want the tsproj file to have
# --fix: Fix the version numbers if a target version is set
# --reason: Add a reason to the error message in case of a non-matching version.
# --pinned: Require the TwinCAT version to be pinned. Apply pinning if combined with --fix.
# --no-pinned: Require the TwinCAT version to not be pinned. Remove pinning if combined with --fix.
args: [--target-version=3.1.4024.20, --pinned, --fix, --reason="This version has a crucial new feature"]
# Optional, if you use pytmc to generate EPICS IOCs:
# - id: pytmc-pragma-linter
4 changes: 1 addition & 3 deletions pre_commit_hooks/check_fixed_library_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from lxml import etree


class PreCommitException(Exception):
pass
from pre_commit_hooks.exceptions import PreCommitException


def check_file(filename):
Expand Down
145 changes: 145 additions & 0 deletions pre_commit_hooks/check_twincat_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import argparse
import re
import xml.etree.ElementTree as ET

from pre_commit_hooks.exceptions import PreCommitException


def tc_version_pinned(xml_content: str) -> bool:
root = ET.fromstring(xml_content)

return (
"TcVersionFixed" in root.attrib and root.attrib.get("TcVersionFixed") == "true"
)


def get_tc_version(xml_content: str) -> str:
root = ET.fromstring(xml_content)

return root.attrib.get("TcVersion")


def fix_tc_version(xml_content: str, new_version: str) -> str:
pattern = r'(TcVersion=")([^"]*)(")'
new_xml_content = re.sub(pattern, r"\g<1>" + new_version + r"\g<3>", xml_content)

return new_xml_content


def fix_pinned_version(xml_content: str, pin_version: bool) -> str:
new_value = "true" if pin_version else "false"

pattern = r'(TcVersionFixed=")([^"]*)(")'

if re.search(pattern, xml_content):
new_xml_content = re.sub(pattern, r"\g<1>" + new_value + r"\g<3>", xml_content)
else:
version_pattern = r'(TcVersion="[^"]*")'
new_xml_content = re.sub(
version_pattern, r'\g<1> TcVersionFixed="' + new_value + r'"', xml_content
)

return new_xml_content


def main(args=None):
if args is None:
parser = argparse.ArgumentParser()
parser.add_argument(
"filenames", nargs="+", help="List of tsproj filenames to process."
)
parser.add_argument(
"--target-version", type=str, help="Target TwinCAT version to enforce."
)
parser.add_argument(
"--fix",
action="store_true",
help="Fix the versions if they do not match the target version and fix the pinned state if combined with --pinned/no-pinned.",
)
parser.add_argument(
"--reason", type=str, help="Reason for targeting a specific version."
)
parser.add_argument(
"--pinned",
action=argparse.BooleanOptionalAction,
help="Check if the TwinCAT version should be pinned. Applies or removes pinning if combined with --fix.",
)

args = parser.parse_args()

try:
versions = {}
pinned = {}
for filename in args.filenames:
with open(filename, "r") as file:
xml_content = file.read()
versions[filename] = get_tc_version(xml_content)
pinned[filename] = tc_version_pinned(xml_content)

itemize = "\n -"
exception_message = ""
if args.target_version:
mismatched_files = [
fname for fname, ver in versions.items() if ver != args.target_version
]
if mismatched_files:
reason_msg = f"\nReason: {args.reason}" if args.reason else ""
if args.fix:
for filename in mismatched_files:
with open(filename, "r") as file:
xml_content = file.read()
fixed_content = fix_tc_version(xml_content, args.target_version)
with open(filename, "w") as file:
file.write(fixed_content)

print(
f"Fixed TwinCAT versions for:{itemize}{itemize.join(mismatched_files)}{reason_msg}"
)
else:
exception_message += (
"The following files are not set to the targeted TwinCAT version "
f"{args.target_version}:{itemize}{itemize.join(mismatched_files)}{reason_msg}"
)
else:
unique_versions = set(versions.values())
if len(unique_versions) > 1:
exception_message += (
"Not all files have the same TwinCAT version:"
f"{itemize}"
+ itemize.join(f"{fname}: {ver}" for fname, ver in versions.items())
)

if args.pinned is not None:
mismatched_files = [
fname for fname, pin in pinned.items() if pin != args.pinned
]
if mismatched_files:
if args.fix:
for filename in mismatched_files:
with open(filename, "r") as file:
xml_content = file.read()
fixed_content = fix_pinned_version(xml_content, args.pinned)
with open(filename, "w") as file:
file.write(fixed_content)
print(
f"Fixed pinned state for:{itemize}{itemize.join(mismatched_files)}"
)
else:
should_be_pinned_message = (
"The following files should have a pinned TwinCAT version"
if args.pinned
else "The following files should NOT have a pinned TwinCAT version"
)
exception_message += "\n\n" if len(exception_message) > 0 else ""
exception_message += f"{should_be_pinned_message}{itemize}{itemize.join(mismatched_files)}"
if len(exception_message) > 0:
raise PreCommitException(exception_message)

return 0
except Exception as exc:
print(exc)
return 1


if __name__ == "__main__":
exit(main())
2 changes: 2 additions & 0 deletions pre_commit_hooks/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
class PreCommitException(Exception):
pass
4 changes: 1 addition & 3 deletions pre_commit_hooks/minimize_id_changes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
from importlib.abc import Traversable
from typing import Union


class PreCommitException(Exception):
pass
from pre_commit_hooks.exceptions import PreCommitException


def minimize_id_changes_checked(filename: Union[Traversable, str]) -> None:
Expand Down
4 changes: 1 addition & 3 deletions pre_commit_hooks/no_product_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from lxml import etree


class PreCommitException(Exception):
pass
from pre_commit_hooks.exceptions import PreCommitException


def check_file(filename):
Expand Down
Loading

0 comments on commit eecdf9a

Please sign in to comment.