Parse a file path that may include a server object specification. Args: file_spec: Path to file, optionally with :object suffix Returns: Tuple of (file_path, server_object)
(file_spec: str)
| 86 | |
| 87 | |
| 88 | def _parse_file_path(file_spec: str) -> tuple[Path, str | None]: |
| 89 | """Parse a file path that may include a server object specification. |
| 90 | |
| 91 | Args: |
| 92 | file_spec: Path to file, optionally with :object suffix |
| 93 | |
| 94 | Returns: |
| 95 | Tuple of (file_path, server_object) |
| 96 | """ |
| 97 | # First check if we have a Windows path (e.g., C:\...) |
| 98 | has_windows_drive = len(file_spec) > 1 and file_spec[1] == ":" |
| 99 | |
| 100 | # Split on the last colon, but only if it's not part of the Windows drive letter |
| 101 | # and there's actually another colon in the string after the drive letter |
| 102 | if ":" in (file_spec[2:] if has_windows_drive else file_spec): |
| 103 | file_str, server_object = file_spec.rsplit(":", 1) |
| 104 | else: |
| 105 | file_str, server_object = file_spec, None |
| 106 | |
| 107 | # Resolve the file path |
| 108 | file_path = Path(file_str).expanduser().resolve() |
| 109 | if not file_path.exists(): |
| 110 | logger.error(f"File not found: {file_path}") |
| 111 | sys.exit(1) |
| 112 | if not file_path.is_file(): |
| 113 | logger.error(f"Not a file: {file_path}") |
| 114 | sys.exit(1) |
| 115 | |
| 116 | return file_path, server_object |
| 117 | |
| 118 | |
| 119 | def _import_server(file: Path, server_object: str | None = None): # pragma: no cover |