diff --git a/azure-devops/azext_devops/dev/boards/arguments.py b/azure-devops/azext_devops/dev/boards/arguments.py index 7893a8ce1..25cd3dd04 100644 --- a/azure-devops/azext_devops/dev/boards/arguments.py +++ b/azure-devops/azext_devops/dev/boards/arguments.py @@ -35,6 +35,8 @@ def load_work_arguments(self, _): context.argument('relation_type', help='Relation type to create. Example: parent, child ') context.argument('target_id', help='ID(s) of work-items to create relation with. \ Multiple values can be passed comma separated. Example: 1,2 ') + context.argument('target_url', help='URL(s) of work-items to create relation with. \ + Multiple values can be passed comma separated.') with self.argument_context('boards work-item relation remove') as context: context.argument('relation_type', help='Relation type to remove. Example: parent, child ') diff --git a/azure-devops/azext_devops/dev/boards/relations.py b/azure-devops/azext_devops/dev/boards/relations.py index 0a7c5f9cc..cf7df3e55 100644 --- a/azure-devops/azext_devops/dev/boards/relations.py +++ b/azure-devops/azext_devops/dev/boards/relations.py @@ -21,9 +21,13 @@ def get_relation_types_show(organization=None, detect=None): return client.get_relation_types() -def add_relation(id, relation_type, target_id, organization=None, detect=None): # pylint: disable=redefined-builtin +def add_relation(id, relation_type, target_id=None, target_url=None, organization=None, detect=None): # pylint: disable=redefined-builtin """ Add relation(s) to work item. """ + + if target_id is None and target_url is None: + raise CLIError('--target-id or --target-url must be provided') + organization = resolve_instance(detect=detect, organization=organization) patch_document = [] client = get_work_item_tracking_client(organization) @@ -31,26 +35,33 @@ def add_relation(id, relation_type, target_id, organization=None, detect=None): relation_types_from_service = client.get_relation_types() relation_type_system_name = get_system_relation_name(relation_types_from_service, relation_type) - target_work_item_ids = target_id.split(',') - work_item_query_clause = [] - for target_work_item_id in target_work_item_ids: - work_item_query_clause.append('[System.Id] = {}'.format(target_work_item_id)) + patch_document = [] + if target_id is not None: + target_work_item_ids = target_id.split(',') + work_item_query_clause = [] + for target_work_item_id in target_work_item_ids: + work_item_query_clause.append('[System.Id] = {}'.format(target_work_item_id)) - wiql_query_format = 'SELECT [System.Id] FROM WorkItems WHERE ({})' - wiql_query_to_get_target_work_items = wiql_query_format.format(' OR '.join(work_item_query_clause)) + wiql_query_format = 'SELECT [System.Id] FROM WorkItems WHERE ({})' + wiql_query_to_get_target_work_items = wiql_query_format.format(' OR '.join(work_item_query_clause)) - wiql_object = Wiql() - wiql_object.query = wiql_query_to_get_target_work_items - target_work_items = client.query_by_wiql(wiql=wiql_object).work_items + wiql_object = Wiql() + wiql_object.query = wiql_query_to_get_target_work_items + target_work_items = client.query_by_wiql(wiql=wiql_object).work_items - if len(target_work_items) != len(target_work_item_ids): - raise CLIError('Id(s) supplied in --target-id is not valid') + if len(target_work_items) != len(target_work_item_ids): + raise CLIError('Id(s) supplied in --target-id is not valid') - patch_document = [] + for target_work_item in target_work_items: + op = _create_patch_operation('add', '/relations/-', relation_type_system_name, target_work_item.url) + patch_document.append(op) + + if target_url is not None: + target_urls = target_url.split(',') - for target_work_item in target_work_items: - op = _create_patch_operation('add', '/relations/-', relation_type_system_name, target_work_item.url) - patch_document.append(op) + for url in target_urls: + op = _create_patch_operation('add', '/relations/-', relation_type_system_name, url) + patch_document.append(op) client.update_work_item(document=patch_document, id=id) work_item = client.get_work_item(id, expand='All')