Repository: conan-io/conan

Issue:
conan upload should print the remote it is using
```
conan upload "*" 
Are you sure you want to upload 'XXX@XXX/XXXX'? (yes/no): 
````
It should be `Are you sure you want to upload 'XXX@XXX/XXXX' to remote 'conan-center'? (yes/no):

Or print first:


```
> conan upload "*" 
Uploading to remote 'conan-center':
Are you sure you want to upload 'XXX@XXX/XXXX'? (yes/no):
```



Discussion:

Resolving patch:
diff --git a/conans/client/cmd/uploader.py b/conans/client/cmd/uploader.py
--- a/conans/client/cmd/uploader.py
+++ b/conans/client/cmd/uploader.py
@@ -1,5 +1,6 @@
 import os
 import time
+from collections import defaultdict
 
 from conans.client.source import complete_recipe_sources
 from conans.errors import ConanException, NotFoundException
@@ -45,18 +46,34 @@ def upload(self, upload_recorder, reference_or_pattern, package_id=None, all_pac
                 raise NotFoundException(("No packages found matching pattern '%s'" %
                                          reference_or_pattern))
 
+        # Group recipes by remote
+        refs_by_remote = defaultdict(list)
+        default_remote = (self._registry.remotes.get(remote_name) if remote_name else
+                          self._registry.remotes.default)
+
         for ref in refs:
+            if not remote_name:
+                remote = self._registry.refs.get(ref) or default_remote
+            else:
+                remote = default_remote
+
             upload = True
             if not confirm:
-                msg = "Are you sure you want to upload '%s'?" % str(ref)
+                msg = "Are you sure you want to upload '%s' to '%s'?" % (str(ref), remote.name)
                 upload = self._user_io.request_boolean(msg)
             if upload:
                 try:
                     conanfile_path = self._cache.conanfile(ref)
-                    conan_file = self._loader.load_class(conanfile_path)
+                    conanfile = self._loader.load_class(conanfile_path)
                 except NotFoundException:
                     raise NotFoundException(("There is no local conanfile exported as %s" %
                                              str(ref)))
+                refs_by_remote[remote].append((ref, conanfile))
+
+        # Do the job
+        for remote, refs in refs_by_remote.items():
+            self._user_io.out.info("Uploading to remote '{}':".format(remote.name))
+            for (ref, conanfile) in refs:
                 if all_packages:
                     packages_ids = self._cache.conan_packages(ref)
                 elif query:
@@ -66,21 +83,14 @@ def upload(self, upload_recorder, reference_or_pattern, package_id=None, all_pac
                     packages_ids = [package_id, ]
                 else:
                     packages_ids = []
-                self._upload(conan_file, ref, packages_ids, retry, retry_wait,
-                             integrity_check, policy, remote_name, upload_recorder)
+                self._upload(conanfile, ref, packages_ids, retry, retry_wait,
+                             integrity_check, policy, remote, upload_recorder)
 
         logger.debug("UPLOAD: Time manager upload: %f" % (time.time() - t1))
 
     def _upload(self, conan_file, ref, packages_ids, retry, retry_wait,
-                integrity_check, policy, remote_name, upload_recorder):
-        """Uploads the recipes and binaries identified by ref"""
-
-        default_remote = self._registry.remotes.default
-        cur_recipe_remote = self._registry.refs.get(ref)
-        if remote_name:  # If remote_name is given, use it
-            recipe_remote = self._registry.remotes.get(remote_name)
-        else:
-            recipe_remote = cur_recipe_remote or default_remote
+                integrity_check, policy, recipe_remote, upload_recorder):
+        """Uploads the recipes and binaries identified by conan_ref"""
 
         conanfile_path = self._cache.conanfile(ref)
         # FIXME: I think it makes no sense to specify a remote to "pre_upload"


Test patch:
diff --git a/conans/test/functional/command/upload_complete_test.py b/conans/test/functional/command/upload_complete_test.py
--- a/conans/test/functional/command/upload_complete_test.py
+++ b/conans/test/functional/command/upload_complete_test.py
@@ -322,12 +322,13 @@ def simple_test(self):
                              stat.S_IRWXU, stat.S_IRWXU)
 
     def upload_all_test(self):
