diff --git a/seqerakit/helper.py b/seqerakit/helper.py index 419d49a..8f41027 100644 --- a/seqerakit/helper.py +++ b/seqerakit/helper.py @@ -36,11 +36,26 @@ def parse_yaml_block(yaml_data, block_name, sp=None, name_filter=None): # Initialize an empty list to hold the lists of command line arguments. cmd_args_list = [] - # Initialize a set to track the --name values within the block. - name_values = set() + # Initialize a set to track unique (workspace, name) or (organization, name) tuples. + # Workspace-scoped resources allow duplicate names across different workspaces. + # Organization-scoped resources allow duplicate names across different organizations. + name_keys = set() + + # Resources scoped to workspace (can have same name in different workspaces) + workspace_scoped = { + "compute-envs", + "credentials", + "pipelines", + "datasets", + "secrets", + "actions", + "participants", + "data-links", + "studios", + } + # Resources scoped to organization + org_scoped = {"workspaces", "teams", "labels", "members"} - # Iterate over each item in the block. - # TODO: fix for resources that can be duplicate named in an org for item in block: # Filter by name if name_filter is specified item_name = item.get("name") or item.get("user") or item.get("email") @@ -49,12 +64,23 @@ def parse_yaml_block(yaml_data, block_name, sp=None, name_filter=None): cmd_args = parse_block(block_name, item, sp) name = find_name(cmd_args) - if name in name_values: + + # Determine the scope key for duplicate detection + if block_name in workspace_scoped: + scope = item.get("workspace") + elif block_name in org_scoped: + scope = item.get("organization") + else: + scope = None + + key = (scope, name) if scope else name + if key in name_keys: + scope_msg = f" in {scope}" if scope else "" raise ValueError( f" Duplicate name key specified in config file" - f" for {block_name}: {name}. Please specify a unique value." + f" for {block_name}: {name}{scope_msg}. Please specify a unique value." ) - name_values.add(name) + name_keys.add(key) cmd_args_list.append(cmd_args) diff --git a/tests/unit/test_helper.py b/tests/unit/test_helper.py index 22d59b8..3da2a52 100644 --- a/tests/unit/test_helper.py +++ b/tests/unit/test_helper.py @@ -535,11 +535,46 @@ def test_error_duplicate_name_yaml_file(mock_yaml_file): helper.parse_all_yaml([file_path]) assert ( "Duplicate name key specified in config file for " - "compute-envs: test_computeenv. Please specify " - "a unique value." in str(e.value) + "compute-envs: test_computeenv in my_organization/my_workspace. " + "Please specify a unique value." in str(e.value) ) +def test_duplicate_name_different_workspaces_allowed(mock_yaml_file): + """Test that duplicate names are allowed across different workspaces.""" + test_data = { + "compute-envs": [ + { + "name": "SharedCE", + "workspace": "my_organization/team1", + "credentials": "my_credentials", + "type": "aws-batch", + "config-mode": "forge", + }, + { + "name": "SharedCE", + "workspace": "my_organization/team2", + "credentials": "my_credentials", + "type": "aws-batch", + "config-mode": "forge", + }, + { + "name": "SharedCE", + "workspace": "my_organization/team3", + "credentials": "my_credentials", + "type": "aws-batch", + "config-mode": "forge", + }, + ], + } + file_path = mock_yaml_file(test_data) + + # Should not raise - duplicate names are allowed in different workspaces + result = helper.parse_all_yaml([file_path]) + assert "compute-envs" in result + assert len(result["compute-envs"]) == 3 + + def test_targets_specified(): # mock YAML data yaml_data = """