From 380845c7ce07b01bc63cb0a2b2dbca29c31fadaf Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Thu, 3 Oct 2024 10:01:12 +0100 Subject: [PATCH 1/8] Global handler changes --- src/builder2ibek/convert.py | 32 +++++++++++++------- src/builder2ibek/converters/globalHandler.py | 12 ++++++++ 2 files changed, 33 insertions(+), 11 deletions(-) create mode 100644 src/builder2ibek/converters/globalHandler.py diff --git a/src/builder2ibek/convert.py b/src/builder2ibek/convert.py index c85315f..59a9e18 100644 --- a/src/builder2ibek/convert.py +++ b/src/builder2ibek/convert.py @@ -7,7 +7,7 @@ from builder2ibek.builder import Builder, Element from builder2ibek.moduleinfos import module_infos from builder2ibek.types import Entity, Generic_IOC - +from builder2ibek.converters.globalHandler import globalHandler def dispatch(builder: Builder, filename) -> Generic_IOC: """ @@ -47,22 +47,32 @@ def do_dispatch(builder: Builder, ioc: Generic_IOC): def do_one_element(element: Element, ioc: Generic_IOC): # first do default conversion to entity entity = convert_generic(element, ioc) - + # then dispatch to a specific handler if there is one assert isinstance(element, Element) if element.module in module_infos: info = module_infos[element.module] entity.type = f"{info.yaml_component}.{element.name}" - new_xml = info.handler(entity, element.name, ioc) + # new_xml = info.handler(entity, element.name, ioc) + new_xml = globalHandler(entity, element.name, ioc, info.handler) if new_xml: - new_builder = Builder() - new_builder.load_string(new_xml) - ioc.entities.remove(entity) - do_dispatch(new_builder, ioc) - if entity.is_deleted(): - ioc.entities.remove(entity) - else: - add_defaults(entity, info.defaults) + handle_new_xml(new_xml, entity, ioc, info) + else: + new_xml = globalHandler(entity, element.name, ioc) + if new_xml: + handle_new_xml(new_xml, entity, ioc) + +def handle_new_xml(new_xml: str, entity: Entity, ioc: Generic_IOC, info=None): + new_builder = Builder() + new_builder.load_string(new_xml) + ioc.entities.remove(entity) + do_dispatch(new_builder, ioc) + if entity.is_deleted(): + ioc.entities.remove(entity) + if not entity.is_deleted and info: + print("a") + add_defaults(entity, info.defaults) + def add_defaults(entity: dict[str, Any], defaults: dict[str, dict[str, Any]]): diff --git a/src/builder2ibek/converters/globalHandler.py b/src/builder2ibek/converters/globalHandler.py new file mode 100644 index 0000000..f4b8ed1 --- /dev/null +++ b/src/builder2ibek/converters/globalHandler.py @@ -0,0 +1,12 @@ +from builder2ibek.types import Entity, Generic_IOC + +xml_component = "global" + + +def globalHandler(entity: Entity, entity_type: str, ioc: Generic_IOC, target_handler=None): + entity.remove("gda_name") + entity.remove("gda_desc") + + if target_handler: + return target_handler(entity, entity_type, ioc) + \ No newline at end of file From 9695fa333c6961831d7791d47a0cd15bc9b287a4 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Thu, 3 Oct 2024 10:20:25 +0100 Subject: [PATCH 2/8] Removed old code --- BL99P-MO-IOC-01.xml | 39 +++++ out.yaml | 330 ++++++++++++++++++++++++++++++++++++ src/builder2ibek/convert.py | 2 +- 3 files changed, 370 insertions(+), 1 deletion(-) create mode 100644 BL99P-MO-IOC-01.xml create mode 100644 out.yaml diff --git a/BL99P-MO-IOC-01.xml b/BL99P-MO-IOC-01.xml new file mode 100644 index 0000000..184e99b --- /dev/null +++ b/BL99P-MO-IOC-01.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/out.yaml b/out.yaml new file mode 100644 index 0000000..e71a43a --- /dev/null +++ b/out.yaml @@ -0,0 +1,330 @@ +# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json + +ioc_name: "{{ __utils__.get_env('IOC_NAME') }}" + +description: auto-generated by https://github.com/epics-containers/builder2ibek + +entities: + + - type: epics.EpicsEnvSet + name: EPICS_TS_MIN_WEST + value: '0' + + - type: devIocStats.iocAdminSoft + IOC: '{{ ioc_name | upper }}' + + - type: epics.EpicsCaMaxArrayBytes + max_bytes: 32000000 + + - type: devIocStats.devIocStatsHelper + __command__: delete + ioc: BL99P-MO-IOC-01 + name: IOC-STATS + + - type: utility.pingWait + ip: 10.177.2.1 + name: BRICK1_PING + + - type: pvlogging.PvLogging + __command__: delete + + - type: pmac.pmacAsynIPPort + IP: 10.177.2.1:1025 + name: BRICK01PORT + + - type: pmac.GeoBrick + MovingPoll: 50 + P: BL99P-MO-STEP-01 + name: BRICK01 + pmacAsynPort: BRICK01PORT + + - type: pmac.GeoBrickTrajectoryControl + NPOINTS: 100000 + PmacController: BRICK01 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 1 + Controller: BRICK01 + DESC: Sample Z + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + M: :Z + MRES: -2e-05 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.001 + UEIP: No + VELO: 1.8 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 2 + Controller: BRICK01 + DESC: Sample X + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + M: :X + MRES: -2e-05 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.001 + UEIP: No + VELO: 1.8 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 3 + Controller: BRICK01 + DESC: Sample Y + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + M: :Y + MRES: 2e-05 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.001 + UEIP: No + VELO: 1.8 + + - type: pmac.pmacDisableLimitsCheck + Axis: 1 + Controller: BRICK01 + + - type: pmac.pmacDisableLimitsCheck + Axis: 2 + Controller: BRICK01 + + - type: pmac.pmacDisableLimitsCheck + Axis: 3 + Controller: BRICK01 + + - type: pmac.autohome + GRP2: F Lens + P: BL99P-MO-STAGE-01 + PLC: 11 + PmacController: BRICK01 + + - type: pmac.autohome + GRP2: Z + GRP3: X + GRP4: Y + P: BL99P-MO-STAGE-02 + PLC: 12 + PmacController: BRICK01 + + - type: pmac.CS + CS: 1 + PmacController: BRICK01 + name: BRICK1.CS1 + + - type: pmac.CS + CS: 2 + PmacController: BRICK01 + name: BRICK01.CS2 + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 7 + Controller: BRICK01.CS2 + DESC: Sample X Lab + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + HOMEVIS: 0 + HOMEVISSTR: This is a virtual motor + M: :LAB:X + MRES: 0.0001 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.1 + UEIP: No + VELO: 17 + is_cs: true + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 8 + Controller: BRICK01.CS2 + DESC: Sample Y Lab + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + HOMEVIS: 0 + HOMEVISSTR: This is a virtual motor + M: :LAB:Y + MRES: 0.0001 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.1 + UEIP: No + VELO: 17 + is_cs: true + + - type: pmac.dls_pmac_asyn_motor + ACCL: 0.1 + ADDR: 9 + Controller: BRICK01.CS2 + DESC: Sample Z Lab + DHLM: 7 + DIR: Pos + DLLM: -7 + EGU: mm + FOFF: Variable + HOMEVIS: 0 + HOMEVISSTR: This is a virtual motor + M: :LAB:Z + MRES: 0.0001 + P: BL99P-MO-STAGE-02 + PREC: 3 + TWV: 0.1 + UEIP: No + VELO: 17 + is_cs: true + + - type: pmac.pmacCreateCsGroup + AxisCount: 3 + Controller: BRICK01 + GroupName: StraightThrough + GroupNumber: 1 + + - type: pmac.pmacCreateCsGroup + AxisCount: 3 + Controller: BRICK01 + GroupName: J13Kinematics + GroupNumber: 2 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: Z + AxisNumber: 1 + Controller: BRICK01 + CoordSysNumber: 1 + GroupNumber: 1 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: X + AxisNumber: 2 + Controller: BRICK01 + CoordSysNumber: 1 + GroupNumber: 1 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: Y + AxisNumber: 3 + Controller: BRICK01 + CoordSysNumber: 1 + GroupNumber: 1 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 1 + Controller: BRICK01 + CoordSysNumber: 2 + GroupNumber: 2 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 2 + Controller: BRICK01 + CoordSysNumber: 2 + GroupNumber: 2 + + - type: pmac.pmacCsGroupAddAxis + AxisDef: I + AxisNumber: 3 + Controller: BRICK01 + CoordSysNumber: 2 + GroupNumber: 2 + + - type: pmac.pmacVariableWrite + EGU: deg + P: BL99P-MO-STAGE-01 + PORT: BRICK01 + Q: :WRITETHETA + VAR: '&2Q21' + VARIABLE_PREC: 4 + + - type: pmac.pmacVariableWrite + EGU: deg + P: BL99P-MO-STAGE-01 + PORT: BRICK01 + Q: :WRITEPITCH + VAR: '&2Q20' + VARIABLE_PREC: 4 + + - type: pmac.pmacVariableWrite + EGU: deg + P: BL99P-MO-STAGE-01 + PORT: BRICK01 + Q: :WRITEROLL + VAR: '&2Q22' + VARIABLE_PREC: 4 + + - type: pmac.pmacMonitorVariables + Controller: BRICK01 + Variables: P4800 P4805 P4806 P4804 P4905 P4900 P4906 P4904 + name: pVars + + - type: pmac.pmacMonitorVariables + Controller: BRICK01 + Variables: '&2Q20 &2Q21 &2Q22' + name: qVars + + - type: positioner.multipositioner + DESC: Filter Wheel + MP: :MP + P: BL99P-MO-STAGE-02 + STRA: Empty + STRB: Mn 5um + STRC: Fe (empty) + STRD: Co 5um + STRE: Ni 5um + STRF: Cu 5um + STRG: Zn 5um + STRH: Zr (empty) + STRI: Mo (empty) + STRJ: Rh (empty) + STRK: Pd (empty) + STRL: Ag (empty) + STRM: Cd 25um + STRN: W (empty) + STRO: Pt (empty) + STRP: User + name: SAM2.MP + + - type: positioner.motorpositioner + DESC: Filter Motor + MP: SAM2.MP + PREC: 1 + Q: :P + VALA: 0 + VALB: 0.1 + VALC: 0.2 + VALD: 0.3 + VALE: 0.4 + VALF: 0.5 + VALG: 0.6 + VALH: 0.7 + VALI: 0.8 + VALJ: 0.9 + VALK: 1 + VALL: 1.1 + VALM: 1.2 + VALN: 1.3 + VALO: 1.41 + VALP: 1.5 + motor: SAM2.Z + name: SAM2.OB1 diff --git a/src/builder2ibek/convert.py b/src/builder2ibek/convert.py index 59a9e18..405e53b 100644 --- a/src/builder2ibek/convert.py +++ b/src/builder2ibek/convert.py @@ -53,7 +53,7 @@ def do_one_element(element: Element, ioc: Generic_IOC): if element.module in module_infos: info = module_infos[element.module] entity.type = f"{info.yaml_component}.{element.name}" - # new_xml = info.handler(entity, element.name, ioc) + new_xml = globalHandler(entity, element.name, ioc, info.handler) if new_xml: handle_new_xml(new_xml, entity, ioc, info) From 0e1a8a502178218772c884989449045bc4f5c8d3 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Thu, 3 Oct 2024 10:31:53 +0100 Subject: [PATCH 3/8] Removed residual testing files --- BL99P-MO-IOC-01.xml | 39 ------ out.yaml | 330 -------------------------------------------- 2 files changed, 369 deletions(-) delete mode 100644 BL99P-MO-IOC-01.xml delete mode 100644 out.yaml diff --git a/BL99P-MO-IOC-01.xml b/BL99P-MO-IOC-01.xml deleted file mode 100644 index 184e99b..0000000 --- a/BL99P-MO-IOC-01.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/out.yaml b/out.yaml deleted file mode 100644 index e71a43a..0000000 --- a/out.yaml +++ /dev/null @@ -1,330 +0,0 @@ -# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json - -ioc_name: "{{ __utils__.get_env('IOC_NAME') }}" - -description: auto-generated by https://github.com/epics-containers/builder2ibek - -entities: - - - type: epics.EpicsEnvSet - name: EPICS_TS_MIN_WEST - value: '0' - - - type: devIocStats.iocAdminSoft - IOC: '{{ ioc_name | upper }}' - - - type: epics.EpicsCaMaxArrayBytes - max_bytes: 32000000 - - - type: devIocStats.devIocStatsHelper - __command__: delete - ioc: BL99P-MO-IOC-01 - name: IOC-STATS - - - type: utility.pingWait - ip: 10.177.2.1 - name: BRICK1_PING - - - type: pvlogging.PvLogging - __command__: delete - - - type: pmac.pmacAsynIPPort - IP: 10.177.2.1:1025 - name: BRICK01PORT - - - type: pmac.GeoBrick - MovingPoll: 50 - P: BL99P-MO-STEP-01 - name: BRICK01 - pmacAsynPort: BRICK01PORT - - - type: pmac.GeoBrickTrajectoryControl - NPOINTS: 100000 - PmacController: BRICK01 - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 1 - Controller: BRICK01 - DESC: Sample Z - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - M: :Z - MRES: -2e-05 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.001 - UEIP: No - VELO: 1.8 - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 2 - Controller: BRICK01 - DESC: Sample X - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - M: :X - MRES: -2e-05 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.001 - UEIP: No - VELO: 1.8 - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 3 - Controller: BRICK01 - DESC: Sample Y - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - M: :Y - MRES: 2e-05 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.001 - UEIP: No - VELO: 1.8 - - - type: pmac.pmacDisableLimitsCheck - Axis: 1 - Controller: BRICK01 - - - type: pmac.pmacDisableLimitsCheck - Axis: 2 - Controller: BRICK01 - - - type: pmac.pmacDisableLimitsCheck - Axis: 3 - Controller: BRICK01 - - - type: pmac.autohome - GRP2: F Lens - P: BL99P-MO-STAGE-01 - PLC: 11 - PmacController: BRICK01 - - - type: pmac.autohome - GRP2: Z - GRP3: X - GRP4: Y - P: BL99P-MO-STAGE-02 - PLC: 12 - PmacController: BRICK01 - - - type: pmac.CS - CS: 1 - PmacController: BRICK01 - name: BRICK1.CS1 - - - type: pmac.CS - CS: 2 - PmacController: BRICK01 - name: BRICK01.CS2 - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 7 - Controller: BRICK01.CS2 - DESC: Sample X Lab - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - HOMEVIS: 0 - HOMEVISSTR: This is a virtual motor - M: :LAB:X - MRES: 0.0001 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.1 - UEIP: No - VELO: 17 - is_cs: true - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 8 - Controller: BRICK01.CS2 - DESC: Sample Y Lab - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - HOMEVIS: 0 - HOMEVISSTR: This is a virtual motor - M: :LAB:Y - MRES: 0.0001 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.1 - UEIP: No - VELO: 17 - is_cs: true - - - type: pmac.dls_pmac_asyn_motor - ACCL: 0.1 - ADDR: 9 - Controller: BRICK01.CS2 - DESC: Sample Z Lab - DHLM: 7 - DIR: Pos - DLLM: -7 - EGU: mm - FOFF: Variable - HOMEVIS: 0 - HOMEVISSTR: This is a virtual motor - M: :LAB:Z - MRES: 0.0001 - P: BL99P-MO-STAGE-02 - PREC: 3 - TWV: 0.1 - UEIP: No - VELO: 17 - is_cs: true - - - type: pmac.pmacCreateCsGroup - AxisCount: 3 - Controller: BRICK01 - GroupName: StraightThrough - GroupNumber: 1 - - - type: pmac.pmacCreateCsGroup - AxisCount: 3 - Controller: BRICK01 - GroupName: J13Kinematics - GroupNumber: 2 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: Z - AxisNumber: 1 - Controller: BRICK01 - CoordSysNumber: 1 - GroupNumber: 1 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: X - AxisNumber: 2 - Controller: BRICK01 - CoordSysNumber: 1 - GroupNumber: 1 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: Y - AxisNumber: 3 - Controller: BRICK01 - CoordSysNumber: 1 - GroupNumber: 1 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: I - AxisNumber: 1 - Controller: BRICK01 - CoordSysNumber: 2 - GroupNumber: 2 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: I - AxisNumber: 2 - Controller: BRICK01 - CoordSysNumber: 2 - GroupNumber: 2 - - - type: pmac.pmacCsGroupAddAxis - AxisDef: I - AxisNumber: 3 - Controller: BRICK01 - CoordSysNumber: 2 - GroupNumber: 2 - - - type: pmac.pmacVariableWrite - EGU: deg - P: BL99P-MO-STAGE-01 - PORT: BRICK01 - Q: :WRITETHETA - VAR: '&2Q21' - VARIABLE_PREC: 4 - - - type: pmac.pmacVariableWrite - EGU: deg - P: BL99P-MO-STAGE-01 - PORT: BRICK01 - Q: :WRITEPITCH - VAR: '&2Q20' - VARIABLE_PREC: 4 - - - type: pmac.pmacVariableWrite - EGU: deg - P: BL99P-MO-STAGE-01 - PORT: BRICK01 - Q: :WRITEROLL - VAR: '&2Q22' - VARIABLE_PREC: 4 - - - type: pmac.pmacMonitorVariables - Controller: BRICK01 - Variables: P4800 P4805 P4806 P4804 P4905 P4900 P4906 P4904 - name: pVars - - - type: pmac.pmacMonitorVariables - Controller: BRICK01 - Variables: '&2Q20 &2Q21 &2Q22' - name: qVars - - - type: positioner.multipositioner - DESC: Filter Wheel - MP: :MP - P: BL99P-MO-STAGE-02 - STRA: Empty - STRB: Mn 5um - STRC: Fe (empty) - STRD: Co 5um - STRE: Ni 5um - STRF: Cu 5um - STRG: Zn 5um - STRH: Zr (empty) - STRI: Mo (empty) - STRJ: Rh (empty) - STRK: Pd (empty) - STRL: Ag (empty) - STRM: Cd 25um - STRN: W (empty) - STRO: Pt (empty) - STRP: User - name: SAM2.MP - - - type: positioner.motorpositioner - DESC: Filter Motor - MP: SAM2.MP - PREC: 1 - Q: :P - VALA: 0 - VALB: 0.1 - VALC: 0.2 - VALD: 0.3 - VALE: 0.4 - VALF: 0.5 - VALG: 0.6 - VALH: 0.7 - VALI: 0.8 - VALJ: 0.9 - VALK: 1 - VALL: 1.1 - VALM: 1.2 - VALN: 1.3 - VALO: 1.41 - VALP: 1.5 - motor: SAM2.Z - name: SAM2.OB1 From 14b5d5f2ede0841c3d27bccb7fa858e20050cb1b Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Fri, 4 Oct 2024 11:43:54 +0100 Subject: [PATCH 4/8] Updated templater --- .copier-answers.yml | 3 +- .devcontainer/devcontainer.json | 2 +- .github/CONTRIBUTING.md | 2 +- .github/ISSUE_TEMPLATE/bug_report.md | 21 ++++++++++++++ .github/ISSUE_TEMPLATE/issue.md | 13 +++++++++ .../pull_request_template.md | 8 +++++ .github/pages/index.html | 2 +- .github/workflows/_release.yml | 2 +- .github/workflows/ci.yml | 2 +- .gitignore | 1 + .pre-commit-config.yaml | 1 + .vscode/extensions.json | 2 +- .vscode/settings.json | 3 +- .vscode/tasks.json | 2 +- catalog-info.yaml | 10 ------- pyproject.toml | 29 +++++++++++-------- src/builder2ibek/__init__.py | 8 +++++ src/builder2ibek/convert.py | 9 +++--- src/builder2ibek/converters/gdaPlugins.yaml | 2 +- src/builder2ibek/converters/globalHandler.py | 5 ++-- tests/conftest.py | 12 ++++++-- 21 files changed, 97 insertions(+), 42 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/issue.md create mode 100644 .github/PULL_REQUEST_TEMPLATE/pull_request_template.md delete mode 100644 catalog-info.yaml diff --git a/.copier-answers.yml b/.copier-answers.yml index 4875a14..e3d184b 100644 --- a/.copier-answers.yml +++ b/.copier-answers.yml @@ -1,9 +1,8 @@ # Changes here will be overwritten by Copier -_commit: 2.1.0 +_commit: 2.3.0 _src_path: gh:diamondlightsource/python-copier-template author_email: giles.knap@diamond.ac.uk author_name: Giles Knap -component_owner: group:default/sscc description: Conversion tool for DLS XML builder IOC instances to ibek ioc.yaml distribution_name: builder2ibek docker: false diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 79b85ff..d3d639a 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -43,4 +43,4 @@ "workspaceMount": "source=${localWorkspaceFolder}/..,target=/workspaces,type=bind", // After the container is created, install the python project in editable form "postCreateCommand": "pip install $([ -f dev-requirements.txt ] && echo '-c dev-requirements.txt') -e '.[dev]' && pre-commit install" -} \ No newline at end of file +} diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index e3a795d..c5e850a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects. -For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.1.0/how-to.html). +For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.3.0/how-to.html). diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..aa65892 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,21 @@ +--- +name: Bug Report +about: The template to use for reporting bugs and usability issues +title: " " +labels: 'bug' +assignees: '' + +--- + +Describe the bug, including a clear and concise description of the expected behavior, the actual behavior and the context in which you encountered it (ideally include details of your environment). + +## Steps To Reproduce +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/ISSUE_TEMPLATE/issue.md b/.github/ISSUE_TEMPLATE/issue.md new file mode 100644 index 0000000..52c84dd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue.md @@ -0,0 +1,13 @@ +--- +name: Issue +about: The standard template to use for feature requests, design discussions and tasks +title: " " +labels: '' +assignees: '' + +--- + +A brief description of the issue, including specific stakeholders and the business case where appropriate + +## Acceptance Criteria +- Specific criteria that will be used to judge if the issue is fixed diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md new file mode 100644 index 0000000..8200afe --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md @@ -0,0 +1,8 @@ +Fixes #ISSUE + +### Instructions to reviewer on how to test: +1. Do thing x +2. Confirm thing y happens + +### Checks for reviewer +- [ ] Would the PR title make sense to a user on a set of release notes diff --git a/.github/pages/index.html b/.github/pages/index.html index 80f0a00..c495f39 100644 --- a/.github/pages/index.html +++ b/.github/pages/index.html @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/.github/workflows/_release.yml b/.github/workflows/_release.yml index e55efdb..10d8ed8 100644 --- a/.github/workflows/_release.yml +++ b/.github/workflows/_release.yml @@ -23,7 +23,7 @@ jobs: - name: Create GitHub Release # We pin to the SHA, not the tag, for security reasons. # https://docs.github.com/en/actions/learn-github-actions/security-hardening-for-github-actions#using-third-party-actions - uses: softprops/action-gh-release@9d7c94cfd0a1f3ed45544c887983e9fa900f0564 # v2.0.4 + uses: softprops/action-gh-release@c062e08bd532815e2082a85e87e3ef29c3e6d191 # v2.0.8 with: prerelease: ${{ contains(github.ref_name, 'a') || contains(github.ref_name, 'b') || contains(github.ref_name, 'rc') }} files: "*" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 93de608..bc606ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: strategy: matrix: runs-on: ["ubuntu-latest"] # can add windows-latest, macos-latest - python-version: ["3.8", "3.9", "3.10", "3.11"] + python-version: ["3.10", "3.11", "3.12"] include: # Include one that runs in the dev environment - runs-on: "ubuntu-latest" diff --git a/.gitignore b/.gitignore index 2593ec7..0f33bf2 100644 --- a/.gitignore +++ b/.gitignore @@ -55,6 +55,7 @@ cov.xml # Sphinx documentation docs/_build/ +docs/_api # PyBuilder target/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 5a4cbf7..60fc23f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,6 +5,7 @@ repos: - id: check-added-large-files - id: check-yaml - id: check-merge-conflict + - id: end-of-file-fixer - repo: local hooks: diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 66ad632..933c580 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,4 +2,4 @@ "recommendations": [ "ms-vscode-remote.remote-containers", ] -} \ No newline at end of file +} diff --git a/.vscode/settings.json b/.vscode/settings.json index c129d99..101c75f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,8 @@ "editor.codeActionsOnSave": { "source.organizeImports": "explicit" }, + "files.insertFinalNewline": true, "[python]": { "editor.defaultFormatter": "charliermarsh.ruff", }, -} \ No newline at end of file +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 946e69d..c999e86 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -13,4 +13,4 @@ "problemMatcher": [], } ] -} \ No newline at end of file +} diff --git a/catalog-info.yaml b/catalog-info.yaml deleted file mode 100644 index 6ad5db7..0000000 --- a/catalog-info.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: backstage.io/v1alpha1 -kind: Component -metadata: - name: builder2ibek - title: builder2ibek - description: Conversion tool for DLS XML builder IOC instances to ibek ioc.yaml -spec: - type: documentation - lifecycle: experimental - owner: group:default/sscc \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 54162fe..23aa299 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["setuptools>=64", "setuptools_scm[toml]>=6.2"] +requires = ["setuptools>=64", "setuptools_scm[toml]>=8"] build-backend = "setuptools.build_meta" [project] @@ -7,11 +7,9 @@ name = "builder2ibek" classifiers = [ "Development Status :: 3 - Alpha", "License :: OSI Approved :: Apache Software License", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", ] description = "Conversion tool for DLS XML builder IOC instances to ibek ioc.yaml" dependencies = ["ibek"] # Add project dependencies here, e.g. ["click", "numpy"] @@ -45,7 +43,7 @@ name = "Giles Knap" [tool.setuptools_scm] -write_to = "src/builder2ibek/_version.py" +version_file = "src/builder2ibek/_version.py" [tool.mypy] ignore_missing_imports = true # Ignore missing stubs in imported modules @@ -97,11 +95,18 @@ lint.ignore = [ ] line-length = 88 lint.select = [ - "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b - "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 - "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e - "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f - "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w - "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i - "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "B", # flake8-bugbear - https://docs.astral.sh/ruff/rules/#flake8-bugbear-b + "C4", # flake8-comprehensions - https://docs.astral.sh/ruff/rules/#flake8-comprehensions-c4 + "E", # pycodestyle errors - https://docs.astral.sh/ruff/rules/#error-e + "F", # pyflakes rules - https://docs.astral.sh/ruff/rules/#pyflakes-f + "W", # pycodestyle warnings - https://docs.astral.sh/ruff/rules/#warning-w + "I", # isort - https://docs.astral.sh/ruff/rules/#isort-i + "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up + "SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self ] + +[tool.ruff.lint.per-file-ignores] +# By default, private member access is allowed in tests +# See https://github.com/DiamondLightSource/python-copier-template/issues/154 +# Remove this line to forbid private member access in tests +"tests/**/*" = ["SLF001"] diff --git a/src/builder2ibek/__init__.py b/src/builder2ibek/__init__.py index 26d23ba..a2ffbf3 100644 --- a/src/builder2ibek/__init__.py +++ b/src/builder2ibek/__init__.py @@ -1,3 +1,11 @@ +"""Top level API. + +.. data:: __version__ + :type: str + + Version number as calculated by https://github.com/pypa/setuptools_scm +""" + from ._version import __version__ __all__ = ["__version__"] diff --git a/src/builder2ibek/convert.py b/src/builder2ibek/convert.py index 405e53b..3e10cad 100644 --- a/src/builder2ibek/convert.py +++ b/src/builder2ibek/convert.py @@ -9,6 +9,7 @@ from builder2ibek.types import Entity, Generic_IOC from builder2ibek.converters.globalHandler import globalHandler + def dispatch(builder: Builder, filename) -> Generic_IOC: """ Dispatch every element in the XML to the correct convertor @@ -47,21 +48,22 @@ def do_dispatch(builder: Builder, ioc: Generic_IOC): def do_one_element(element: Element, ioc: Generic_IOC): # first do default conversion to entity entity = convert_generic(element, ioc) - + # then dispatch to a specific handler if there is one assert isinstance(element, Element) if element.module in module_infos: info = module_infos[element.module] entity.type = f"{info.yaml_component}.{element.name}" - + new_xml = globalHandler(entity, element.name, ioc, info.handler) if new_xml: - handle_new_xml(new_xml, entity, ioc, info) + handle_new_xml(new_xml, entity, ioc, info) else: new_xml = globalHandler(entity, element.name, ioc) if new_xml: handle_new_xml(new_xml, entity, ioc) + def handle_new_xml(new_xml: str, entity: Entity, ioc: Generic_IOC, info=None): new_builder = Builder() new_builder.load_string(new_xml) @@ -74,7 +76,6 @@ def handle_new_xml(new_xml: str, entity: Entity, ioc: Generic_IOC, info=None): add_defaults(entity, info.defaults) - def add_defaults(entity: dict[str, Any], defaults: dict[str, dict[str, Any]]): this_entity_defaults = defaults.get(entity["type"]) if this_entity_defaults: diff --git a/src/builder2ibek/converters/gdaPlugins.yaml b/src/builder2ibek/converters/gdaPlugins.yaml index a3c789d..f3960f4 100644 --- a/src/builder2ibek/converters/gdaPlugins.yaml +++ b/src/builder2ibek/converters/gdaPlugins.yaml @@ -67,4 +67,4 @@ PORT: $(PORTPREFIX).hdf QUEUE: $(PLUGINQUEUE=16) R: ':HDF5:' - TIMEOUT: 1 \ No newline at end of file + TIMEOUT: 1 diff --git a/src/builder2ibek/converters/globalHandler.py b/src/builder2ibek/converters/globalHandler.py index f4b8ed1..1ce1aa3 100644 --- a/src/builder2ibek/converters/globalHandler.py +++ b/src/builder2ibek/converters/globalHandler.py @@ -3,10 +3,11 @@ xml_component = "global" -def globalHandler(entity: Entity, entity_type: str, ioc: Generic_IOC, target_handler=None): +def globalHandler( + entity: Entity, entity_type: str, ioc: Generic_IOC, target_handler=None +): entity.remove("gda_name") entity.remove("gda_desc") if target_handler: return target_handler(entity, entity_type, ioc) - \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index d5cdd5f..ebe9c10 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,4 +1,5 @@ import os +from typing import Any import pytest @@ -7,9 +8,14 @@ if os.getenv("PYTEST_RAISE", "0") == "1": @pytest.hookimpl(tryfirst=True) - def pytest_exception_interact(call): - raise call.excinfo.value + def pytest_exception_interact(call: pytest.CallInfo[Any]): + if call.excinfo is not None: + raise call.excinfo.value + else: + raise RuntimeError( + f"{call} has no exception data, an unknown error has occurred" + ) @pytest.hookimpl(tryfirst=True) - def pytest_internalerror(excinfo): + def pytest_internalerror(excinfo: pytest.ExceptionInfo[Any]): raise excinfo.value From 8565d81f1bed6185a658ef4dd94789eecfe8f607 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Mon, 7 Oct 2024 10:44:52 +0100 Subject: [PATCH 5/8] Added test case --- tests/samples/BL99P-EA-IOC-05.xml | 9 +++++++++ tests/test_file_conversion.py | 15 +++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 tests/samples/BL99P-EA-IOC-05.xml create mode 100644 tests/test_file_conversion.py diff --git a/tests/samples/BL99P-EA-IOC-05.xml b/tests/samples/BL99P-EA-IOC-05.xml new file mode 100644 index 0000000..ebee17a --- /dev/null +++ b/tests/samples/BL99P-EA-IOC-05.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/test_file_conversion.py b/tests/test_file_conversion.py new file mode 100644 index 0000000..9b7a48a --- /dev/null +++ b/tests/test_file_conversion.py @@ -0,0 +1,15 @@ +import subprocess +import sys + + +def test_cli_version(): + cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", "tests/samples/BL45P-MO-IOC-01.xml"] + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + assert result.stderr == b"" + + cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", "tests/samples/BL99P-EA-IOC-05.xml"] + result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + assert result.stderr == b"" + + + From 97d72f1fcf31ce038de7a87561d29ae4148772e1 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Mon, 7 Oct 2024 10:52:53 +0100 Subject: [PATCH 6/8] Improved coverage test --- tests/test_file_conversion.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_file_conversion.py b/tests/test_file_conversion.py index 9b7a48a..4a2c55a 100644 --- a/tests/test_file_conversion.py +++ b/tests/test_file_conversion.py @@ -1,15 +1,15 @@ import subprocess import sys - +import os def test_cli_version(): - cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", "tests/samples/BL45P-MO-IOC-01.xml"] - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - assert result.stderr == b"" - - cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", "tests/samples/BL99P-EA-IOC-05.xml"] - result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - assert result.stderr == b"" + conversion_samples = ["tests/samples/BL45P-MO-IOC-01.xml", + "tests/samples/BL99P-EA-IOC-05.xml"] + + for sample in conversion_samples: + cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", sample] + result = subprocess.run(cmd) + assert result.returncode == 0 From 3938a2ae78c2bf4ee00e53361cef84a4eb9b4b57 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Mon, 7 Oct 2024 11:22:24 +0100 Subject: [PATCH 7/8] Updated test format --- tests/test_file_conversion.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/test_file_conversion.py b/tests/test_file_conversion.py index 4a2c55a..43de264 100644 --- a/tests/test_file_conversion.py +++ b/tests/test_file_conversion.py @@ -1,15 +1,22 @@ -import subprocess import sys -import os +import subprocess + def test_cli_version(): - conversion_samples = ["tests/samples/BL45P-MO-IOC-01.xml", - "tests/samples/BL99P-EA-IOC-05.xml"] - + conversion_samples = [ + "tests/samples/BL45P-MO-IOC-01.xml", + "tests/samples/BL99P-EA-IOC-05.xml", + ] + for sample in conversion_samples: - cmd = [sys.executable, "-m", "builder2ibek", "file", "--yaml", "out.yaml", sample] + cmd = [ + sys.executable, + "-m", + "builder2ibek", + "file", + "--yaml", + "out.yaml", + sample, + ] result = subprocess.run(cmd) assert result.returncode == 0 - - - From eef8375c98a26c7f37b5837c29be680e0abb8be0 Mon Sep 17 00:00:00 2001 From: Max Herbert Date: Tue, 8 Oct 2024 10:19:43 +0100 Subject: [PATCH 8/8] Fixed linting issues --- out.yaml | 42 +++++++++++++++++++++++ src/builder2ibek/convert.py | 5 ++- src/builder2ibek/converters/digitelMpc.py | 2 +- src/builder2ibek/converters/dlsPLC.py | 3 +- tests/test_file_conversion.py | 2 +- 5 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 out.yaml diff --git a/out.yaml b/out.yaml new file mode 100644 index 0000000..c5d137f --- /dev/null +++ b/out.yaml @@ -0,0 +1,42 @@ +# yaml-language-server: $schema=/epics/ibek-defs/ioc.schema.json + +ioc_name: "{{ __utils__.get_env('IOC_NAME') }}" + +description: auto-generated by https://github.com/epics-containers/builder2ibek + +entities: + + - type: epics.EpicsEnvSet + name: EPICS_TS_MIN_WEST + value: '0' + + - type: devIocStats.iocAdminSoft + IOC: '{{ ioc_name | upper }}' + + - type: epics.EpicsCaMaxArrayBytes + max_bytes: 9000000 + + - type: devIocStats.devIocStatsHelper + __command__: delete + ioc: BL99P-EA-IOC-05 + name: IOC-STATS + + - type: ADAndor.andorCCD + ADDR: 0 + BUFFERS: 2000 + INSTALLPATH: /dls_sw/prod/R3.14.12.7/support/ANAndor/etc + P: BL99P-EA-DET-03 + PORT: DET3.cam + R: ':CAM:' + TIMEOUT: 1 + + - type: ADCore.NDPosPlugin + ADDR: 0 + BLOCK: 0 + ENABLED: 1 + NDARRAY_PORT: DET3.cam + P: BL99P-EA-DET-03 + PORT: DET3.pos + QUEUE: 1000 + R: ':POS:' + TIMEOUT: 1 diff --git a/src/builder2ibek/convert.py b/src/builder2ibek/convert.py index 3e10cad..2943e26 100644 --- a/src/builder2ibek/convert.py +++ b/src/builder2ibek/convert.py @@ -5,9 +5,9 @@ from typing import Any from builder2ibek.builder import Builder, Element +from builder2ibek.converters.globalHandler import globalHandler from builder2ibek.moduleinfos import module_infos from builder2ibek.types import Entity, Generic_IOC -from builder2ibek.converters.globalHandler import globalHandler def dispatch(builder: Builder, filename) -> Generic_IOC: @@ -71,8 +71,7 @@ def handle_new_xml(new_xml: str, entity: Entity, ioc: Generic_IOC, info=None): do_dispatch(new_builder, ioc) if entity.is_deleted(): ioc.entities.remove(entity) - if not entity.is_deleted and info: - print("a") + if not entity.is_deleted() and info: add_defaults(entity, info.defaults) diff --git a/src/builder2ibek/converters/digitelMpc.py b/src/builder2ibek/converters/digitelMpc.py index 7536954..d8e6ec7 100644 --- a/src/builder2ibek/converters/digitelMpc.py +++ b/src/builder2ibek/converters/digitelMpc.py @@ -9,6 +9,6 @@ def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ if entity_type in ["digitelMpc", "digitelMpcTsp"]: # transform unit into quoted 2 digit format - unit = int(entity.get("unit")) + unit = int(entity.get("unit")) # type: ignore unit_enum = f"{unit:02d}" entity.unit = unit_enum diff --git a/src/builder2ibek/converters/dlsPLC.py b/src/builder2ibek/converters/dlsPLC.py index e9e4326..99223d1 100644 --- a/src/builder2ibek/converters/dlsPLC.py +++ b/src/builder2ibek/converters/dlsPLC.py @@ -9,7 +9,8 @@ def handler(entity: Entity, entity_type: str, ioc: Generic_IOC): """ if entity_type == "fastVacuumChannel": # transform unit into quoted 2 digit format - id = int(entity.get("id")) + id_val = entity.get("id") + id = int(id_val) # type: ignore id_enum = f"{id:02d}" entity.id = id_enum elif entity_type == "NX102_readReal": diff --git a/tests/test_file_conversion.py b/tests/test_file_conversion.py index 43de264..49ffc43 100644 --- a/tests/test_file_conversion.py +++ b/tests/test_file_conversion.py @@ -1,5 +1,5 @@ -import sys import subprocess +import sys def test_cli_version():