-        '''Upload conans and package together'''
+        """Upload conans and package together"""
         # Try to upload all conans and packages
         self.client.run('upload %s --all' % str(self.ref))
         lines = [line.strip() for line in str(self.client.user_io.out).splitlines()
                  if line.startswith("Uploading")]
-        self.assertEqual(lines, ["Uploading Hello/1.2.1@frodo/stable to remote 'default'",
+        self.assertEqual(lines, ["Uploading to remote 'default':",
+                                 "Uploading Hello/1.2.1@frodo/stable to remote 'default'",
                                  "Uploading conanmanifest.txt",
                                  "Uploading conanfile.py",
                                  "Uploading conan_export.tgz",
diff --git a/conans/test/functional/command/upload_test.py b/conans/test/functional/command/upload_test.py
--- a/conans/test/functional/command/upload_test.py
+++ b/conans/test/functional/command/upload_test.py
@@ -55,7 +55,7 @@ def invalid_reference_error_test(self):
     def non_existing_recipe_error_test(self):
         """ Trying to upload a non-existing recipe must raise an Error
         """
-        client = TestClient()
+        client = TestClient(servers={"default": TestServer()})
         client.run("upload Pkg/0.1@user/channel", assert_error=True)
         self.assertIn("ERROR: There is no local conanfile exported as Pkg/0.1@user/channel",
                       client.user_io.out)
@@ -63,7 +63,8 @@ def non_existing_recipe_error_test(self):
     def non_existing_package_error_test(self):
         """ Trying to upload a non-existing package must raise an Error
         """
-        client = TestClient()
+        servers = {"default": TestServer()}
+        client = TestClient(servers=servers)
         client.run("upload Pkg/0.1@user/channel -p hash1", assert_error=True)
         self.assertIn("ERROR: There is no local conanfile exported as Pkg/0.1@user/channel",
                       client.user_io.out)
@@ -114,10 +115,8 @@ def query_upload_test(self):
         self.assertNotIn("Uploading package", client.user_io.out)
 
         # Check that an invalid query fails
-        try:
-            client.run("upload Hello1/*@user/testing --confirm -q 'blah blah blah'")
-        except:
-            self.assertIn("Invalid package query", client.user_io.out)
+        client.run("upload Hello1/*@user/testing --confirm -q 'blah blah blah'", assert_error=True)
+        self.assertIn("Invalid package query", client.user_io.out)
 
     def broken_sources_tgz_test(self):
         # https://github.com/conan-io/conan/issues/2854
@@ -129,7 +128,8 @@ def broken_sources_tgz_test(self):
 
         def gzopen_patched(name, mode="r", fileobj=None, compresslevel=None, **kwargs):
             raise ConanException("Error gzopen %s" % name)
-        with mock.patch('conans.client.remote_manager.gzopen_without_timestamps', new=gzopen_patched):
+        with mock.patch('conans.client.remote_manager.gzopen_without_timestamps',
+                        new=gzopen_patched):
             client.run("upload * --confirm", assert_error=True)
             self.assertIn("ERROR: Error gzopen conan_sources.tgz", client.out)
 
@@ -156,7 +156,8 @@ def gzopen_patched(name, mode="r", fileobj=None, compresslevel=None, **kwargs):
             if name == PACKAGE_TGZ_NAME:
                 raise ConanException("Error gzopen %s" % name)
             return gzopen_without_timestamps(name, mode, fileobj, compresslevel, **kwargs)
-        with mock.patch('conans.client.remote_manager.gzopen_without_timestamps', new=gzopen_patched):
+        with mock.patch('conans.client.remote_manager.gzopen_without_timestamps',
+                        new=gzopen_patched):
             client.run("upload * --confirm --all", assert_error=True)
             self.assertIn("ERROR: Error gzopen conan_package.tgz", client.out)