1212import ramble .cmd
1313import ramble .paths
1414import ramble .repository
15+ import ramble .spec
1516from ramble .util .logger import logger
1617
1718from spack .util .editor import editor
@@ -25,8 +26,8 @@ def normalize_type_name(type_name):
2526 if not type_name :
2627 return None
2728
28- # Map aliases
29- aliases = {
29+ # Map non-object type aliases
30+ extra_type_aliases = {
3031 "test" : "test" ,
3132 "tests" : "test" ,
3233 "command" : "command" ,
@@ -36,18 +37,14 @@ def normalize_type_name(type_name):
3637 "module" : "module" ,
3738 "modules" : "module" ,
3839 }
39- if type_name in aliases :
40- return aliases [type_name ]
41-
42- # Map singular to plural for ObjectTypes
43- norm_type = type_name .lower ().replace ("-" , " " ).replace ("_" , " " )
44- for obj_type in ramble .repository .ObjectTypes :
45- if norm_type == obj_type .name .lower ().replace ("_" , " " ):
46- return obj_type .name
47- if obj_type in ramble .repository .type_definitions :
48- singular = ramble .repository .type_definitions [obj_type ]["singular" ]
49- if norm_type == singular .lower ().replace ("_" , " " ).replace ("-" , " " ):
50- return obj_type .name
40+ norm_type = type_name .lower ().strip ().replace (" " , "_" )
41+ if norm_type in extra_type_aliases :
42+ return extra_type_aliases [norm_type ]
43+
44+ # Map object types using repository's get_object_type_map()
45+ type_map = ramble .repository .get_object_type_map ()
46+ if norm_type in type_map :
47+ return type_map [norm_type ].name
5148
5249 return type_name
5350
@@ -65,27 +62,36 @@ def find_all_matches(name, repo_path=None, namespace=None, obj_type=None):
6562 extra_types = ["test" , "command" , "docs" , "module" ]
6663 allowed_types = ramble .repository .OBJECT_NAMES + extra_types
6764
68- types_to_check = [obj_type ] if obj_type else allowed_types
65+ # Parse spec if name might be a namespaced spec
66+ spec = ramble .spec .Spec (name )
67+ spec_obj_type = spec .object_type .name if spec .object_type else None
68+ spec_namespace = spec .namespace
69+ spec_name = spec .name if spec .name else name
70+
71+ effective_obj_type = obj_type or spec_obj_type
72+ types_to_check = [effective_obj_type ] if effective_obj_type else allowed_types
73+
74+ effective_namespace = namespace or spec_namespace
6975
7076 for t in types_to_check :
7177 if t in ramble .repository .OBJECT_NAMES :
7278 # Check object type
73- obj_type = ramble .repository .ObjectTypes [t ]
79+ repo_obj_type = ramble .repository .ObjectTypes [t ]
7480 if repo_path :
7581 try :
76- repos = [ramble .repository .Repo (repo_path , object_type = obj_type )]
82+ repos = [ramble .repository .Repo (repo_path , object_type = repo_obj_type )]
7783 except Exception :
7884 repos = []
79- elif namespace :
85+ elif effective_namespace :
8086 try :
81- repos = [ramble .repository .paths [obj_type ].get_repo (namespace )]
87+ repos = [ramble .repository .paths [repo_obj_type ].get_repo (effective_namespace )]
8288 except Exception :
8389 repos = []
8490 else :
85- repos = ramble .repository .paths [obj_type ].repos
91+ repos = ramble .repository .paths [repo_obj_type ].repos
8692
8793 for repo in repos :
88- path = repo .filename_for_object_name (name )
94+ path = repo .filename_for_object_name (spec_name )
8995 if os .path .isfile (path ):
9096 matches .append ({"type" : t , "path" : path , "repo_namespace" : repo .namespace })
9197 elif t in extra_types :
@@ -142,7 +148,12 @@ def setup_parser(subparser):
142148 excl_args .add_argument ("-r" , "--repo" , default = None , help = "path to repo to edit object in" )
143149 excl_args .add_argument ("-N" , "--namespace" , default = None , help = "namespace of object to edit" )
144150
145- subparser .add_argument ("object_name" , nargs = "?" , default = None , help = "object name" )
151+ subparser .add_argument (
152+ "object_name" ,
153+ nargs = "?" ,
154+ default = None ,
155+ help = ("object name or namespaced spec to edit " "(e.g., my-app or builtin.app.my-app)" ),
156+ )
146157
147158
148159def edit (parser , args ):
@@ -206,7 +217,12 @@ def edit(parser, args):
206217
207218 # If no matches found, reproduce the original behavior/messages:
208219 # 1. If type is specified/defaulted, we show type-specific "not found" messages.
209- type_name = args .type or ramble .repository .default_type .name
220+ spec = ramble .spec .Spec (name )
221+ spec_obj_type = spec .object_type .name if spec .object_type else None
222+ type_name = args .type or spec_obj_type or ramble .repository .default_type .name
223+ effective_namespace = args .namespace or spec .namespace
224+ spec_name = spec .name if spec .name else name
225+
210226 type_to_path = {
211227 "test" : ramble .paths .test_path ,
212228 "command" : ramble .paths .command_path ,
@@ -226,11 +242,11 @@ def edit(parser, args):
226242 obj_type = ramble .repository .ObjectTypes [type_name ]
227243 if args .repo :
228244 repo = ramble .repository .Repo (args .repo , object_type = obj_type )
229- elif args . namespace :
230- repo = ramble .repository .paths [obj_type ].get_repo (args . namespace )
245+ elif effective_namespace :
246+ repo = ramble .repository .paths [obj_type ].get_repo (effective_namespace )
231247 else :
232248 repo = ramble .repository .paths [obj_type ]
233- path = repo .filename_for_object_name (name )
249+ path = repo .filename_for_object_name (spec_name )
234250 except Exception :
235251 path = None
236252
0 commit comments