Coverage for src/sparkle/CLI/help/nicknames.py: 87%
45 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-08 12:00 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-08 12:00 +0000
1"""Helper functions for CLI nicknames."""
3from __future__ import annotations
4from pathlib import Path
5from typing import Callable
7from sparkle.instance import Instance_Set, InstanceSet, MultiFileInstanceSet
10def resolve_object_name(
11 name: str | Path,
12 nickname_dict: dict = {},
13 target_dir: Path = Path(),
14 class_name: Callable = None,
15) -> Path | any:
16 """Attempts to resolve a (nick) name.
18 Args:
19 name: The (nick)name to resolve
20 target_dir: The location where the file object should exist
21 nickname_dict: Nicknames
22 class_name: If passed, will attempt to return an object
23 that is constructed from this Path.
25 Returns:
26 Path to the object, None if unresolvable.
27 """
28 path = None
29 # We cannot handle None as a name
30 if name is None:
31 return None
32 # First check if the name already is a path
33 if isinstance(name, (str, Path)) and Path(name).exists():
34 path = Path(name)
35 # Second check if its a nickname registered in Sparkle
36 elif str(name) in nickname_dict:
37 path = Path(nickname_dict[str(name)])
38 # Third check if we can create a valid path with the name
39 elif isinstance(name, (str, Path)) and (target_dir / name).exists():
40 path = target_dir / name
41 # Finally, attempt to construct the object from the Path
42 try:
43 if class_name is not None:
44 if path is not None:
45 return class_name(path)
46 if name is not None:
47 return class_name(name)
48 except Exception:
49 return None
50 return path
53def resolve_instance_name(
54 instance_set: str,
55 instance_name: str,
56 search_location: str | Path | list[InstanceSet],
57) -> str | Path | list[Path] | None:
58 """Attempts to resolve an instance to its file path(s).
60 The inverse of resolve_instance_pair, which maps a path back to its (set, instance).
62 Args:
63 instance_set: The name of the set the instance belongs to. Used to look in the
64 correct set, so instances sharing a name across different sets are not
65 confused with one another.
66 instance_name: The name of the instance to resolve.
67 search_location: Where to look for the instance. Either a str/Path to a
68 directory containing instance sets, or the instance sets themselves as
69 a list.
71 Returns:
72 The Path of the instance, or None if it cannot be resolved. Multi-file instances
73 are returned as a space-joined string of their paths, as they are passed on to
74 a command line as a single argument.
75 """
76 # Check if the name is already an instance file path
77 name_path = Path(instance_name)
78 if name_path.exists() and name_path.is_file():
79 return name_path
80 # Attempt to find files
81 matches = [path for path in name_path.parent.glob(name_path.name + ".*")]
82 if matches:
83 return " ".join(str(path) for path in matches) # Concat for multi file instance
84 # Normalise search_location into a list of InstanceSet objects. A str/Path points to
85 # a directory that contains instance set directories.
86 if isinstance(search_location, (str, Path)):
87 instance_sets = [
88 Instance_Set(instance_dir)
89 for instance_dir in Path(search_location).iterdir()
90 if instance_dir.is_dir()
91 ]
92 else:
93 instance_sets = search_location
94 # We know which set the instance belongs to so restrict the search to that set so a
95 # shared instance name in another set cannot shadow it. Fall back to all sets if the
96 # named set is not among those given.
97 matching_sets = [
98 inst_set for inst_set in instance_sets if inst_set.name == instance_set
99 ]
100 search_sets = matching_sets if matching_sets else instance_sets
102 instance_path = None
103 for current_set in search_sets:
104 instance_path = current_set.get_path_by_name(instance_name)
105 if instance_path is None:
106 continue
107 # Handle multi file instance
108 if isinstance(current_set, MultiFileInstanceSet):
109 instance_path = (
110 [instance_path] if not isinstance(instance_path, list) else instance_path
111 )
112 instance_path = " ".join(str(path) for path in instance_path)
113 break
114 return instance_path