Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[hotfix] Remove package by its reference #9459

Merged
merged 2 commits into from Aug 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 14 additions & 2 deletions conans/client/command.py
Expand Up @@ -1182,8 +1182,20 @@ def remove(self, *args):
if not args.pattern_or_reference:
raise ConanException('Please specify a pattern to be removed ("*" for all)')

return self._conan.remove(pattern=args.pattern_or_reference, query=args.query,
packages=args.packages, builds=args.builds, src=args.src,
try:
pref = PackageReference.loads(args.pattern_or_reference, validate=True)
packages = [pref.id]
pattern_or_reference = repr(pref.ref)
except ConanException:
pref = None
pattern_or_reference = args.pattern_or_reference
packages = args.packages

if pref and args.packages:
raise ConanException("Use package ID only as -p argument or reference, not both")

return self._conan.remove(pattern=pattern_or_reference, query=args.query,
packages=packages, builds=args.builds, src=args.src,
force=args.force, remote_name=args.remote, outdated=args.outdated)

def copy(self, *args):
Expand Down
77 changes: 77 additions & 0 deletions conans/test/integration/command/remove_test.py
Expand Up @@ -519,3 +519,80 @@ def test_remote(self):
self.client.run("remove lib/1.0 -f -r default")
self.client.run("install lib/1.0@", assert_error=True)
self.assertIn("ERROR: Unable to find 'lib/1.0' in remotes", self.client.out)


class RemovePackageRevisionsTest(unittest.TestCase):

NO_SETTINGS_RREF = "f3367e0e7d170aa12abccb175fee5f97"

def setUp(self):
self.test_server = TestServer(users={"user": "password"},
write_permissions=[("foobar/0.1@*/*", "user")])
servers = {"default": self.test_server}
self.client = TestClient(servers=servers, users={"default": [("user", "password")]})
self.client.run("config set general.revisions_enabled=1")

def test_remove_local_package_id_argument(self):
""" Remove package ID based on recipe revision. The package must be deleted, but
the recipe must be preserved
Package ID is a separated argument: <package>#<rref> -p <pkgid>
"""
self.client.save({"conanfile.py": GenConanfile()})
self.client.run("create . foobar/0.1@user/testing")
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Cache", self.client.out)
self.assertIn("Revision: f3367e0e7d170aa12abccb175fee5f97", self.client.out)
self.assertIn("Package revision: 83c38d3b4e5f1b8450434436eec31b00", self.client.out)

self.client.run("remove -f foobar/0.1@user/testing#{} -p {}"
.format(self.NO_SETTINGS_RREF, NO_SETTINGS_PACKAGE_ID))
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Missing", self.client.out)
self.assertIn("Revision: f3367e0e7d170aa12abccb175fee5f97", self.client.out)
self.assertIn("Package revision: None", self.client.out)

def test_remove_local_package_id_reference(self):
""" Remove package ID based on recipe revision. The package must be deleted, but
the recipe must be preserved.
Package ID is part of package reference: <package>#<rref>:<pkgid>
"""
self.client.save({"conanfile.py": GenConanfile()})
self.client.run("create . foobar/0.1@user/testing")
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Cache", self.client.out)
self.assertIn("Revision: f3367e0e7d170aa12abccb175fee5f97", self.client.out)
self.assertIn("Package revision: 83c38d3b4e5f1b8450434436eec31b00", self.client.out)

self.client.run("remove -f foobar/0.1@user/testing#{}:{}"
.format(self.NO_SETTINGS_RREF, NO_SETTINGS_PACKAGE_ID))
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Missing", self.client.out)
self.assertIn("Revision: f3367e0e7d170aa12abccb175fee5f97", self.client.out)
self.assertIn("Package revision: None", self.client.out)

def test_remove_duplicated_package_id(self):
""" The package ID must not be present in both -p argument and package reference
"""
self.client.save({"conanfile.py": GenConanfile()})
self.client.run("create . foobar/0.1@user/testing")
self.client.run("remove -f foobar/0.1@user/testing#{}:{} -p {}"
.format(self.NO_SETTINGS_RREF, NO_SETTINGS_PACKAGE_ID,
NO_SETTINGS_PACKAGE_ID), assert_error=True)
self.assertIn("Use package ID only as -p argument or reference, not both", self.client.out)

def test_remove_remote_package_id_reference(self):
""" Remove remote package ID based on recipe revision. The package must be deleted, but
the recipe must be preserved.
Package ID is part of package reference: <package>#<rref>:<pkgid>
"""
self.client.save({"conanfile.py": GenConanfile()})
self.client.run("create . foobar/0.1@user/testing")
self.client.run("upload foobar/0.1@user/testing -r default -c --all")
self.client.run("remove -f foobar/0.1@user/testing#{}:{}"
.format(self.NO_SETTINGS_RREF, NO_SETTINGS_PACKAGE_ID))
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Download", self.client.out)
self.client.run("remove -f foobar/0.1@user/testing#{}:{} -r default"
.format(self.NO_SETTINGS_RREF, NO_SETTINGS_PACKAGE_ID))
self.client.run("info foobar/0.1@user/testing")
self.assertIn("Binary: Missing", self.client.out)