55import shutil
66import subprocess
77import tempfile
8+ from typing import Generator , LiteralString , TextIO
89
910import lxml .etree
1011from ibex_install_utils .user_prompt import UserPrompt
2425from ibex_install_utils .tasks import BaseTasks
2526from ibex_install_utils .tasks .common_paths import (
2627 APPS_BASE_DIR ,
27- EPICS_IOC_PATH ,
2828 EPICS_PATH ,
2929 INST_SHARE_AREA ,
3030 INSTRUMENT_BASE_DIR ,
6969
7070
7171class ServerTasks (BaseTasks ):
72- """Tasks relating to installing or maintaining an IBEX server and it's associated configuration files."""
72+ """Tasks relating to installing or maintaining an IBEX server and
73+ its associated configuration files."""
7374
7475 @staticmethod
75- def _get_config_path ():
76+ def _get_config_path () -> LiteralString | str | bytes :
7677 """Returns:
7778 The path to the instrument's configurations directory
7879
@@ -82,15 +83,15 @@ def _get_config_path():
8283 )
8384
8485 @task ("Removing old settings file" )
85- def remove_settings (self ):
86+ def remove_settings (self ) -> None :
8687 """Remove old settings
8788 Returns:
8889
8990 """
9091 self ._file_utils .remove_tree (SETTINGS_CONFIG_PATH , self .prompt )
9192
9293 @task ("Install settings" )
93- def install_settings (self ):
94+ def install_settings (self ) -> None :
9495 """Install new settings from the current folder
9596 Returns:
9697
@@ -118,7 +119,7 @@ def install_settings(self):
118119 )
119120
120121 @task ("Installing IBEX Server" )
121- def install_ibex_server (self , use_old_galil = None ):
122+ def install_ibex_server (self , use_old_galil : bool = None ) -> None :
122123 """Install ibex server.
123124
124125 Args:
@@ -131,8 +132,9 @@ def install_ibex_server(self, use_old_galil=None):
131132 self ._swap_galil_driver (use_old_galil )
132133
133134 @task ("Set up configuration repository" )
134- def setup_config_repository (self ):
135- """Creates the configuration repository, and swaps or creates a branch for the instrument."""
135+ def setup_config_repository (self ) -> None :
136+ """Creates the configuration repository,
137+ and swaps or creates a branch for the instrument."""
136138 inst_name = BaseTasks ._get_machine_name ()
137139
138140 RunProcess (
@@ -238,13 +240,14 @@ def setup_config_repository(self):
238240 ).run ()
239241 except Exception as e :
240242 self .prompt .prompt_and_raise_if_not_yes (
241- f"Something went wrong setting up the configurations repository. Please resolve manually, "
243+ f"Something went wrong setting up the configurations repository. "
244+ f"Please resolve manually, "
242245 f"instructions are in the developers manual under "
243246 f"First-time-installing-and-building-(Windows): \n { e } "
244247 )
245248
246249 @task ("Upgrading instrument configuration" )
247- def upgrade_instrument_configuration (self ):
250+ def upgrade_instrument_configuration (self ) -> None :
248251 """Update the configuration on the instrument using its upgrade config script."""
249252 manual_prompt = (
250253 "Merge the master configurations branch into the instrument configuration. "
@@ -263,7 +266,8 @@ def upgrade_instrument_configuration(self):
263266 repo = git .Repo (os .path .join (SETTINGS_CONFIG_PATH , BaseTasks ._get_machine_name ()))
264267 if repo .active_branch .name != BaseTasks ._get_machine_name ():
265268 print (
266- f"Git branch, '{ repo .active_branch } ', is not the same as machine name ,'{ BaseTasks ._get_machine_name ()} ' "
269+ f"Git branch, '{ repo .active_branch } ', is not the same as"
270+ f" machine name ,'{ BaseTasks ._get_machine_name ()} ' "
267271 )
268272 raise ErrorInTask ("Git branch is not the same as machine name" )
269273 try :
@@ -287,7 +291,7 @@ def upgrade_instrument_configuration(self):
287291 RunProcess (CONFIG_UPGRADE_SCRIPT_DIR , "upgrade.bat" , capture_pipes = False ).run ()
288292
289293 @task ("Install shared instrument scripts repository" )
290- def install_shared_scripts_repository (self ):
294+ def install_shared_scripts_repository (self ) -> None :
291295 """Install shared instrument scripts repository containing"""
292296 if os .path .isdir (INST_SCRIPTS_PATH ):
293297 if (
@@ -309,7 +313,7 @@ def install_shared_scripts_repository(self):
309313 ).run ()
310314
311315 @task ("Set up shared instrument scripts library" )
312- def update_shared_scripts_repository (self ):
316+ def update_shared_scripts_repository (self ) -> None :
313317 """Update the shared instrument scripts repository containing"""
314318 try :
315319 repo = git .Repo (INST_SCRIPTS_PATH )
@@ -321,7 +325,7 @@ def update_shared_scripts_repository(self):
321325 )
322326
323327 @task ("Set up calibrations repository" )
324- def setup_calibrations_repository (self ):
328+ def setup_calibrations_repository (self ) -> None :
325329 """Set up the calibration repository"""
326330 if os .path .isdir (CALIBRATION_PATH ):
327331 if (
@@ -344,7 +348,7 @@ def setup_calibrations_repository(self):
344348 ).run ()
345349
346350 @task ("Updating calibrations repository" )
347- def update_calibrations_repository (self ):
351+ def update_calibrations_repository (self ) -> None :
348352 """Update the calibration repository"""
349353 try :
350354 repo = git .Repo (CALIBRATION_PATH )
@@ -356,7 +360,7 @@ def update_calibrations_repository(self):
356360 )
357361
358362 @task ("Server release tests" )
359- def perform_server_tests (self ):
363+ def perform_server_tests (self ) -> None :
360364 """Test that the server works"""
361365 server_release_tests_url = (
362366 "https://github.com/ISISComputingGroup/ibex_developers_manual/wiki/Server-Release-Tests"
@@ -366,7 +370,9 @@ def perform_server_tests(self):
366370 self .prompt .prompt_and_raise_if_not_yes ("Check that blocks are logging as expected" )
367371
368372 print (
369- f"Checking that configurations are being pushed to the appropriate repository ({ INSTCONFIGS_GIT_URL .format (ServerTasks ._get_machine_name ())} )"
373+ f"Checking that configurations are being pushed to"
374+ f" the appropriate repository "
375+ f"({ INSTCONFIGS_GIT_URL .format (ServerTasks ._get_machine_name ())} )"
370376 )
371377 repo = git .Repo (self ._get_config_path ())
372378 repo .git .fetch ()
@@ -376,9 +382,11 @@ def perform_server_tests(self):
376382 print ("Configurations updating correctly" )
377383 else :
378384 self .prompt .prompt_and_raise_if_not_yes (
379- f"Repository status shown above is either not 'up to date' or not attached to correct branch. "
385+ f"Repository status shown above is either not 'up to date' or "
386+ f"not attached to correct branch. "
380387 f"Please confirm that configurations are being pushed to the appropriate "
381- f"remote repository branch ({ INSTCONFIGS_GIT_URL .format (ServerTasks ._get_machine_name ())} )"
388+ f"remote repository branch"
389+ f" ({ INSTCONFIGS_GIT_URL .format (ServerTasks ._get_machine_name ())} )"
382390 )
383391
384392 self .prompt .prompt_and_raise_if_not_yes (
@@ -387,7 +395,7 @@ def perform_server_tests(self):
387395 )
388396
389397 @task ("Install wiring tables" )
390- def install_wiring_tables (self ):
398+ def install_wiring_tables (self ) -> None :
391399 """Prompt user to install wiring tables in the appropriate folder."""
392400 tables_dir = os .path .join (
393401 SETTINGS_CONFIG_PATH ,
@@ -398,7 +406,7 @@ def install_wiring_tables(self):
398406 self .prompt .prompt_and_raise_if_not_yes (f"Install the wiring tables in { tables_dir } ." )
399407
400408 @task ("Configure motion setpoints" )
401- def configure_motion (self ):
409+ def configure_motion (self ) -> None :
402410 """Prompt user to configure Galils"""
403411 url = (
404412 "https://github.com/ISISComputingGroup/ibex_developers_manual/wiki/"
@@ -417,7 +425,8 @@ def configure_motion(self):
417425 self .prompt .prompt_and_raise_if_not_yes ("Confirm motion set points have been configured." )
418426
419427 @contextmanager
420- def timestamped_pv_backups_file (self , name , directory , extension = "txt" ):
428+ def timestamped_pv_backups_file (self , name : str , directory : str , extension : str = "txt" ) \
429+ -> Generator [TextIO , None , None ]:
421430 """Context manager to create a timestamped file in the pv backups directory
422431
423432 Args:
@@ -440,7 +449,7 @@ def timestamped_pv_backups_file(self, name, directory, extension="txt"):
440449 yield f
441450
442451 @task ("Backup motors, blocks and blockserver to csv files" )
443- def save_motor_blocks_blockserver_to_file (self ):
452+ def save_motor_blocks_blockserver_to_file (self ) -> None :
444453 """Saves the motor, blocks and blockserver to csv file."""
445454 print ("Backing up: motor params pvs" )
446455 self .save_motor_parameters_to_file ()
@@ -454,15 +463,15 @@ def save_motor_blocks_blockserver_to_file(self):
454463 self .save_blockserver_pv_to_file ()
455464 print ("Finished backing up: blockserver config pvs" )
456465
457- def save_motor_parameters_to_file (self ):
466+ def save_motor_parameters_to_file (self ) -> None :
458467 """Saves the motor parameters to csv file."""
459468 with self .timestamped_pv_backups_file (
460469 name = "motors" , directory = "motors" , extension = "csv"
461470 ) as f :
462471 print (f"saving motor params to { f .name } " )
463472 get_params_and_save_to_file (f )
464473
465- def save_blocks_to_file (self ):
474+ def save_blocks_to_file (self ) -> None :
466475 """Saves block parameters in a file."""
467476 blocks = self ._ca .get_blocks ()
468477 if blocks is None :
@@ -473,7 +482,7 @@ def save_blocks_to_file(self):
473482 counter = 0
474483 manager = multiprocessing .Manager ()
475484 data = manager .list ()
476- for block in blocks :
485+ for _ in blocks :
477486 data .append (" " )
478487 for block in blocks :
479488 block_processes .append (
@@ -501,10 +510,10 @@ def save_blocks_to_file(self):
501510 else :
502511 print ("Blockserver available but no blocks found - not archiving anything" )
503512
504- def block_caget (self , block , counter , data ) :
513+ def block_caget (self , block : str , counter : int , data : list [ str ]) -> None :
505514 data [counter ] = f"{ self ._ca .cget (block )} \r \n "
506515
507- def save_blockserver_pv_to_file (self ):
516+ def save_blockserver_pv_to_file (self ) -> None :
508517 """Saves the blockserver PV to a file."""
509518 pvs_to_save = [
510519 ("all_component_details" , "CS:BLOCKSERVER:ALL_COMPONENT_DETAILS" ),
@@ -535,23 +544,24 @@ def save_blockserver_pv_to_file(self):
535544 process .start ()
536545 process .join ()
537546
538- def get_pv (self , pv , name ) :
539- def _pretty_print (data ) :
547+ def get_pv (self , pv : str , name : str ) -> None :
548+ def _pretty_print (data : str | None ) -> str :
540549 return pprint .pformat (data , width = 800 , indent = 2 )
541550
542551 with self .timestamped_pv_backups_file (directory = "inst_servers" , name = name ) as f :
543552 try :
544553 f .write (f"{ _pretty_print (self ._ca .get_object_from_compressed_hexed_json (pv ))} \r \n " )
545- except :
554+ except : # noqa: E722
546555 pass
547556
548557 @task ("Update the ICP" )
549- def update_icp (self , icp_in_labview_modules , register_icp = True ):
550- """Updates the IPC to the latest version.
558+ def update_icp (self , icp_in_labview_modules : bool , register_icp : bool = True ) -> None :
559+ """Updates the ICP to the latest version.
551560
552561 Args:
553562 icp_in_labview_modules (bool): true if the ICP is in labview modules
554- register_icp (bool): whether to re-register the ISISICP program (requires admin rights; interactive only)
563+ register_icp (bool): whether to re-register the ISISICP program
564+ (requires admin rights; interactive only)
555565 """
556566 register_icp_commands = AdminCommandBuilder ()
557567
@@ -563,7 +573,8 @@ def update_icp(self, icp_in_labview_modules, register_icp=True):
563573 except Exception as e :
564574 print (f"Failed to find dae_type ({ e } ), not installing ICP" )
565575 return
566- # If the ICP is talking to a DAE2 it's DAEType will be 1 or 2, if it's talking to a DAE3 it will be 3 or 4
576+ # If the ICP is talking to a DAE2 it's DAEType will be 1 or 2,
577+ # if it's talking to a DAE3 it will be 3 or 4
567578 if dae_type in [1 , 2 ]:
568579 dae_type = 2
569580 elif dae_type in [3 , 4 ]:
@@ -619,7 +630,7 @@ def update_icp(self, icp_in_labview_modules, register_icp=True):
619630 @task (
620631 "Set username and password for alerts (only required if this is a SECI to IBEX migration)"
621632 )
622- def set_alert_url_and_password (self ):
633+ def set_alert_url_and_password (self ) -> None :
623634 print (
624635 "The URL and password for alerts are at http://www.facilities.rl.ac.uk/isis/computing/instruments/Lists/Access/AllItems.aspx"
625636 )
@@ -635,7 +646,7 @@ def set_alert_url_and_password(self):
635646 print ("No username/password provided - skipping step" )
636647
637648 @task ("Run config checker" )
638- def run_config_checker (self ):
649+ def run_config_checker (self ) -> None :
639650 with tempfile .TemporaryDirectory () as tmpdir :
640651 print (f"Cloning InstrumentChecker to { tmpdir } " )
641652 git .Repo .clone_from (
@@ -669,15 +680,15 @@ def run_config_checker(self):
669680
670681 RunProcess (tmpdir , python , prog_args = args ).run ()
671682
672- def select_galil_driver (self ):
683+ def select_galil_driver (self ) -> bool :
673684 """Select galil driver to use. Return True if old driver in operation or should be used"""
674685 # GALIL_OLD.txt file gets copied to the tmp dir by instrument_deploy.bat
675686 tmpdir = tempfile .gettempdir ()
676687
677688 if os .path .exists (os .path .join (tmpdir , "GALIL_OLD.txt" )):
678689 os .remove (os .path .join (tmpdir , "GALIL_OLD.txt" ))
679- # we don't need to swap back to new GALIL for the update as install will remove all files anyway
680- # we just need to record our current choice
690+ # we don't need to swap back to new GALIL for the update as install will remove all
691+ # files anyway, we just need to record our current choice
681692 print (
682693 "Old galil driver version detected and will automatically be restored after update."
683694 )
@@ -698,11 +709,12 @@ def select_galil_driver(self):
698709 return True
699710 else :
700711 print (
701- "Old Galil driver is default - only change to new driver if you explicitly know this is needed!"
712+ "Old Galil driver is default - only change to new driver if you explicitly"
713+ " know this is needed!"
702714 )
703715 return not self .prompt .confirm_step ("Use new Galil driver" )
704716
705- def _swap_galil_driver (self , use_old ) :
717+ def _swap_galil_driver (self , use_old : bool ) -> None :
706718 """Swap galil back to old if needed
707719 Args:
708720 use_old(bool): whether to restore old driver version
@@ -717,12 +729,8 @@ def _swap_galil_driver(self, use_old):
717729 prog_args = ["checkout" , "galil-old" ],
718730 ).run ()
719731
720- def ioc_dir_exists (self , ioc_dirname ):
721- full_ioc_path = os .path .join (EPICS_IOC_PATH , ioc_dirname )
722- return os .path .exists (full_ioc_path )
723-
724732 @task ("Set up log rotation" )
725- def setup_log_rotation (self ):
733+ def setup_log_rotation (self ) -> None :
726734 """Sets up instrument log rotation via windows scheduled task."""
727735 python = r"c:\instrument\apps\python3\python.exe"
728736 logrotate = r"c:\instrument\apps\epics\utils\logrotate.py"
0 commit comments