Coverage for qpdk / install_tech.py: 22%

27 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-14 10:27 +0000

1"""Symlink tech to klayout.""" 

2 

3import shutil 

4import sys 

5from pathlib import Path 

6 

7from qpdk.logger import logger 

8 

9 

10def remove_path_or_dir(dest: Path) -> None: 

11 """Remove a path or directory.""" 

12 if not dest.exists(): 

13 raise FileNotFoundError(f"Path does not exist: {dest}") 

14 

15 if dest.is_dir(): 

16 shutil.rmtree(dest) 

17 else: 

18 dest.unlink() 

19 

20 

21def make_link(src: str | Path, dest: str | Path, overwrite: bool = True) -> None: 

22 """Make a symbolic link from src to dest.""" 

23 src, dest = Path(src), Path(dest) 

24 if not src.exists(): 

25 raise FileNotFoundError(f"{src} does not exist") 

26 

27 if dest.exists() and not overwrite: 

28 logger.warning("{} already exists", dest) 

29 return 

30 if dest.exists() or dest.is_symlink(): 

31 logger.info("removing {} already installed", dest) 

32 remove_path_or_dir(dest) 

33 try: 

34 Path.symlink_to(src, dest, target_is_directory=True) 

35 except OSError: 

36 shutil.copytree(src, dest) 

37 logger.info("link made:") 

38 logger.info("From: {}", src) 

39 logger.info("To: {}", dest) 

40 

41 

42if __name__ == "__main__": 

43 klayout_folder = "KLayout" if sys.platform == "win32" else ".klayout" 

44 home = Path.home() 

45 dest_folder = home / klayout_folder / "tech" 

46 dest_folder.mkdir(exist_ok=True, parents=True) 

47 cwd = Path(__file__).resolve().parent 

48 repo_root = cwd.parent 

49 src = repo_root / "qpdk" / "klayout" 

50 dest = dest_folder / "qpdk" 

51 make_link(src=src, dest=dest)