From 750a4ef02effe8c97c374796037ea017a3df47c5 Mon Sep 17 00:00:00 2001 From: omsadegaonkar Date: Mon, 17 Aug 2026 07:00:32 +0530 Subject: [PATCH] Feature: Parse reference attributes from --ref in workspace add (#20261) - Removed mutual exclusion check for path and --ref - Added parsing of --ref to extract name, version, user, channel - Uses RecipeReference.loads() for robust parsing - Added clear error message for invalid reference format fixes #20261 --- conan/cli/commands/workspace.py | 16 +++++++- .../workspace/test_workspace_ref_parse.py | 38 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 test/integration/workspace/test_workspace_ref_parse.py diff --git a/conan/cli/commands/workspace.py b/conan/cli/commands/workspace.py index f128dd48215..46a7a1f0c37 100644 --- a/conan/cli/commands/workspace.py +++ b/conan/cli/commands/workspace.py @@ -97,13 +97,27 @@ def workspace_add(conan_api: ConanAPI, parser, subparser, *args): raise ConanException("Do not use both 'path' and '--ref' argument") if args.folder and not args.ref: raise ConanException("'--folder' requires '--ref'") + if args.ref and any((args.name, args.version, args.user, args.channel)): + raise ConanException( + "Do not use '--ref' together with '--name', '--version', " + "'--user' or '--channel' arguments" + ) remotes = conan_api.remotes.list(args.remote) if not args.no_remote else [] path = args.path + name = args.name + version = args.version + user = args.user + channel = args.channel if args.ref: + ref = RecipeReference.loads(args.ref) cwd, folder = _resolve_ws_relative_folder(conan_api, args.folder) path = conan_api.workspace.open(args.ref, remotes, cwd=cwd, folder=folder) + name = ref.name + version = ref.version + user = ref.user + channel = ref.channel ref = conan_api.workspace.add(path, - args.name, args.version, args.user, args.channel, + name, version, user, channel, args.output_folder, remotes=remotes) ConanOutput().success("Reference '{}' added to workspace".format(ref)) diff --git a/test/integration/workspace/test_workspace_ref_parse.py b/test/integration/workspace/test_workspace_ref_parse.py new file mode 100644 index 00000000000..e1eef13f6c7 --- /dev/null +++ b/test/integration/workspace/test_workspace_ref_parse.py @@ -0,0 +1,38 @@ +import textwrap + +from conan.test.utils.tools import TestClient + + +def test_workspace_add_ref_parses_and_persists(): + client = TestClient() + conanfile = textwrap.dedent(""" + from conan import ConanFile + + class MyPkg(ConanFile): + name = "mypkg" + version = "1.0" + """) + client.save({"conanfile.py": conanfile}) + client.run("export . --user=company") + client.run("workspace init .") + client.run("workspace add --ref=mypkg/1.0@company") + client.run("workspace info") + assert "mypkg/1.0@company" in client.out + + +def test_workspace_add_ref_rejects_individual_reference_arguments(): + client = TestClient() + client.run("workspace init .") + client.run( + "workspace add --ref=mypkg/1.0@company --version=2.0", + assert_error=True + ) + assert "Do not use '--ref' together with '--name', '--version', " \ + "'--user' or '--channel' arguments" in client.out + + +def test_workspace_add_ref_rejects_invalid_reference(): + client = TestClient() + client.run("workspace init .") + client.run("workspace add --ref=invalid-format", assert_error=True) + assert "not a valid recipe reference" in client.out